CLanguage by praeclarum

<PackageReference Include="CLanguage" Version="0.15.30" />

 BinaryExpression

public class BinaryExpression : Expression
using CLanguage.Compiler; using CLanguage.Interpreter; using CLanguage.Types; using System; using System.Runtime.CompilerServices; namespace CLanguage.Syntax { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public class BinaryExpression : Expression { public Expression Left { get; set; } public Binop Op { get; set; } public Expression Right { get; set; } public BinaryExpression(Expression left, Binop op, Expression right) { if (left == null) throw new ArgumentNullException("left"); if (right == null) throw new ArgumentNullException("right"); Left = left; Op = op; Right = right; } protected override void DoEmit(EmitContext ec) { Expression left = Left; Expression right = Right; Binop op = Op; CType arithmeticType = Expression.GetArithmeticType(left, right, op.ToString(), ec); Left.Emit(ec); ec.EmitCast(Left.GetEvaluatedCType(ec), arithmeticType); Right.Emit(ec); ec.EmitCast(Right.GetEvaluatedCType(ec), arithmeticType); int instructionOffset = ec.GetInstructionOffset(arithmeticType); op = Op; switch (op) { case Binop.Add: ec.Emit((OpCode)(18 + instructionOffset)); break; case Binop.Subtract: ec.Emit((OpCode)(28 + instructionOffset)); break; case Binop.Multiply: ec.Emit((OpCode)(38 + instructionOffset)); break; case Binop.Divide: ec.Emit((OpCode)(48 + instructionOffset)); break; case Binop.Mod: ec.Emit((OpCode)(78 + instructionOffset)); break; case Binop.BinaryAnd: ec.Emit((OpCode)(118 + instructionOffset)); break; case Binop.BinaryOr: ec.Emit((OpCode)(128 + instructionOffset)); break; case Binop.BinaryXor: ec.Emit((OpCode)(138 + instructionOffset)); break; case Binop.ShiftLeft: ec.Emit((OpCode)(58 + instructionOffset)); break; case Binop.ShiftRight: ec.Emit((OpCode)(68 + instructionOffset)); break; default: throw new NotSupportedException("Unsupported binary operator '" + Op.ToString() + "'"); } } public override CType GetEvaluatedCType(EmitContext ec) { return Expression.GetArithmeticType(Left, Right, Op.ToString(), ec); } public override string ToString() { return string.Format("({0} {1} {2})", new object[3] { Left, Op, Right }); } public override Value EvalConstant(EmitContext ec) { CType evaluatedCType = Left.GetEvaluatedCType(ec); CType evaluatedCType2 = Right.GetEvaluatedCType(ec); if (evaluatedCType.IsIntegral && evaluatedCType2.IsIntegral) { int num = (int)Left.EvalConstant(ec); int num2 = (int)Right.EvalConstant(ec); switch (Op) { case Binop.Add: return num + num2; case Binop.Subtract: return num - num2; case Binop.Multiply: return num * num2; case Binop.Divide: return num / num2; case Binop.Mod: return num % num2; case Binop.BinaryAnd: return num & num2; case Binop.BinaryOr: return num | num2; case Binop.BinaryXor: return num ^ num2; case Binop.ShiftLeft: return num << num2; case Binop.ShiftRight: return num >> num2; default: throw new NotSupportedException("Unsupported binary operator '" + Op.ToString() + "'"); } } return base.EvalConstant(ec); } } }