CLanguage by praeclarum

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

 RelationalExpression

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 RelationalExpression : Expression { public Expression Left { get; set; } public RelationalOp Op { get; set; } public Expression Right { get; set; } public RelationalExpression(Expression left, RelationalOp op, Expression right) { Left = left; Op = op; Right = right; } protected override void DoEmit(EmitContext ec) { Expression left = Left; Expression right = Right; RelationalOp 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 RelationalOp.Equals: ec.Emit((OpCode)(88 + instructionOffset)); break; case RelationalOp.NotEquals: ec.Emit((OpCode)(88 + instructionOffset)); ec.Emit((OpCode)(148 + instructionOffset)); break; case RelationalOp.LessThan: ec.Emit((OpCode)(98 + instructionOffset)); break; case RelationalOp.LessThanOrEqual: ec.Emit((OpCode)(108 + instructionOffset)); ec.Emit((OpCode)(148 + instructionOffset)); break; case RelationalOp.GreaterThan: ec.Emit((OpCode)(108 + instructionOffset)); break; case RelationalOp.GreaterThanOrEqual: ec.Emit((OpCode)(98 + instructionOffset)); ec.Emit((OpCode)(148 + instructionOffset)); break; default: throw new NotSupportedException("Unsupported relational operator '" + Op.ToString() + "'"); } } 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 RelationalOp.Equals: return num == num2; case RelationalOp.NotEquals: return num != num2; case RelationalOp.LessThan: return num < num2; case RelationalOp.LessThanOrEqual: return num <= num2; case RelationalOp.GreaterThan: return num > num2; case RelationalOp.GreaterThanOrEqual: return num >= num2; default: throw new NotSupportedException("Unsupported relational operator '" + Op.ToString() + "'"); } } return base.EvalConstant(ec); } public override CType GetEvaluatedCType(EmitContext ec) { return CBasicType.Bool; } public override string ToString() { return string.Format("({0} {1} {2})", new object[3] { Left, Op, Right }); } } }