Expression
using CLanguage.Compiler;
using CLanguage.Types;
using System;
using System.Runtime.CompilerServices;
namespace CLanguage.Syntax
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public abstract class Expression
{
public Location Location { get; set; }
public Location EndLocation { 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, "'" + op + "' cannot be applied to operand of type '" + evaluatedCType?.ToString() + "'");
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, "'" + op + "' cannot be applied to operands of type '" + evaluatedCType?.ToString() + "' and '" + evaluatedCType2?.ToString() + "'");
return CBasicType.SignedInt;
}
return cBasicType.ArithmeticConvert(cBasicType2, ec);
}
public virtual Value EvalConstant(EmitContext ec)
{
ec.Report.Error(133, $"""{this}""");
return 0;
}
}
}