ShintenScript/ASTNodeBlock.cs

97 lines
3.0 KiB
C#
Raw Permalink Normal View History

2023-02-02 14:05:53 +00:00
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();
}
}
}