namespace AST {
using static SemanticAnalysis;
///
/// Assignment: Left = Right
///
///
/// Left must be a lvalue, but this check is left to the cgen phase.
///
public sealed class Assignment : Expr {
private Assignment(Expr left, Expr right) {
this.Left = left;
this.Right = right;
}
public Expr Left { get; }
public Expr Right { get; }
public static Expr Create(Expr left, Expr right) =>
new Assignment(left, right);
protected override ABT.Expr GetExprImpl(ABT.Env env, ILineInfo info)
{
var left = SemantExpr(this.Left, ref env);
var right = SemantExpr(this.Right, ref env);
right = ABT.TypeCast.MakeCast(right, left.Type);
return new ABT.Assign(left, right);
}
}
///
/// Assignment operator
///
public abstract class AssignOp : Expr {
protected AssignOp(Expr left, Expr right) {
this.Left = left;
this.Right = right;
}
public Expr Left { get; }
public Expr Right { get; }
public abstract Expr ConstructBinaryOp();
protected override sealed ABT.Expr GetExprImpl(ABT.Env env, ILineInfo info) =>
Assignment.Create(this.Left, ConstructBinaryOp()).GetExpr(env, info);
}
///
/// MultAssign: a *= b
///
public sealed class MultAssign : AssignOp {
private MultAssign(Expr left, Expr right)
: base(left, right) { }
public static Expr Create(Expr left, Expr right) => new MultAssign(left, right);
public override Expr ConstructBinaryOp() => Multiply.Create(this.Left, this.Right);
}
///
/// DivAssign: a /= b
///
public sealed class DivAssign : AssignOp {
private DivAssign(Expr left, Expr right)
: base(left, right) { }
public static Expr Create(Expr left, Expr right) => new DivAssign(left, right);
public override Expr ConstructBinaryOp() => Divide.Create(this.Left, this.Right);
}
///
/// ModAssign: a %= b
///
public sealed class ModAssign : AssignOp {
private ModAssign(Expr left, Expr right)
: base(left, right) { }
public static Expr Create(Expr left, Expr right) => new ModAssign(left, right);
public override Expr ConstructBinaryOp() => Modulo.Create(this.Left, this.Right);
}
///
/// AddAssign: a += b
///
public sealed class AddAssign : AssignOp {
private AddAssign(Expr left, Expr right)
: base(left, right) { }
public static Expr Create(Expr left, Expr right) => new AddAssign(left, right);
public override Expr ConstructBinaryOp() => Add.Create(this.Left, this.Right);
}
///
/// SubAssign: a -= b
///
public sealed class SubAssign : AssignOp {
private SubAssign(Expr left, Expr right)
: base(left, right) { }
public static Expr Create(Expr left, Expr right) => new SubAssign(left, right);
public override Expr ConstructBinaryOp() => Sub.Create(this.Left, this.Right);
}
///
/// LShiftAssign: a <<= b
///
public sealed class LShiftAssign : AssignOp {
private LShiftAssign(Expr left, Expr right)
: base(left, right) { }
public static Expr Create(Expr left, Expr right) => new LShiftAssign(left, right);
public override Expr ConstructBinaryOp() => LShift.Create(this.Left, this.Right);
}
///
/// RShiftAssign: a >>= b
///
public sealed class RShiftAssign : AssignOp {
private RShiftAssign(Expr left, Expr right)
: base(left, right) { }
public static Expr Create(Expr left, Expr right) => new RShiftAssign(left, right);
public override Expr ConstructBinaryOp() => RShift.Create(this.Left, this.Right);
}
///
/// BitwiseAndAssign: a &= b
///
public sealed class BitwiseAndAssign : AssignOp {
private BitwiseAndAssign(Expr left, Expr right)
: base(left, right) { }
public static Expr Create(Expr left, Expr right) => new BitwiseAndAssign(left, right);
public override Expr ConstructBinaryOp() => BitwiseAnd.Create(this.Left, this.Right);
}
///
/// XorAssign: a ^= b
///
public sealed class XorAssign : AssignOp {
private XorAssign(Expr left, Expr right)
: base(left, right) { }
public static Expr Create(Expr left, Expr right) => new XorAssign(left, right);
public override Expr ConstructBinaryOp() => Xor.Create(this.Left, this.Right);
}
///
/// BitwiseOrAssign: a |= b
///
public sealed class BitwiseOrAssign : AssignOp {
private BitwiseOrAssign(Expr left, Expr right)
: base(left, right) { }
public static Expr Create(Expr left, Expr right) => new BitwiseOrAssign(left, right);
public override Expr ConstructBinaryOp() => BitwiseOr.Create(this.Left, this.Right);
}
}