private void Run(ProgramNode program, EbiScope scope) { foreach (var(node, i) in program.Nodes.Select((node, i) => (node, i))) { Evaluate(scope, node); } }
public void Run(ProgramNode program) { if (!configuration.PersistContext) { globalScope = EbiScope.CreateGlobalScope(); } Run(program, globalScope); }
private EbiValueBase Evaluate(EbiScope scope, ExpressionNode expr) { return(expr switch { LiteralNode l => l.Value, IdentifierNode id => scope[id.Name]?.Value ?? throw new RuntimeException($"No such identifier named '{id.Name}'"), CallExpressionNode call => Evaluate(scope, call), UnaryExpressionNode un => Evaluate(scope, un), BinaryExpressionNode bin => Evaluate(scope, bin), _ => new EbiNull(), });
private void Evaluate(EbiScope scope, StatementNode statement) { switch (statement) { case ExpressionStatementNode expr: Evaluate(scope, expr.Expression); break; case BlockStatementNode block: Run(block.Statements, new EbiScope(scope)); break; case RepeatStatementNode repeat: try { while (true) { Evaluate(scope, repeat.Statement); } } catch (BreakException) { } catch (ContinueException) { // TODO: ここだけじゃないけど、現在の実装だとあっという間にstackoverflowになってしまうので実装法を考え直したい Evaluate(scope, repeat); } break; case BreakStatementNode: throw new BreakException(); case ContinueStatementNode: throw new ContinueException(); } ; }