public override void VisitCycleNode(CycleNode c) { var i = genc.DeclareLocal(typeof(int)); // переменная цикла cycle c.Expr.Visit(this); // сгенерировать команды, связанные с вычислением количества итераций цикла genc.Emit(OpCodes.Stloc, i); // i := кво итераций Label startLoop = genc.DefineLabel(); Label endLoop = genc.DefineLabel(); genc.MarkLabel(startLoop); genc.Emit(OpCodes.Ldloc, i); genc.Emit(OpCodes.Ldc_I4_0); genc.Emit(OpCodes.Ble, endLoop); // if i<=0 then goto endLoop c.Stat.Visit(this); // выполнить тело цикла genc.Emit(OpCodes.Ldloc, i); // положить i на стек genc.Emit(OpCodes.Ldc_I4_1); // положить 1 на стек genc.Emit(OpCodes.Sub); genc.Emit(OpCodes.Stloc, i); // i := i - 1; genc.Emit(OpCodes.Br, startLoop); genc.MarkLabel(endLoop); }
public override void VisitBinOpNode(BinOpNode binop) { binop.Left.Visit(this); binop.Right.Visit(this); switch (binop.Op) { case '+': genc.Emit(OpCodes.Add); break; case '-': genc.Emit(OpCodes.Sub); break; case '*': genc.Emit(OpCodes.Mul); break; case '/': genc.Emit(OpCodes.Div); break; case '%': LocalBuilder x = genc.DeclareLocal(typeof(int)); LocalBuilder y = genc.DeclareLocal(typeof(int)); LocalBuilder temp = genc.DeclareLocal(typeof(int)); genc.Emit(OpCodes.Stloc, y); genc.Emit(OpCodes.Stloc, x); genc.Emit(OpCodes.Ldloc, x); genc.Emit(OpCodes.Ldloc, y); genc.Emit(OpCodes.Div); genc.Emit(OpCodes.Ldloc, y); genc.Emit(OpCodes.Mul); genc.Emit(OpCodes.Stloc, y); genc.Emit(OpCodes.Ldloc, x); genc.Emit(OpCodes.Ldloc, y); genc.Emit(OpCodes.Sub); break; } }