BinaryExpression
using CLanguage.Interpreter;
using CLanguage.Types;
using System;
namespace CLanguage.Syntax
{
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;
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 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)(58 + instructionOffset));
break;
default:
throw new NotSupportedException("Unsupported binary operator '" + Op + "'");
}
}
public override CType GetEvaluatedCType(EmitContext ec)
{
return Expression.GetArithmeticType(Left, Right, Op.ToString(), ec);
}
public override string ToString()
{
return $"""{Left}""{Op}""{Right}""";
}
}
}