void MulExpr(out Expression expr, Expression leftOperand) { expr = leftOperand; while (la.kind == 47 || la.kind == 50 || la.kind == 51) { expr = new BinaryExpression(leftOperand); if (la.kind == 47) { Get(); (expr as BinaryExpression).op = BinaryOperator.Mul; } else if (la.kind == 50) { Get(); (expr as BinaryExpression).op = BinaryOperator.Div; } else { Get(); (expr as BinaryExpression).op = BinaryOperator.Rem; } expr.t = t; UnaryExpr(out (expr as BinaryExpression).rightOperand); } }
void LogExpr(out Expression expr, Expression leftOperand) { expr = null; Expression rightOperand; AddExpr(out expr, leftOperand); while (la.kind == 17 || la.kind == 18 || la.kind == 19) { expr = new BinaryExpression(expr); if (la.kind == 17) { Get(); (expr as BinaryExpression).op = BinaryOperator.And; } else if (la.kind == 18) { Get(); (expr as BinaryExpression).op = BinaryOperator.Or; } else { Get(); (expr as BinaryExpression).op = BinaryOperator.Xor; } expr.t = t; UnaryExpr(out rightOperand); AddExpr(out (expr as BinaryExpression).rightOperand, rightOperand); } }
void AddExpr(out Expression expr, Expression leftOperand) { expr = null; Expression rightOperand; MulExpr(out expr, leftOperand); while (la.kind == 40 || la.kind == 42) { expr = new BinaryExpression(expr); if (la.kind == 42) { Get(); (expr as BinaryExpression).op = BinaryOperator.Add; } else { Get(); (expr as BinaryExpression).op = BinaryOperator.Sub; } expr.t = t; UnaryExpr(out rightOperand); MulExpr(out (expr as BinaryExpression).rightOperand, rightOperand); } }
void EqExpr(out Expression expr, Expression leftOperand) { expr = null; Expression rightOperand; LogExpr(out expr, leftOperand); while (StartOf(4)) { expr = new BinaryExpression(expr); switch (la.kind) { case 33: { Get(); (expr as BinaryExpression).op = BinaryOperator.Eq; break; } case 48: { Get(); (expr as BinaryExpression).op = BinaryOperator.Neq; break; } case 34: { Get(); (expr as BinaryExpression).op = BinaryOperator.Gt; break; } case 39: { Get(); (expr as BinaryExpression).op = BinaryOperator.Lt; break; } case 35: { Get(); (expr as BinaryExpression).op = BinaryOperator.Geq; break; } case 49: { Get(); (expr as BinaryExpression).op = BinaryOperator.Leq; break; } } expr.t = t; UnaryExpr(out rightOperand); LogExpr(out (expr as BinaryExpression).rightOperand, rightOperand); } }
/// <summary> /// Emits code for this statement /// </summary> /// <param name="ilGen">IL generator object</param> /// <param name="scope">The scope of this statement</param> public override void EmitCode(ILGenerator ilGen, Scope scope) { // Define labels Label loopLabel = ilGen.DefineLabel(); Label endLabel = ilGen.DefineLabel(); // Call EmitAssignement for parameter, assigning it the initial expression (variable as AssignableExpression).EmitAssignement(ilGen, scope, initial); // Mark beginning of loop ilGen.MarkLabel(loopLabel); // Emit parameter code (load value onto the stack) variable.EmitCode(ilGen, scope); // Emit final expression (load expression value onto the stack) final.EmitCode(ilGen, scope); // If parameter is increased if (direction == ForDirection.Up) { // If parameter is greater than final, jump to the end of the statement ilGen.Emit(OpCodes.Bgt, endLabel); } // If parameter is decreased else { // If parameter is less than final, jump to the end of the statement ilGen.Emit(OpCodes.Blt, endLabel); } // Emit code for repetitive statement body.EmitCode(ilGen, scope); // Increment or decrement parameter: // Create a new binary expression with the parameter as left operand BinaryExpression step = new BinaryExpression(variable); // If parameter is increasing, operator is Add, if it is decreasing, operator is Sub step.op = direction == ForDirection.Up ? BinaryOperator.Add : BinaryOperator.Sub; // Right operand is 1 step.rightOperand = new ConstantExpression(Primitive.Int, "1"); // Emit assignement - parameter is assigned the result of the binary expression (variable as AssignableExpression).EmitAssignement(ilGen, scope, step); // Emit unconditional break to beginning of loop ilGen.Emit(OpCodes.Br, loopLabel); // Mark end label ilGen.MarkLabel(endLabel); }