Skip to content

Commit

Permalink
refactor deref
Browse files Browse the repository at this point in the history
  • Loading branch information
distributivgesetz committed Jan 2, 2024
1 parent 5194bcd commit 4db46ae
Show file tree
Hide file tree
Showing 5 changed files with 293 additions and 412 deletions.
64 changes: 36 additions & 28 deletions DMCompiler/Compiler/DM/DMAST.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2693,34 +2693,42 @@ public override void Visit(DMASTVisitor visitor) {


public sealed class DMASTDereference : DMASTExpression {
public enum OperationKind {
Invalid,

Field, // x.y
FieldSafe, // x?.y
FieldSearch, // x:y
FieldSafeSearch, // x?:y

Index, // x[y]
IndexSafe, // x?[y]

Call, // x.y()
CallSafe, // x?.y()
CallSearch, // x:y()
CallSafeSearch, // x?:y()
}

public struct Operation {
public OperationKind Kind;

// Field*, Call*
public DMASTIdentifier Identifier;

// Index*
public DMASTExpression Index;

// Call*
public DMASTCallParameter[] Parameters;
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 DMASTExpression Expression;
Expand Down
84 changes: 32 additions & 52 deletions DMCompiler/Compiler/DM/DMParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2254,46 +2254,39 @@ private void BracketWhitespace() {
break;
}

DMASTDereference.Operation operation = new() {
Kind = DMASTDereference.OperationKind.Invalid,
};
DMASTDereference.Operation operation;

switch (token.Type) {
case TokenType.DM_Period:
case TokenType.DM_QuestionPeriod:
case TokenType.DM_Colon:
case TokenType.DM_QuestionColon: {
DMASTIdentifier identifier = Identifier();

operation.Kind = token.Type switch {
TokenType.DM_Period => DMASTDereference.OperationKind.Field,
TokenType.DM_QuestionPeriod => DMASTDereference.OperationKind.FieldSafe,
TokenType.DM_Colon => DMASTDereference.OperationKind.FieldSearch,
TokenType.DM_QuestionColon => DMASTDereference.OperationKind.FieldSafeSearch,
_ => throw new InvalidOperationException(),
};

operation.Identifier = identifier;
}
DMASTIdentifier identifier = Identifier();

operation = new DMASTDereference.FieldOperation {
Location = identifier.Location,
Safe = token.Type is TokenType.DM_QuestionPeriod or TokenType.DM_QuestionColon,
Identifier = identifier.Identifier,
NoSearch = token.Type is TokenType.DM_Colon or TokenType.DM_QuestionColon
};
break;
}

case TokenType.DM_LeftBracket:
case TokenType.DM_QuestionLeftBracket: {
ternaryBHasPriority = true;

Whitespace();
DMASTExpression index = Expression();
ConsumeRightBracket();

operation.Kind = token.Type switch {
TokenType.DM_LeftBracket => DMASTDereference.OperationKind.Index,
TokenType.DM_QuestionLeftBracket => DMASTDereference.OperationKind.IndexSafe,
_ => throw new InvalidOperationException(),
};
ternaryBHasPriority = true;

operation.Index = index;
}
Whitespace();
DMASTExpression index = Expression();
ConsumeRightBracket();

operation = new DMASTDereference.IndexOperation {
Index = index,
Location = index.Location,
Safe = token.Type is TokenType.DM_QuestionLeftBracket
};
break;
}

default:
throw new InvalidOperationException("unhandled dereference token");
Expand All @@ -2308,34 +2301,21 @@ private void BracketWhitespace() {
if (parameters != null) {
ternaryBHasPriority = true;

switch (operation.Kind) {
case DMASTDereference.OperationKind.Field:
operation.Kind = DMASTDereference.OperationKind.Call;
operation.Parameters = parameters;
break;

case DMASTDereference.OperationKind.FieldSafe:
operation.Kind = DMASTDereference.OperationKind.CallSafe;
operation.Parameters = parameters;
break;

case DMASTDereference.OperationKind.FieldSearch:
operation.Kind = DMASTDereference.OperationKind.CallSearch;
operation.Parameters = parameters;
break;

case DMASTDereference.OperationKind.FieldSafeSearch:
operation.Kind = DMASTDereference.OperationKind.CallSafeSearch;
operation.Parameters = parameters;
switch (operation) {
case DMASTDereference.FieldOperation fieldOperation:
operation = new DMASTDereference.CallOperation {
Parameters = parameters,
Location = fieldOperation.Location,
Safe = fieldOperation.Safe,
Identifier = fieldOperation.Identifier,
NoSearch = fieldOperation.NoSearch
};
break;

case DMASTDereference.OperationKind.Index:
case DMASTDereference.OperationKind.IndexSafe:
case DMASTDereference.IndexOperation:
Error("attempt to call an invalid l-value");
return null;

case DMASTDereference.OperationKind.Call:
case DMASTDereference.OperationKind.CallSafe:
default:
throw new InvalidOperationException("unhandled dereference operation kind");
}
Expand All @@ -2345,7 +2325,7 @@ private void BracketWhitespace() {
operations.Add(operation);
}

if (operations.Any()) {
if (operations.Count != 0) {
Whitespace();
return new DMASTDereference(expression.Location, expression, operations.ToArray());
}
Expand Down
Loading

0 comments on commit 4db46ae

Please sign in to comment.