IFPSTools.NET/LibIFPSCC/AST/AssignmentOperators.cs
zc e16c00799d ifpscc: initial commit
libifpscc: initial commit
readme: document ifpscc/libifpscc
license: add credits for ifpscc/libifpscc (derived from code also MIT licensed)
libifps: make additional fields/types public for libifpscc
libifps: fix field documentation for some opcodes
libifps: fix loading functions that are not exported
libifps: allow saving a nonexistant primitive type if the same primitive type was added already
libifps: fix parsing Extended constants
libifps: fix ushort/short being mapped to the wrong types in one table
csproj: set Prefer32Bit=false for release builds
2023-03-28 17:24:19 +01:00

151 lines
5.2 KiB
C#

namespace AST {
using static SemanticAnalysis;
/// <summary>
/// Assignment: Left = Right
/// </summary>
/// <remarks>
/// Left must be a lvalue, but this check is left to the cgen phase.
/// </remarks>
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);
}
}
/// <summary>
/// Assignment operator
/// </summary>
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);
}
/// <summary>
/// MultAssign: a *= b
/// </summary>
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);
}
/// <summary>
/// DivAssign: a /= b
/// </summary>
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);
}
/// <summary>
/// ModAssign: a %= b
/// </summary>
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);
}
/// <summary>
/// AddAssign: a += b
/// </summary>
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);
}
/// <summary>
/// SubAssign: a -= b
/// </summary>
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);
}
/// <summary>
/// LShiftAssign: a &lt;&lt;= b
/// </summary>
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);
}
/// <summary>
/// RShiftAssign: a >>= b
/// </summary>
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);
}
/// <summary>
/// BitwiseAndAssign: a &= b
/// </summary>
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);
}
/// <summary>
/// XorAssign: a ^= b
/// </summary>
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);
}
/// <summary>
/// BitwiseOrAssign: a |= b
/// </summary>
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);
}
}