diff --git a/DMCompiler/Bytecode/DreamProcOpcode.cs b/DMCompiler/Bytecode/DreamProcOpcode.cs
index 766f8b9f41..9a5b230d8a 100644
--- a/DMCompiler/Bytecode/DreamProcOpcode.cs
+++ b/DMCompiler/Bytecode/DreamProcOpcode.cs
@@ -155,7 +155,7 @@ public static class StringFormatEncoder {
/// (DM uses this because it uses UTF8 and 0xFF is just an invalid character in that encoding, no biggie)
/// See: "Halfwidth and Fullwidth Forms" on https://en.wikibooks.org/wiki/Unicode/Character_reference/F000-FFFF
///
- public static UInt16 FormatPrefix = 0xFF00;
+ public static ushort FormatPrefix = 0xFF00;
///
/// The lower byte of the aforementioned formatting marker thingies we stuff into our UTF16 strings.
@@ -164,14 +164,14 @@ public static class StringFormatEncoder {
///
/// This requires FormatPrefix to be added to it in order to be a useful formatting character!!
///
- public enum FormatSuffix : UInt16 {
+ public enum FormatSuffix : ushort {
//States that Interpolated values can have (the [] thingies)
StringifyWithArticle = 0x0, //[] and we include an appropriate article for the resulting value, if necessary
StringifyNoArticle = 0x1, //[] and we never include an article (because it's elsewhere)
ReferenceOfValue = 0x2, //\ref[]
//States that macros can have
- //(these can have any arbitrary value as long as compiler/server/cilent all agree)
+ //(these can have any arbitrary value as long as compiler/server/client all agree)
//(Some of these values may not align with what they are internally in BYOND; too bad!!)
UpperDefiniteArticle, //The
LowerDefiniteArticle, //the
@@ -214,12 +214,12 @@ public enum FormatSuffix : UInt16 {
/// The UTF16 character we should be actually storing to articulate this format marker.
public static char Encode(FormatSuffix suffix) {
- return (char)(FormatPrefix | ((UInt16)suffix));
+ return (char)(FormatPrefix | ((ushort)suffix));
}
/// true if the input character was actually a formatting codepoint. false if not.
public static bool Decode(char c, [NotNullWhen(true)] out FormatSuffix? suffix) {
- UInt16 bytes = c; // this is an implicit reinterpret_cast, in C++ lingo
+ ushort bytes = c; // this is an implicit reinterpret_cast, in C++ lingo
suffix = null;
if((bytes & FormatPrefix) != FormatPrefix)
return false;
@@ -228,7 +228,7 @@ public static bool Decode(char c, [NotNullWhen(true)] out FormatSuffix? suffix)
}
public static bool Decode(char c) {
- UInt16 bytes = c;
+ ushort bytes = c;
return (bytes & FormatPrefix) == FormatPrefix; // Could also check that the lower byte is a valid enum but... ehhhhh
}
@@ -386,23 +386,15 @@ public static string GetOpcodesHash() {
/// Custom attribute for declaring metadata for individual opcodes
///
[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
-internal sealed class OpcodeMetadataAttribute : Attribute {
- public OpcodeMetadata Metadata;
-
- public OpcodeMetadataAttribute(int stackDelta = 0) {
- Metadata = new OpcodeMetadata(stackDelta);
- }
+internal sealed class OpcodeMetadataAttribute(int stackDelta = 0) : Attribute {
+ public OpcodeMetadata Metadata = new(stackDelta);
}
///
/// Miscellaneous metadata associated with individual opcodes using the attribute
///
-public struct OpcodeMetadata {
- public readonly int StackDelta; // Net change in stack size caused by this opcode
-
- public OpcodeMetadata(int stackDelta = 0) {
- StackDelta = stackDelta;
- }
+public struct OpcodeMetadata(int stackDelta = 0) {
+ public readonly int StackDelta = stackDelta; // Net change in stack size caused by this opcode
}
///
@@ -415,7 +407,7 @@ static OpcodeMetadataCache() {
foreach (DreamProcOpcode opcode in Enum.GetValues(typeof(DreamProcOpcode))) {
var field = typeof(DreamProcOpcode).GetField(opcode.ToString());
var attribute = Attribute.GetCustomAttribute(field!, typeof(OpcodeMetadataAttribute));
- var metadataAttribute = (OpcodeMetadataAttribute)attribute;
+ var metadataAttribute = (OpcodeMetadataAttribute?)attribute;
MetadataCache[(byte)opcode] = metadataAttribute?.Metadata ?? new OpcodeMetadata();
}
}
diff --git a/DMCompiler/Compiler/DM/AST/DMAST.Expression.cs b/DMCompiler/Compiler/DM/AST/DMAST.Expression.cs
new file mode 100644
index 0000000000..8301665973
--- /dev/null
+++ b/DMCompiler/Compiler/DM/AST/DMAST.Expression.cs
@@ -0,0 +1,234 @@
+using System.Collections.Generic;
+using System.Linq;
+using DMCompiler.DM;
+
+namespace DMCompiler.Compiler.DM.AST;
+
+public abstract class DMASTExpression(Location location) : DMASTNode(location) {
+ public virtual IEnumerable Leaves() {
+ yield break;
+ }
+
+ ///
+ /// If this is a , returns the expression inside.
+ /// Returns this expression if not.
+ ///
+ public virtual DMASTExpression GetUnwrapped() {
+ return this;
+ }
+}
+
+public sealed class DMASTVoid(Location location) : DMASTExpression(location);
+
+public sealed class DMASTIdentifier(Location location, string identifier) : DMASTExpression(location) {
+ public readonly string Identifier = identifier;
+}
+
+public sealed class DMASTSwitchCaseRange(Location location, DMASTExpression rangeStart, DMASTExpression rangeEnd)
+ : DMASTExpression(location) {
+ public DMASTExpression RangeStart = rangeStart, RangeEnd = rangeEnd;
+}
+
+public sealed class DMASTStringFormat(Location location, string value, DMASTExpression?[] interpolatedValues)
+ : DMASTExpression(location) {
+ public readonly string Value = value;
+ public readonly DMASTExpression?[] InterpolatedValues = interpolatedValues;
+}
+
+public sealed class DMASTList(Location location, DMASTCallParameter[] values) : DMASTExpression(location) {
+ public readonly DMASTCallParameter[] Values = values;
+
+ public bool AllValuesConstant() {
+ return Values.All(
+ value => (value is {
+ Key: DMASTExpressionConstant,
+ Value: DMASTExpressionConstant
+ })
+ ||
+ (value is {
+ Key: DMASTExpressionConstant,
+ Value: DMASTList valueList
+ } && valueList.AllValuesConstant())
+ );
+ }
+}
+
+///
+/// Represents the value of a var defined as var/list/L[1][2][3]
+///
+public sealed class DMASTDimensionalList(Location location, List sizes)
+ : DMASTExpression(location) {
+ public readonly List Sizes = sizes;
+}
+
+public sealed class DMASTAddText(Location location, DMASTCallParameter[] parameters) : DMASTExpression(location) {
+ public readonly DMASTCallParameter[] Parameters = parameters;
+}
+
+public sealed class DMASTNewList(Location location, DMASTCallParameter[] parameters) : DMASTExpression(location) {
+ public readonly DMASTCallParameter[] Parameters = parameters;
+}
+
+public sealed class DMASTInput(
+ Location location,
+ DMASTCallParameter[] parameters,
+ DMValueType? types,
+ DMASTExpression? list) : DMASTExpression(location) {
+ public readonly DMASTCallParameter[] Parameters = parameters;
+ public DMValueType? Types = types;
+ public readonly DMASTExpression? List = list;
+}
+
+public sealed class DMASTLocateCoordinates(
+ Location location,
+ DMASTExpression x,
+ DMASTExpression y,
+ DMASTExpression z) : DMASTExpression(location) {
+ public readonly DMASTExpression X = x, Y = y, Z = z;
+}
+
+public sealed class DMASTLocate(Location location, DMASTExpression? expression, DMASTExpression? container)
+ : DMASTExpression(location) {
+ public readonly DMASTExpression? Expression = expression;
+ public readonly DMASTExpression? Container = container;
+}
+
+public sealed class DMASTGradient(Location location, DMASTCallParameter[] parameters) : DMASTExpression(location) {
+ public readonly DMASTCallParameter[] Parameters = parameters;
+}
+
+public sealed class DMASTPick(Location location, DMASTPick.PickValue[] values) : DMASTExpression(location) {
+ public struct PickValue(DMASTExpression? weight, DMASTExpression value) {
+ public readonly DMASTExpression? Weight = weight;
+ public readonly DMASTExpression Value = value;
+ }
+
+ public readonly PickValue[] Values = values;
+}
+
+public class DMASTLog(Location location, DMASTExpression expression, DMASTExpression? baseExpression)
+ : DMASTExpression(location) {
+ public readonly DMASTExpression Expression = expression;
+ public readonly DMASTExpression? BaseExpression = baseExpression;
+}
+
+public sealed class DMASTCall(
+ Location location,
+ DMASTCallParameter[] callParameters,
+ DMASTCallParameter[] procParameters) : DMASTExpression(location) {
+ public readonly DMASTCallParameter[] CallParameters = callParameters, ProcParameters = procParameters;
+}
+
+public class DMASTVarDeclExpression(Location location, DMASTPath path) : DMASTExpression(location) {
+ public readonly DMASTPath DeclPath = path;
+}
+
+public sealed class DMASTNewPath(Location location, DMASTConstantPath path, DMASTCallParameter[]? parameters)
+ : DMASTExpression(location) {
+ public readonly DMASTConstantPath Path = path;
+ public readonly DMASTCallParameter[]? Parameters = parameters;
+}
+
+public sealed class DMASTNewExpr(Location location, DMASTExpression expression, DMASTCallParameter[]? parameters)
+ : DMASTExpression(location) {
+ public readonly DMASTExpression Expression = expression;
+ public readonly DMASTCallParameter[]? Parameters = parameters;
+}
+
+public sealed class DMASTNewInferred(Location location, DMASTCallParameter[] parameters)
+ : DMASTExpression(location) {
+ public readonly DMASTCallParameter[] Parameters = parameters;
+}
+
+public sealed class DMASTTernary(Location location, DMASTExpression a, DMASTExpression b, DMASTExpression c)
+ : DMASTExpression(location) {
+ public readonly DMASTExpression A = a, B = b, C = c;
+
+ public override IEnumerable Leaves() {
+ yield return A;
+ yield return B;
+ yield return C;
+ }
+}
+
+public sealed class DMASTExpressionInRange(
+ Location location,
+ DMASTExpression value,
+ DMASTExpression startRange,
+ DMASTExpression endRange,
+ DMASTExpression? step = null) : DMASTExpression(location) {
+ public DMASTExpression Value = value;
+ public DMASTExpression StartRange = startRange;
+ public DMASTExpression EndRange = endRange;
+ public readonly DMASTExpression? Step = step;
+
+ public override IEnumerable Leaves() {
+ yield return Value;
+ yield return StartRange;
+ yield return EndRange;
+ }
+}
+
+public sealed class DMASTProcCall(Location location, IDMASTCallable callable, DMASTCallParameter[] parameters)
+ : DMASTExpression(location) {
+ public readonly IDMASTCallable Callable = callable;
+ public readonly DMASTCallParameter[] Parameters = parameters;
+}
+
+public sealed class DMASTDereference(
+ Location location,
+ DMASTExpression expression,
+ DMASTDereference.Operation[] operations) : DMASTExpression(location) {
+ public abstract class Operation {
+ ///
+ /// The location of the operation.
+ ///
+ public required Location Location;
+ ///
+ /// Whether we should short circuit if the expression we are accessing is null.
+ ///
+ public required bool Safe; // x?.y, x?.y() etc
+ }
+
+ public abstract class NamedOperation : Operation {
+ ///
+ /// Name of the identifier.
+ ///
+ public required string Identifier;
+ ///
+ /// Whether we should check if the variable exists or not.
+ ///
+ public required bool NoSearch; // x:y, x:y()
+ }
+
+ public sealed class FieldOperation : NamedOperation;
+
+ public sealed class IndexOperation : Operation {
+ ///
+ /// The index expression that we use to index this expression (constant or otherwise).
+ ///
+ public required DMASTExpression Index; // x[y], x?[y]
+ }
+
+ public sealed class CallOperation : NamedOperation {
+ ///
+ /// The parameters that we call this proc with.
+ ///
+ public required DMASTCallParameter[] Parameters; // x.y(),
+ }
+
+ public readonly DMASTExpression Expression = expression;
+
+ // Always contains at least one operation
+ public readonly Operation[] Operations = operations;
+}
+
+public interface IDMASTCallable;
+
+public sealed class DMASTCallableProcIdentifier(Location location, string identifier) : DMASTExpression(location), IDMASTCallable {
+ public readonly string Identifier = identifier;
+}
+
+public sealed class DMASTCallableSuper(Location location) : DMASTExpression(location), IDMASTCallable;
+
+public sealed class DMASTCallableSelf(Location location) : DMASTExpression(location), IDMASTCallable;
diff --git a/DMCompiler/Compiler/DM/AST/DMAST.ExpressionBinary.cs b/DMCompiler/Compiler/DM/AST/DMAST.ExpressionBinary.cs
new file mode 100644
index 0000000000..93b62c9fd5
--- /dev/null
+++ b/DMCompiler/Compiler/DM/AST/DMAST.ExpressionBinary.cs
@@ -0,0 +1,56 @@
+using System.Collections.Generic;
+
+namespace DMCompiler.Compiler.DM.AST;
+
+public class DMASTBinary(Location location, DMASTExpression lhs, DMASTExpression rhs) : DMASTExpression(location) {
+ public DMASTExpression LHS = lhs;
+ public DMASTExpression RHS = rhs;
+
+ public override IEnumerable Leaves() {
+ yield return LHS;
+ yield return RHS;
+ }
+}
+
+public sealed class DMASTAssign(Location location, DMASTExpression expression, DMASTExpression value) : DMASTBinary(location, expression, value);
+public sealed class DMASTAssignInto(Location location, DMASTExpression expression, DMASTExpression value) : DMASTBinary(location, expression, value);
+public sealed class DMASTAppend(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTRemove(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTCombine(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTMask(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTLogicalAndAssign(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTLogicalOrAssign(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTMultiplyAssign(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTDivideAssign(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTLeftShiftAssign(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTRightShiftAssign(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTXorAssign(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTModulusAssign(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTModulusModulusAssign(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTOr(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTAnd(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTBinaryAnd(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTBinaryXor(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTBinaryOr(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTLeftShift(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTRightShift(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTEqual(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTNotEqual(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTEquivalent(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTNotEquivalent(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTLessThan(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTLessThanOrEqual(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTGreaterThan(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTGreaterThanOrEqual(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTMultiply(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTDivide(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTModulus(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTModulusModulus(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTPower(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTAdd(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTSubtract(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
+public sealed class DMASTArctan2(Location location, DMASTExpression xExpression, DMASTExpression yExpression) : DMASTBinary(location, xExpression, yExpression);
+public sealed class DMASTIsType(Location location, DMASTExpression value, DMASTExpression type) : DMASTBinary(location, value, type);
+public sealed class DMASTGetStep(Location location, DMASTExpression refValue, DMASTExpression dir) : DMASTBinary(location, refValue, dir);
+public sealed class DMASTGetDir(Location location, DMASTExpression loc1, DMASTExpression loc2) : DMASTBinary(location, loc1, loc2);
+public sealed class DMASTExpressionIn(Location location, DMASTExpression value, DMASTExpression list) : DMASTBinary(location, value, list);
diff --git a/DMCompiler/Compiler/DM/AST/DMAST.ExpressionConstant.cs b/DMCompiler/Compiler/DM/AST/DMAST.ExpressionConstant.cs
new file mode 100644
index 0000000000..81a79fbd98
--- /dev/null
+++ b/DMCompiler/Compiler/DM/AST/DMAST.ExpressionConstant.cs
@@ -0,0 +1,31 @@
+namespace DMCompiler.Compiler.DM.AST;
+
+public abstract class DMASTExpressionConstant(Location location) : DMASTExpression(location);
+
+public sealed class DMASTConstantInteger(Location location, int value) : DMASTExpressionConstant(location) {
+ public readonly int Value = value;
+}
+
+public sealed class DMASTConstantFloat(Location location, float value) : DMASTExpressionConstant(location) {
+ public readonly float Value = value;
+}
+
+public sealed class DMASTConstantString(Location location, string value) : DMASTExpressionConstant(location) {
+ public readonly string Value = value;
+}
+
+public sealed class DMASTConstantResource(Location location, string path) : DMASTExpressionConstant(location) {
+ public readonly string Path = path;
+}
+
+public sealed class DMASTConstantNull(Location location) : DMASTExpressionConstant(location);
+
+public sealed class DMASTConstantPath(Location location, DMASTPath value) : DMASTExpressionConstant(location) {
+ public readonly DMASTPath Value = value;
+}
+
+public sealed class DMASTUpwardPathSearch(Location location, DMASTExpressionConstant path, DMASTPath search)
+ : DMASTExpressionConstant(location) {
+ public readonly DMASTExpressionConstant Path = path;
+ public readonly DMASTPath Search = search;
+}
diff --git a/DMCompiler/Compiler/DM/AST/DMAST.ExpressionUnary.cs b/DMCompiler/Compiler/DM/AST/DMAST.ExpressionUnary.cs
new file mode 100644
index 0000000000..8cbb8183b5
--- /dev/null
+++ b/DMCompiler/Compiler/DM/AST/DMAST.ExpressionUnary.cs
@@ -0,0 +1,48 @@
+using System.Collections.Generic;
+
+namespace DMCompiler.Compiler.DM.AST;
+
+public class DMASTUnary(Location location, DMASTExpression value) : DMASTExpression(location) {
+ public DMASTExpression Value = value;
+
+ public override IEnumerable Leaves() {
+ yield return Value;
+ }
+}
+
+public sealed class DMASTBinaryNot(Location location, DMASTExpression value) : DMASTUnary(location, value);
+public sealed class DMASTNot(Location location, DMASTExpression expression) : DMASTUnary(location, expression);
+public sealed class DMASTNegate(Location location, DMASTExpression expression) : DMASTUnary(location, expression);
+public sealed class DMASTPreIncrement(Location location, DMASTExpression expression) : DMASTUnary(location, expression);
+public sealed class DMASTPreDecrement(Location location, DMASTExpression expression) : DMASTUnary(location, expression);
+public sealed class DMASTPostIncrement(Location location, DMASTExpression expression) : DMASTUnary(location, expression);
+public sealed class DMASTPostDecrement(Location location, DMASTExpression expression) : DMASTUnary(location, expression);
+public sealed class DMASTSin(Location location, DMASTExpression expression) : DMASTUnary(location, expression);
+public sealed class DMASTCos(Location location, DMASTExpression expression) : DMASTUnary(location, expression);
+public sealed class DMASTTan(Location location, DMASTExpression expression) : DMASTUnary(location, expression);
+public sealed class DMASTArcsin(Location location, DMASTExpression expression) : DMASTUnary(location, expression);
+public sealed class DMASTArccos(Location location, DMASTExpression expression) : DMASTUnary(location, expression);
+public sealed class DMASTArctan(Location location, DMASTExpression expression) : DMASTUnary(location, expression);
+public sealed class DMASTSqrt(Location location, DMASTExpression expression) : DMASTUnary(location, expression);
+public sealed class DMASTAbs(Location location, DMASTExpression expression) : DMASTUnary(location, expression);
+public sealed class DMASTProb(Location location, DMASTExpression p) : DMASTUnary(location, p);
+public sealed class DMASTInitial(Location location, DMASTExpression expression) : DMASTUnary(location, expression);
+public sealed class DMASTNameof(Location location, DMASTExpression expression) : DMASTUnary(location, expression);
+public sealed class DMASTIsSaved(Location location, DMASTExpression expression) : DMASTUnary(location, expression);
+public sealed class DMASTIsNull(Location location, DMASTExpression value) : DMASTUnary(location, value);
+public sealed class DMASTLength(Location location, DMASTExpression value) : DMASTUnary(location, value);
+public sealed class DMASTImplicitIsType(Location location, DMASTExpression value) : DMASTUnary(location, value);
+
+///
+/// An expression wrapped around parentheses
+/// (1 + 1)
+///
+public sealed class DMASTExpressionWrapped(Location location, DMASTExpression expression) : DMASTUnary(location, expression) {
+ public override DMASTExpression GetUnwrapped() {
+ DMASTExpression expr = Value;
+ while (expr is DMASTExpressionWrapped wrapped)
+ expr = wrapped.Value;
+
+ return expr;
+ }
+}
diff --git a/DMCompiler/Compiler/DM/AST/DMAST.ObjectStatements.cs b/DMCompiler/Compiler/DM/AST/DMAST.ObjectStatements.cs
new file mode 100644
index 0000000000..3e99dc76b0
--- /dev/null
+++ b/DMCompiler/Compiler/DM/AST/DMAST.ObjectStatements.cs
@@ -0,0 +1,91 @@
+using DMCompiler.DM;
+
+namespace DMCompiler.Compiler.DM.AST;
+
+///
+/// A statement used in object definitions (outside of procs)
+///
+public abstract class DMASTStatement(Location location) : DMASTNode(location);
+
+public sealed class DMASTObjectDefinition(Location location, DreamPath path, DMASTBlockInner? innerBlock)
+ : DMASTStatement(location) {
+ /// Unlike other Path variables stored by AST nodes, this path is guaranteed to be the real, absolute path of this object definition block.
+ /// That includes any inherited pathing from being tabbed into a different, base definition.
+ ///
+ public DreamPath Path = path;
+
+ public readonly DMASTBlockInner? InnerBlock = innerBlock;
+}
+
+/// Also includes proc overrides; see the member. Verbs too.
+public sealed class DMASTProcDefinition : DMASTStatement {
+ public readonly DreamPath ObjectPath;
+ public readonly string Name;
+ public readonly bool IsOverride;
+ public readonly bool IsVerb;
+ public readonly DMASTDefinitionParameter[] Parameters;
+ public readonly DMASTProcBlockInner? Body;
+
+ public DMASTProcDefinition(Location location, DreamPath path, DMASTDefinitionParameter[] parameters,
+ DMASTProcBlockInner? body) : base(location) {
+ int procElementIndex = path.FindElement("proc");
+
+ if (procElementIndex == -1) {
+ procElementIndex = path.FindElement("verb");
+
+ if (procElementIndex != -1) IsVerb = true;
+ else IsOverride = true;
+ }
+
+ if (procElementIndex != -1) path = path.RemoveElement(procElementIndex);
+
+ ObjectPath = (path.Elements.Length > 1) ? path.FromElements(0, -2) : DreamPath.Root;
+ Name = path.LastElement;
+ Parameters = parameters;
+ Body = body;
+ }
+}
+
+public sealed class DMASTObjectVarDefinition(
+ Location location,
+ DreamPath path,
+ DMASTExpression value,
+ DMValueType valType = DMValueType.Anything) : DMASTStatement(location) {
+ /// The path of the object that we are a property of.
+ public DreamPath ObjectPath => _varDecl.ObjectPath;
+
+ /// The actual type of the variable itself.
+ public DreamPath? Type => _varDecl.IsList ? DreamPath.List : _varDecl.TypePath;
+
+ public string Name => _varDecl.VarName;
+ public DMASTExpression Value = value;
+
+ private readonly ObjVarDeclInfo _varDecl = new(path);
+
+ public bool IsStatic => _varDecl.IsStatic;
+
+ // TODO: Standardize our phrasing in the codebase. Are we calling these Statics or Globals?
+ public bool IsGlobal => _varDecl.IsStatic;
+
+ public bool IsConst => _varDecl.IsConst;
+ public bool IsTmp => _varDecl.IsTmp;
+
+ public readonly DMValueType ValType = valType;
+}
+
+public sealed class DMASTMultipleObjectVarDefinitions(Location location, DMASTObjectVarDefinition[] varDefinitions)
+ : DMASTStatement(location) {
+ public readonly DMASTObjectVarDefinition[] VarDefinitions = varDefinitions;
+}
+
+public sealed class DMASTObjectVarOverride : DMASTStatement {
+ public readonly DreamPath ObjectPath;
+ public readonly string VarName;
+ public DMASTExpression Value;
+
+ public DMASTObjectVarOverride(Location location, DreamPath path, DMASTExpression value) : base(location) {
+ ObjectPath = path.FromElements(0, -2);
+ VarName = path.LastElement;
+ Value = value;
+ }
+}
diff --git a/DMCompiler/Compiler/DM/AST/DMAST.ProcStatements.cs b/DMCompiler/Compiler/DM/AST/DMAST.ProcStatements.cs
new file mode 100644
index 0000000000..c0f67552c3
--- /dev/null
+++ b/DMCompiler/Compiler/DM/AST/DMAST.ProcStatements.cs
@@ -0,0 +1,215 @@
+using DMCompiler.DM;
+
+namespace DMCompiler.Compiler.DM.AST;
+
+///
+/// A statement found within procs
+///
+public abstract class DMASTProcStatement(Location location) : DMASTNode(location) {
+ ///
+ /// Returns true if this statement is either T or an aggregation of T (stored by an instance). False otherwise.
+ ///
+ public bool IsAggregateOr() where T : DMASTProcStatement {
+ return (this is T or DMASTAggregate);
+ }
+}
+
+public sealed class DMASTNullProcStatement(Location location) : DMASTProcStatement(location);
+
+public sealed class DMASTProcStatementExpression(Location location, DMASTExpression expression)
+ : DMASTProcStatement(location) {
+ public DMASTExpression Expression = expression;
+}
+
+public sealed class DMASTProcStatementVarDeclaration(Location location, DMASTPath path, DMASTExpression? value)
+ : DMASTProcStatement(location) {
+ public DMASTExpression? Value = value;
+
+ public DreamPath? Type => _varDecl.IsList ? DreamPath.List : _varDecl.TypePath;
+ public string Name => _varDecl.VarName;
+ public bool IsGlobal => _varDecl.IsStatic;
+ public bool IsConst => _varDecl.IsConst;
+
+ private readonly ProcVarDeclInfo _varDecl = new(path.Path);
+}
+
+///
+/// A kinda-abstract class that represents several statements that were created in unison by one "super-statement"
+/// Such as, a var declaration that actually declares several vars at once (which in our parser must become "one" statement, hence this thing)
+///
+/// The DMASTProcStatement-derived class that this AST node holds.
+public sealed class DMASTAggregate(Location location, T[] statements) : DMASTProcStatement(location)
+ where T : DMASTProcStatement { // Gotta be honest? I like this "where" syntax better than C++20 concepts
+ public T[] Statements { get; } = statements;
+}
+
+public sealed class DMASTProcStatementReturn(Location location, DMASTExpression? value) : DMASTProcStatement(location) {
+ public DMASTExpression? Value = value;
+}
+
+public sealed class DMASTProcStatementBreak(Location location, DMASTIdentifier? label = null)
+ : DMASTProcStatement(location) {
+ public readonly DMASTIdentifier? Label = label;
+}
+
+public sealed class DMASTProcStatementContinue(Location location, DMASTIdentifier? label = null)
+ : DMASTProcStatement(location) {
+ public readonly DMASTIdentifier? Label = label;
+}
+
+public sealed class DMASTProcStatementGoto(Location location, DMASTIdentifier label) : DMASTProcStatement(location) {
+ public readonly DMASTIdentifier Label = label;
+}
+
+public sealed class DMASTProcStatementLabel(Location location, string name, DMASTProcBlockInner? body) : DMASTProcStatement(location) {
+ public readonly string Name = name;
+ public readonly DMASTProcBlockInner? Body = body;
+}
+
+public sealed class DMASTProcStatementDel(Location location, DMASTExpression value) : DMASTProcStatement(location) {
+ public DMASTExpression Value = value;
+}
+
+public sealed class DMASTProcStatementSet(
+ Location location,
+ string attribute,
+ DMASTExpression value,
+ bool wasInKeyword) : DMASTProcStatement(location) {
+ public readonly string Attribute = attribute;
+ public readonly DMASTExpression Value = value;
+ public readonly bool WasInKeyword = wasInKeyword; // Marks whether this was a "set x in y" expression, or a "set x = y" one
+}
+
+public sealed class DMASTProcStatementSpawn(Location location, DMASTExpression delay, DMASTProcBlockInner body)
+ : DMASTProcStatement(location) {
+ public DMASTExpression Delay = delay;
+ public readonly DMASTProcBlockInner Body = body;
+}
+
+public sealed class DMASTProcStatementIf(
+ Location location,
+ DMASTExpression condition,
+ DMASTProcBlockInner body,
+ DMASTProcBlockInner? elseBody = null) : DMASTProcStatement(location) {
+ public DMASTExpression Condition = condition;
+ public readonly DMASTProcBlockInner Body = body;
+ public readonly DMASTProcBlockInner? ElseBody = elseBody;
+}
+
+public sealed class DMASTProcStatementFor(
+ Location location,
+ DMASTExpression? expr1,
+ DMASTExpression? expr2,
+ DMASTExpression? expr3,
+ DMValueType? dmTypes,
+ DMASTProcBlockInner body) : DMASTProcStatement(location) {
+ public DMASTExpression? Expression1 = expr1, Expression2 = expr2, Expression3 = expr3;
+ public DMValueType? DMTypes = dmTypes;
+ public readonly DMASTProcBlockInner Body = body;
+}
+
+public sealed class DMASTProcStatementInfLoop(Location location, DMASTProcBlockInner body) : DMASTProcStatement(location) {
+ public readonly DMASTProcBlockInner Body = body;
+}
+
+public sealed class DMASTProcStatementWhile(
+ Location location,
+ DMASTExpression conditional,
+ DMASTProcBlockInner body) : DMASTProcStatement(location) {
+ public DMASTExpression Conditional = conditional;
+ public readonly DMASTProcBlockInner Body = body;
+}
+
+public sealed class DMASTProcStatementDoWhile(
+ Location location,
+ DMASTExpression conditional,
+ DMASTProcBlockInner body) : DMASTProcStatement(location) {
+ public DMASTExpression Conditional = conditional;
+ public readonly DMASTProcBlockInner Body = body;
+}
+
+public sealed class DMASTProcStatementSwitch(
+ Location location,
+ DMASTExpression value,
+ DMASTProcStatementSwitch.SwitchCase[] cases) : DMASTProcStatement(location) {
+ public class SwitchCase {
+ public readonly DMASTProcBlockInner Body;
+
+ protected SwitchCase(DMASTProcBlockInner body) {
+ Body = body;
+ }
+ }
+
+ public sealed class SwitchCaseDefault(DMASTProcBlockInner body) : SwitchCase(body);
+
+ public sealed class SwitchCaseValues(DMASTExpression[] values, DMASTProcBlockInner body) : SwitchCase(body) {
+ public readonly DMASTExpression[] Values = values;
+ }
+
+ public DMASTExpression Value = value;
+ public readonly SwitchCase[] Cases = cases;
+}
+
+public sealed class DMASTProcStatementBrowse(
+ Location location,
+ DMASTExpression receiver,
+ DMASTExpression body,
+ DMASTExpression options) : DMASTProcStatement(location) {
+ public DMASTExpression Receiver = receiver;
+ public DMASTExpression Body = body;
+ public DMASTExpression Options = options;
+}
+
+public sealed class DMASTProcStatementBrowseResource(
+ Location location,
+ DMASTExpression receiver,
+ DMASTExpression file,
+ DMASTExpression filename) : DMASTProcStatement(location) {
+ public DMASTExpression Receiver = receiver;
+ public DMASTExpression File = file;
+ public DMASTExpression Filename = filename;
+}
+
+public sealed class DMASTProcStatementOutputControl(
+ Location location,
+ DMASTExpression receiver,
+ DMASTExpression message,
+ DMASTExpression control) : DMASTProcStatement(location) {
+ public DMASTExpression Receiver = receiver;
+ public DMASTExpression Message = message;
+ public DMASTExpression Control = control;
+}
+
+public sealed class DMASTProcStatementFtp(
+ Location location,
+ DMASTExpression receiver,
+ DMASTExpression file,
+ DMASTExpression name) : DMASTProcStatement(location) {
+ public readonly DMASTExpression Receiver = receiver;
+ public readonly DMASTExpression File = file;
+ public readonly DMASTExpression Name = name;
+}
+
+public sealed class DMASTProcStatementOutput(Location location, DMASTExpression a, DMASTExpression b)
+ : DMASTProcStatement(location) {
+ public readonly DMASTExpression A = a, B = b;
+}
+
+public sealed class DMASTProcStatementInput(Location location, DMASTExpression a, DMASTExpression b)
+ : DMASTProcStatement(location) {
+ public readonly DMASTExpression A = a, B = b;
+}
+
+public sealed class DMASTProcStatementTryCatch(
+ Location location,
+ DMASTProcBlockInner tryBody,
+ DMASTProcBlockInner? catchBody,
+ DMASTProcStatement? catchParameter) : DMASTProcStatement(location) {
+ public readonly DMASTProcBlockInner TryBody = tryBody;
+ public readonly DMASTProcBlockInner? CatchBody = catchBody;
+ public readonly DMASTProcStatement? CatchParameter = catchParameter;
+}
+
+public sealed class DMASTProcStatementThrow(Location location, DMASTExpression value) : DMASTProcStatement(location) {
+ public DMASTExpression Value = value;
+}
diff --git a/DMCompiler/Compiler/DM/AST/DMAST.cs b/DMCompiler/Compiler/DM/AST/DMAST.cs
new file mode 100644
index 0000000000..88475daf86
--- /dev/null
+++ b/DMCompiler/Compiler/DM/AST/DMAST.cs
@@ -0,0 +1,78 @@
+using System;
+using DMCompiler.DM;
+
+namespace DMCompiler.Compiler.DM.AST;
+
+public abstract class DMASTNode(Location location) {
+ public readonly Location Location = location;
+}
+
+public sealed class DMASTFile(Location location, DMASTBlockInner blockInner) : DMASTNode(location) {
+ public readonly DMASTBlockInner BlockInner = blockInner;
+}
+
+public sealed class DMASTBlockInner(Location location, DMASTStatement[] statements) : DMASTNode(location) {
+ public readonly DMASTStatement[] Statements = statements;
+}
+
+public sealed class DMASTProcBlockInner : DMASTNode {
+ public readonly DMASTProcStatement[] Statements;
+
+ ///
+ /// SetStatements is held separately because all set statements need to be, to borrow cursed JS terms, "hoisted" to the top of the block, before anything else.
+ /// This isn't SPECIFICALLY a array because some of these may be DMASTAggregate instances.
+ ///
+ public readonly DMASTProcStatement[] SetStatements;
+
+ /// Initializes an empty block.
+ public DMASTProcBlockInner(Location location) : base(location) {
+ Statements = Array.Empty();
+ SetStatements = Array.Empty();
+ }
+
+ /// Initializes a block with only one statement (which may be a :o)
+ public DMASTProcBlockInner(Location location, DMASTProcStatement statement) : base(location) {
+ if (statement.IsAggregateOr()) {
+ // If this is a Set statement or a set of Set statements
+ Statements = Array.Empty();
+ SetStatements = new[] { statement };
+ } else {
+ Statements = new[] { statement };
+ SetStatements = Array.Empty();
+ }
+ }
+
+ public DMASTProcBlockInner(Location location, DMASTProcStatement[] statements,
+ DMASTProcStatement[]? setStatements)
+ : base(location) {
+ Statements = statements;
+ SetStatements = setStatements ?? Array.Empty();
+ }
+}
+
+// TODO: This can probably be replaced with a DreamPath nullable
+public sealed class DMASTPath(Location location, DreamPath path, bool operatorFlag = false) : DMASTNode(location) {
+ public DreamPath Path = path;
+ public readonly bool IsOperator = operatorFlag;
+}
+
+public sealed class DMASTCallParameter(Location location, DMASTExpression value, DMASTExpression? key = null)
+ : DMASTNode(location) {
+ public DMASTExpression Value = value;
+ public readonly DMASTExpression? Key = key;
+}
+
+public sealed class DMASTDefinitionParameter(
+ Location location,
+ DMASTPath astPath,
+ DMASTExpression? value,
+ DMValueType type,
+ DMASTExpression possibleValues) : DMASTNode(location) {
+ public DreamPath? ObjectType => _paramDecl.IsList ? DreamPath.List : _paramDecl.TypePath;
+ public string Name => _paramDecl.VarName;
+ public DMASTExpression? Value = value;
+ public readonly DMValueType Type = type;
+ public DMASTExpression PossibleValues = possibleValues;
+
+ private readonly ProcParameterDeclInfo _paramDecl = new(astPath.Path);
+}
diff --git a/DMCompiler/Compiler/DM/DMAST.cs b/DMCompiler/Compiler/DM/DMAST.cs
deleted file mode 100644
index fc3ce3467e..0000000000
--- a/DMCompiler/Compiler/DM/DMAST.cs
+++ /dev/null
@@ -1,2805 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using DMCompiler.DM;
-
-namespace DMCompiler.Compiler.DM {
- public interface DMASTVisitor {
- public void VisitFile(DMASTFile file) {
- throw new NotImplementedException();
- }
-
- public void VisitBlockInner(DMASTBlockInner block) {
- throw new NotImplementedException();
- }
-
- public void VisitProcBlockInner(DMASTProcBlockInner procBlock) {
- throw new NotImplementedException();
- }
-
- public void VisitObjectDefinition(DMASTObjectDefinition statement) {
- throw new NotImplementedException();
- }
-
- public void VisitPath(DMASTPath path) {
- throw new NotImplementedException();
- }
-
- public void VisitObjectVarDefinition(DMASTObjectVarDefinition objectVarDefinition) {
- throw new NotImplementedException();
- }
-
- public void VisitMultipleObjectVarDefinitions(DMASTMultipleObjectVarDefinitions multipleObjectVarDefinitions) {
- throw new NotImplementedException();
- }
-
- public void VisitObjectVarOverride(DMASTObjectVarOverride objectVarOverride) {
- throw new NotImplementedException();
- }
-
- public void VisitNullProcStatement(DMASTNullProcStatement nullProcStatement) {
- throw new NotImplementedException();
- }
-
- public void VisitProcStatementExpression(DMASTProcStatementExpression statementExpression) {
- throw new NotImplementedException();
- }
-
- public void VisitProcStatementVarDeclaration(DMASTProcStatementVarDeclaration varDeclaration) {
- throw new NotImplementedException();
- }
-
- public void VisitProcStatementReturn(DMASTProcStatementReturn statementReturn) {
- throw new NotImplementedException();
- }
-
- public void VisitProcStatementBreak(DMASTProcStatementBreak statementBreak) {
- throw new NotImplementedException();
- }
-
- public void VisitProcStatementContinue(DMASTProcStatementContinue statementContinue) {
- throw new NotImplementedException();
- }
-
- public void VisitProcStatementGoto(DMASTProcStatementGoto statementGoto) {
- throw new NotImplementedException();
- }
-
- public void VisitProcStatementLabel(DMASTProcStatementLabel statementLabel) {
- throw new NotImplementedException();
- }
-
- public void VisitProcStatementDel(DMASTProcStatementDel statementDel) {
- throw new NotImplementedException();
- }
-
- public void VisitProcStatementSet(DMASTProcStatementSet statementSet) {
- throw new NotImplementedException();
- }
-
- public void VisitProcStatementSpawn(DMASTProcStatementSpawn statementSpawn) {
- throw new NotImplementedException();
- }
-
- public void VisitProcStatementIf(DMASTProcStatementIf statementIf) {
- throw new NotImplementedException();
- }
-
- public void VisitProcStatementFor(DMASTProcStatementFor statementFor) {
- throw new NotImplementedException();
- }
-
- public void VisitProcStatementInfLoop(DMASTProcStatementInfLoop statementInfLoop) {
- throw new NotImplementedException();
- }
-
- public void VisitProcStatementWhile(DMASTProcStatementWhile statementWhile) {
- throw new NotImplementedException();
- }
-
- public void VisitProcStatementDoWhile(DMASTProcStatementDoWhile statementDoWhile) {
- throw new NotImplementedException();
- }
-
- public void VisitProcStatementSwitch(DMASTProcStatementSwitch statementSwitch) {
- throw new NotImplementedException();
- }
-
- public void VisitProcStatementBrowse(DMASTProcStatementBrowse statementBrowse) {
- throw new NotImplementedException();
- }
-
- public void VisitProcStatementBrowseResource(DMASTProcStatementBrowseResource statementBrowseResource) {
- throw new NotImplementedException();
- }
-
- public void VisitProcStatementOutputControl(DMASTProcStatementOutputControl statementOutputControl) {
- throw new NotImplementedException();
- }
-
- public void VisitProcStatementFtp(DMASTProcStatementFtp statementFtp) {
- throw new NotImplementedException();
- }
-
- public void VisitProcStatementOutput(DMASTProcStatementOutput statementOutput) {
- throw new NotImplementedException();
- }
-
- public void VisitProcStatementInput(DMASTProcStatementInput statementInput) {
- throw new NotImplementedException();
- }
-
- public void VisitProcStatementTryCatch(DMASTProcStatementTryCatch statementTryCatch) {
- throw new NotImplementedException();
- }
-
- public void VisitProcStatementThrow(DMASTProcStatementThrow statementThrow) {
- throw new NotImplementedException();
- }
-
- public void VisitProcDefinition(DMASTProcDefinition procDefinition) {
- throw new NotImplementedException();
- }
-
- public void VisitVoid(DMASTVoid voidNode) {
- throw new NotImplementedException();
- }
-
- public void VisitIdentifier(DMASTIdentifier identifier) {
- throw new NotImplementedException();
- }
-
- public void VisitGlobalIdentifier(DMASTGlobalIdentifier globalIdentifier) {
- throw new NotImplementedException();
- }
-
- public void VisitConstantInteger(DMASTConstantInteger constant) {
- throw new NotImplementedException();
- }
-
- public void VisitConstantFloat(DMASTConstantFloat constant) {
- throw new NotImplementedException();
- }
-
- public void VisitConstantString(DMASTConstantString constant) {
- throw new NotImplementedException();
- }
-
- public void VisitConstantResource(DMASTConstantResource constant) {
- throw new NotImplementedException();
- }
-
- public void VisitConstantNull(DMASTConstantNull constant) {
- throw new NotImplementedException();
- }
-
- public void VisitConstantPath(DMASTConstantPath constant) {
- throw new NotImplementedException();
- }
-
- public void VisitUpwardPathSearch(DMASTUpwardPathSearch upwardPathSearch) {
- throw new NotImplementedException();
- }
-
- public void VisitSwitchCaseRange(DMASTSwitchCaseRange switchCaseRange) {
- throw new NotImplementedException();
- }
-
- public void VisitStringFormat(DMASTStringFormat stringFormat) {
- throw new NotImplementedException();
- }
-
- public void VisitList(DMASTList list) {
- throw new NotImplementedException();
- }
-
- public void VisitDimensionalList(DMASTDimensionalList list) {
- throw new NotImplementedException();
- }
-
- public void VisitNewList(DMASTNewList newList) {
- throw new NotImplementedException();
- }
-
- public void VisitAddText(DMASTAddText input) {
- throw new NotImplementedException();
- }
-
- public void VisitProb(DMASTProb prob) {
- throw new NotImplementedException();
- }
-
- public void VisitInput(DMASTInput input) {
- throw new NotImplementedException();
- }
-
- public void VisitInitial(DMASTInitial initial) {
- throw new NotImplementedException();
- }
-
- public void VisitNameof(DMASTNameof nameof) {
- throw new NotImplementedException();
- }
-
- public void VisitIsSaved(DMASTIsSaved isSaved) {
- throw new NotImplementedException();
- }
-
- public void VisitIsType(DMASTIsType isType) {
- throw new NotImplementedException();
- }
-
- public void VisitIsNull(DMASTIsNull isNull) {
- throw new NotImplementedException();
- }
-
- public void VisitLength(DMASTLength length) {
- throw new NotImplementedException();
- }
-
- public void VisitGetStep(DMASTGetStep getStep) {
- throw new NotImplementedException();
- }
-
- public void VisitGetDir(DMASTGetDir getDir) {
- throw new NotImplementedException();
- }
-
- public void VisitImplicitIsType(DMASTImplicitIsType isType) {
- throw new NotImplementedException();
- }
-
- public void VisitLocateCoordinates(DMASTLocateCoordinates locateCoordinates) {
- throw new NotImplementedException();
- }
-
- public void VisitLocate(DMASTLocate locate) {
- throw new NotImplementedException();
- }
-
- public void VisitGradient(DMASTGradient gradient) {
- throw new NotImplementedException();
- }
-
- public void VisitPick(DMASTPick pick) {
- throw new NotImplementedException();
- }
- public void VisitSin(DMASTSin sin) {
- throw new NotImplementedException();
- }
- public void VisitCos(DMASTCos cos) {
- throw new NotImplementedException();
- }
- public void VisitTan(DMASTTan tan) {
- throw new NotImplementedException();
- }
- public void VisitArcsin(DMASTArcsin asin) {
- throw new NotImplementedException();
- }
- public void VisitArccos(DMASTArccos acos) {
- throw new NotImplementedException();
- }
- public void VisitArctan(DMASTArctan atan) {
- throw new NotImplementedException();
- }
- public void VisitArctan2(DMASTArctan2 atan) {
- throw new NotImplementedException();
- }
- public void VisitSqrt(DMASTSqrt sqrt) {
- throw new NotImplementedException();
- }
- public void VisitLog(DMASTLog log) {
- throw new NotImplementedException();
- }
- public void VisitAbs(DMASTAbs abs) {
- throw new NotImplementedException();
- }
- public void VisitCall(DMASTCall call) {
- throw new NotImplementedException();
- }
-
- public void VisitAssign(DMASTAssign assign) {
- throw new NotImplementedException();
- }
-
- public void VisitAssignInto(DMASTAssignInto assign) {
- throw new NotImplementedException();
- }
-
- public void VisitVarDeclExpression(DMASTVarDeclExpression vardecl) {
- throw new NotImplementedException();
- }
-
- public void VisitNewPath(DMASTNewPath newPath) {
- throw new NotImplementedException();
- }
-
- public void VisitNewExpr(DMASTNewExpr newExpr) {
- throw new NotImplementedException();
- }
-
- public void VisitNewInferred(DMASTNewInferred newInferred) {
- throw new NotImplementedException();
- }
-
- public void VisitNot(DMASTNot not) {
- throw new NotImplementedException();
- }
-
- public void VisitNegate(DMASTNegate negate) {
- throw new NotImplementedException();
- }
-
- public void VisitEqual(DMASTEqual equal) {
- throw new NotImplementedException();
- }
-
- public void VisitNotEqual(DMASTNotEqual notEqual) {
- throw new NotImplementedException();
- }
-
- public void VisitEquivalent(DMASTEquivalent equivalent) {
- throw new NotImplementedException();
- }
-
- public void VisitNotEquivalent(DMASTNotEquivalent notEquivalent) {
- throw new NotImplementedException();
- }
-
- public void VisitLessThan(DMASTLessThan lessThan) {
- throw new NotImplementedException();
- }
-
- public void VisitLessThanOrEqual(DMASTLessThanOrEqual lessThanOrEqual) {
- throw new NotImplementedException();
- }
-
- public void VisitGreaterThan(DMASTGreaterThan greaterThan) {
- throw new NotImplementedException();
- }
-
- public void VisitGreaterThanOrEqual(DMASTGreaterThanOrEqual greaterThanOrEqual) {
- throw new NotImplementedException();
- }
-
- public void VisitMultiply(DMASTMultiply multiply) {
- throw new NotImplementedException();
- }
-
- public void VisitDivide(DMASTDivide divide) {
- throw new NotImplementedException();
- }
-
- public void VisitModulus(DMASTModulus modulus) {
- throw new NotImplementedException();
- }
-
- public void VisitModulusModulus(DMASTModulusModulus modulusModulus) {
- throw new NotImplementedException();
- }
-
- public void VisitPower(DMASTPower power) {
- throw new NotImplementedException();
- }
-
- public void VisitAdd(DMASTAdd add) {
- throw new NotImplementedException();
- }
-
- public void VisitSubtract(DMASTSubtract subtract) {
- throw new NotImplementedException();
- }
-
- public void VisitPreIncrement(DMASTPreIncrement preIncrement) {
- throw new NotImplementedException();
- }
-
- public void VisitPreDecrement(DMASTPreDecrement preDecrement) {
- throw new NotImplementedException();
- }
-
- public void VisitPostIncrement(DMASTPostIncrement postIncrement) {
- throw new NotImplementedException();
- }
-
- public void VisitPostDecrement(DMASTPostDecrement postDecrement) {
- throw new NotImplementedException();
- }
-
- public void VisitTernary(DMASTTernary ternary) {
- throw new NotImplementedException();
- }
-
- public void VisitAppend(DMASTAppend append) {
- throw new NotImplementedException();
- }
-
- public void VisitRemove(DMASTRemove remove) {
- throw new NotImplementedException();
- }
-
- public void VisitCombine(DMASTCombine combine) {
- throw new NotImplementedException();
- }
-
- public void VisitMask(DMASTMask mask) {
- throw new NotImplementedException();
- }
-
- public void VisitLogicalAndAssign(DMASTLogicalAndAssign landAssign) {
- throw new NotImplementedException();
- }
-
- public void VisitLogicalOrAssign(DMASTLogicalOrAssign lorAssign) {
- throw new NotImplementedException();
- }
-
- public void VisitMultiplyAssign(DMASTMultiplyAssign multiplyAssign) {
- throw new NotImplementedException();
- }
-
- public void VisitDivideAssign(DMASTDivideAssign divideAssign) {
- throw new NotImplementedException();
- }
-
- public void VisitLeftShiftAssign(DMASTLeftShiftAssign leftShiftAssign) {
- throw new NotImplementedException();
- }
-
- public void VisitRightShiftAssign(DMASTRightShiftAssign rightShiftAssign) {
- throw new NotImplementedException();
- }
-
- public void VisitXorAssign(DMASTXorAssign xorAssign) {
- throw new NotImplementedException();
- }
-
- public void VisitModulusAssign(DMASTModulusAssign modulusAssign) {
- throw new NotImplementedException();
- }
-
- public void VisitModulusModulusAssign(DMASTModulusModulusAssign modulusModulusAssign) {
- throw new NotImplementedException();
- }
-
- public void VisitOr(DMASTOr or) {
- throw new NotImplementedException();
- }
-
- public void VisitAnd(DMASTAnd and) {
- throw new NotImplementedException();
- }
-
- public void VisitBinaryAnd(DMASTBinaryAnd binaryAnd) {
- throw new NotImplementedException();
- }
-
- public void VisitBinaryXor(DMASTBinaryXor binaryXor) {
- throw new NotImplementedException();
- }
-
- public void VisitBinaryOr(DMASTBinaryOr binaryOr) {
- throw new NotImplementedException();
- }
-
- public void VisitBinaryNot(DMASTBinaryNot binaryNot) {
- throw new NotImplementedException();
- }
-
- public void VisitLeftShift(DMASTLeftShift leftShift) {
- throw new NotImplementedException();
- }
-
- public void VisitRightShift(DMASTRightShift rightShift) {
- throw new NotImplementedException();
- }
-
- public void VisitIn(DMASTExpressionIn expressionIn) {
- throw new NotImplementedException();
- }
-
- public void VisitInRange(DMASTExpressionInRange expressionInRange) {
- throw new NotImplementedException();
- }
-
- public void VisitProcCall(DMASTProcCall procCall) {
- throw new NotImplementedException();
- }
-
- public void VisitCallParameter(DMASTCallParameter callParameter) {
- throw new NotImplementedException();
- }
-
- public void VisitDefinitionParameter(DMASTDefinitionParameter definitionParameter) {
- throw new NotImplementedException();
- }
-
- public void VisitDereference(DMASTDereference deref) {
- throw new NotImplementedException();
- }
-
- public void VisitCallableProcIdentifier(DMASTCallableProcIdentifier procIdentifier) {
- throw new NotImplementedException();
- }
-
- public void VisitCallableSuper(DMASTCallableSuper super) {
- throw new NotImplementedException();
- }
-
- public void VisitCallableSelf(DMASTCallableSelf self) {
- throw new NotImplementedException();
- }
-
- public void VisitCallableGlobalProc(DMASTCallableGlobalProc globalIdentifier) {
- throw new NotImplementedException();
- }
- }
-
- public abstract class DMASTNode(Location location) {
- public readonly Location Location = location;
-
- public abstract void Visit(DMASTVisitor visitor);
- }
-
- public abstract class DMASTStatement : DMASTNode {
- protected DMASTStatement(Location location) : base(location) {
- }
- }
-
- public abstract class DMASTProcStatement : DMASTNode {
- protected DMASTProcStatement(Location location)
- : base(location) {
- }
-
- ///
- /// Returns true if this statement is either T or an aggregation of T (stored by an instance). False otherwise.
- ///
- public bool IsAggregateOr() where T : DMASTProcStatement {
- return (this is T or DMASTAggregate);
- }
- }
-
- public abstract class DMASTExpression : DMASTNode {
- protected DMASTExpression(Location location) : base(location) {
- }
-
- public virtual IEnumerable Leaves() {
- yield break;
- }
-
- ///
- /// If this is a , returns the expression inside.
- /// Returns this expression if not.
- ///
- public virtual DMASTExpression GetUnwrapped() {
- return this;
- }
- }
-
- public abstract class DMASTExpressionConstant : DMASTExpression {
- protected DMASTExpressionConstant(Location location) : base(location) {
- }
- }
-
- public interface DMASTCallable {
- }
-
- public sealed class DMASTFile : DMASTNode {
- public readonly DMASTBlockInner BlockInner;
-
- public DMASTFile(Location location, DMASTBlockInner blockInner) : base(location) {
- BlockInner = blockInner;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitFile(this);
- }
- }
-
- public sealed class DMASTBlockInner : DMASTNode {
- public readonly DMASTStatement[] Statements;
-
- public DMASTBlockInner(Location location, DMASTStatement[] statements) : base(location) {
- Statements = statements;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitBlockInner(this);
- }
- }
-
- public sealed class DMASTProcBlockInner : DMASTNode {
- public readonly DMASTProcStatement[] Statements;
-
- ///
- /// SetStatements is held separately because all set statements need to be, to borrow cursed JS terms, "hoisted" to the top of the block, before anything else.
- /// This isn't SPECIFICALLY a array because some of these may be DMASTAggregate instances.
- ///
- public readonly DMASTProcStatement[] SetStatements;
-
- /// Initializes an empty block.
- public DMASTProcBlockInner(Location location) : base(location) {
- Statements = Array.Empty();
- SetStatements = Array.Empty();
- }
-
- /// Initializes a block with only one statement (which may be a :o)
- public DMASTProcBlockInner(Location location, DMASTProcStatement statement) : base(location) {
- if (statement.IsAggregateOr()) {
- // If this is a Set statement or a set of Set statements
- Statements = Array.Empty();
- SetStatements = new[] { statement };
- } else {
- Statements = new[] { statement };
- SetStatements = Array.Empty();
- }
- }
-
- public DMASTProcBlockInner(Location location, DMASTProcStatement[] statements,
- DMASTProcStatement[]? setStatements)
- : base(location) {
- Statements = statements;
- SetStatements = setStatements ?? Array.Empty();
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcBlockInner(this);
- }
- }
-
- public sealed class DMASTObjectDefinition : DMASTStatement {
- /// Unlike other Path variables stored by AST nodes, this path is guaranteed to be the real, absolute path of this object definition block.
- /// That includes any inherited pathing from being tabbed into a different, base definition.
- ///
- public DreamPath Path;
-
- public readonly DMASTBlockInner? InnerBlock;
-
- public DMASTObjectDefinition(Location location, DreamPath path, DMASTBlockInner? innerBlock) : base(location) {
- Path = path;
- InnerBlock = innerBlock;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitObjectDefinition(this);
- }
- }
-
- /// Also includes proc overrides; see the member. Verbs too.
- public sealed class DMASTProcDefinition : DMASTStatement {
- public readonly DreamPath ObjectPath;
- public readonly string Name;
- public readonly bool IsOverride;
- public readonly bool IsVerb;
- public readonly DMASTDefinitionParameter[] Parameters;
- public readonly DMASTProcBlockInner? Body;
-
- public DMASTProcDefinition(Location location, DreamPath path, DMASTDefinitionParameter[] parameters,
- DMASTProcBlockInner? body) : base(location) {
- int procElementIndex = path.FindElement("proc");
-
- if (procElementIndex == -1) {
- procElementIndex = path.FindElement("verb");
-
- if (procElementIndex != -1) IsVerb = true;
- else IsOverride = true;
- }
-
- if (procElementIndex != -1) path = path.RemoveElement(procElementIndex);
-
- ObjectPath = (path.Elements.Length > 1) ? path.FromElements(0, -2) : DreamPath.Root;
- Name = path.LastElement;
- Parameters = parameters;
- Body = body;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcDefinition(this);
- }
- }
-
- //TODO: This can probably be replaced with a DreamPath nullable
- public sealed class DMASTPath : DMASTNode {
- public DreamPath Path;
- public bool IsOperator = false;
-
- public DMASTPath(Location location, DreamPath path, bool operatorFlag = false) : base(location) {
- Path = path;
- IsOperator = operatorFlag;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitPath(this);
- }
- }
-
- public sealed class DMASTObjectVarDefinition : DMASTStatement {
- /// The path of the object that we are a property of.
- public DreamPath ObjectPath => _varDecl.ObjectPath;
-
- /// The actual type of the variable itself.
- public DreamPath? Type => _varDecl.IsList ? DreamPath.List : _varDecl.TypePath;
-
- public string Name => _varDecl.VarName;
- public DMASTExpression Value;
-
- private readonly ObjVarDeclInfo _varDecl;
-
- public bool IsStatic => _varDecl.IsStatic;
-
- public bool IsGlobal =>
- _varDecl.IsStatic; // TODO: Standardize our phrasing in the codebase. Are we calling these Statics or Globals?
-
- public bool IsConst => _varDecl.IsConst;
- public bool IsTmp => _varDecl.IsTmp;
-
- public readonly DMValueType ValType;
-
- public DMASTObjectVarDefinition(Location location, DreamPath path, DMASTExpression value,
- DMValueType valType = DMValueType.Anything) : base(location) {
- _varDecl = new ObjVarDeclInfo(path);
- Value = value;
- ValType = valType;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitObjectVarDefinition(this);
- }
- }
-
- public sealed class DMASTMultipleObjectVarDefinitions : DMASTStatement {
- public readonly DMASTObjectVarDefinition[] VarDefinitions;
-
- public DMASTMultipleObjectVarDefinitions(Location location, DMASTObjectVarDefinition[] varDefinitions) :
- base(location) {
- VarDefinitions = varDefinitions;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitMultipleObjectVarDefinitions(this);
- }
- }
-
- public sealed class DMASTObjectVarOverride : DMASTStatement {
- public readonly DreamPath ObjectPath;
- public readonly string VarName;
- public DMASTExpression Value;
-
- public DMASTObjectVarOverride(Location location, DreamPath path, DMASTExpression value) : base(location) {
- ObjectPath = path.FromElements(0, -2);
- VarName = path.LastElement;
- Value = value;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitObjectVarOverride(this);
- }
- }
-
- /// Lone semicolon, analogous to null statements in C.
- /// Main purpose is to suppress EmptyBlock emissions.
- public sealed class DMASTNullProcStatement(Location location) : DMASTProcStatement(location) {
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitNullProcStatement(this);
- }
- }
-
- public sealed class DMASTProcStatementExpression : DMASTProcStatement {
- public DMASTExpression Expression;
-
- public DMASTProcStatementExpression(Location location, DMASTExpression expression) : base(location) {
- Expression = expression;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcStatementExpression(this);
- }
- }
-
- public sealed class DMASTProcStatementVarDeclaration : DMASTProcStatement {
- public DMASTExpression? Value;
-
- public DreamPath? Type => _varDecl.IsList ? DreamPath.List : _varDecl.TypePath;
- public string Name => _varDecl.VarName;
- public bool IsGlobal => _varDecl.IsStatic;
- public bool IsConst => _varDecl.IsConst;
-
- private readonly ProcVarDeclInfo _varDecl;
-
- public DMASTProcStatementVarDeclaration(Location location, DMASTPath path, DMASTExpression? value) :
- base(location) {
- _varDecl = new ProcVarDeclInfo(path.Path);
- Value = value;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcStatementVarDeclaration(this);
- }
- }
-
- ///
- /// A kinda-abstract class that represents several statements that were created in unison by one "super-statement"
- /// Such as, a var declaration that actually declares several vars at once (which in our parser must become "one" statement, hence this thing)
- ///
- /// The DMASTProcStatement-derived class that this AST node holds.
- public sealed class DMASTAggregate : DMASTProcStatement where T : DMASTProcStatement {
- // Gotta be honest? I like this "where" syntax better than C++20 concepts
- public T[] Statements { get; }
-
- public DMASTAggregate(Location location, T[] statements) : base(location) {
- Statements = statements;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- foreach (T statement in Statements)
- statement.Visit(visitor);
- }
- }
-
- public sealed class DMASTProcStatementReturn : DMASTProcStatement {
- public DMASTExpression? Value;
-
- public DMASTProcStatementReturn(Location location, DMASTExpression? value) : base(location) {
- Value = value;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcStatementReturn(this);
- }
- }
-
- public sealed class DMASTProcStatementBreak : DMASTProcStatement {
- public readonly DMASTIdentifier? Label;
-
- public DMASTProcStatementBreak(Location location, DMASTIdentifier? label = null) : base(location) {
- Label = label;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcStatementBreak(this);
- }
- }
-
- public sealed class DMASTProcStatementContinue : DMASTProcStatement {
- public readonly DMASTIdentifier? Label;
-
- public DMASTProcStatementContinue(Location location, DMASTIdentifier? label = null) : base(location) {
- Label = label;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcStatementContinue(this);
- }
- }
-
- public sealed class DMASTProcStatementGoto : DMASTProcStatement {
- public readonly DMASTIdentifier Label;
-
- public DMASTProcStatementGoto(Location location, DMASTIdentifier label) : base(location) {
- Label = label;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcStatementGoto(this);
- }
- }
-
- public sealed class DMASTProcStatementLabel : DMASTProcStatement {
- public readonly string Name;
- public readonly DMASTProcBlockInner? Body;
-
- public DMASTProcStatementLabel(Location location, string name, DMASTProcBlockInner? body) : base(location) {
- Name = name;
- Body = body;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcStatementLabel(this);
- }
- }
-
- public sealed class DMASTProcStatementDel : DMASTProcStatement {
- public DMASTExpression Value;
-
- public DMASTProcStatementDel(Location location, DMASTExpression value) : base(location) {
- Value = value;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcStatementDel(this);
- }
- }
-
- public sealed class DMASTProcStatementSet : DMASTProcStatement {
- public readonly string Attribute;
- public readonly DMASTExpression Value;
- public readonly bool WasInKeyword; // Marks whether this was a "set x in y" expression, or a "set x = y" one
-
- public DMASTProcStatementSet(Location location, string attribute, DMASTExpression value, bool wasInKeyword) :
- base(location) {
- Attribute = attribute;
- Value = value;
- WasInKeyword = wasInKeyword;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcStatementSet(this);
- }
- }
-
- public sealed class DMASTProcStatementSpawn : DMASTProcStatement {
- public DMASTExpression Delay;
- public readonly DMASTProcBlockInner Body;
-
- public DMASTProcStatementSpawn(Location location, DMASTExpression delay, DMASTProcBlockInner body) :
- base(location) {
- Delay = delay;
- Body = body;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcStatementSpawn(this);
- }
- }
-
- public sealed class DMASTProcStatementIf : DMASTProcStatement {
- public DMASTExpression Condition;
- public readonly DMASTProcBlockInner Body;
- public readonly DMASTProcBlockInner? ElseBody;
-
- public DMASTProcStatementIf(Location location, DMASTExpression condition, DMASTProcBlockInner body,
- DMASTProcBlockInner? elseBody = null) : base(location) {
- Condition = condition;
- Body = body;
- ElseBody = elseBody;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcStatementIf(this);
- }
- }
-
- public sealed class DMASTProcStatementFor : DMASTProcStatement {
- public DMASTExpression? Expression1, Expression2, Expression3;
- public DMValueType? DMTypes;
- public readonly DMASTProcBlockInner Body;
-
- public DMASTProcStatementFor(Location location, DMASTExpression? expr1, DMASTExpression? expr2,
- DMASTExpression? expr3, DMValueType? dmTypes, DMASTProcBlockInner body) : base(location) {
- Expression1 = expr1;
- Expression2 = expr2;
- Expression3 = expr3;
- DMTypes = dmTypes;
- Body = body;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcStatementFor(this);
- }
- }
-
- public sealed class DMASTProcStatementInfLoop : DMASTProcStatement {
- public readonly DMASTProcBlockInner Body;
-
- public DMASTProcStatementInfLoop(Location location, DMASTProcBlockInner body) : base(location) {
- Body = body;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcStatementInfLoop(this);
- }
- }
-
- public sealed class DMASTProcStatementWhile : DMASTProcStatement {
- public DMASTExpression Conditional;
- public readonly DMASTProcBlockInner Body;
-
- public DMASTProcStatementWhile(Location location, DMASTExpression conditional, DMASTProcBlockInner body) :
- base(location) {
- Conditional = conditional;
- Body = body;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcStatementWhile(this);
- }
- }
-
- public sealed class DMASTProcStatementDoWhile : DMASTProcStatement {
- public DMASTExpression Conditional;
- public readonly DMASTProcBlockInner Body;
-
- public DMASTProcStatementDoWhile(Location location, DMASTExpression conditional, DMASTProcBlockInner body) :
- base(location) {
- Conditional = conditional;
- Body = body;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcStatementDoWhile(this);
- }
- }
-
- public sealed class DMASTProcStatementSwitch : DMASTProcStatement {
- public class SwitchCase {
- public readonly DMASTProcBlockInner Body;
-
- protected SwitchCase(DMASTProcBlockInner body) {
- Body = body;
- }
- }
-
- public sealed class SwitchCaseDefault : SwitchCase {
- public SwitchCaseDefault(DMASTProcBlockInner body) : base(body) {
- }
- }
-
- public sealed class SwitchCaseValues : SwitchCase {
- public readonly DMASTExpression[] Values;
-
- public SwitchCaseValues(DMASTExpression[] values, DMASTProcBlockInner body) : base(body) {
- Values = values;
- }
- }
-
- public DMASTExpression Value;
- public readonly SwitchCase[] Cases;
-
- public DMASTProcStatementSwitch(Location location, DMASTExpression value, SwitchCase[] cases) : base(location) {
- Value = value;
- Cases = cases;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcStatementSwitch(this);
- }
- }
-
- public sealed class DMASTProcStatementBrowse : DMASTProcStatement {
- public DMASTExpression Receiver;
- public DMASTExpression Body;
- public DMASTExpression Options;
-
- public DMASTProcStatementBrowse(Location location, DMASTExpression receiver, DMASTExpression body,
- DMASTExpression options) : base(location) {
- Receiver = receiver;
- Body = body;
- Options = options;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcStatementBrowse(this);
- }
- }
-
- public sealed class DMASTProcStatementBrowseResource : DMASTProcStatement {
- public DMASTExpression Receiver;
- public DMASTExpression File;
- public DMASTExpression Filename;
-
- public DMASTProcStatementBrowseResource(Location location, DMASTExpression receiver, DMASTExpression file,
- DMASTExpression filename) : base(location) {
- Receiver = receiver;
- File = file;
- Filename = filename;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcStatementBrowseResource(this);
- }
- }
-
- public sealed class DMASTProcStatementOutputControl : DMASTProcStatement {
- public DMASTExpression Receiver;
- public DMASTExpression Message;
- public DMASTExpression Control;
-
- public DMASTProcStatementOutputControl(Location location, DMASTExpression receiver, DMASTExpression message,
- DMASTExpression control) : base(location) {
- Receiver = receiver;
- Message = message;
- Control = control;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcStatementOutputControl(this);
- }
- }
-
- public sealed class DMASTProcStatementFtp : DMASTProcStatement {
- public DMASTExpression Receiver;
- public DMASTExpression File;
- public DMASTExpression Name;
-
- public DMASTProcStatementFtp(Location location, DMASTExpression receiver, DMASTExpression file, DMASTExpression name) : base(location) {
- Receiver = receiver;
- File = file;
- Name = name;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcStatementFtp(this);
- }
- }
-
- public sealed class DMASTProcStatementOutput : DMASTProcStatement {
- public DMASTExpression A, B;
-
- public DMASTProcStatementOutput(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcStatementOutput(this);
- }
- }
-
- public sealed class DMASTProcStatementInput : DMASTProcStatement {
- public DMASTExpression A, B;
-
- public DMASTProcStatementInput(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcStatementInput(this);
- }
- }
-
- public sealed class DMASTProcStatementTryCatch : DMASTProcStatement {
- public readonly DMASTProcBlockInner TryBody;
- public readonly DMASTProcBlockInner? CatchBody;
- public readonly DMASTProcStatement? CatchParameter;
-
- public DMASTProcStatementTryCatch(Location location, DMASTProcBlockInner tryBody,
- DMASTProcBlockInner? catchBody, DMASTProcStatement? catchParameter) : base(location) {
- TryBody = tryBody;
- CatchBody = catchBody;
- CatchParameter = catchParameter;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcStatementTryCatch(this);
- }
- }
-
- public sealed class DMASTProcStatementThrow : DMASTProcStatement {
- public DMASTExpression Value;
-
- public DMASTProcStatementThrow(Location location, DMASTExpression value) : base(location) {
- Value = value;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcStatementThrow(this);
- }
- }
-
- public sealed class DMASTVoid : DMASTExpression {
- public DMASTVoid(Location location) : base(location) {
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitVoid(this);
- }
- }
-
- public sealed class DMASTIdentifier : DMASTExpression {
- public readonly string Identifier;
-
- public DMASTIdentifier(Location location, string identifier) : base(location) {
- Identifier = identifier;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitIdentifier(this);
- }
- }
-
- public sealed class DMASTGlobalIdentifier : DMASTExpression {
- public readonly string Identifier;
-
- public DMASTGlobalIdentifier(Location location, string identifier) : base(location) {
- Identifier = identifier;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitGlobalIdentifier(this);
- }
- }
-
- public sealed class DMASTConstantInteger : DMASTExpressionConstant {
- public readonly int Value;
-
- public DMASTConstantInteger(Location location, int value) : base(location) {
- Value = value;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitConstantInteger(this);
- }
- }
-
- public sealed class DMASTConstantFloat : DMASTExpressionConstant {
- public readonly float Value;
-
- public DMASTConstantFloat(Location location, float value) : base(location) {
- Value = value;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitConstantFloat(this);
- }
- }
-
- public sealed class DMASTConstantString : DMASTExpressionConstant {
- public readonly string Value;
-
- public DMASTConstantString(Location location, string value) : base(location) {
- Value = value;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitConstantString(this);
- }
- }
-
- public sealed class DMASTConstantResource : DMASTExpressionConstant {
- public readonly string Path;
-
- public DMASTConstantResource(Location location, string path) : base(location) {
- Path = path;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitConstantResource(this);
- }
- }
-
- public sealed class DMASTConstantNull : DMASTExpressionConstant {
- public DMASTConstantNull(Location location)
- : base(location) {
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitConstantNull(this);
- }
- }
-
- public sealed class DMASTConstantPath : DMASTExpressionConstant {
- public readonly DMASTPath Value;
-
- public DMASTConstantPath(Location location, DMASTPath value) : base(location) {
- Value = value;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitConstantPath(this);
- }
- }
-
- public sealed class DMASTUpwardPathSearch : DMASTExpressionConstant {
- public readonly DMASTExpressionConstant Path;
- public readonly DMASTPath Search;
-
- public DMASTUpwardPathSearch(Location location, DMASTExpressionConstant path, DMASTPath search) :
- base(location) {
- Path = path;
- Search = search;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitUpwardPathSearch(this);
- }
- }
-
- public sealed class DMASTSwitchCaseRange : DMASTExpression {
- public DMASTExpression RangeStart, RangeEnd;
-
- public DMASTSwitchCaseRange(Location location, DMASTExpression rangeStart, DMASTExpression rangeEnd) :
- base(location) {
- RangeStart = rangeStart;
- RangeEnd = rangeEnd;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitSwitchCaseRange(this);
- }
- }
-
- public sealed class DMASTStringFormat : DMASTExpression {
- public readonly string Value;
- public readonly DMASTExpression?[] InterpolatedValues;
-
- public DMASTStringFormat(Location location, string value, DMASTExpression?[] interpolatedValues) :
- base(location) {
- Value = value;
- InterpolatedValues = interpolatedValues;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitStringFormat(this);
- }
- }
-
- public sealed class DMASTList : DMASTExpression {
- public readonly DMASTCallParameter[] Values;
-
- public DMASTList(Location location, DMASTCallParameter[] values) : base(location) {
- Values = values;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitList(this);
- }
-
- public bool AllValuesConstant() {
- return Values.All(
- value => (value is {
- Key: DMASTExpressionConstant,
- Value: DMASTExpressionConstant
- })
- ||
- (value is {
- Key: DMASTExpressionConstant,
- Value: DMASTList valueList
- } && valueList.AllValuesConstant())
- );
- }
- }
-
- ///
- /// Represents the value of a var defined as var/list/L[1][2][3]
- ///
- public sealed class DMASTDimensionalList : DMASTExpression {
- public readonly List Sizes;
-
- public DMASTDimensionalList(Location location, List sizes) : base(location) {
- Sizes = sizes;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitDimensionalList(this);
- }
- }
-
- public sealed class DMASTAddText : DMASTExpression {
- public readonly DMASTCallParameter[] Parameters;
-
- public DMASTAddText(Location location, DMASTCallParameter[] parameters) : base(location) {
- Parameters = parameters;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitAddText(this);
- }
- }
-
- public sealed class DMASTProb : DMASTExpression {
- public readonly DMASTExpression P;
-
- public DMASTProb(Location location, DMASTExpression p) : base(location) {
- P = p;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProb(this);
- }
- }
-
- public sealed class DMASTNewList : DMASTExpression {
- public readonly DMASTCallParameter[] Parameters;
-
- public DMASTNewList(Location location, DMASTCallParameter[] parameters) : base(location) {
- Parameters = parameters;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitNewList(this);
- }
- }
-
- public sealed class DMASTInput : DMASTExpression {
- public readonly DMASTCallParameter[] Parameters;
- public DMValueType? Types;
- public readonly DMASTExpression? List;
-
- public DMASTInput(Location location, DMASTCallParameter[] parameters, DMValueType? types,
- DMASTExpression? list) : base(location) {
- Parameters = parameters;
- Types = types;
- List = list;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitInput(this);
- }
- }
-
- public sealed class DMASTInitial : DMASTExpression {
- public readonly DMASTExpression Expression;
-
- public DMASTInitial(Location location, DMASTExpression expression) : base(location) {
- Expression = expression;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitInitial(this);
- }
- }
-
- public sealed class DMASTNameof : DMASTExpression {
- public DMASTExpression Expression;
-
- public DMASTNameof(Location location, DMASTExpression expression) : base(location) {
- Expression = expression;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitNameof(this);
- }
- }
-
- public sealed class DMASTIsSaved : DMASTExpression {
- public readonly DMASTExpression Expression;
-
- public DMASTIsSaved(Location location, DMASTExpression expression) : base(location) {
- Expression = expression;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitIsSaved(this);
- }
- }
-
- public sealed class DMASTIsType : DMASTExpression {
- public readonly DMASTExpression Value;
- public readonly DMASTExpression Type;
-
- public DMASTIsType(Location location, DMASTExpression value, DMASTExpression type) : base(location) {
- Value = value;
- Type = type;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitIsType(this);
- }
- }
-
- public sealed class DMASTIsNull : DMASTExpression {
- public readonly DMASTExpression Value;
-
- public DMASTIsNull(Location location, DMASTExpression value) : base(location) {
- Value = value;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitIsNull(this);
- }
- }
-
- public sealed class DMASTLength : DMASTExpression {
- public readonly DMASTExpression Value;
-
- public DMASTLength(Location location, DMASTExpression value) : base(location) {
- Value = value;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitLength(this);
- }
- }
-
- public sealed class DMASTGetStep : DMASTExpression {
- public readonly DMASTExpression Ref;
- public readonly DMASTExpression Dir;
-
- public DMASTGetStep(Location location, DMASTExpression refValue, DMASTExpression dir) : base(location) {
- Ref = refValue;
- Dir = dir;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitGetStep(this);
- }
- }
-
- public sealed class DMASTGetDir : DMASTExpression {
- public readonly DMASTExpression Loc1;
- public readonly DMASTExpression Loc2;
-
- public DMASTGetDir(Location location, DMASTExpression loc1, DMASTExpression loc2) : base(location) {
- Loc1 = loc1;
- Loc2 = loc2;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitGetDir(this);
- }
- }
-
- public sealed class DMASTImplicitIsType : DMASTExpression {
- public readonly DMASTExpression Value;
-
- public DMASTImplicitIsType(Location location, DMASTExpression value) : base(location) {
- Value = value;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitImplicitIsType(this);
- }
- }
-
- public sealed class DMASTLocateCoordinates : DMASTExpression {
- public readonly DMASTExpression X, Y, Z;
-
- public DMASTLocateCoordinates(Location location, DMASTExpression x, DMASTExpression y, DMASTExpression z) :
- base(location) {
- X = x;
- Y = y;
- Z = z;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitLocateCoordinates(this);
- }
- }
-
- public sealed class DMASTLocate : DMASTExpression {
- public readonly DMASTExpression? Expression;
- public readonly DMASTExpression? Container;
-
- public DMASTLocate(Location location, DMASTExpression? expression, DMASTExpression? container) :
- base(location) {
- Expression = expression;
- Container = container;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitLocate(this);
- }
- }
-
- public sealed class DMASTGradient : DMASTExpression {
- public readonly DMASTCallParameter[] Parameters;
-
- public DMASTGradient(Location location, DMASTCallParameter[] parameters) : base(location) {
- Parameters = parameters;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitGradient(this);
- }
- }
-
- public sealed class DMASTPick : DMASTExpression {
- public struct PickValue {
- public readonly DMASTExpression? Weight;
- public readonly DMASTExpression Value;
-
- public PickValue(DMASTExpression? weight, DMASTExpression value) {
- Weight = weight;
- Value = value;
- }
- }
-
- public readonly PickValue[] Values;
-
- public DMASTPick(Location location, PickValue[] values) : base(location) {
- Values = values;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitPick(this);
- }
- }
-
- public class DMASTSin : DMASTExpression {
- public DMASTExpression Expression;
-
- public DMASTSin(Location location, DMASTExpression expression) : base(location) {
- Expression = expression;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitSin(this);
- }
- }
-
- public class DMASTCos : DMASTExpression {
- public DMASTExpression Expression;
-
- public DMASTCos(Location location, DMASTExpression expression) : base(location) {
- Expression = expression;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitCos(this);
- }
- }
-
- public class DMASTTan : DMASTExpression {
- public DMASTExpression Expression;
-
- public DMASTTan(Location location, DMASTExpression expression) : base(location) {
- Expression = expression;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitTan(this);
- }
- }
-
- public class DMASTArcsin : DMASTExpression {
- public DMASTExpression Expression;
-
- public DMASTArcsin(Location location, DMASTExpression expression) : base(location) {
- Expression = expression;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitArcsin(this);
- }
- }
-
- public class DMASTArccos : DMASTExpression {
- public DMASTExpression Expression;
-
- public DMASTArccos(Location location, DMASTExpression expression) : base(location) {
- Expression = expression;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitArccos(this);
- }
- }
-
- public class DMASTArctan : DMASTExpression {
- public DMASTExpression Expression;
-
- public DMASTArctan(Location location, DMASTExpression expression) : base(location) {
- Expression = expression;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitArctan(this);
- }
- }
-
- public class DMASTArctan2 : DMASTExpression {
- public DMASTExpression XExpression;
- public DMASTExpression YExpression;
-
- public DMASTArctan2(Location location, DMASTExpression xExpression, DMASTExpression yExpression) : base(location) {
- XExpression = xExpression;
- YExpression = yExpression;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitArctan2(this);
- }
- }
-
- public class DMASTSqrt : DMASTExpression {
- public DMASTExpression Expression;
-
- public DMASTSqrt(Location location, DMASTExpression expression) : base(location) {
- Expression = expression;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitSqrt(this);
- }
- }
-
- public class DMASTLog : DMASTExpression {
- public DMASTExpression Expression;
- public DMASTExpression? BaseExpression;
-
- public DMASTLog(Location location, DMASTExpression expression, DMASTExpression? baseExpression) : base(location) {
- Expression = expression;
- BaseExpression = baseExpression;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitLog(this);
- }
- }
-
- public class DMASTAbs : DMASTExpression {
- public DMASTExpression Expression;
-
- public DMASTAbs(Location location, DMASTExpression expression) : base(location) {
- Expression = expression;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitAbs(this);
- }
- }
- public sealed class DMASTCall : DMASTExpression {
- public readonly DMASTCallParameter[] CallParameters, ProcParameters;
-
- public DMASTCall(Location location, DMASTCallParameter[] callParameters, DMASTCallParameter[] procParameters) :
- base(location) {
- CallParameters = callParameters;
- ProcParameters = procParameters;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitCall(this);
- }
- }
-
- public sealed class DMASTAssign : DMASTExpression {
- public DMASTExpression Expression, Value;
-
- public DMASTAssign(Location location, DMASTExpression expression, DMASTExpression value) : base(location) {
- Expression = expression;
- Value = value;
- }
-
- public override IEnumerable Leaves() {
- yield return Expression;
- yield return Value;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitAssign(this);
- }
- }
-
- public class DMASTAssignInto : DMASTExpression {
- public DMASTExpression Expression, Value;
-
- public DMASTAssignInto(Location location, DMASTExpression expression, DMASTExpression value) : base(location) {
- Expression = expression;
- Value = value;
- }
-
- public override IEnumerable Leaves() {
- yield return Expression;
- yield return Value;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitAssignInto(this);
- }
- }
-
- public class DMASTVarDeclExpression : DMASTExpression {
- public DMASTPath DeclPath;
- public DMASTVarDeclExpression(Location location, DMASTPath path) : base(location) {
- DeclPath = path;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitVarDeclExpression(this);
- }
- }
-
- public sealed class DMASTNewPath : DMASTExpression {
- public readonly DMASTConstantPath Path;
- public readonly DMASTCallParameter[] Parameters;
-
- public DMASTNewPath(Location location, DMASTConstantPath path, DMASTCallParameter[] parameters) : base(location) {
- Path = path;
- Parameters = parameters;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitNewPath(this);
- }
- }
-
- public sealed class DMASTNewExpr : DMASTExpression {
- public DMASTExpression Expression;
- public readonly DMASTCallParameter[] Parameters;
-
- public DMASTNewExpr(Location location, DMASTExpression expression, DMASTCallParameter[] parameters) :
- base(location) {
- Expression = expression;
- Parameters = parameters;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitNewExpr(this);
- }
- }
-
- public sealed class DMASTNewInferred : DMASTExpression {
- public readonly DMASTCallParameter[] Parameters;
-
- public DMASTNewInferred(Location location, DMASTCallParameter[] parameters) : base(location) {
- Parameters = parameters;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitNewInferred(this);
- }
- }
-
- public sealed class DMASTNot : DMASTExpression {
- public DMASTExpression Expression;
-
- public DMASTNot(Location location, DMASTExpression expression) : base(location) {
- Expression = expression;
- }
-
- public override IEnumerable Leaves() {
- yield return Expression;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitNot(this);
- }
- }
-
- public sealed class DMASTNegate : DMASTExpression {
- public DMASTExpression Expression;
-
- public DMASTNegate(Location location, DMASTExpression expression) : base(location) {
- Expression = expression;
- }
-
- public override IEnumerable Leaves() {
- yield return Expression;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitNegate(this);
- }
- }
-
- public sealed class DMASTEqual : DMASTExpression {
- public DMASTExpression A, B;
-
- public DMASTEqual(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitEqual(this);
- }
- }
-
- public sealed class DMASTNotEqual : DMASTExpression {
- public DMASTExpression A, B;
-
- public DMASTNotEqual(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitNotEqual(this);
- }
- }
-
- public sealed class DMASTEquivalent : DMASTExpression {
- public readonly DMASTExpression A, B;
-
- public DMASTEquivalent(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitEquivalent(this);
- }
- }
-
- public sealed class DMASTNotEquivalent : DMASTExpression {
- public readonly DMASTExpression A, B;
-
- public DMASTNotEquivalent(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitNotEquivalent(this);
- }
- }
-
- public sealed class DMASTLessThan : DMASTExpression {
- public DMASTExpression A, B;
-
- public DMASTLessThan(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitLessThan(this);
- }
- }
-
- public sealed class DMASTLessThanOrEqual : DMASTExpression {
- public DMASTExpression A, B;
-
- public DMASTLessThanOrEqual(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitLessThanOrEqual(this);
- }
- }
-
- public sealed class DMASTGreaterThan : DMASTExpression {
- public DMASTExpression A, B;
-
- public DMASTGreaterThan(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitGreaterThan(this);
- }
- }
-
- public sealed class DMASTGreaterThanOrEqual : DMASTExpression {
- public DMASTExpression A, B;
-
- public DMASTGreaterThanOrEqual(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitGreaterThanOrEqual(this);
- }
- }
-
- public sealed class DMASTMultiply : DMASTExpression {
- public DMASTExpression A, B;
-
- public DMASTMultiply(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitMultiply(this);
- }
- }
-
- public sealed class DMASTDivide : DMASTExpression {
- public DMASTExpression A, B;
-
- public DMASTDivide(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitDivide(this);
- }
- }
-
- public sealed class DMASTModulus : DMASTExpression {
- public DMASTExpression A, B;
-
- public DMASTModulus(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitModulus(this);
- }
- }
-
- public sealed class DMASTModulusModulus : DMASTExpression {
- public readonly DMASTExpression A, B;
-
- public DMASTModulusModulus(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitModulusModulus(this);
- }
- }
-
- public sealed class DMASTPower : DMASTExpression {
- public DMASTExpression A, B;
-
- public DMASTPower(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitPower(this);
- }
- }
-
- public sealed class DMASTAdd : DMASTExpression {
- public DMASTExpression A, B;
-
- public DMASTAdd(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitAdd(this);
- }
- }
-
- public sealed class DMASTSubtract : DMASTExpression {
- public DMASTExpression A, B;
-
- public DMASTSubtract(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitSubtract(this);
- }
- }
-
- public sealed class DMASTPreIncrement : DMASTExpression {
- public readonly DMASTExpression Expression;
-
- public DMASTPreIncrement(Location location, DMASTExpression expression) : base(location) {
- Expression = expression;
- }
-
- public override IEnumerable Leaves() {
- yield return Expression;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitPreIncrement(this);
- }
- }
-
- public sealed class DMASTPreDecrement : DMASTExpression {
- public readonly DMASTExpression Expression;
-
- public DMASTPreDecrement(Location location, DMASTExpression expression) : base(location) {
- Expression = expression;
- }
-
- public override IEnumerable Leaves() {
- yield return Expression;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitPreDecrement(this);
- }
- }
-
- public sealed class DMASTPostIncrement : DMASTExpression {
- public readonly DMASTExpression Expression;
-
- public DMASTPostIncrement(Location location, DMASTExpression expression) : base(location) {
- Expression = expression;
- }
-
- public override IEnumerable Leaves() {
- yield return Expression;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitPostIncrement(this);
- }
- }
-
- public sealed class DMASTPostDecrement : DMASTExpression {
- public readonly DMASTExpression Expression;
-
- public DMASTPostDecrement(Location location, DMASTExpression expression) : base(location) {
- Expression = expression;
- }
-
- public override IEnumerable Leaves() {
- yield return Expression;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitPostDecrement(this);
- }
- }
-
- public sealed class DMASTTernary : DMASTExpression {
- public readonly DMASTExpression A, B, C;
-
- public DMASTTernary(Location location, DMASTExpression a, DMASTExpression b, DMASTExpression c) :
- base(location) {
- A = a;
- B = b;
- C = c;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- yield return C;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitTernary(this);
- }
- }
-
- public sealed class DMASTAppend : DMASTExpression {
- public DMASTExpression A, B;
-
- public DMASTAppend(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitAppend(this);
- }
- }
-
- public sealed class DMASTRemove : DMASTExpression {
- public DMASTExpression A, B;
-
- public DMASTRemove(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitRemove(this);
- }
- }
-
- public sealed class DMASTCombine : DMASTExpression {
- public DMASTExpression A, B;
-
- public DMASTCombine(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitCombine(this);
- }
- }
-
- public sealed class DMASTMask : DMASTExpression {
- public DMASTExpression A, B;
-
- public DMASTMask(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitMask(this);
- }
- }
-
- public sealed class DMASTLogicalAndAssign : DMASTExpression {
- public readonly DMASTExpression A, B;
-
- public DMASTLogicalAndAssign(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitLogicalAndAssign(this);
- }
- }
-
- public sealed class DMASTLogicalOrAssign : DMASTExpression {
- public readonly DMASTExpression A, B;
-
- public DMASTLogicalOrAssign(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitLogicalOrAssign(this);
- }
- }
-
- public sealed class DMASTMultiplyAssign : DMASTExpression {
- public readonly DMASTExpression A, B;
-
- public DMASTMultiplyAssign(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitMultiplyAssign(this);
- }
- }
-
- public sealed class DMASTDivideAssign : DMASTExpression {
- public readonly DMASTExpression A, B;
-
- public DMASTDivideAssign(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitDivideAssign(this);
- }
- }
-
- public sealed class DMASTLeftShiftAssign : DMASTExpression {
- public readonly DMASTExpression A, B;
-
- public DMASTLeftShiftAssign(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitLeftShiftAssign(this);
- }
- }
-
- public sealed class DMASTRightShiftAssign : DMASTExpression {
- public readonly DMASTExpression A, B;
-
- public DMASTRightShiftAssign(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitRightShiftAssign(this);
- }
- }
-
- public sealed class DMASTXorAssign : DMASTExpression {
- public readonly DMASTExpression A, B;
-
- public DMASTXorAssign(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitXorAssign(this);
- }
- }
-
- public sealed class DMASTModulusAssign : DMASTExpression {
- public readonly DMASTExpression A, B;
-
- public DMASTModulusAssign(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitModulusAssign(this);
- }
- }
-
- public sealed class DMASTModulusModulusAssign : DMASTExpression {
- public readonly DMASTExpression A, B;
-
- public DMASTModulusModulusAssign(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitModulusModulusAssign(this);
- }
- }
-
- public sealed class DMASTOr : DMASTExpression {
- public DMASTExpression A, B;
-
- public DMASTOr(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitOr(this);
- }
- }
-
- public sealed class DMASTAnd : DMASTExpression {
- public DMASTExpression A, B;
-
- public DMASTAnd(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitAnd(this);
- }
- }
-
- public sealed class DMASTBinaryAnd : DMASTExpression {
- public DMASTExpression A, B;
-
- public DMASTBinaryAnd(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitBinaryAnd(this);
- }
- }
-
- public sealed class DMASTBinaryXor : DMASTExpression {
- public readonly DMASTExpression A, B;
-
- public DMASTBinaryXor(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitBinaryXor(this);
- }
- }
-
- public sealed class DMASTBinaryOr : DMASTExpression {
- public DMASTExpression A, B;
-
- public DMASTBinaryOr(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitBinaryOr(this);
- }
- }
-
- public sealed class DMASTBinaryNot : DMASTExpression {
- public DMASTExpression Value;
-
- public DMASTBinaryNot(Location location, DMASTExpression value) : base(location) {
- Value = value;
- }
-
- public override IEnumerable Leaves() {
- yield return Value;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitBinaryNot(this);
- }
- }
-
- public sealed class DMASTLeftShift : DMASTExpression {
- public DMASTExpression A, B;
-
- public DMASTLeftShift(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitLeftShift(this);
- }
- }
-
- public sealed class DMASTRightShift : DMASTExpression {
- public DMASTExpression A, B;
-
- public DMASTRightShift(Location location, DMASTExpression a, DMASTExpression b) : base(location) {
- A = a;
- B = b;
- }
-
- public override IEnumerable Leaves() {
- yield return A;
- yield return B;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitRightShift(this);
- }
- }
-
- ///
- /// An expression wrapped around parentheses
- /// (1 + 1)
- ///
- public sealed class DMASTExpressionWrapped : DMASTExpression {
- public DMASTExpression Expression;
-
- public DMASTExpressionWrapped(Location location, DMASTExpression expression) : base(location) {
- Expression = expression;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- Expression.Visit(visitor);
- }
-
- public override DMASTExpression GetUnwrapped() {
- DMASTExpression expr = Expression;
- while (expr is DMASTExpressionWrapped wrapped)
- expr = wrapped.Expression;
-
- return expr;
- }
- }
-
- public sealed class DMASTExpressionIn : DMASTExpression {
- public readonly DMASTExpression Value;
- public readonly DMASTExpression List;
-
- public DMASTExpressionIn(Location location, DMASTExpression value, DMASTExpression list) : base(location) {
- Value = value;
- List = list;
- }
-
- public override IEnumerable Leaves() {
- yield return Value;
- yield return List;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitIn(this);
- }
- }
-
- public sealed class DMASTExpressionInRange : DMASTExpression {
- public DMASTExpression Value;
- public DMASTExpression StartRange;
- public DMASTExpression EndRange;
- public readonly DMASTExpression? Step;
-
- public DMASTExpressionInRange(Location location, DMASTExpression value, DMASTExpression startRange,
- DMASTExpression endRange, DMASTExpression? step = null) : base(location) {
- Value = value;
- StartRange = startRange;
- EndRange = endRange;
- Step = step;
- }
-
- public override IEnumerable Leaves() {
- yield return Value;
- yield return StartRange;
- yield return EndRange;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitInRange(this);
- }
- }
-
- public sealed class DMASTProcCall : DMASTExpression {
- public readonly DMASTCallable Callable;
- public readonly DMASTCallParameter[] Parameters;
-
- public DMASTProcCall(Location location, DMASTCallable callable, DMASTCallParameter[] parameters) :
- base(location) {
- Callable = callable;
- Parameters = parameters;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitProcCall(this);
- }
- }
-
- public sealed class DMASTCallParameter : DMASTNode {
- public DMASTExpression Value;
- public readonly DMASTExpression? Key;
-
- public DMASTCallParameter(Location location, DMASTExpression value, DMASTExpression? key = null) :
- base(location) {
- Value = value;
- Key = key;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitCallParameter(this);
- }
- }
-
- public sealed class DMASTDefinitionParameter : DMASTNode {
- public DreamPath? ObjectType => _paramDecl.IsList ? DreamPath.List : _paramDecl.TypePath;
- public string Name => _paramDecl.VarName;
- public DMASTExpression? Value;
- public readonly DMValueType Type;
- public DMASTExpression PossibleValues;
-
- private readonly ProcParameterDeclInfo _paramDecl;
-
- public DMASTDefinitionParameter(Location location, DMASTPath astPath, DMASTExpression? value, DMValueType type,
- DMASTExpression possibleValues) : base(location) {
- _paramDecl = new ProcParameterDeclInfo(astPath.Path);
-
- Value = value;
- Type = type;
- PossibleValues = possibleValues;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitDefinitionParameter(this);
- }
- }
-
-
- public sealed class DMASTDereference : DMASTExpression {
- public abstract class Operation {
- ///
- /// The location of the operation.
- ///
- public required Location Location;
- ///
- /// Whether we should short circuit if the expression we are accessing is null.
- ///
- public required bool Safe; // x?.y, x?.y() etc
- }
-
- public abstract class NamedOperation : Operation {
- ///
- /// Name of the identifier.
- ///
- public required string Identifier;
- ///
- /// Whether we should check if the variable exists or not.
- ///
- public required bool NoSearch; // x:y, x:y()
- }
-
- public sealed class FieldOperation : NamedOperation;
-
- public sealed class IndexOperation : Operation {
- ///
- /// The index expression that we use to index this expression (constant or otherwise).
- ///
- public required DMASTExpression Index; // x[y], x?[y]
- }
-
- public sealed class CallOperation : NamedOperation {
- ///
- /// The parameters that we call this proc with.
- ///
- public required DMASTCallParameter[] Parameters; // x.y(),
- }
-
- public DMASTExpression Expression;
-
- // Always contains at least one operation
- public Operation[] Operations;
-
- public DMASTDereference(Location location, DMASTExpression expression, Operation[] operations) :
- base(location) {
- Expression = expression;
- Operations = operations;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitDereference(this);
- }
- }
-
- public sealed class DMASTCallableProcIdentifier : DMASTExpression, DMASTCallable {
- public readonly string Identifier;
-
- public DMASTCallableProcIdentifier(Location location, string identifier) : base(location) {
- Identifier = identifier;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitCallableProcIdentifier(this);
- }
- }
-
- public sealed class DMASTCallableSuper : DMASTExpression, DMASTCallable {
- public DMASTCallableSuper(Location location) : base(location) {
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitCallableSuper(this);
- }
- }
-
- public sealed class DMASTCallableSelf : DMASTExpression, DMASTCallable {
- public DMASTCallableSelf(Location location) : base(location) {
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitCallableSelf(this);
- }
- }
-
- public sealed class DMASTCallableGlobalProc : DMASTExpression, DMASTCallable {
- public readonly string Identifier;
-
- public DMASTCallableGlobalProc(Location location, string identifier) : base(location) {
- Identifier = identifier;
- }
-
- public override void Visit(DMASTVisitor visitor) {
- visitor.VisitCallableGlobalProc(this);
- }
- }
-}
diff --git a/DMCompiler/Compiler/DM/DMParser.cs b/DMCompiler/Compiler/DM/DMParser.cs
index 51da75118a..4bdae03853 100644
--- a/DMCompiler/Compiler/DM/DMParser.cs
+++ b/DMCompiler/Compiler/DM/DMParser.cs
@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using DMCompiler.Compiler.DM.AST;
using DMCompiler.DM;
namespace DMCompiler.Compiler.DM {
@@ -444,7 +445,7 @@ public DMASTFile File() {
return null;
}
- public DMASTCallable? Callable() {
+ public IDMASTCallable? Callable() {
var loc = Current().Location;
if (Check(TokenType.DM_SuperProc)) return new DMASTCallableSuper(loc);
if (Check(TokenType.DM_Period)) return new DMASTCallableSelf(loc);
@@ -656,11 +657,11 @@ public DMASTFile File() {
return Label(identifier);
case DMASTRightShift rightShift:
// A right shift on its own becomes a special "input" statement
- return new DMASTProcStatementInput(loc, rightShift.A, rightShift.B);
+ return new DMASTProcStatementInput(loc, rightShift.LHS, rightShift.RHS);
case DMASTLeftShift leftShift: {
// A left shift on its own becomes a special "output" statement
// Or something else depending on what's on the right ( browse(), browse_rsc(), output(), etc )
- if (leftShift.B.GetUnwrapped() is DMASTProcCall {Callable: DMASTCallableProcIdentifier identifier} procCall) {
+ if (leftShift.RHS.GetUnwrapped() is DMASTProcCall {Callable: DMASTCallableProcIdentifier identifier} procCall) {
switch (identifier.Identifier) {
case "browse": {
if (procCall.Parameters.Length != 1 && procCall.Parameters.Length != 2)
@@ -670,7 +671,7 @@ public DMASTFile File() {
DMASTExpression options = (procCall.Parameters.Length == 2)
? procCall.Parameters[1].Value
: new DMASTConstantNull(loc);
- return new DMASTProcStatementBrowse(loc, leftShift.A, body, options);
+ return new DMASTProcStatementBrowse(loc, leftShift.LHS, body, options);
}
case "browse_rsc": {
if (procCall.Parameters.Length != 1 && procCall.Parameters.Length != 2)
@@ -680,7 +681,7 @@ public DMASTFile File() {
DMASTExpression filepath = (procCall.Parameters.Length == 2)
? procCall.Parameters[1].Value
: new DMASTConstantNull(loc);
- return new DMASTProcStatementBrowseResource(loc, leftShift.A, file, filepath);
+ return new DMASTProcStatementBrowseResource(loc, leftShift.LHS, file, filepath);
}
case "output": {
if (procCall.Parameters.Length != 2)
@@ -688,7 +689,7 @@ public DMASTFile File() {
DMASTExpression msg = procCall.Parameters[0].Value;
DMASTExpression control = procCall.Parameters[1].Value;
- return new DMASTProcStatementOutputControl(loc, leftShift.A, msg, control);
+ return new DMASTProcStatementOutputControl(loc, leftShift.LHS, msg, control);
}
case "ftp": {
if (procCall.Parameters.Length is not 1 and not 2)
@@ -698,12 +699,12 @@ public DMASTFile File() {
DMASTExpression name = (procCall.Parameters.Length == 2)
? procCall.Parameters[1].Value
: new DMASTConstantNull(loc);
- return new DMASTProcStatementFtp(loc, leftShift.A, file, name);
+ return new DMASTProcStatementFtp(loc, leftShift.LHS, file, name);
}
}
}
- return new DMASTProcStatementOutput(loc, leftShift.A, leftShift.B);
+ return new DMASTProcStatementOutput(loc, leftShift.LHS, leftShift.RHS);
}
}
@@ -1149,7 +1150,7 @@ private DMASTProcStatementSet[] ProcSetEnd(bool allowMultiple) {
if (expr1 is DMASTAssign assign) {
ExpressionTo(out var endRange, out var step);
Consume(TokenType.DM_RightParenthesis, "Expected ')' in for after to expression");
- return new DMASTProcStatementFor(loc, new DMASTExpressionInRange(loc, assign.Expression, assign.Value, endRange, step), null, null, dmTypes, GetForBody(loc));
+ return new DMASTProcStatementFor(loc, new DMASTExpressionInRange(loc, assign.LHS, assign.RHS, endRange, step), null, null, dmTypes, GetForBody(loc));
} else {
Error("Expected = before to in for");
}
@@ -1605,14 +1606,14 @@ public DMASTProcStatementLabel Label(DMASTIdentifier expression) {
return null;
if (expression is DMASTAssign assign) {
- DMASTExpression key = assign.Expression;
+ DMASTExpression key = assign.LHS;
if (key is DMASTIdentifier identifier) {
key = new DMASTConstantString(key.Location, identifier.Identifier);
} else if (key is DMASTConstantNull) {
key = new DMASTConstantString(key.Location, "null");
}
- return new DMASTCallParameter(assign.Location, assign.Value, key);
+ return new DMASTCallParameter(assign.Location, assign.RHS, key);
} else {
return new DMASTCallParameter(expression.Location, expression);
}
@@ -2361,7 +2362,7 @@ private void BracketWhitespace() {
}
private DMASTExpression? ParseProcCall(DMASTExpression? expression) {
- if (expression is not (DMASTCallable or DMASTIdentifier or DMASTGlobalIdentifier)) return expression;
+ if (expression is not (IDMASTCallable or DMASTIdentifier)) return expression;
Whitespace();
@@ -2377,10 +2378,7 @@ private void BracketWhitespace() {
DMASTCallParameter[]? callParameters = ProcCall();
if (callParameters != null) {
- if (expression is DMASTGlobalIdentifier gid) {
- var globalProc = new DMASTCallableGlobalProc(expression.Location, gid.Identifier);
- return new DMASTProcCall(gid.Location, globalProc, callParameters);
- } else if (expression is DMASTCallable callable) {
+ if (expression is IDMASTCallable callable) {
return new DMASTProcCall(expression.Location, callable, callParameters);
}
diff --git a/DMCompiler/Compiler/DM/DMParserHelper.cs b/DMCompiler/Compiler/DM/DMParserHelper.cs
index 747401479f..fa49a17c44 100644
--- a/DMCompiler/Compiler/DM/DMParserHelper.cs
+++ b/DMCompiler/Compiler/DM/DMParserHelper.cs
@@ -3,6 +3,7 @@
using System.Linq;
using System.Text;
using DMCompiler.Bytecode;
+using DMCompiler.Compiler.DM.AST;
namespace DMCompiler.Compiler.DM;
diff --git a/DMCompiler/Compiler/DMM/DMMParser.cs b/DMCompiler/Compiler/DMM/DMMParser.cs
index 88b2aecc1d..72ee17f914 100644
--- a/DMCompiler/Compiler/DMM/DMMParser.cs
+++ b/DMCompiler/Compiler/DMM/DMMParser.cs
@@ -2,6 +2,7 @@
using DMCompiler.DM;
using System.Collections.Generic;
using DMCompiler.Compiler.DM;
+using DMCompiler.Compiler.DM.AST;
using DMCompiler.Json;
namespace DMCompiler.Compiler.DMM;
diff --git a/DMCompiler/Compiler/DMPreprocessor/DMMacro.cs b/DMCompiler/Compiler/DMPreprocessor/DMMacro.cs
index c7841abae2..c5bbf5bb78 100644
--- a/DMCompiler/Compiler/DMPreprocessor/DMMacro.cs
+++ b/DMCompiler/Compiler/DMPreprocessor/DMMacro.cs
@@ -5,12 +5,12 @@
namespace DMCompiler.Compiler.DMPreprocessor;
internal class DMMacro {
- private readonly List _parameters;
- private readonly List _tokens;
- private readonly string _overflowParameter;
+ private readonly List? _parameters;
+ private readonly List? _tokens;
+ private readonly string? _overflowParameter;
private readonly int _overflowParameterIndex;
- public DMMacro(List parameters, List tokens) {
+ public DMMacro(List? parameters, List? tokens) {
_parameters = parameters;
_tokens = tokens;
@@ -53,7 +53,10 @@ public bool HasParameters() {
/// A list of tokens replacing the identifier
/// Thrown if no parameters were given but are required
// TODO: Convert this to an IEnumerator? Could cut down on allocations.
- public virtual List Expand(Token replacing, List>? parameters) {
+ public virtual List? Expand(Token replacing, List>? parameters) {
+ if (_tokens == null)
+ return null;
+
// If this macro has no parameters then we can just return our list of tokens
if (!HasParameters())
return _tokens;
@@ -66,9 +69,9 @@ public virtual List Expand(Token replacing, List>? parameters
foreach (Token token in _tokens) {
string parameterName =
token.Type is TokenType.DM_Preproc_TokenConcat or TokenType.DM_Preproc_ParameterStringify
- ? (string) token.Value
+ ? (string) token.Value!
: token.Text;
- int parameterIndex = _parameters.IndexOf(parameterName);
+ int parameterIndex = _parameters!.IndexOf(parameterName);
if (parameterIndex != -1 && parameters.Count > parameterIndex) {
List parameter = parameters[parameterIndex];
@@ -136,49 +139,43 @@ token.Type is TokenType.DM_Preproc_TokenConcat or TokenType.DM_Preproc_Parameter
}
// __LINE__
-internal sealed class DMMacroLine : DMMacro {
- public DMMacroLine() : base(null, null) { }
-
- public override List Expand(Token replacing, List> parameters) {
- return new(1) {
- new Token(TokenType.DM_Preproc_Number, replacing.Location.Line.ToString(), replacing.Location, null)
- };
+internal sealed class DMMacroLine() : DMMacro(null, null) {
+ public override List Expand(Token replacing, List>? parameters) {
+ var line = replacing.Location.Line;
+ if (line == null)
+ throw new ArgumentException($"Token {replacing} does not have a line number", nameof(replacing));
+
+ return [
+ new Token(TokenType.DM_Preproc_Number, line.Value.ToString(), replacing.Location, null)
+ ];
}
}
// __FILE__
-internal sealed class DMMacroFile : DMMacro {
- public DMMacroFile() : base(null, null) { }
-
- public override List Expand(Token replacing, List> parameters) {
+internal sealed class DMMacroFile() : DMMacro(null, null) {
+ public override List Expand(Token replacing, List>? parameters) {
string path = replacing.Location.SourceFile.Replace(@"\", @"\\"); //Escape any backwards slashes
- return new(1) {
+ return [
new Token(TokenType.DM_Preproc_ConstantString, $"\"{path}\"", replacing.Location, path)
- };
+ ];
}
}
// DM_VERSION
-
-internal sealed class DMMacroVersion : DMMacro {
- public DMMacroVersion() : base(null, null) { }
-
- public override List Expand(Token replacing, List> parameters) {
- return new(1) {
+internal sealed class DMMacroVersion() : DMMacro(null, null) {
+ public override List Expand(Token replacing, List>? parameters) {
+ return [
new Token(TokenType.DM_Preproc_Number, DMCompiler.Settings.DMVersion, replacing.Location, null)
- };
+ ];
}
}
// DM_BUILD
-
-internal sealed class DMMacroBuild : DMMacro {
- public DMMacroBuild() : base(null, null) { }
-
- public override List Expand(Token replacing, List> parameters) {
- return new(1) {
+internal sealed class DMMacroBuild() : DMMacro(null, null) {
+ public override List Expand(Token replacing, List>? parameters) {
+ return [
new Token(TokenType.DM_Preproc_Number, DMCompiler.Settings.DMBuild, replacing.Location, null)
- };
+ ];
}
}
diff --git a/DMCompiler/Compiler/DMPreprocessor/DMPreprocessor.cs b/DMCompiler/Compiler/DMPreprocessor/DMPreprocessor.cs
index 75edb9219d..8be226d712 100644
--- a/DMCompiler/Compiler/DMPreprocessor/DMPreprocessor.cs
+++ b/DMCompiler/Compiler/DMPreprocessor/DMPreprocessor.cs
@@ -12,7 +12,7 @@ namespace DMCompiler.Compiler.DMPreprocessor;
/// The master class for handling DM preprocessing.
/// This is an , and is usually accessed via its output in a for-loop.
///
-public sealed class DMPreprocessor : IEnumerable {
+public sealed class DMPreprocessor(bool enableDirectives) : IEnumerable {
public readonly List IncludedMaps = new(8);
public string? IncludedInterface;
@@ -24,7 +24,7 @@ public sealed class DMPreprocessor : IEnumerable {
private bool _canUseDirective = true;
private readonly HashSet _includedFiles = new(5120); // Capacity Note: TG peaks at 4860 at time of writing
private readonly Stack _unprocessedTokens = new(8192); // Capacity Note: TG peaks at 6802 at time of writing
- private readonly bool _enableDirectives;
+
private readonly Dictionary _defines = new(12288) { // Capacity Note: TG peaks at 9827 at time of writing. Current value is arbitrarily 4096 * 3.
{ "__LINE__", new DMMacroLine() },
{ "__FILE__", new DMMacroFile() },
@@ -39,25 +39,6 @@ public sealed class DMPreprocessor : IEnumerable {
private readonly Stack _lastIfEvaluations = new(16);
private Location _lastSeenIf = Location.Unknown; // used by the errors emitted for when the above var isn't empty at exit
- private static readonly TokenType[] DirectiveTypes = {
- TokenType.DM_Preproc_Include,
- TokenType.DM_Preproc_Define,
- TokenType.DM_Preproc_Undefine,
- TokenType.DM_Preproc_If,
- TokenType.DM_Preproc_Ifdef,
- TokenType.DM_Preproc_Ifndef,
- TokenType.DM_Preproc_Elif,
- TokenType.DM_Preproc_Else,
- TokenType.DM_Preproc_Warning,
- TokenType.DM_Preproc_Error,
- TokenType.DM_Preproc_EndIf,
- TokenType.DM_Preproc_Pragma
- };
-
- public DMPreprocessor(bool enableDirectives) {
- _enableDirectives = enableDirectives;
- }
-
public IEnumerator GetEnumerator() {
while (_lexerStack.Count > 0) {
Token token = GetNextToken();
@@ -261,7 +242,7 @@ public void PreprocessFile(string includeDir, string file) {
}
private bool VerifyDirectiveUsage(Token token) {
- if (!_enableDirectives) {
+ if (!enableDirectives) {
DMCompiler.Emit(WarningCode.MisplacedDirective, token.Location, "Cannot use a preprocessor directive here");
return false;
}
@@ -486,13 +467,15 @@ private bool TryMacro(Token token) {
return false;
}
- List expandedTokens = macro.Expand(token, parameters);
- for (int i = expandedTokens.Count - 1; i >= 0; i--) {
- Token expandedToken = expandedTokens[i];
- expandedToken.Location = token.Location;
+ List? expandedTokens = macro.Expand(token, parameters);
+ if (expandedTokens != null) {
+ for (int i = expandedTokens.Count - 1; i >= 0; i--) {
+ Token expandedToken = expandedTokens[i];
+ expandedToken.Location = token.Location;
- // These tokens are pushed so that nested macros get processed
- PushToken(expandedToken);
+ // These tokens are pushed so that nested macros get processed
+ PushToken(expandedToken);
+ }
}
return true;
diff --git a/DMCompiler/DM/Builders/DMASTFolder.cs b/DMCompiler/DM/Builders/DMASTFolder.cs
new file mode 100644
index 0000000000..1885a4d7df
--- /dev/null
+++ b/DMCompiler/DM/Builders/DMASTFolder.cs
@@ -0,0 +1,345 @@
+using System;
+using DMCompiler.Compiler.DM.AST;
+
+namespace DMCompiler.DM.Builders;
+
+// Takes in an AST node and attempts to fold what mathematical expressions it can
+// TODO: Constant folding should instead be done by either expression or bytecode generation
+public class DMASTFolder {
+ public void FoldAst(DMASTNode? ast) {
+ if (ast == null)
+ return;
+
+ switch (ast) {
+ case DMASTFile file: FoldAst(file.BlockInner); break;
+ case DMASTObjectDefinition { InnerBlock: not null } objectDef: FoldAst(objectDef.InnerBlock); break;
+ case DMASTObjectVarDefinition objectVarDef: objectVarDef.Value = FoldExpression(objectVarDef.Value); break;
+ case DMASTObjectVarOverride objectVarOverride: objectVarOverride.Value = FoldExpression(objectVarOverride.Value); break;
+ case DMASTProcStatementExpression procExpr: procExpr.Expression = FoldExpression(procExpr.Expression); break;
+ case DMASTProcStatementReturn procRet: procRet.Value = FoldExpression(procRet.Value); break;
+ case DMASTProcStatementDel procDel: procDel.Value = FoldExpression(procDel.Value); break;
+ case DMASTProcStatementThrow procThrow: procThrow.Value = FoldExpression(procThrow.Value); break;
+ case DMASTProcStatementVarDeclaration procVarDecl: procVarDecl.Value = FoldExpression(procVarDecl.Value); break;
+ case DMASTMultipleObjectVarDefinitions objectVarDefs:
+ foreach (DMASTObjectVarDefinition varDefinition in objectVarDefs.VarDefinitions) {
+ FoldAst(varDefinition);
+ }
+
+ break;
+ case DMASTAggregate procVarDecls:
+ foreach (DMASTProcStatementVarDeclaration varDefinition in procVarDecls.Statements) {
+ FoldAst(varDefinition);
+ }
+
+ break;
+ case DMASTBlockInner blockInner:
+ foreach (DMASTStatement statement in blockInner.Statements) {
+ FoldAst(statement);
+ }
+
+ break;
+ case DMASTProcBlockInner procBlockInner:
+ foreach (DMASTProcStatement statement in procBlockInner.Statements) {
+ FoldAst(statement);
+ }
+
+ break;
+ case DMASTProcDefinition procDef:
+ foreach (DMASTDefinitionParameter parameter in procDef.Parameters) {
+ parameter.Value = FoldExpression(parameter.Value);
+ }
+
+ FoldAst(procDef.Body);
+ break;
+ case DMASTProcStatementIf statementIf:
+ statementIf.Condition = FoldExpression(statementIf.Condition);
+ FoldAst(statementIf.Body);
+ FoldAst(statementIf.ElseBody);
+
+ break;
+ case DMASTProcStatementFor statementFor:
+ statementFor.Expression1 = FoldExpression(statementFor.Expression1);
+ statementFor.Expression2 = FoldExpression(statementFor.Expression2);
+ statementFor.Expression3 = FoldExpression(statementFor.Expression3);
+ FoldAst(statementFor.Body);
+
+ break;
+ case DMASTProcStatementWhile statementWhile:
+ statementWhile.Conditional = FoldExpression(statementWhile.Conditional);
+ FoldAst(statementWhile.Body);
+
+ break;
+ case DMASTProcStatementDoWhile statementDoWhile:
+ statementDoWhile.Conditional = FoldExpression(statementDoWhile.Conditional);
+ FoldAst(statementDoWhile.Body);
+
+ break;
+ case DMASTProcStatementInfLoop statementInfLoop:
+ FoldAst(statementInfLoop.Body);
+
+ break;
+ case DMASTProcStatementSwitch statementSwitch:
+ statementSwitch.Value = FoldExpression(statementSwitch.Value);
+
+ foreach (DMASTProcStatementSwitch.SwitchCase switchCase in statementSwitch.Cases) {
+ if (switchCase is DMASTProcStatementSwitch.SwitchCaseValues switchCaseValues) {
+ for (var i = 0; i < switchCaseValues.Values.Length; i++) {
+ switchCaseValues.Values[i] = FoldExpression(switchCaseValues.Values[i]);
+ }
+ }
+
+ FoldAst(switchCase.Body);
+ }
+
+ break;
+ case DMASTProcStatementSpawn statementSpawn:
+ statementSpawn.Delay = FoldExpression(statementSpawn.Delay);
+ FoldAst(statementSpawn.Body);
+
+ break;
+ case DMASTProcStatementBrowse statementBrowse:
+ statementBrowse.Receiver = FoldExpression(statementBrowse.Receiver);
+ statementBrowse.Body = FoldExpression(statementBrowse.Body);
+ statementBrowse.Options = FoldExpression(statementBrowse.Options);
+
+ break;
+ case DMASTProcStatementBrowseResource statementBrowseResource:
+ statementBrowseResource.Receiver = FoldExpression(statementBrowseResource.Receiver);
+ statementBrowseResource.File = FoldExpression(statementBrowseResource.File);
+ statementBrowseResource.Filename = FoldExpression(statementBrowseResource.Filename);
+
+ break;
+ case DMASTProcStatementOutputControl statementOutputControl:
+ statementOutputControl.Receiver = FoldExpression(statementOutputControl.Receiver);
+ statementOutputControl.Message = FoldExpression(statementOutputControl.Message);
+ statementOutputControl.Control = FoldExpression(statementOutputControl.Control);
+
+ break;
+ case DMASTProcStatementTryCatch tryCatch:
+ FoldAst(tryCatch.TryBody);
+ FoldAst(tryCatch.CatchBody);
+
+ break;
+ }
+ }
+
+ private DMASTExpression FoldExpression(DMASTExpression? expression) {
+ if (expression is DMASTUnary unary) {
+ unary.Value = FoldExpression(unary.Value);
+ } else if (expression is DMASTBinary binary) {
+ binary.LHS = FoldExpression(binary.LHS);
+ binary.RHS = FoldExpression(binary.RHS);
+ }
+
+ switch (expression) {
+ case DMASTExpressionInRange inRange:
+ inRange.Value = FoldExpression(inRange.Value);
+ inRange.StartRange = FoldExpression(inRange.StartRange);
+ inRange.EndRange = FoldExpression(inRange.EndRange);
+ break;
+ case DMASTSwitchCaseRange switchCaseRange:
+ switchCaseRange.RangeStart = FoldExpression(switchCaseRange.RangeStart);
+ switchCaseRange.RangeEnd = FoldExpression(switchCaseRange.RangeEnd);
+ break;
+ case DMASTList list:
+ foreach (DMASTCallParameter parameter in list.Values) {
+ parameter.Value = FoldExpression(parameter.Value);
+ }
+
+ break;
+ case DMASTAddText addText:
+ foreach (DMASTCallParameter parameter in addText.Parameters) {
+ parameter.Value = FoldExpression(parameter.Value);
+ }
+
+ break;
+ case DMASTNewPath newPath:
+ if (newPath.Parameters != null) {
+ foreach (DMASTCallParameter parameter in newPath.Parameters) {
+ parameter.Value = FoldExpression(parameter.Value);
+ }
+ }
+
+ break;
+ case DMASTNewExpr newExpr:
+ if (newExpr.Parameters != null) {
+ foreach (DMASTCallParameter parameter in newExpr.Parameters) {
+ parameter.Value = FoldExpression(parameter.Value);
+ }
+ }
+
+ break;
+ case DMASTProcCall procCall:
+ foreach (DMASTCallParameter parameter in procCall.Parameters) {
+ parameter.Value = FoldExpression(parameter.Value);
+ }
+
+ break;
+ case DMASTStringFormat stringFormat:
+ for (int i = 0; i < stringFormat.InterpolatedValues.Length; i++) {
+ stringFormat.InterpolatedValues[i] = FoldExpression(stringFormat.InterpolatedValues[i]);
+ }
+
+ break;
+
+ #region Math
+ case DMASTNegate negate:
+ switch (negate.Value) {
+ case DMASTConstantInteger exprInteger: negate.Value = new DMASTConstantInteger(expression.Location, -exprInteger.Value); break;
+ case DMASTConstantFloat exprFloat: negate.Value = new DMASTConstantFloat(expression.Location, -exprFloat.Value); break;
+ }
+
+ break;
+ case DMASTNot not:
+ switch (not.Value) {
+ case DMASTConstantInteger exprInteger: not.Value = new DMASTConstantInteger(expression.Location, (exprInteger.Value != 0) ? 1 : 0); break;
+ case DMASTConstantFloat exprFloat: not.Value = new DMASTConstantInteger(expression.Location, (exprFloat.Value != 0) ? 1 : 0); break;
+ }
+
+ break;
+ case DMASTOr or: {
+ bool? simpleTruth = SimpleTruth(or.LHS);
+
+ if (simpleTruth == true) {
+ return or.LHS;
+ } else if (simpleTruth == false) {
+ return or.RHS;
+ }
+
+ break;
+ }
+ case DMASTAnd and: {
+ bool? simpleTruth = SimpleTruth(and.LHS);
+
+ if (simpleTruth == false) {
+ return and.LHS;
+ } else if (simpleTruth == true) {
+ return and.RHS;
+ }
+
+ break;
+ }
+ case DMASTLeftShift leftShift: {
+ if (leftShift is { LHS: DMASTConstantInteger lhsInt, RHS: DMASTConstantInteger rhsInt }) {
+ return new DMASTConstantInteger(expression.Location, lhsInt.Value << rhsInt.Value);
+ }
+
+ break;
+ }
+ case DMASTRightShift rightShift: {
+ if (rightShift is { LHS: DMASTConstantInteger lhsInt, RHS: DMASTConstantInteger rhsInt }) {
+ return new DMASTConstantInteger(expression.Location, lhsInt.Value >> rhsInt.Value);
+ }
+
+ break;
+ }
+ case DMASTBinaryAnd binaryAnd: {
+ if (binaryAnd is { LHS: DMASTConstantInteger lhsInt, RHS: DMASTConstantInteger rhsInt }) {
+ return new DMASTConstantInteger(expression.Location, lhsInt.Value & rhsInt.Value);
+ }
+
+ break;
+ }
+ case DMASTBinaryOr binaryOr: {
+ if (binaryOr is { LHS: DMASTConstantInteger lhsInt, RHS: DMASTConstantInteger rhsInt }) {
+ return new DMASTConstantInteger(expression.Location, lhsInt.Value | rhsInt.Value);
+ }
+
+ break;
+ }
+ case DMASTBinaryNot binaryNot: {
+ if (binaryNot.Value is DMASTConstantInteger exprInt) {
+ return new DMASTConstantInteger(expression.Location, (~exprInt.Value) & 0xFFFFFF);
+ }
+
+ break;
+ }
+ case DMASTAdd add: {
+ DMASTConstantInteger? lhsInt = add.LHS as DMASTConstantInteger;
+ DMASTConstantFloat? lhsFloat = add.LHS as DMASTConstantFloat;
+ DMASTConstantString? lhsString = add.LHS as DMASTConstantString;
+ DMASTConstantInteger? rhsInt = add.RHS as DMASTConstantInteger;
+ DMASTConstantFloat? rhsFloat = add.RHS as DMASTConstantFloat;
+ DMASTConstantString? rhsString = add.RHS as DMASTConstantString;
+
+ if (lhsInt != null && rhsInt != null) return new DMASTConstantInteger(expression.Location, lhsInt.Value + rhsInt.Value);
+ if (lhsInt != null && rhsFloat != null) return new DMASTConstantFloat(expression.Location, lhsInt.Value + rhsFloat.Value);
+ if (lhsFloat != null && rhsInt != null) return new DMASTConstantFloat(expression.Location, lhsFloat.Value + rhsInt.Value);
+ if (lhsFloat != null && rhsFloat != null) return new DMASTConstantFloat(expression.Location, lhsFloat.Value + rhsFloat.Value);
+ if (lhsString != null && rhsString != null) return new DMASTConstantString(expression.Location, lhsString.Value + rhsString.Value);
+
+ break;
+ }
+ case DMASTSubtract subtract: {
+ DMASTConstantInteger? lhsInt = subtract.LHS as DMASTConstantInteger;
+ DMASTConstantFloat? lhsFloat = subtract.LHS as DMASTConstantFloat;
+ DMASTConstantInteger? rhsInt = subtract.RHS as DMASTConstantInteger;
+ DMASTConstantFloat? rhsFloat = subtract.RHS as DMASTConstantFloat;
+
+ if (lhsInt != null && rhsInt != null) return new DMASTConstantInteger(expression.Location, lhsInt.Value - rhsInt.Value);
+ if (lhsInt != null && rhsFloat != null) return new DMASTConstantFloat(expression.Location, lhsInt.Value - rhsFloat.Value);
+ if (lhsFloat != null && rhsInt != null) return new DMASTConstantFloat(expression.Location, lhsFloat.Value - rhsInt.Value);
+ if (lhsFloat != null && rhsFloat != null) return new DMASTConstantFloat(expression.Location, lhsFloat.Value - rhsFloat.Value);
+
+ break;
+ }
+ case DMASTMultiply multiply: {
+ DMASTConstantInteger? lhsInt = multiply.LHS as DMASTConstantInteger;
+ DMASTConstantFloat? lhsFloat = multiply.LHS as DMASTConstantFloat;
+ DMASTConstantInteger? rhsInt = multiply.RHS as DMASTConstantInteger;
+ DMASTConstantFloat? rhsFloat = multiply.RHS as DMASTConstantFloat;
+
+ if (lhsInt != null && rhsInt != null) return new DMASTConstantInteger(expression.Location, lhsInt.Value * rhsInt.Value);
+ if (lhsInt != null && rhsFloat != null) return new DMASTConstantFloat(expression.Location, lhsInt.Value * rhsFloat.Value);
+ if (lhsFloat != null && rhsInt != null) return new DMASTConstantFloat(expression.Location, lhsFloat.Value * rhsInt.Value);
+ if (lhsFloat != null && rhsFloat != null) return new DMASTConstantFloat(expression.Location, lhsFloat.Value * rhsFloat.Value);
+
+ break;
+ }
+ case DMASTDivide divide: {
+ DMASTConstantInteger? lhsInt = divide.LHS as DMASTConstantInteger;
+ DMASTConstantFloat? lhsFloat = divide.LHS as DMASTConstantFloat;
+ DMASTConstantInteger? rhsInt = divide.RHS as DMASTConstantInteger;
+ DMASTConstantFloat? rhsFloat = divide.RHS as DMASTConstantFloat;
+
+ if (lhsInt != null && rhsInt != null) return new DMASTConstantFloat(expression.Location, (float)lhsInt.Value / rhsInt.Value);
+ if (lhsInt != null && rhsFloat != null) return new DMASTConstantFloat(expression.Location, lhsInt.Value / rhsFloat.Value);
+ if (lhsFloat != null && rhsInt != null) return new DMASTConstantFloat(expression.Location, lhsFloat.Value / rhsInt.Value);
+ if (lhsFloat != null && rhsFloat != null) return new DMASTConstantFloat(expression.Location, lhsFloat.Value / rhsFloat.Value);
+
+ break;
+ }
+ case DMASTModulus modulus: {
+ if (modulus is { LHS: DMASTConstantInteger lhsInt, RHS: DMASTConstantInteger rhsInt }) {
+ return new DMASTConstantInteger(expression.Location, lhsInt.Value % rhsInt.Value);
+ }
+
+ break;
+ }
+ case DMASTPower power: {
+ if (power is { LHS: DMASTConstantInteger lhsInt, RHS: DMASTConstantInteger rhsInt }) {
+ return new DMASTConstantInteger(expression.Location, (int)Math.Pow(lhsInt.Value, rhsInt.Value));
+ }
+
+ break;
+ }
+ #endregion Math
+ default:
+ break;
+ }
+
+ return expression;
+ }
+
+ private static bool? SimpleTruth(DMASTExpression expr) {
+ switch (expr) {
+ case DMASTConstantInteger e: return e.Value != 0;
+ case DMASTConstantFloat e: return e.Value != 0;
+ case DMASTConstantString e: return e.Value.Length != 0;
+ case DMASTConstantNull: return false;
+ case DMASTConstantPath: return true;
+ case DMASTConstantResource: return true;
+ default: return null;
+ }
+ }
+}
diff --git a/DMCompiler/DM/Visitors/DMExpressionBuilder.cs b/DMCompiler/DM/Builders/DMExpressionBuilder.cs
similarity index 82%
rename from DMCompiler/DM/Visitors/DMExpressionBuilder.cs
rename to DMCompiler/DM/Builders/DMExpressionBuilder.cs
index 3ba04073a4..09957355b3 100644
--- a/DMCompiler/DM/Visitors/DMExpressionBuilder.cs
+++ b/DMCompiler/DM/Builders/DMExpressionBuilder.cs
@@ -1,9 +1,9 @@
-using DMCompiler.Compiler.DM;
-using DMCompiler.DM.Expressions;
using System;
using DMCompiler.Compiler;
+using DMCompiler.Compiler.DM.AST;
+using DMCompiler.DM.Expressions;
-namespace DMCompiler.DM.Visitors;
+namespace DMCompiler.DM.Builders;
internal static class DMExpressionBuilder {
public enum ScopeMode {
@@ -24,10 +24,8 @@ public static DMExpression BuildExpression(DMASTExpression expression, DMObject
case DMASTExpressionConstant constant: return BuildConstant(constant, dmObject, proc);
case DMASTStringFormat stringFormat: return BuildStringFormat(stringFormat, dmObject, proc, inferredPath);
case DMASTIdentifier identifier: return BuildIdentifier(identifier, dmObject, proc);
- case DMASTGlobalIdentifier globalIdentifier: return BuildGlobalIdentifier(globalIdentifier, dmObject);
case DMASTCallableSelf: return new ProcSelf(expression.Location);
case DMASTCallableSuper: return new ProcSuper(expression.Location);
- case DMASTCallableGlobalProc globalProc: return new GlobalProc(expression.Location, globalProc.Identifier);
case DMASTCallableProcIdentifier procIdentifier: return BuildCallableProcIdentifier(procIdentifier, dmObject);
case DMASTProcCall procCall: return BuildProcCall(procCall, dmObject, proc, inferredPath);
case DMASTAssign assign: return BuildAssign(assign, dmObject, proc, inferredPath);
@@ -45,148 +43,148 @@ public static DMExpression BuildExpression(DMASTExpression expression, DMObject
case DMASTPick pick: return BuildPick(pick, dmObject, proc);
case DMASTLog log: return BuildLog(log, dmObject, proc, inferredPath);
case DMASTCall call: return BuildCall(call, dmObject, proc, inferredPath);
- case DMASTExpressionWrapped wrapped: return BuildExpression(wrapped.Expression, dmObject, proc, inferredPath);
+ case DMASTExpressionWrapped wrapped: return BuildExpression(wrapped.Value, dmObject, proc, inferredPath);
case DMASTNegate negate:
- return new Negate(negate.Location, BuildExpression(negate.Expression, dmObject, proc, inferredPath));
+ return new Negate(negate.Location, BuildExpression(negate.Value, dmObject, proc, inferredPath));
case DMASTNot not:
- return new Not(not.Location, BuildExpression(not.Expression, dmObject, proc, inferredPath));
+ return new Not(not.Location, BuildExpression(not.Value, dmObject, proc, inferredPath));
case DMASTBinaryNot binaryNot:
return new BinaryNot(binaryNot.Location, BuildExpression(binaryNot.Value, dmObject, proc, inferredPath));
case DMASTAdd add:
return new Add(add.Location,
- BuildExpression(add.A, dmObject, proc, inferredPath),
- BuildExpression(add.B, dmObject, proc, inferredPath));
+ BuildExpression(add.LHS, dmObject, proc, inferredPath),
+ BuildExpression(add.RHS, dmObject, proc, inferredPath));
case DMASTSubtract subtract:
return new Subtract(subtract.Location,
- BuildExpression(subtract.A, dmObject, proc, inferredPath),
- BuildExpression(subtract.B, dmObject, proc, inferredPath));
+ BuildExpression(subtract.LHS, dmObject, proc, inferredPath),
+ BuildExpression(subtract.RHS, dmObject, proc, inferredPath));
case DMASTMultiply multiply:
return new Multiply(multiply.Location,
- BuildExpression(multiply.A, dmObject, proc, inferredPath),
- BuildExpression(multiply.B, dmObject, proc, inferredPath));
+ BuildExpression(multiply.LHS, dmObject, proc, inferredPath),
+ BuildExpression(multiply.RHS, dmObject, proc, inferredPath));
case DMASTDivide divide:
return new Divide(divide.Location,
- BuildExpression(divide.A, dmObject, proc, inferredPath),
- BuildExpression(divide.B, dmObject, proc, inferredPath));
+ BuildExpression(divide.LHS, dmObject, proc, inferredPath),
+ BuildExpression(divide.RHS, dmObject, proc, inferredPath));
case DMASTModulus modulus:
return new Modulo(modulus.Location,
- BuildExpression(modulus.A, dmObject, proc, inferredPath),
- BuildExpression(modulus.B, dmObject, proc, inferredPath));
+ BuildExpression(modulus.LHS, dmObject, proc, inferredPath),
+ BuildExpression(modulus.RHS, dmObject, proc, inferredPath));
case DMASTModulusModulus modulusModulus:
return new ModuloModulo(modulusModulus.Location,
- BuildExpression(modulusModulus.A, dmObject, proc, inferredPath),
- BuildExpression(modulusModulus.B, dmObject, proc, inferredPath));
+ BuildExpression(modulusModulus.LHS, dmObject, proc, inferredPath),
+ BuildExpression(modulusModulus.RHS, dmObject, proc, inferredPath));
case DMASTPower power:
return new Power(power.Location,
- BuildExpression(power.A, dmObject, proc, inferredPath),
- BuildExpression(power.B, dmObject, proc, inferredPath));
+ BuildExpression(power.LHS, dmObject, proc, inferredPath),
+ BuildExpression(power.RHS, dmObject, proc, inferredPath));
case DMASTAppend append:
return new Append(append.Location,
- BuildExpression(append.A, dmObject, proc, inferredPath),
- BuildExpression(append.B, dmObject, proc, inferredPath));
+ BuildExpression(append.LHS, dmObject, proc, inferredPath),
+ BuildExpression(append.RHS, dmObject, proc, inferredPath));
case DMASTCombine combine:
return new Combine(combine.Location,
- BuildExpression(combine.A, dmObject, proc, inferredPath),
- BuildExpression(combine.B, dmObject, proc, inferredPath));
+ BuildExpression(combine.LHS, dmObject, proc, inferredPath),
+ BuildExpression(combine.RHS, dmObject, proc, inferredPath));
case DMASTRemove remove:
return new Remove(remove.Location,
- BuildExpression(remove.A, dmObject, proc, inferredPath),
- BuildExpression(remove.B, dmObject, proc, inferredPath));
+ BuildExpression(remove.LHS, dmObject, proc, inferredPath),
+ BuildExpression(remove.RHS, dmObject, proc, inferredPath));
case DMASTMask mask:
return new Mask(mask.Location,
- BuildExpression(mask.A, dmObject, proc, inferredPath),
- BuildExpression(mask.B, dmObject, proc, inferredPath));
+ BuildExpression(mask.LHS, dmObject, proc, inferredPath),
+ BuildExpression(mask.RHS, dmObject, proc, inferredPath));
case DMASTLogicalAndAssign lAnd:
- var lAndLHS = BuildExpression(lAnd.A, dmObject, proc, inferredPath);
- var lAndRHS = BuildExpression(lAnd.B, dmObject, proc, lAndLHS.NestedPath);
+ var lAndLHS = BuildExpression(lAnd.LHS, dmObject, proc, inferredPath);
+ var lAndRHS = BuildExpression(lAnd.RHS, dmObject, proc, lAndLHS.NestedPath);
return new LogicalAndAssign(lAnd.Location,
lAndLHS,
lAndRHS);
case DMASTLogicalOrAssign lOr:
- var lOrLHS = BuildExpression(lOr.A, dmObject, proc, inferredPath);
- var lOrRHS = BuildExpression(lOr.B, dmObject, proc, lOrLHS.NestedPath);
+ var lOrLHS = BuildExpression(lOr.LHS, dmObject, proc, inferredPath);
+ var lOrRHS = BuildExpression(lOr.RHS, dmObject, proc, lOrLHS.NestedPath);
return new LogicalOrAssign(lOr.Location, lOrLHS, lOrRHS);
case DMASTMultiplyAssign multiplyAssign:
return new MultiplyAssign(multiplyAssign.Location,
- BuildExpression(multiplyAssign.A, dmObject, proc, inferredPath),
- BuildExpression(multiplyAssign.B, dmObject, proc, inferredPath));
+ BuildExpression(multiplyAssign.LHS, dmObject, proc, inferredPath),
+ BuildExpression(multiplyAssign.RHS, dmObject, proc, inferredPath));
case DMASTDivideAssign divideAssign:
return new DivideAssign(divideAssign.Location,
- BuildExpression(divideAssign.A, dmObject, proc, inferredPath),
- BuildExpression(divideAssign.B, dmObject, proc, inferredPath));
+ BuildExpression(divideAssign.LHS, dmObject, proc, inferredPath),
+ BuildExpression(divideAssign.RHS, dmObject, proc, inferredPath));
case DMASTLeftShiftAssign leftShiftAssign:
return new LeftShiftAssign(leftShiftAssign.Location,
- BuildExpression(leftShiftAssign.A, dmObject, proc, inferredPath),
- BuildExpression(leftShiftAssign.B, dmObject, proc, inferredPath));
+ BuildExpression(leftShiftAssign.LHS, dmObject, proc, inferredPath),
+ BuildExpression(leftShiftAssign.RHS, dmObject, proc, inferredPath));
case DMASTRightShiftAssign rightShiftAssign:
return new RightShiftAssign(rightShiftAssign.Location,
- BuildExpression(rightShiftAssign.A, dmObject, proc, inferredPath),
- BuildExpression(rightShiftAssign.B, dmObject, proc, inferredPath));
+ BuildExpression(rightShiftAssign.LHS, dmObject, proc, inferredPath),
+ BuildExpression(rightShiftAssign.RHS, dmObject, proc, inferredPath));
case DMASTXorAssign xorAssign:
return new XorAssign(xorAssign.Location,
- BuildExpression(xorAssign.A, dmObject, proc, inferredPath),
- BuildExpression(xorAssign.B, dmObject, proc, inferredPath));
+ BuildExpression(xorAssign.LHS, dmObject, proc, inferredPath),
+ BuildExpression(xorAssign.RHS, dmObject, proc, inferredPath));
case DMASTModulusAssign modulusAssign:
return new ModulusAssign(modulusAssign.Location,
- BuildExpression(modulusAssign.A, dmObject, proc, inferredPath),
- BuildExpression(modulusAssign.B, dmObject, proc, inferredPath));
+ BuildExpression(modulusAssign.LHS, dmObject, proc, inferredPath),
+ BuildExpression(modulusAssign.RHS, dmObject, proc, inferredPath));
case DMASTModulusModulusAssign modulusModulusAssign:
- var mmAssignLHS = BuildExpression(modulusModulusAssign.A, dmObject, proc, inferredPath);
- var mmAssignRHS = BuildExpression(modulusModulusAssign.B, dmObject, proc, mmAssignLHS.NestedPath);
+ var mmAssignLHS = BuildExpression(modulusModulusAssign.LHS, dmObject, proc, inferredPath);
+ var mmAssignRHS = BuildExpression(modulusModulusAssign.RHS, dmObject, proc, mmAssignLHS.NestedPath);
return new ModulusModulusAssign(modulusModulusAssign.Location, mmAssignLHS, mmAssignRHS);
case DMASTLeftShift leftShift:
return new LeftShift(leftShift.Location,
- BuildExpression(leftShift.A, dmObject, proc, inferredPath),
- BuildExpression(leftShift.B, dmObject, proc, inferredPath));
+ BuildExpression(leftShift.LHS, dmObject, proc, inferredPath),
+ BuildExpression(leftShift.RHS, dmObject, proc, inferredPath));
case DMASTRightShift rightShift:
return new RightShift(rightShift.Location,
- BuildExpression(rightShift.A, dmObject, proc, inferredPath),
- BuildExpression(rightShift.B, dmObject, proc, inferredPath));
+ BuildExpression(rightShift.LHS, dmObject, proc, inferredPath),
+ BuildExpression(rightShift.RHS, dmObject, proc, inferredPath));
case DMASTBinaryAnd binaryAnd:
return new BinaryAnd(binaryAnd.Location,
- BuildExpression(binaryAnd.A, dmObject, proc, inferredPath),
- BuildExpression(binaryAnd.B, dmObject, proc, inferredPath));
+ BuildExpression(binaryAnd.LHS, dmObject, proc, inferredPath),
+ BuildExpression(binaryAnd.RHS, dmObject, proc, inferredPath));
case DMASTBinaryXor binaryXor:
return new BinaryXor(binaryXor.Location,
- BuildExpression(binaryXor.A, dmObject, proc, inferredPath),
- BuildExpression(binaryXor.B, dmObject, proc, inferredPath));
+ BuildExpression(binaryXor.LHS, dmObject, proc, inferredPath),
+ BuildExpression(binaryXor.RHS, dmObject, proc, inferredPath));
case DMASTBinaryOr binaryOr:
return new BinaryOr(binaryOr.Location,
- BuildExpression(binaryOr.A, dmObject, proc, inferredPath),
- BuildExpression(binaryOr.B, dmObject, proc, inferredPath));
+ BuildExpression(binaryOr.LHS, dmObject, proc, inferredPath),
+ BuildExpression(binaryOr.RHS, dmObject, proc, inferredPath));
case DMASTEquivalent equivalent:
return new Equivalent(equivalent.Location,
- BuildExpression(equivalent.A, dmObject, proc, inferredPath),
- BuildExpression(equivalent.B, dmObject, proc, inferredPath));
+ BuildExpression(equivalent.LHS, dmObject, proc, inferredPath),
+ BuildExpression(equivalent.RHS, dmObject, proc, inferredPath));
case DMASTNotEquivalent notEquivalent:
return new NotEquivalent(notEquivalent.Location,
- BuildExpression(notEquivalent.A, dmObject, proc, inferredPath),
- BuildExpression(notEquivalent.B, dmObject, proc, inferredPath));
+ BuildExpression(notEquivalent.LHS, dmObject, proc, inferredPath),
+ BuildExpression(notEquivalent.RHS, dmObject, proc, inferredPath));
case DMASTGreaterThan greaterThan:
return new GreaterThan(greaterThan.Location,
- BuildExpression(greaterThan.A, dmObject, proc, inferredPath),
- BuildExpression(greaterThan.B, dmObject, proc, inferredPath));
+ BuildExpression(greaterThan.LHS, dmObject, proc, inferredPath),
+ BuildExpression(greaterThan.RHS, dmObject, proc, inferredPath));
case DMASTGreaterThanOrEqual greaterThanOrEqual:
return new GreaterThanOrEqual(greaterThanOrEqual.Location,
- BuildExpression(greaterThanOrEqual.A, dmObject, proc, inferredPath),
- BuildExpression(greaterThanOrEqual.B, dmObject, proc, inferredPath));
+ BuildExpression(greaterThanOrEqual.LHS, dmObject, proc, inferredPath),
+ BuildExpression(greaterThanOrEqual.RHS, dmObject, proc, inferredPath));
case DMASTLessThan lessThan:
return new LessThan(lessThan.Location,
- BuildExpression(lessThan.A, dmObject, proc, inferredPath),
- BuildExpression(lessThan.B, dmObject, proc, inferredPath));
+ BuildExpression(lessThan.LHS, dmObject, proc, inferredPath),
+ BuildExpression(lessThan.RHS, dmObject, proc, inferredPath));
case DMASTLessThanOrEqual lessThanOrEqual:
return new LessThanOrEqual(lessThanOrEqual.Location,
- BuildExpression(lessThanOrEqual.A, dmObject, proc, inferredPath),
- BuildExpression(lessThanOrEqual.B, dmObject, proc, inferredPath));
+ BuildExpression(lessThanOrEqual.LHS, dmObject, proc, inferredPath),
+ BuildExpression(lessThanOrEqual.RHS, dmObject, proc, inferredPath));
case DMASTOr or:
return new Or(or.Location,
- BuildExpression(or.A, dmObject, proc, inferredPath),
- BuildExpression(or.B, dmObject, proc, inferredPath));
+ BuildExpression(or.LHS, dmObject, proc, inferredPath),
+ BuildExpression(or.RHS, dmObject, proc, inferredPath));
case DMASTAnd and:
return new And(and.Location,
- BuildExpression(and.A, dmObject, proc, inferredPath),
- BuildExpression(and.B, dmObject, proc, inferredPath));
+ BuildExpression(and.LHS, dmObject, proc, inferredPath),
+ BuildExpression(and.RHS, dmObject, proc, inferredPath));
case DMASTTernary ternary:
return new Ternary(ternary.Location,
BuildExpression(ternary.A, dmObject, proc, inferredPath),
@@ -213,13 +211,13 @@ public static DMExpression BuildExpression(DMASTExpression expression, DMObject
return new NewPath(newInferred.Location, new Path(newInferred.Location, dmObject, inferredPath.Value),
new ArgumentList(newInferred.Location, dmObject, proc, newInferred.Parameters, inferredPath));
case DMASTPreIncrement preIncrement:
- return new PreIncrement(preIncrement.Location, BuildExpression(preIncrement.Expression, dmObject, proc, inferredPath));
+ return new PreIncrement(preIncrement.Location, BuildExpression(preIncrement.Value, dmObject, proc, inferredPath));
case DMASTPostIncrement postIncrement:
- return new PostIncrement(postIncrement.Location, BuildExpression(postIncrement.Expression, dmObject, proc, inferredPath));
+ return new PostIncrement(postIncrement.Location, BuildExpression(postIncrement.Value, dmObject, proc, inferredPath));
case DMASTPreDecrement preDecrement:
- return new PreDecrement(preDecrement.Location, BuildExpression(preDecrement.Expression, dmObject, proc, inferredPath));
+ return new PreDecrement(preDecrement.Location, BuildExpression(preDecrement.Value, dmObject, proc, inferredPath));
case DMASTPostDecrement postDecrement:
- return new PostDecrement(postDecrement.Location, BuildExpression(postDecrement.Expression, dmObject, proc, inferredPath));
+ return new PostDecrement(postDecrement.Location, BuildExpression(postDecrement.Value, dmObject, proc, inferredPath));
case DMASTGradient gradient:
return new Gradient(gradient.Location,
new ArgumentList(gradient.Location, dmObject, proc, gradient.Parameters));
@@ -229,59 +227,59 @@ public static DMExpression BuildExpression(DMASTExpression expression, DMObject
BuildExpression(locateCoordinates.Y, dmObject, proc, inferredPath),
BuildExpression(locateCoordinates.Z, dmObject, proc, inferredPath));
case DMASTIsSaved isSaved:
- return new IsSaved(isSaved.Location, BuildExpression(isSaved.Expression, dmObject, proc, inferredPath));
+ return new IsSaved(isSaved.Location, BuildExpression(isSaved.Value, dmObject, proc, inferredPath));
case DMASTIsType isType:
return new IsType(isType.Location,
- BuildExpression(isType.Value, dmObject, proc, inferredPath),
- BuildExpression(isType.Type, dmObject, proc, inferredPath));
+ BuildExpression(isType.LHS, dmObject, proc, inferredPath),
+ BuildExpression(isType.RHS, dmObject, proc, inferredPath));
case DMASTIsNull isNull:
return new IsNull(isNull.Location, BuildExpression(isNull.Value, dmObject, proc, inferredPath));
case DMASTLength length:
return new Length(length.Location, BuildExpression(length.Value, dmObject, proc, inferredPath));
case DMASTGetStep getStep:
return new GetStep(getStep.Location,
- BuildExpression(getStep.Ref, dmObject, proc, inferredPath),
- BuildExpression(getStep.Dir, dmObject, proc, inferredPath));
+ BuildExpression(getStep.LHS, dmObject, proc, inferredPath),
+ BuildExpression(getStep.RHS, dmObject, proc, inferredPath));
case DMASTGetDir getDir:
return new GetDir(getDir.Location,
- BuildExpression(getDir.Loc1, dmObject, proc, inferredPath),
- BuildExpression(getDir.Loc2, dmObject, proc, inferredPath));
+ BuildExpression(getDir.LHS, dmObject, proc, inferredPath),
+ BuildExpression(getDir.RHS, dmObject, proc, inferredPath));
case DMASTProb prob:
return new Prob(prob.Location,
- BuildExpression(prob.P, dmObject, proc, inferredPath));
+ BuildExpression(prob.Value, dmObject, proc, inferredPath));
case DMASTInitial initial:
- return new Initial(initial.Location, BuildExpression(initial.Expression, dmObject, proc, inferredPath));
+ return new Initial(initial.Location, BuildExpression(initial.Value, dmObject, proc, inferredPath));
case DMASTNameof nameof:
return BuildNameof(nameof, dmObject, proc, inferredPath);
case DMASTExpressionIn expressionIn:
return new In(expressionIn.Location,
- BuildExpression(expressionIn.Value, dmObject, proc, inferredPath),
- BuildExpression(expressionIn.List, dmObject, proc, inferredPath));
+ BuildExpression(expressionIn.LHS, dmObject, proc, inferredPath),
+ BuildExpression(expressionIn.RHS, dmObject, proc, inferredPath));
case DMASTExpressionInRange expressionInRange:
return new InRange(expressionInRange.Location,
BuildExpression(expressionInRange.Value, dmObject, proc, inferredPath),
BuildExpression(expressionInRange.StartRange, dmObject, proc, inferredPath),
BuildExpression(expressionInRange.EndRange, dmObject, proc, inferredPath));
case DMASTSin sin:
- return new Sin(sin.Location, BuildExpression(sin.Expression, dmObject, proc, inferredPath));
+ return new Sin(sin.Location, BuildExpression(sin.Value, dmObject, proc, inferredPath));
case DMASTCos cos:
- return new Cos(cos.Location, BuildExpression(cos.Expression, dmObject, proc, inferredPath));
+ return new Cos(cos.Location, BuildExpression(cos.Value, dmObject, proc, inferredPath));
case DMASTTan tan:
- return new Tan(tan.Location, BuildExpression(tan.Expression, dmObject, proc, inferredPath));
+ return new Tan(tan.Location, BuildExpression(tan.Value, dmObject, proc, inferredPath));
case DMASTArcsin arcSin:
- return new ArcSin(arcSin.Location, BuildExpression(arcSin.Expression, dmObject, proc, inferredPath));
+ return new ArcSin(arcSin.Location, BuildExpression(arcSin.Value, dmObject, proc, inferredPath));
case DMASTArccos arcCos:
- return new ArcCos(arcCos.Location, BuildExpression(arcCos.Expression, dmObject, proc, inferredPath));
+ return new ArcCos(arcCos.Location, BuildExpression(arcCos.Value, dmObject, proc, inferredPath));
case DMASTArctan arcTan:
- return new ArcTan(arcTan.Location, BuildExpression(arcTan.Expression, dmObject, proc, inferredPath));
+ return new ArcTan(arcTan.Location, BuildExpression(arcTan.Value, dmObject, proc, inferredPath));
case DMASTArctan2 arcTan2:
return new ArcTan2(arcTan2.Location,
- BuildExpression(arcTan2.XExpression, dmObject, proc, inferredPath),
- BuildExpression(arcTan2.YExpression, dmObject, proc, inferredPath));
+ BuildExpression(arcTan2.LHS, dmObject, proc, inferredPath),
+ BuildExpression(arcTan2.RHS, dmObject, proc, inferredPath));
case DMASTSqrt sqrt:
- return new Sqrt(sqrt.Location, BuildExpression(sqrt.Expression, dmObject, proc, inferredPath));
+ return new Sqrt(sqrt.Location, BuildExpression(sqrt.Value, dmObject, proc, inferredPath));
case DMASTAbs abs:
- return new Abs(abs.Location, BuildExpression(abs.Expression, dmObject, proc, inferredPath));
+ return new Abs(abs.Location, BuildExpression(abs.Value, dmObject, proc, inferredPath));
case DMASTVarDeclExpression varDeclExpr:
var declIdentifier = new DMASTIdentifier(expression.Location, varDeclExpr.DeclPath.Path.LastElement);
@@ -378,22 +376,6 @@ private static DMExpression BuildIdentifier(DMASTIdentifier identifier, DMObject
}
}
- private static DMExpression BuildGlobalIdentifier(DMASTGlobalIdentifier globalIdentifier, DMObject dmObject) {
- string name = globalIdentifier.Identifier;
-
- if (CurrentScopeMode != ScopeMode.FirstPassStatic) {
- int? globalId = dmObject?.GetGlobalVariableId(name);
- if (globalId != null) {
- return new GlobalField(globalIdentifier.Location, DMObjectTree.Globals[globalId.Value].Type,
- globalId.Value);
- } else if (name == "vars") {
- return new GlobalVars(globalIdentifier.Location);
- }
- }
-
- throw new CompileErrorException(globalIdentifier.Location, $"Unknown global \"{name}\"");
- }
-
private static DMExpression BuildCallableProcIdentifier(DMASTCallableProcIdentifier procIdentifier, DMObject dmObject) {
if (CurrentScopeMode is ScopeMode.Static or ScopeMode.FirstPassStatic)
return new GlobalProc(procIdentifier.Location, procIdentifier.Identifier);
@@ -432,28 +414,28 @@ private static DMExpression BuildProcCall(DMASTProcCall procCall, DMObject dmObj
}
private static DMExpression BuildAssign(DMASTAssign assign, DMObject dmObject, DMProc proc, DreamPath? inferredPath) {
- var lhs = DMExpression.Create(dmObject, proc, assign.Expression, inferredPath);
- var rhs = DMExpression.Create(dmObject, proc, assign.Value, lhs.NestedPath);
+ var lhs = DMExpression.Create(dmObject, proc, assign.LHS, inferredPath);
+ var rhs = DMExpression.Create(dmObject, proc, assign.RHS, lhs.NestedPath);
if(lhs.TryAsConstant(out _)) {
- DMCompiler.Emit(WarningCode.WriteToConstant, assign.Expression.Location, "Cannot write to const var");
+ DMCompiler.Emit(WarningCode.WriteToConstant, assign.LHS.Location, "Cannot write to const var");
}
return new Assignment(assign.Location, lhs, rhs);
}
private static DMExpression BuildAssignInto(DMASTAssignInto assign, DMObject dmObject, DMProc proc, DreamPath? inferredPath) {
- var lhs = DMExpression.Create(dmObject, proc, assign.Expression, inferredPath);
- var rhs = DMExpression.Create(dmObject, proc, assign.Value, lhs.NestedPath);
+ var lhs = DMExpression.Create(dmObject, proc, assign.LHS, inferredPath);
+ var rhs = DMExpression.Create(dmObject, proc, assign.RHS, lhs.NestedPath);
if(lhs.TryAsConstant(out _)) {
- DMCompiler.Emit(WarningCode.WriteToConstant, assign.Expression.Location, "Cannot write to const var");
+ DMCompiler.Emit(WarningCode.WriteToConstant, assign.LHS.Location, "Cannot write to const var");
}
return new AssignmentInto(assign.Location, lhs, rhs);
}
private static DMExpression BuildEqual(DMASTEqual equal, DMObject dmObject, DMProc proc, DreamPath? inferredPath) {
- var lhs = DMExpression.Create(dmObject, proc, equal.A, inferredPath);
- var rhs = DMExpression.Create(dmObject, proc, equal.B, inferredPath);
+ var lhs = DMExpression.Create(dmObject, proc, equal.LHS, inferredPath);
+ var rhs = DMExpression.Create(dmObject, proc, equal.RHS, inferredPath);
// (x == null) can be changed to isnull(x) which compiles down to an opcode
// TODO: Bytecode optimizations instead
@@ -464,8 +446,8 @@ private static DMExpression BuildEqual(DMASTEqual equal, DMObject dmObject, DMPr
}
private static DMExpression BuildNotEqual(DMASTNotEqual notEqual, DMObject dmObject, DMProc proc, DreamPath? inferredPath) {
- var lhs = DMExpression.Create(dmObject, proc, notEqual.A, inferredPath);
- var rhs = DMExpression.Create(dmObject, proc, notEqual.B, inferredPath);
+ var lhs = DMExpression.Create(dmObject, proc, notEqual.LHS, inferredPath);
+ var rhs = DMExpression.Create(dmObject, proc, notEqual.RHS, inferredPath);
// (x != null) can be changed to !isnull(x) which compiles down to two opcodes
// TODO: Bytecode optimizations instead
@@ -726,7 +708,7 @@ private static DMExpression BuildDimensionalList(DMASTDimensionalList list, DMOb
// nameof(x)
private static DMExpression BuildNameof(DMASTNameof nameof, DMObject dmObject, DMProc proc, DreamPath? inferredPath) {
- var expr = BuildExpression(nameof.Expression, dmObject, proc, inferredPath);
+ var expr = BuildExpression(nameof.Value, dmObject, proc, inferredPath);
if (expr.GetNameof(dmObject, proc) is { } name) {
return new Expressions.String(nameof.Location, name);
}
diff --git a/DMCompiler/DM/Visitors/DMObjectBuilder.cs b/DMCompiler/DM/Builders/DMObjectBuilder.cs
similarity index 99%
rename from DMCompiler/DM/Visitors/DMObjectBuilder.cs
rename to DMCompiler/DM/Builders/DMObjectBuilder.cs
index 758346f232..4af5fc1396 100644
--- a/DMCompiler/DM/Visitors/DMObjectBuilder.cs
+++ b/DMCompiler/DM/Builders/DMObjectBuilder.cs
@@ -1,8 +1,8 @@
-using DMCompiler.Compiler.DM;
using System.Collections.Generic;
using DMCompiler.Compiler;
+using DMCompiler.Compiler.DM.AST;
-namespace DMCompiler.DM.Visitors {
+namespace DMCompiler.DM.Builders {
internal static class DMObjectBuilder {
private static readonly List<(DMObject, DMASTObjectVarDefinition)> VarDefinitions = new();
private static readonly List<(DMObject, DMASTObjectVarOverride)> VarOverrides = new();
@@ -118,7 +118,7 @@ public static void BuildObjectTree(DMASTFile astFile) {
// Success! Remove this one from the list
lateProcVarDefs.RemoveAt(i--);
- } catch (UnknownIdentifierException e) {
+ } catch (UnknownIdentifierException) {
// Keep it in the list, try again after the rest have been processed
} finally {
DMExpressionBuilder.CurrentScopeMode = DMExpressionBuilder.ScopeMode.Normal;
diff --git a/DMCompiler/DM/Visitors/DMProcBuilder.cs b/DMCompiler/DM/Builders/DMProcBuilder.cs
similarity index 99%
rename from DMCompiler/DM/Visitors/DMProcBuilder.cs
rename to DMCompiler/DM/Builders/DMProcBuilder.cs
index 7b946ffe3a..615012c4f7 100644
--- a/DMCompiler/DM/Visitors/DMProcBuilder.cs
+++ b/DMCompiler/DM/Builders/DMProcBuilder.cs
@@ -1,12 +1,13 @@
-using DMCompiler.Compiler.DM;
-using System.Collections.Generic;
using System;
-using DMCompiler.DM.Expressions;
+using System.Collections.Generic;
using System.Diagnostics;
using DMCompiler.Bytecode;
using DMCompiler.Compiler;
+using DMCompiler.Compiler.DM;
+using DMCompiler.Compiler.DM.AST;
+using DMCompiler.DM.Expressions;
-namespace DMCompiler.DM.Visitors {
+namespace DMCompiler.DM.Builders {
internal sealed class DMProcBuilder {
private readonly DMObject _dmObject;
private readonly DMProc _proc;
@@ -473,7 +474,7 @@ public void ProcessStatementFor(DMASTProcStatementFor statementFor) {
ProcessStatementForStandard(initializer, comparator, incrementor, statementFor.Body);
} else {
switch (statementFor.Expression1) {
- case DMASTAssign {Expression: DMASTVarDeclExpression decl, Value: DMASTExpressionInRange range}: {
+ case DMASTAssign {LHS: DMASTVarDeclExpression decl, RHS: DMASTExpressionInRange range}: {
var identifier = new DMASTIdentifier(decl.Location, decl.DeclPath.Path.LastElement);
var outputVar = DMExpression.Create(_dmObject, _proc, identifier);
@@ -489,7 +490,7 @@ public void ProcessStatementFor(DMASTProcStatementFor statementFor) {
case DMASTExpressionInRange exprRange: {
DMASTVarDeclExpression? decl = exprRange.Value as DMASTVarDeclExpression;
decl ??= exprRange.Value is DMASTAssign assign
- ? assign.Expression as DMASTVarDeclExpression
+ ? assign.LHS as DMASTVarDeclExpression
: null;
DMASTExpression outputExpr;
@@ -520,14 +521,14 @@ public void ProcessStatementFor(DMASTProcStatementFor statementFor) {
}
case DMASTExpressionIn exprIn: {
DMASTExpression outputExpr;
- if (exprIn.Value is DMASTVarDeclExpression decl) {
+ if (exprIn.LHS is DMASTVarDeclExpression decl) {
outputExpr = new DMASTIdentifier(decl.Location, decl.DeclPath.Path.LastElement);
} else {
- outputExpr = exprIn.Value;
+ outputExpr = exprIn.LHS;
}
var outputVar = DMExpression.Create(_dmObject, _proc, outputExpr);
- var list = DMExpression.Create(_dmObject, _proc, exprIn.List);
+ var list = DMExpression.Create(_dmObject, _proc, exprIn.RHS);
ProcessStatementForList(list, outputVar, statementFor.DMTypes, statementFor.Body);
break;
diff --git a/DMCompiler/DM/DMExpression.cs b/DMCompiler/DM/DMExpression.cs
index ecc2f1971a..4ed9f90204 100644
--- a/DMCompiler/DM/DMExpression.cs
+++ b/DMCompiler/DM/DMExpression.cs
@@ -1,9 +1,9 @@
using DMCompiler.Bytecode;
-using DMCompiler.Compiler.DM;
-using DMCompiler.DM.Visitors;
using System;
using System.Diagnostics.CodeAnalysis;
using DMCompiler.Compiler;
+using DMCompiler.Compiler.DM.AST;
+using DMCompiler.DM.Builders;
namespace DMCompiler.DM;
diff --git a/DMCompiler/DM/DMObjectTree.cs b/DMCompiler/DM/DMObjectTree.cs
index f6942726d3..60c37af544 100644
--- a/DMCompiler/DM/DMObjectTree.cs
+++ b/DMCompiler/DM/DMObjectTree.cs
@@ -3,7 +3,7 @@
using System.Diagnostics.CodeAnalysis;
using DMCompiler.Bytecode;
using DMCompiler.Compiler;
-using DMCompiler.Compiler.DM;
+using DMCompiler.Compiler.DM.AST;
using DMCompiler.Json;
namespace DMCompiler.DM;
diff --git a/DMCompiler/DM/DMProc.cs b/DMCompiler/DM/DMProc.cs
index 85d04ca0b8..9bcf083db4 100644
--- a/DMCompiler/DM/DMProc.cs
+++ b/DMCompiler/DM/DMProc.cs
@@ -1,11 +1,11 @@
using DMCompiler.Bytecode;
-using DMCompiler.Compiler.DM;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using DMCompiler.Compiler;
-using DMCompiler.DM.Visitors;
+using DMCompiler.Compiler.DM.AST;
+using DMCompiler.DM.Builders;
using DMCompiler.Json;
namespace DMCompiler.DM {
diff --git a/DMCompiler/DM/Expressions/Builtins.cs b/DMCompiler/DM/Expressions/Builtins.cs
index 3880a5bce0..4a679c8c23 100644
--- a/DMCompiler/DM/Expressions/Builtins.cs
+++ b/DMCompiler/DM/Expressions/Builtins.cs
@@ -1,8 +1,8 @@
using DMCompiler.Bytecode;
-using DMCompiler.Compiler.DM;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using DMCompiler.Compiler;
+using DMCompiler.Compiler.DM.AST;
using DMCompiler.Json;
namespace DMCompiler.DM.Expressions {
diff --git a/DMCompiler/DM/Expressions/Procs.cs b/DMCompiler/DM/Expressions/Procs.cs
index 3a0a0716bc..1cf3d6ecc8 100644
--- a/DMCompiler/DM/Expressions/Procs.cs
+++ b/DMCompiler/DM/Expressions/Procs.cs
@@ -38,15 +38,9 @@ public override DMReference EmitReference(DMObject dmObject, DMProc proc, string
/// This doesn't actually contain the GlobalProc itself;
/// this is just a hopped-up string that we eventually deference to get the real global proc during compilation.
///
- sealed class GlobalProc : DMExpression {
- private readonly string _name;
-
- public GlobalProc(Location location, string name) : base(location) {
- _name = name;
- }
-
+ internal sealed class GlobalProc(Location location, string name) : DMExpression(location) {
public override void EmitPushValue(DMObject dmObject, DMProc proc) {
- DMCompiler.Emit(WarningCode.InvalidReference, Location, $"Attempt to use proc \"{_name}\" as value");
+ DMCompiler.Emit(WarningCode.InvalidReference, Location, $"Attempt to use proc \"{name}\" as value");
}
public override DMReference EmitReference(DMObject dmObject, DMProc proc, string endLabel, ShortCircuitMode shortCircuitMode) {
@@ -55,8 +49,8 @@ public override DMReference EmitReference(DMObject dmObject, DMProc proc, string
}
public DMProc GetProc() {
- if (!DMObjectTree.TryGetGlobalProc(_name, out var globalProc)) {
- DMCompiler.Emit(WarningCode.ItemDoesntExist, Location, $"No global proc named \"{_name}\"");
+ if (!DMObjectTree.TryGetGlobalProc(name, out var globalProc)) {
+ DMCompiler.Emit(WarningCode.ItemDoesntExist, Location, $"No global proc named \"{name}\"");
return DMObjectTree.GlobalInitProc; // Just give this, who cares
}
@@ -117,7 +111,7 @@ public ProcCall(Location location, DMExpression target, ArgumentList arguments)
public override void EmitPushValue(DMObject dmObject, DMProc proc) {
(DMObject? procOwner, DMProc? targetProc) = GetTargetProc(dmObject);
- DoCompiletimeLinting(procOwner, targetProc);
+ DoCompileTimeLinting(procOwner, targetProc);
if ((targetProc?.Attributes & ProcAttributes.Unimplemented) == ProcAttributes.Unimplemented) {
DMCompiler.UnimplementedWarning(Location, $"{procOwner?.Path.ToString() ?? "/"}.{targetProc.Name}() is not implemented");
}
@@ -143,7 +137,7 @@ public override void EmitPushValue(DMObject dmObject, DMProc proc) {
/// This is a good place to do some compile-time linting of any native procs that require it,
/// such as native procs that check ahead of time if the number of arguments is correct (like matrix() or sin())
///
- protected void DoCompiletimeLinting(DMObject? procOwner, DMProc? targetProc) {
+ private void DoCompileTimeLinting(DMObject? procOwner, DMProc? targetProc) {
if(procOwner is null || procOwner.Path == DreamPath.Root) {
if (targetProc is null)
return;
diff --git a/DMCompiler/DM/Visitors/DMASTSimplifier.cs b/DMCompiler/DM/Visitors/DMASTSimplifier.cs
deleted file mode 100644
index 5e9f1529e7..0000000000
--- a/DMCompiler/DM/Visitors/DMASTSimplifier.cs
+++ /dev/null
@@ -1,627 +0,0 @@
-using DMCompiler.Compiler.DM;
-using DMCompiler.DM.Expressions;
-using System;
-
-namespace DMCompiler.DM.Visitors {
- public sealed class DMASTSimplifier : DMASTVisitor {
- public void SimplifyAST(DMASTNode ast) {
- ast.Visit(this);
- }
-
- public void VisitFile(DMASTFile dmFile) {
- dmFile.BlockInner.Visit(this);
- }
-
- #region Objects
- public void VisitObjectDefinition(DMASTObjectDefinition statement) {
- statement.InnerBlock?.Visit(this);
- }
-
- public void VisitBlockInner(DMASTBlockInner blockInner) {
- foreach (DMASTStatement statement in blockInner.Statements) {
- statement.Visit(this);
- }
- }
-
- public void VisitObjectVarDefinition(DMASTObjectVarDefinition objectVarDefinition) {
- SimplifyExpression(ref objectVarDefinition.Value);
- }
-
- public void VisitMultipleObjectVarDefinitions(DMASTMultipleObjectVarDefinitions multipleObjectVarDefinitions) {
- foreach (DMASTObjectVarDefinition varDefinition in multipleObjectVarDefinitions.VarDefinitions) {
- varDefinition.Visit(this);
- }
- }
-
- public void VisitObjectVarOverride(DMASTObjectVarOverride objectVarOverride) {
- SimplifyExpression(ref objectVarOverride.Value);
- }
- #endregion Objects
-
- #region Procs
- public void VisitProcDefinition(DMASTProcDefinition procDefinition) {
- foreach (DMASTDefinitionParameter parameter in procDefinition.Parameters) {
- SimplifyExpression(ref parameter.Value);
- }
-
- procDefinition.Body?.Visit(this);
- }
-
- public void VisitProcBlockInner(DMASTProcBlockInner procBlockInner) {
- foreach (DMASTProcStatement statement in procBlockInner.Statements) {
- statement.Visit(this);
- }
- }
-
- public void VisitNullProcStatement(DMASTNullProcStatement nullProcStatement) { }
-
- public void VisitProcStatementExpression(DMASTProcStatementExpression statementExpression) {
- SimplifyExpression(ref statementExpression.Expression);
- }
-
- public void VisitProcStatementIf(DMASTProcStatementIf statementIf) {
- SimplifyExpression(ref statementIf.Condition);
-
- statementIf.Body?.Visit(this);
- statementIf.ElseBody?.Visit(this);
- }
-
- public void VisitProcStatementFor(DMASTProcStatementFor statementFor) {
- if (statementFor.Expression1 != null) SimplifyExpression(ref statementFor.Expression1);
- if (statementFor.Expression2 != null) SimplifyExpression(ref statementFor.Expression2);
- if (statementFor.Expression3 != null) SimplifyExpression(ref statementFor.Expression3);
- statementFor.Body?.Visit(this);
- }
-
- public void VisitProcStatementWhile(DMASTProcStatementWhile statementWhile) {
- SimplifyExpression(ref statementWhile.Conditional);
-
- statementWhile.Body?.Visit(this);
- }
-
- public void VisitProcStatementInfLoop(DMASTProcStatementInfLoop statementInfLoop){
- statementInfLoop.Body?.Visit(this);
- }
-
- public void VisitProcStatementDoWhile(DMASTProcStatementDoWhile statementDoWhile) {
- SimplifyExpression(ref statementDoWhile.Conditional);
-
- statementDoWhile.Body?.Visit(this);
- }
-
- public void VisitProcStatementSwitch(DMASTProcStatementSwitch statementSwitch) {
- SimplifyExpression(ref statementSwitch.Value);
-
- foreach (DMASTProcStatementSwitch.SwitchCase switchCase in statementSwitch.Cases) {
- if (switchCase is DMASTProcStatementSwitch.SwitchCaseValues switchCaseValues) {
- for (var i = 0; i < switchCaseValues.Values.Length; i++) {
- SimplifyExpression(ref switchCaseValues.Values[i]);
- }
- }
- switchCase.Body?.Visit(this);
- }
- }
-
- public void VisitProcStatementReturn(DMASTProcStatementReturn statementReturn) {
- SimplifyExpression(ref statementReturn.Value);
- }
-
- public void VisitProcStatementBreak(DMASTProcStatementBreak statementBreak) {
-
- }
-
- public void VisitProcStatementContinue(DMASTProcStatementContinue statementContinue) {
-
- }
-
- public void VisitProcStatementSet(DMASTProcStatementSet statementSet) {
-
- }
-
- public void VisitProcStatementDel(DMASTProcStatementDel statementDel) {
- SimplifyExpression(ref statementDel.Value);
- }
-
- public void VisitProcStatementSpawn(DMASTProcStatementSpawn statementSpawn) {
- SimplifyExpression(ref statementSpawn.Delay);
- statementSpawn.Body.Visit(this);
- }
-
- public void VisitProcStatementGoto(DMASTProcStatementGoto statementGoto) {
-
- }
-
- public void VisitProcStatementLabel(DMASTProcStatementLabel statementLabel) {
-
- }
-
- public void VisitProcStatementBrowse(DMASTProcStatementBrowse statementBrowse) {
- SimplifyExpression(ref statementBrowse.Receiver);
- SimplifyExpression(ref statementBrowse.Body);
- SimplifyExpression(ref statementBrowse.Options);
- }
-
- public void VisitProcStatementBrowseResource(DMASTProcStatementBrowseResource statementBrowseResource) {
- SimplifyExpression(ref statementBrowseResource.Receiver);
- SimplifyExpression(ref statementBrowseResource.File);
- SimplifyExpression(ref statementBrowseResource.Filename);
- }
-
- public void VisitProcStatementOutputControl(DMASTProcStatementOutputControl statementOutputControl) {
- SimplifyExpression(ref statementOutputControl.Receiver);
- SimplifyExpression(ref statementOutputControl.Message);
- SimplifyExpression(ref statementOutputControl.Control);
- }
-
- public void VisitProcStatementOutput(DMASTProcStatementOutput statementOutput) {
- SimplifyExpression(ref statementOutput.A);
- SimplifyExpression(ref statementOutput.B);
- }
-
- public void VisitProcStatementFtp(DMASTProcStatementFtp statementFtp) {
- SimplifyExpression(ref statementFtp.Receiver);
- SimplifyExpression(ref statementFtp.File);
- SimplifyExpression(ref statementFtp.Name);
- }
-
- public void VisitProcStatementInput(DMASTProcStatementInput statementInput) {
- SimplifyExpression(ref statementInput.A);
- SimplifyExpression(ref statementInput.B);
- }
-
- public void VisitProcStatementVarDeclaration(DMASTProcStatementVarDeclaration varDeclaration) {
- SimplifyExpression(ref varDeclaration.Value);
- }
-
- public void VisitProcStatementTryCatch(DMASTProcStatementTryCatch tryCatch) {
- tryCatch.TryBody.Visit(this);
- tryCatch.CatchBody?.Visit(this);
- }
-
- public void VisitProcStatementThrow(DMASTProcStatementThrow statementThrow) {
- SimplifyExpression(ref statementThrow.Value);
- }
- #endregion Procs
-
- private void SimplifyExpression(ref DMASTExpression expression) {
- if (expression == null || expression is DMASTExpressionConstant || expression is DMASTCallable) return;
-
- if (expression is DMASTExpressionWrapped wrapped) {
- SimplifyExpression(ref wrapped.Expression);
- return;
- }
-
- #region Comparators
- DMASTEqual equal = expression as DMASTEqual;
- if (equal != null) {
- SimplifyExpression(ref equal.A);
- SimplifyExpression(ref equal.B);
-
- return;
- }
-
- DMASTNotEqual notEqual = expression as DMASTNotEqual;
- if (notEqual != null) {
- SimplifyExpression(ref notEqual.A);
- SimplifyExpression(ref notEqual.B);
-
- return;
- }
-
- DMASTLessThan lessThan = expression as DMASTLessThan;
- if (lessThan != null) {
- SimplifyExpression(ref lessThan.A);
- SimplifyExpression(ref lessThan.B);
-
- return;
- }
-
- DMASTLessThanOrEqual lessThanOrEqual = expression as DMASTLessThanOrEqual;
- if (lessThanOrEqual != null) {
- SimplifyExpression(ref lessThanOrEqual.A);
- SimplifyExpression(ref lessThanOrEqual.B);
-
- return;
- }
-
- DMASTGreaterThan greaterThan = expression as DMASTGreaterThan;
- if (greaterThan != null) {
- SimplifyExpression(ref greaterThan.A);
- SimplifyExpression(ref greaterThan.B);
-
- return;
- }
-
- DMASTGreaterThanOrEqual greaterThanOrEqual = expression as DMASTGreaterThanOrEqual;
- if (greaterThanOrEqual != null) {
- SimplifyExpression(ref greaterThanOrEqual.A);
- SimplifyExpression(ref greaterThanOrEqual.B);
-
- return;
- }
-
- DMASTExpressionInRange inRange = expression as DMASTExpressionInRange;
- if (inRange != null) {
- SimplifyExpression(ref inRange.Value);
- SimplifyExpression(ref inRange.StartRange);
- SimplifyExpression(ref inRange.EndRange);
-
- return;
- }
- #endregion Comparators
-
- #region Math
- DMASTNegate negate = expression as DMASTNegate;
- if (negate != null) {
- SimplifyExpression(ref negate.Expression);
- if (negate.Expression is not DMASTExpressionConstant) return;
-
- switch (negate.Expression) {
- case DMASTConstantInteger exprInteger: expression = new DMASTConstantInteger(expression.Location, -exprInteger.Value); break;
- case DMASTConstantFloat exprFloat: expression = new DMASTConstantFloat(expression.Location, -exprFloat.Value); break;
- }
-
- return;
- }
-
- DMASTNot not = expression as DMASTNot;
- if (not != null) {
- SimplifyExpression(ref not.Expression);
- if (not.Expression is not DMASTExpressionConstant) return;
-
- DMASTConstantInteger exprInteger = not.Expression as DMASTConstantInteger;
- DMASTConstantFloat exprFloat = not.Expression as DMASTConstantFloat;
-
- if (exprInteger != null) expression = new DMASTConstantInteger(expression.Location, (exprInteger.Value != 0) ? 1 : 0);
- else if (exprFloat != null) expression = new DMASTConstantFloat(expression.Location, (exprFloat.Value != 0) ? 1 : 0);
-
- return;
- }
-
- DMASTOr or = expression as DMASTOr;
- if (or != null) {
- SimplifyExpression(ref or.A);
- SimplifyExpression(ref or.B);
- if (SimpleTruth(or.A) == true) {
- expression = or.A;
- return;
- }
- if (or.A is not DMASTExpressionConstant || or.B is not DMASTExpressionConstant) return;
- DMASTConstantInteger aInteger = or.A as DMASTConstantInteger;
- DMASTConstantInteger bInteger = or.B as DMASTConstantInteger;
- if (aInteger != null && bInteger != null) expression = new DMASTConstantInteger(expression.Location, ((aInteger.Value != 0) || (bInteger.Value != 0)) ? bInteger.Value : 0);
-
- return;
- }
-
- DMASTAnd and = expression as DMASTAnd;
- if (and != null) {
- SimplifyExpression(ref and.A);
- SimplifyExpression(ref and.B);
- if (SimpleTruth(and.A) == false) {
- expression = and.A;
- return;
- }
- if (and.A is not DMASTExpressionConstant || and.B is not DMASTExpressionConstant) return;
- DMASTConstantInteger aInteger = and.A as DMASTConstantInteger;
- DMASTConstantInteger bInteger = and.B as DMASTConstantInteger;
- if (aInteger != null && bInteger != null) expression = new DMASTConstantInteger(expression.Location, ((aInteger.Value != 0) && (bInteger.Value != 0)) ? bInteger.Value : 0);
-
- return;
- }
-
- DMASTLeftShift leftShift = expression as DMASTLeftShift;
- if (leftShift != null) {
- SimplifyExpression(ref leftShift.A);
- SimplifyExpression(ref leftShift.B);
- if (leftShift.A is not DMASTExpressionConstant || leftShift.B is not DMASTExpressionConstant) return;
-
- DMASTConstantInteger aInteger = leftShift.A as DMASTConstantInteger;
- DMASTConstantInteger bInteger = leftShift.B as DMASTConstantInteger;
-
- if (aInteger != null && bInteger != null) expression = new DMASTConstantInteger(expression.Location, aInteger.Value << bInteger.Value);
-
- return;
- }
-
- DMASTRightShift rightShift = expression as DMASTRightShift;
- if (rightShift != null) {
- SimplifyExpression(ref rightShift.A);
- SimplifyExpression(ref rightShift.B);
- if (rightShift.A is not DMASTExpressionConstant || rightShift.B is not DMASTExpressionConstant) return;
-
- DMASTConstantInteger aInteger = rightShift.A as DMASTConstantInteger;
- DMASTConstantInteger bInteger = rightShift.B as DMASTConstantInteger;
-
- if (aInteger != null && bInteger != null) expression = new DMASTConstantInteger(expression.Location, aInteger.Value >> bInteger.Value);
-
- return;
- }
-
- DMASTBinaryAnd binaryAnd = expression as DMASTBinaryAnd;
- if (binaryAnd != null) {
- SimplifyExpression(ref binaryAnd.A);
- SimplifyExpression(ref binaryAnd.B);
- if (binaryAnd.A is not DMASTExpressionConstant || binaryAnd.B is not DMASTExpressionConstant) return;
-
- DMASTConstantInteger aInteger = binaryAnd.A as DMASTConstantInteger;
- DMASTConstantInteger bInteger = binaryAnd.B as DMASTConstantInteger;
-
- if (aInteger != null && bInteger != null) expression = new DMASTConstantInteger(expression.Location, aInteger.Value & bInteger.Value);
-
- return;
- }
-
- DMASTBinaryOr binaryOr = expression as DMASTBinaryOr;
- if (binaryOr != null) {
- SimplifyExpression(ref binaryOr.A);
- SimplifyExpression(ref binaryOr.B);
- if (binaryOr.A is not DMASTExpressionConstant || binaryOr.B is not DMASTExpressionConstant) return;
-
- DMASTConstantInteger aInteger = binaryOr.A as DMASTConstantInteger;
- DMASTConstantInteger bInteger = binaryOr.B as DMASTConstantInteger;
-
- if (aInteger != null && bInteger != null) expression = new DMASTConstantInteger(expression.Location, aInteger.Value | bInteger.Value);
-
- return;
- }
-
- DMASTBinaryNot binaryNot = expression as DMASTBinaryNot;
- if (binaryNot != null) {
- SimplifyExpression(ref binaryNot.Value);
- if (binaryNot.Value is not DMASTExpressionConstant) return;
-
- DMASTConstantInteger valueInteger = binaryNot.Value as DMASTConstantInteger;
-
- if (valueInteger != null) expression = new DMASTConstantInteger(expression.Location, (~valueInteger.Value) & 0xFFFFFF);
-
- return;
- }
-
- DMASTAdd add = expression as DMASTAdd;
- if (add != null) {
- SimplifyExpression(ref add.A);
- SimplifyExpression(ref add.B);
- if (add.A is not DMASTExpressionConstant || add.B is not DMASTExpressionConstant) return;
-
- DMASTConstantInteger aInteger = add.A as DMASTConstantInteger;
- DMASTConstantFloat aFloat = add.A as DMASTConstantFloat;
- DMASTConstantString aString = add.A as DMASTConstantString;
- DMASTConstantInteger bInteger = add.B as DMASTConstantInteger;
- DMASTConstantFloat bFloat = add.B as DMASTConstantFloat;
- DMASTConstantString bString = add.B as DMASTConstantString;
-
- if (aInteger != null && bInteger != null) expression = new DMASTConstantInteger(expression.Location, aInteger.Value + bInteger.Value);
- else if (aInteger != null && bFloat != null) expression = new DMASTConstantFloat(expression.Location, aInteger.Value + bFloat.Value);
- else if (aFloat != null && bInteger != null) expression = new DMASTConstantFloat(expression.Location, aFloat.Value + bInteger.Value);
- else if (aFloat != null && bFloat != null) expression = new DMASTConstantFloat(expression.Location, aFloat.Value + bFloat.Value);
- else if (aString != null && bString != null) expression = new DMASTConstantString(expression.Location, aString.Value + bString.Value);
-
- return;
- }
-
- DMASTSubtract subtract = expression as DMASTSubtract;
- if (subtract != null) {
- SimplifyExpression(ref subtract.A);
- SimplifyExpression(ref subtract.B);
- if (subtract.A is not DMASTExpressionConstant || subtract.B is not DMASTExpressionConstant) return;
-
- DMASTConstantInteger aInteger = subtract.A as DMASTConstantInteger;
- DMASTConstantInteger bInteger = subtract.B as DMASTConstantInteger;
-
- if (aInteger != null && bInteger != null) expression = new DMASTConstantInteger(expression.Location, aInteger.Value - bInteger.Value);
-
- return;
- }
-
- DMASTMultiply multiply = expression as DMASTMultiply;
- if (multiply != null) {
- SimplifyExpression(ref multiply.A);
- SimplifyExpression(ref multiply.B);
- if (multiply.A is not DMASTExpressionConstant || multiply.B is not DMASTExpressionConstant) return;
-
- DMASTConstantInteger aInteger = multiply.A as DMASTConstantInteger;
- DMASTConstantFloat aFloat = multiply.A as DMASTConstantFloat;
- DMASTConstantInteger bInteger = multiply.B as DMASTConstantInteger;
- DMASTConstantFloat bFloat = multiply.B as DMASTConstantFloat;
-
- if (aInteger != null && bInteger != null) expression = new DMASTConstantInteger(expression.Location, aInteger.Value * bInteger.Value);
- else if (aInteger != null && bFloat != null) expression = new DMASTConstantFloat(expression.Location, aInteger.Value * bFloat.Value);
- else if (aFloat != null && bInteger != null) expression = new DMASTConstantFloat(expression.Location, aFloat.Value * bInteger.Value);
- else if (aFloat != null && bFloat != null) expression = new DMASTConstantFloat(expression.Location, aFloat.Value * bFloat.Value);
-
- return;
- }
-
- DMASTDivide divide = expression as DMASTDivide;
- if (divide != null) {
- SimplifyExpression(ref divide.A);
- SimplifyExpression(ref divide.B);
- if (divide.A is not DMASTExpressionConstant || divide.B is not DMASTExpressionConstant) return;
-
- DMASTConstantInteger aInteger = divide.A as DMASTConstantInteger;
- DMASTConstantFloat aFloat = divide.A as DMASTConstantFloat;
- DMASTConstantInteger bInteger = divide.B as DMASTConstantInteger;
- DMASTConstantFloat bFloat = divide.B as DMASTConstantFloat;
-
- if (aInteger != null && bInteger != null) {
- if (aInteger.Value % bInteger.Value == 0) expression = new DMASTConstantFloat(expression.Location, aInteger.Value / bInteger.Value);
- else expression = new DMASTConstantFloat(expression.Location, (float)aInteger.Value / (float)bInteger.Value);
- } else if (aFloat != null && bInteger != null) {
- expression = new DMASTConstantFloat(expression.Location, aFloat.Value / bInteger.Value);
- } else if (aFloat != null && bFloat != null) {
- expression = new DMASTConstantFloat(expression.Location, aFloat.Value / bFloat.Value);
- }
-
- return;
- }
-
- DMASTModulus modulus = expression as DMASTModulus;
- if (modulus != null) {
- SimplifyExpression(ref modulus.A);
- SimplifyExpression(ref modulus.B);
- if (modulus.A is not DMASTExpressionConstant || modulus.B is not DMASTExpressionConstant) return;
-
- DMASTConstantInteger aInteger = modulus.A as DMASTConstantInteger;
- DMASTConstantInteger bInteger = modulus.B as DMASTConstantInteger;
-
- if (aInteger != null && bInteger != null) expression = new DMASTConstantInteger(expression.Location, aInteger.Value % bInteger.Value);
-
- return;
- }
-
- DMASTPower power = expression as DMASTPower;
- if (power != null) {
- SimplifyExpression(ref power.A);
- SimplifyExpression(ref power.B);
- if (power.A is not DMASTExpressionConstant || power.B is not DMASTExpressionConstant) return;
-
- DMASTConstantInteger aInteger = power.A as DMASTConstantInteger;
- DMASTConstantInteger bInteger = power.B as DMASTConstantInteger;
-
- if (aInteger != null && bInteger != null) expression = new DMASTConstantInteger(expression.Location, (int)MathF.Pow(aInteger.Value, bInteger.Value));
-
- return;
- }
-
- DMASTAppend append = expression as DMASTAppend;
- if (append != null) {
- SimplifyExpression(ref append.A);
- SimplifyExpression(ref append.B);
-
- return;
- }
-
- DMASTRemove remove = expression as DMASTRemove;
- if (remove != null) {
- SimplifyExpression(ref remove.A);
- SimplifyExpression(ref remove.B);
-
- return;
- }
-
- DMASTCombine combine = expression as DMASTCombine;
- if (combine != null) {
- SimplifyExpression(ref combine.A);
- SimplifyExpression(ref combine.B);
-
- return;
- }
-
- DMASTMask mask = expression as DMASTMask;
- if (mask != null) {
- SimplifyExpression(ref mask.A);
- SimplifyExpression(ref mask.B);
-
- return;
- }
- #endregion Math
-
- #region Others
- DMASTList list = expression as DMASTList;
- if (list != null) {
- foreach (DMASTCallParameter parameter in list.Values) {
- SimplifyExpression(ref parameter.Value);
- }
-
- return;
- }
-
- DMASTAddText addtext = expression as DMASTAddText;
- if(addtext != null) {
- foreach (DMASTCallParameter parameter in addtext.Parameters)
- {
- SimplifyExpression(ref parameter.Value);
- }
-
- return;
- }
-
- DMASTNewPath newPath = expression as DMASTNewPath;
- if (newPath != null) {
- if (newPath.Parameters != null) {
- foreach (DMASTCallParameter parameter in newPath.Parameters) {
- SimplifyExpression(ref parameter.Value);
- }
- }
-
- return;
- }
-
- DMASTNewExpr newExpr = expression as DMASTNewExpr;
- if (newExpr != null) {
- SimplifyExpression(ref newExpr.Expression);
-
- if (newExpr.Parameters != null) {
- foreach (DMASTCallParameter parameter in newExpr.Parameters) {
- SimplifyExpression(ref parameter.Value);
- }
- }
- }
-
- if (expression is DMASTDereference deref) {
- SimplifyExpression(ref deref.Expression);
-
- foreach (var operation in deref.Operations) {
- switch (operation) {
- case DMASTDereference.IndexOperation indexOperation:
- SimplifyExpression(ref indexOperation.Index);
- break;
- case DMASTDereference.CallOperation callOperation:
- foreach (var param in callOperation.Parameters) {
- SimplifyExpression(ref param.Value);
- }
- break;
- }
- }
- }
-
- DMASTProcCall procCall = expression as DMASTProcCall;
- if (procCall != null) {
- foreach (DMASTCallParameter parameter in procCall.Parameters) {
- SimplifyExpression(ref parameter.Value);
- }
-
- return;
- }
-
- DMASTAssign assign = expression as DMASTAssign;
- if (assign != null) {
- SimplifyExpression(ref assign.Expression);
- SimplifyExpression(ref assign.Value);
-
- return;
- }
-
- DMASTStringFormat stringFormat = expression as DMASTStringFormat;
- if (stringFormat != null) {
- for (int i = 0; i < stringFormat.InterpolatedValues.Length; i++) {
- DMASTExpression simplifiedValue = stringFormat.InterpolatedValues[i];
-
- SimplifyExpression(ref simplifiedValue);
- stringFormat.InterpolatedValues[i] = simplifiedValue;
- }
-
- return;
- }
- if (expression is DMASTSwitchCaseRange switchCaseRange) {
- SimplifyExpression(ref switchCaseRange.RangeStart);
- SimplifyExpression(ref switchCaseRange.RangeEnd);
- return;
- }
- #endregion Others
- }
-
- bool? SimpleTruth(DMASTExpression expr) {
- switch (expr) {
- case DMASTConstantInteger e: return e.Value != 0;
- case DMASTConstantFloat e: return e.Value != 0;
- case DMASTConstantString e: return e.Value.Length != 0;
- case DMASTConstantNull: return false;
- case DMASTConstantPath: return true;
- case DMASTConstantResource: return true;
- default: return null;
- }
- }
- }
-}
diff --git a/DMCompiler/DMCompiler.cs b/DMCompiler/DMCompiler.cs
index 1f5af12f48..9a1d354cbc 100644
--- a/DMCompiler/DMCompiler.cs
+++ b/DMCompiler/DMCompiler.cs
@@ -3,7 +3,6 @@
using DMCompiler.Compiler.DMM;
using DMCompiler.Compiler.DMPreprocessor;
using DMCompiler.DM;
-using DMCompiler.DM.Visitors;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -14,6 +13,8 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using DMCompiler.Compiler;
+using DMCompiler.Compiler.DM.AST;
+using DMCompiler.DM.Builders;
using DMCompiler.Json;
namespace DMCompiler;
@@ -157,9 +158,9 @@ private static bool Compile(IEnumerable preprocessedTokens) {
Emit(warning);
}
- DMASTSimplifier astSimplifier = new DMASTSimplifier();
+ DMASTFolder astSimplifier = new DMASTFolder();
VerbosePrint("Constant folding");
- astSimplifier.SimplifyAST(astFile);
+ astSimplifier.FoldAst(astFile);
DMObjectBuilder.BuildObjectTree(astFile);