public void CompileDoWhileStatement(SyntaxTreeNode node) { string beginLabel = builder.CurrentMethod.NextLabel; PushNewTable(); CompileNode(node[1]); InterBranch checkBranch = new InterBranch(ToIntermediateExpression(node[0]), InterBranch.BranchCondition.OnTrue); checkBranch.SetLabel(beginLabel); builder.AddInstruction(checkBranch); string endLabel = builder.CurrentMethod.NextLabel; foreach (var b in builder.GetBreaks()) { b.SetLabel(endLabel); } foreach (var c in builder.GetContinues()) { c.SetLabel(beginLabel); } Tables.Pop(); }
public void AddBreakStatement() { var b = new InterBranch(); AddInstruction(b); _breakInstructions.Add(b); }
public void AddContinueStatement() { var b = new InterBranch(); AddInstruction(b); _continueInstructions.Add(b); }
public void CompileIfStatement(SyntaxTreeNode node) { InterBranch branch = new InterBranch(ToIntermediateExpression(node[0]), InterBranch.BranchCondition.OnFalse); PushNewTable(); builder.AddInstruction(branch); CompileNode(node[1]); branch.SetLabel(builder.CurrentMethod.NextLabel); Tables.Pop(); }
public void CompileForStatement(SyntaxTreeNode node) { PushNewTable(); if (node[0].Op != "Empty") { CompileNode(node[0]); } InterBranch initialBranch = new InterBranch(); builder.AddInstruction(initialBranch); string beginLabel = builder.CurrentMethod.NextLabel; if (node[3].Op != "Empty") { CompileNode(node[3]); } string continueLabel = builder.CurrentMethod.NextLabel; if (node[2].Op != "Empty") { CompileStatementExpressionList(node[2]); } initialBranch.SetLabel(builder.CurrentMethod.NextLabel); InterBranch checkBranch = new InterBranch(ToIntermediateExpression(node[1]), InterBranch.BranchCondition.OnTrue); checkBranch.SetLabel(beginLabel); builder.AddInstruction(checkBranch); string endLabel = builder.CurrentMethod.NextLabel; foreach (var b in builder.GetBreaks()) { b.SetLabel(endLabel); } foreach (var c in builder.GetContinues()) { c.SetLabel(continueLabel); } Tables.Pop(); }
public void CompileTryBlock(SyntaxTreeNode node) { List <InterBranch> exits = new List <InterBranch>(); void StartTryBlock() { builder.AddInstruction(new InterBlock(".try")); } void EndTryBlock() { InterBranch b1 = new InterBranch(InterBranch.BranchCondition.Leave); exits.Add(b1); builder.AddInstruction(b1); builder.AddInstruction(new InterBlock()); } bool hasFinally = node.Children.Length > 2; if (hasFinally) { StartTryBlock(); } StartTryBlock(); CompileNode(node[0]); EndTryBlock(); foreach (var c in node[1].Children) { bool hasException = c.Children.Length > 1; TypeName exceptionType = hasException ? TypeNameFromNode(c[1]) : TypeName.Unknown; PushNewTable(); if (hasException) { var loc = builder.AddLocal(c[2].ValueString, exceptionType); builder.AddInstruction(new InterCopy(loc, new InterOpValue(new InterBlock("catch", exceptionType)))); } else { builder.AddInstruction(new InterBlock(".catch")); } CompileNode(c[0]); InterBranch b = new InterBranch(InterBranch.BranchCondition.Leave); exits.Add(b); builder.AddInstruction(b); Tables.Pop(); builder.AddInstruction(new InterBlock()); } if (hasFinally) { EndTryBlock(); builder.AddInstruction(new InterBlock("finally")); CompileNode(node[2][0]); builder.AddInstruction(new InterEndFinally()); builder.AddInstruction(new InterBlock()); } string exitLabel = builder.CurrentMethod.NextLabel; foreach (var b in exits) { b.SetLabel(exitLabel); } }
public void CompileSwitchStatement(SyntaxTreeNode node) { var exp = ToIntermediateExpression(node[0]); var loc = builder.AddLocal("switchLocl" + builder.CurrentMethod.Locals.Count, exp); builder.AddInstruction(new InterCopy(loc, exp)); InterBranch[] branches = new InterBranch[node[1].Children.Length]; SyntaxTreeNode defaultCase = null; InterBranch defaultBranch = null; for (int i = 0; i < branches.Length; i++) { var sect = node[1][i]; if (sect[0].Op == "DefaultLabel") { defaultCase = sect; continue; } var bin = new InterBinOp(new Operator(Operator.OperatorType.Ceq), ToIntermediateExpression(sect[0][0]), loc); var branch = new InterBranch(new InterOpValue(bin), InterBranch.BranchCondition.OnTrue); builder.AddInstruction(branch); branches[i] = branch; } if (defaultCase == null) { builder.AddBreakStatement(); } else { defaultBranch = new InterBranch(); builder.AddInstruction(defaultBranch); } for (int i = 0; i < branches.Length; i++) { var sect = node[1][i]; if (sect[0].Op == "DefaultLabel") { continue; } string label = builder.CurrentMethod.NextLabel; CompileNode(sect[1]); branches[i].SetLabel(label); } if (defaultCase != null) { string defaultLabel = builder.CurrentMethod.NextLabel; CompileNode(defaultCase[1]); defaultBranch.SetLabel(defaultLabel); } string endLabel = builder.CurrentMethod.NextLabel; foreach (var b in builder.GetBreaks()) { b.SetLabel(endLabel); } }
public void CompileForEachStatement(SyntaxTreeNode node) { PushNewTable(); var enumerable = ToIntermediateExpression(node[2]); var typeVal = new GenericParamValue(enumerable); var enumCall = new InterPushEnumerator(enumerable, typeVal); var enumVal = new InterOpValue(enumCall); var enumerator = builder.AddLocal("loc_" + builder.CurrentMethod.Locals.Count, enumVal); builder.AddInstruction(new InterCopy(enumerator, enumVal)); InterBranch initialBranch = new InterBranch(); var loc = builder.AddLocal(node[1].ValueString, typeVal); builder.AddInstruction(new InterBlock(".try")); builder.AddInstruction(initialBranch); string beginLabel = builder.CurrentMethod.NextLabel; builder.AddInstruction(new InterCopy(loc, new InterOpValue(new InterCall("get_Current", new CodeValue[0], true, enumerator)))); CompileNode(node[3]); var continueLabel = builder.CurrentMethod.NextLabel; initialBranch.SetLabel(continueLabel); var moveCall = new InterCall("MoveNext", new CodeValue[0], true, enumerator) { ThisPointerTypeNameOverride = new BasicTypeName("System.Collections.IEnumerator", new ResolutionContext()) }; InterBranch checkBranch = new InterBranch(new InterOpValue(moveCall), InterBranch.BranchCondition.OnTrue); checkBranch.SetLabel(beginLabel); builder.AddInstruction(checkBranch); InterBranch tryLeave = (InterBranch)builder.AddInstruction(new InterBranch(InterBranch.BranchCondition.Leave)); builder.AddInstruction(new InterBlock()); builder.AddInstruction(new InterBlock("finally")); builder.AddInstruction(new InterCall("Dispose", new CodeValue[0], false, enumerator) { ThisPointerTypeNameOverride = new BasicTypeName("System.IDisposable") }); builder.AddInstruction(new InterEndFinally()); builder.AddInstruction(new InterBlock()); string endLabel = builder.CurrentMethod.NextLabel; tryLeave.SetLabel(endLabel); foreach (var b in builder.GetBreaks()) { b.SetLabel(endLabel); } foreach (var c in builder.GetContinues()) { c.SetLabel(continueLabel); } Tables.Pop(); }