IFPSTools.NET/LibIFPSCC/ABT/UnaryOperators.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

134 lines
3.6 KiB
C#

using System;
using System.Diagnostics;
using CodeGeneration;
namespace ABT {
// IncDecExpr
// |
// +-- PostIncrement, PostDecrement, PreIncrement, PreDecrement
public abstract partial class IncDecExpr : Expr {
protected IncDecExpr(Expr expr) {
if (!(expr.Type is ScalarType)) {
throw new InvalidOperationException("Only supports scalars.").Attach(expr);
}
this.Expr = expr;
}
public Expr Expr { get; }
public override Env Env => this.Expr.Env;
public override Boolean IsLValue => false;
public override ExprType Type => this.Expr.Type;
}
/// <summary>
/// Expr++: must be integral, float or pointer.
///
/// If Expr is an array, it is converted to a pointer in semantic analysis.
/// </summary>
public sealed partial class PostIncrement : IncDecExpr {
public PostIncrement(Expr expr)
: base(expr) { }
}
/// <summary>
/// Expr--: must be a scalar
/// </summary>
public sealed partial class PostDecrement : IncDecExpr {
public PostDecrement(Expr expr)
: base(expr) { }
}
/// <summary>
/// ++Expr: must be a scalar
/// </summary>
public sealed partial class PreIncrement : IncDecExpr {
public PreIncrement(Expr expr)
: base(expr) { }
}
/// <summary>
/// --Expr: must be a scalar
/// </summary>
public sealed partial class PreDecrement : IncDecExpr {
public PreDecrement(Expr expr)
: base(expr) { }
}
public abstract partial class UnaryArithOp : Expr {
protected UnaryArithOp(Expr expr) {
this.Expr = expr;
}
public Expr Expr { get; }
public override Env Env => this.Expr.Env;
public override Boolean IsLValue => false;
public override abstract ExprType Type { get; }
}
/// <summary>
/// -Expr: only takes arithmetic Type.
///
/// After semantic analysis, only the following 4 types are possible:
/// 1) long
/// 2) ulong
/// 3) float
/// 4) double
/// </summary>
public sealed partial class Negative : UnaryArithOp {
public Negative(Expr expr)
: base(expr) { }
public override ExprType Type => this.Expr.Type;
}
/// <summary>
/// ~Expr: only takes integral Type.
///
/// After semantic analysis, only the following 2 types are possible:
/// 1) long
/// 2) ulong
/// </summary>
public sealed partial class BitwiseNot : UnaryArithOp {
public BitwiseNot(Expr expr)
: base(expr) {
if (!(expr.Type is LongType || expr.Type is ULongType)) {
throw new InvalidOperationException("Invalid operand type.").Attach(expr);
}
}
public override ExprType Type => this.Expr.Type;
}
/// <summary>
/// !Expr: only takes scalar Type.
///
/// After semantic analysis, only the following 4 types are possible:
/// 1) long
/// 2) ulong
/// 3) float
/// 4) double
///
/// Pointers are converted to ulongs.
/// </summary>
public sealed partial class LogicalNot : UnaryArithOp {
public LogicalNot(Expr expr)
: base(expr) {
if (!(expr.Type is LongType || expr.Type is ULongType
|| expr.Type is FloatType || expr.Type is DoubleType)) {
throw new InvalidOperationException("Invalid operand type.").Attach(expr);
}
}
private static ExprType _type = new LongType(true);
public override ExprType Type => _type;
}
}