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);