public InterOp CompileAssignExpression(SyntaxTreeNode node) { CodeSymbol symbol = ToIntermediateExpression(node[0]) as CodeSymbol; InterCopy copy; CodeValue source; if (node[2].ValueString == "None") { source = ToIntermediateExpression(node[1]); } else { var i = new InterBinOp(Operator.FromName(node[2].ValueString), symbol, ToIntermediateExpression(node[1])); source = new InterOpValue(i, builder.CurrentMethod); } if (symbol == null) { copy = new InterCopy(new LateReferenceResolver(node[0], builder.CurrentType.NamespaceContext), source); } else { copy = new InterCopy(symbol, source); } copy.SetOwner(builder.CurrentMethod); return(copy); }
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(); }