public static void GenerateCode(ElseIfHeader header, GeneratorContext builder) { string currentEndLabel = builder.DeclareLabel("endElif"); builder.AddCode(header.Condition); builder.AddOp(new JumpLabelConditionalNegated(currentEndLabel), header.IfToken); foreach (Expression statement in header.ParentBlockHint.Statements) { builder.AddCode(statement); } string finalEndLabel = header.EndLabelHint; if (finalEndLabel == null) { throw new Exception("Encountered ElseIf Header without an end label!"); } if (header.NextConditionalComponentHint == null) { builder.SetLabelToNext(finalEndLabel); if (header.RequiresScopeHint) { builder.AddOp(new ScopeEnd(), header.ParentBlockHint.EndToken); } } else { builder.AddOp(new JumpLabel(finalEndLabel)); } builder.SetLabelToNext(currentEndLabel); }
public static void GenerateCode(VariableAssignment assignment, GeneratorContext builder) { if (assignment.IsDeclaration) { if (assignment.HasValue) { builder.AddCode(assignment.Value); } else { builder.AddOp(new LiteralValue(assignment.DeclarationType.Default()), assignment.TypeToken); } builder.AddOp(new VariableCreate(assignment.Name), assignment.NameToken); } else { if (assignment.Indices.Count > 1) { throw new NotImplementedException("Only one level of indexing is supported at the moment"); } if (assignment.BuiltInFunctionHint != null) { if (assignment.Indices.Count == 0) { builder.AddOp(new VariableGet(assignment.Name), assignment.NameToken); } else { builder.AddOp(new VariableGet(assignment.Name)); builder.AddCode(assignment.Indices[0].Index); builder.AddOp(new ArrayElementGet()); } } if (assignment.Value != null) { builder.AddCode(assignment.Value); } if (assignment.BuiltInFunctionHint != null) { builder.AddOp(new CallBuiltIn(assignment.BuiltInFunctionHint), assignment.OperatorToken); } if (assignment.Indices.Count == 0) { builder.AddOp(new VariableSet(assignment.Name), assignment.NameToken); } else { builder.AddCode(assignment.Indices[0].Index); builder.AddOp(new ArrayElementSet(assignment.Name), assignment.NameToken); } } }
public static void GenerateCode(OperatorCall call, GeneratorContext builder) { if (call.LeftInput != null) { builder.AddCode(call.LeftInput); } if (call.RightInput != null) { builder.AddCode(call.RightInput); } builder.AddOp(new CallBuiltIn(call.BuiltInFunctionHint), call.OperatorToken); }
public static void GenerateCode(Block block, GeneratorContext builder) { builder.AddComment("Begin " + block.Header.FriendlyBlockName); builder.AddCode(block.Header); builder.AddComment("End " + block.Header.FriendlyBlockName); }
public static void GenerateCode(IfHeader header, GeneratorContext builder) { if (header.RequiresScopeHint) { builder.AddOp(new ScopeBegin(), header.IfToken); } string currentEndLabel = builder.DeclareLabel("endIf"); string finalEndLabel = null; if (header.NextConditionalComponentHint != null) { finalEndLabel = builder.DeclareLabel("endConditional"); } builder.AddCode(header.Condition); builder.AddOp(new JumpLabelConditionalNegated(currentEndLabel), header.IfToken); foreach (Expression statement in header.ParentBlockHint.Statements) { builder.AddCode(statement); } if (header.NextConditionalComponentHint != null) { IConditionalSubComponent current = header.NextConditionalComponentHint; while (current != null) { current.EndLabelHint = finalEndLabel; current = current.NextConditionalComponentHint; } builder.AddOp(new JumpLabel(finalEndLabel)); } builder.SetLabelToNext(currentEndLabel); if (header.NextConditionalComponentHint == null && header.RequiresScopeHint) { builder.AddOp(new ScopeEnd(), header.ParentBlockHint.EndToken); } }
public static void GenerateCode(Expressions.Types.Return statement, GeneratorContext builder) { if (statement.HasValue) { builder.AddCode(statement.Value); } builder.AddOp(new Types.Return(), statement.ReturnToken); }
public static void GenerateCode(LiteralArrayGet literal, GeneratorContext builder) { foreach (Expression element in literal.Elements) { builder.AddCode(element); } builder.AddOp(new ArrayValue(literal.Elements.Count), literal.StartToken); }
public static void GenerateCode(FunctionHeader header, GeneratorContext builder) { foreach (string name in header.ParameterNames.Reverse()) { builder.AddOp(new VariableCreate(name), header.NameToken); } foreach (Expression statement in header.ParentBlockHint.Statements) { builder.AddCode(statement); } // This is hacky, and might be cleaned up someday List <Op> sheet = builder.Operations; bool returnMissing = sheet.Count == 0 || !(sheet[^ 1] is Types.Return);
public static void GenerateCode(FunctionCall call, GeneratorContext builder) { foreach (Expression arg in call.Arguments) { builder.AddCode(arg); } if (call.BuiltInFunctionHint != null) { builder.AddOp(new CallBuiltIn(call.BuiltInFunctionHint), call.NameToken); } else { builder.AddOp(new Call(call.UserFunctionHint), call.NameToken); } }
public static void GenerateCode(ElseHeader header, GeneratorContext builder) { foreach (Expression statement in header.ParentBlockHint.Statements) { builder.AddCode(statement); } string conditionalEndLabel = header.EndLabelHint; if (conditionalEndLabel == null) { throw new Exception("Encountered Else Header without an end label!"); } builder.SetLabelToNext(conditionalEndLabel); if (header.RequiresScopeHint) { builder.AddOp(new ScopeEnd(), header.ParentBlockHint.EndToken); } }
public static void GenerateCode(Indexer indexer, GeneratorContext builder) { builder.AddCode(indexer.SourceExpression); builder.AddCode(indexer.IndexExpression); builder.AddOp(new ArrayElementGet(), indexer.OpeningBracket); }
public static void GenerateCode(LoopHeader header, GeneratorContext builder) { bool requiresOuterScope = !header.IsInfinite; bool requiresInnerScope = header.RequiresScopeHint; if (requiresOuterScope) { builder.AddOp(new ScopeBegin(), header.LoopToken); } string endLabel = builder.DeclareLabel("LoopEnd"); builder.BreakLabels.Push(endLabel); string continueLabel = builder.DeclareLabel("LoopContinue"); builder.ContinueLabels.Push(continueLabel); string indexName = null; if (header.IsInfinite) { builder.SetLabelToNext(continueLabel); } else if (header.IsRange) { builder.PushIndex(); indexName = header.Name; // For the end expression, don't use a variable if a literal could be used instead // Actually, it would be better if this were generalized to statements that translate to a single // op, but that is an optimization for another day. Op endOp; if (header.RangeEnd is LiteralGet end) { endOp = new LiteralValue(end.Value); } else { string endName = builder.GetIndexedName("end"); builder.AddCode(header.RangeEnd); builder.AddOp(new VariableCreate(endName), header.LoopToken); endOp = new VariableGet(endName); } builder.AddCode(header.RangeStart); builder.AddOp(new VariableCreate(indexName), header.NameToken); builder.SetLabelToNext(continueLabel); builder.AddOp(new VariableGet(indexName), header.NameToken); builder.AddOp(endOp); builder.AddOp(new GreaterThan(), header.FromToken); builder.AddOp(new JumpLabelConditional(endLabel), header.FromToken); } else { builder.PushIndex(); indexName = builder.GetIndexedName("index"); string arrayName = builder.GetIndexedName("array"); string countName = builder.GetIndexedName("count"); string currentName = header.Name ?? "@"; builder.AddCode(header.Array); builder.AddOp(new VariableCreate(arrayName), header.LoopToken); builder.AddOp(new ArrayCount(arrayName), header.LoopToken); builder.AddOp(new VariableCreate(countName), header.LoopToken); builder.AddOp(new LiteralValue(new SprakNumber(0)), header.LoopToken); builder.AddOp(new VariableCreate(indexName), header.LoopToken); builder.AddOp(new LiteralValue(SprakUnit.Value), header.LoopToken); builder.AddOp(new VariableCreate(currentName), header.LoopToken); builder.SetLabelToNext(continueLabel); builder.AddOp(new VariableGet(indexName), header.LoopToken); builder.AddOp(new VariableGet(countName), header.LoopToken); builder.AddOp(new GreaterThanOrEqualTo(), header.LoopToken); builder.AddOp(new JumpLabelConditional(endLabel), header.LoopToken); builder.AddOp(new VariableGet(arrayName), header.InToken); builder.AddOp(new VariableGet(indexName), header.InToken); builder.AddOp(new ArrayElementGet(), header.InToken); builder.AddOp(new VariableSet(currentName), header.InToken); builder.AddOp(new Increment(indexName), header.InToken); }; // This is used by the continue command, currently. header.IndexNameHint = indexName; if (requiresInnerScope) { builder.AddOp(new ScopeBegin(), header.LoopToken); } foreach (Expression statement in header.ParentBlockHint.Statements) { builder.AddCode(statement); } if (requiresInnerScope) { builder.AddOp(new ScopeEnd(), header.EndToken); } if (header.IsRange) { builder.AddOp(new Increment(indexName), header.EndToken); } builder.AddOp(new JumpLabel(continueLabel), header.EndToken); builder.SetLabelToNext(endLabel); if (!header.IsInfinite) { builder.PopIndex(); } if (requiresOuterScope) { builder.AddOp(new ScopeEnd(), header.EndToken); } builder.BreakLabels.Pop(); builder.ContinueLabels.Pop(); }
public static void GenerateCode(Group group, GeneratorContext builder) { builder.AddCode(group.Value); }