RelationalExpression
using CLanguage.Interpreter;
using CLanguage.Types;
using System;
namespace CLanguage.Syntax
{
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;
CBasicType 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)(68 + instructionOffset));
break;
case RelationalOp.NotEquals:
ec.Emit((OpCode)(68 + instructionOffset));
ec.Emit(OpCode.LogicalNot);
break;
case RelationalOp.LessThan:
ec.Emit((OpCode)(78 + instructionOffset));
break;
case RelationalOp.LessThanOrEqual:
ec.Emit((OpCode)(88 + instructionOffset));
ec.Emit(OpCode.LogicalNot);
break;
case RelationalOp.GreaterThan:
ec.Emit((OpCode)(88 + instructionOffset));
break;
case RelationalOp.GreaterThanOrEqual:
ec.Emit((OpCode)(78 + instructionOffset));
ec.Emit(OpCode.LogicalNot);
break;
default:
throw new NotSupportedException("Unsupported relational operator '" + Op + "'");
}
}
public override CType GetEvaluatedCType(EmitContext ec)
{
return CBasicType.Bool;
}
public override string ToString()
{
return $"""{Left}""{Op}""{Right}""";
}
}
}