Expression
using CLanguage.Interpreter;
using CLanguage.Types;
using System;
namespace CLanguage.Syntax
{
public abstract class Expression
{
public Location Location { get; set; }
public bool HasError { get; set; }
public void Emit(EmitContext ec)
{
DoEmit(ec);
}
public void EmitPointer(EmitContext ec)
{
DoEmitPointer(ec);
}
public abstract CType GetEvaluatedCType(EmitContext ec);
protected abstract void DoEmit(EmitContext ec);
protected virtual void DoEmitPointer(EmitContext ec)
{
throw new NotSupportedException($"""{GetType().Name}""{this}""");
}
protected static CBasicType GetPromotedType(Expression expr, string op, EmitContext ec)
{
CType evaluatedCType = expr.GetEvaluatedCType(ec);
CBasicType cBasicType = evaluatedCType as CBasicType;
if (cBasicType == null) {
ec.Report.Error(19, "Operator '" + op + "' cannot be applied to operand of type '" + evaluatedCType + "'");
return CBasicType.SignedInt;
}
return cBasicType.IntegerPromote(ec);
}
protected static CBasicType GetArithmeticType(Expression leftExpr, Expression rightExpr, string op, EmitContext ec)
{
CType evaluatedCType = leftExpr.GetEvaluatedCType(ec);
CType evaluatedCType2 = rightExpr.GetEvaluatedCType(ec);
CBasicType cBasicType = evaluatedCType as CBasicType;
CBasicType cBasicType2 = evaluatedCType2 as CBasicType;
if (cBasicType == null || cBasicType2 == null) {
ec.Report.Error(19, "Operator '" + op + "' cannot be applied to operands of type '" + evaluatedCType + "' and '" + evaluatedCType2 + "'");
return CBasicType.SignedInt;
}
return cBasicType.ArithmeticConvert(cBasicType2, ec);
}
}
}