Skip to content

Commit

Permalink
Organize AST definitions (#1644)
Browse files Browse the repository at this point in the history
  • Loading branch information
wixoaGit authored Feb 12, 2024
1 parent ca4f0b8 commit 9e11562
Show file tree
Hide file tree
Showing 25 changed files with 1,304 additions and 3,688 deletions.
30 changes: 11 additions & 19 deletions DMCompiler/Bytecode/DreamProcOpcode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)<br/>
/// See: "Halfwidth and Fullwidth Forms" on https://en.wikibooks.org/wiki/Unicode/Character_reference/F000-FFFF
/// </remarks>
public static UInt16 FormatPrefix = 0xFF00;
public static ushort FormatPrefix = 0xFF00;

/// <summary>
/// The lower byte of the aforementioned formatting marker thingies we stuff into our UTF16 strings.<br/>
Expand All @@ -164,14 +164,14 @@ public static class StringFormatEncoder {
/// <remarks>
/// <see langword="DO NOT CAST TO CHAR!"/> This requires FormatPrefix to be added to it in order to be a useful formatting character!!
/// </remarks>
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
Expand Down Expand Up @@ -214,12 +214,12 @@ public enum FormatSuffix : UInt16 {

/// <returns>The UTF16 character we should be actually storing to articulate this format marker.</returns>
public static char Encode(FormatSuffix suffix) {
return (char)(FormatPrefix | ((UInt16)suffix));
return (char)(FormatPrefix | ((ushort)suffix));
}

/// <returns>true if the input character was actually a formatting codepoint. false if not.</returns>
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;
Expand All @@ -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
}

Expand Down Expand Up @@ -386,23 +386,15 @@ public static string GetOpcodesHash() {
/// Custom attribute for declaring <see cref="OpcodeMetadata"/> metadata for individual opcodes
/// </summary>
[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);
}

/// <summary>
/// Miscellaneous metadata associated with individual <see cref="DreamProcOpcode"/> opcodes using the <see cref="OpcodeMetadataAttribute"/> attribute
/// </summary>
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
}

/// <summary>
Expand All @@ -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();
}
}
Expand Down
234 changes: 234 additions & 0 deletions DMCompiler/Compiler/DM/AST/DMAST.Expression.cs
Original file line number Diff line number Diff line change
@@ -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<DMASTExpression> Leaves() {
yield break;
}

/// <summary>
/// If this is a <see cref="DMASTExpressionWrapped"/>, returns the expression inside.
/// Returns this expression if not.
/// </summary>
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())
);
}
}

/// <summary>
/// Represents the value of a var defined as <code>var/list/L[1][2][3]</code>
/// </summary>
public sealed class DMASTDimensionalList(Location location, List<DMASTExpression> sizes)
: DMASTExpression(location) {
public readonly List<DMASTExpression> 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<DMASTExpression> 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<DMASTExpression> 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 {
/// <summary>
/// The location of the operation.
/// </summary>
public required Location Location;
/// <summary>
/// Whether we should short circuit if the expression we are accessing is null.
/// </summary>
public required bool Safe; // x?.y, x?.y() etc
}

public abstract class NamedOperation : Operation {
/// <summary>
/// Name of the identifier.
/// </summary>
public required string Identifier;
/// <summary>
/// Whether we should check if the variable exists or not.
/// </summary>
public required bool NoSearch; // x:y, x:y()
}

public sealed class FieldOperation : NamedOperation;

public sealed class IndexOperation : Operation {
/// <summary>
/// The index expression that we use to index this expression (constant or otherwise).
/// </summary>
public required DMASTExpression Index; // x[y], x?[y]
}

public sealed class CallOperation : NamedOperation {
/// <summary>
/// The parameters that we call this proc with.
/// </summary>
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;
56 changes: 56 additions & 0 deletions DMCompiler/Compiler/DM/AST/DMAST.ExpressionBinary.cs
Original file line number Diff line number Diff line change
@@ -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<DMASTExpression> 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);
Loading

0 comments on commit 9e11562

Please sign in to comment.