97 lines
3.0 KiB
C#
97 lines
3.0 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Linq;
|
|||
|
using System.Text;
|
|||
|
using System.Threading.Tasks;
|
|||
|
|
|||
|
namespace ShintenScript
|
|||
|
{
|
|||
|
public class ASTNodeBlock : IASTNode
|
|||
|
{
|
|||
|
public IList<IASTNode> statements;
|
|||
|
|
|||
|
public ASTNodeBlock(IList<IASTNode> statements)
|
|||
|
{
|
|||
|
this.statements = statements;
|
|||
|
}
|
|||
|
|
|||
|
bool IASTNode.Const() => false;
|
|||
|
|
|||
|
object IASTNode.CreateFunction()
|
|||
|
{
|
|||
|
SSType type = ((IASTNode)this).Type();
|
|||
|
|
|||
|
if (type == SSType.none)
|
|||
|
{
|
|||
|
List<Action<ExecutionContext>> actions = new List<Action<ExecutionContext>>();
|
|||
|
|
|||
|
foreach (IASTNode statement in statements)
|
|||
|
{
|
|||
|
object func = statement.CreateFunction();
|
|||
|
if (func is Action<ExecutionContext> action)
|
|||
|
actions.Add(action);
|
|||
|
else
|
|||
|
{
|
|||
|
Func<ExecutionContext, object> ofunc = (Func<ExecutionContext, object>)func;
|
|||
|
actions.Add(ctx => ofunc.DynamicInvoke(ctx));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return (Action<ExecutionContext>)(ctx =>
|
|||
|
{
|
|||
|
foreach (Action<ExecutionContext> action in actions)
|
|||
|
action(ctx);
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
List<Action<ExecutionContext>> actionsm1 = new List<Action<ExecutionContext>>();
|
|||
|
|
|||
|
foreach (IASTNode statement in statements)
|
|||
|
{
|
|||
|
if (actionsm1.Count == statements.Count - 1)
|
|||
|
break;
|
|||
|
|
|||
|
object func = statement.CreateFunction();
|
|||
|
if (func is Action<ExecutionContext> action)
|
|||
|
actionsm1.Add(action);
|
|||
|
else
|
|||
|
{
|
|||
|
Delegate ofunc = (Delegate)func;
|
|||
|
actionsm1.Add(ctx => ofunc.DynamicInvoke(ctx));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (type == SSType.real)
|
|||
|
{
|
|||
|
Func<ExecutionContext, float> final = (Func<ExecutionContext, float>)statements[statements.Count - 1].CreateFunction();
|
|||
|
return (Func<ExecutionContext, float>)(ctx =>
|
|||
|
{
|
|||
|
foreach (Action<ExecutionContext> action in actionsm1)
|
|||
|
action(ctx);
|
|||
|
|
|||
|
return final(ctx);
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
if (type == SSType.boolean)
|
|||
|
{
|
|||
|
Func<ExecutionContext, bool> final = (Func<ExecutionContext, bool>)statements[statements.Count - 1].CreateFunction();
|
|||
|
return (Func<ExecutionContext, bool>)(ctx =>
|
|||
|
{
|
|||
|
foreach (Action<ExecutionContext> action in actionsm1)
|
|||
|
action(ctx);
|
|||
|
|
|||
|
return final(ctx);
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
throw new Exception("This should be unreachable");
|
|||
|
}
|
|||
|
|
|||
|
SSType IASTNode.Type()
|
|||
|
{
|
|||
|
return statements[statements.Count - 1].Type();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|