From de3e65e6cf2373cbaad7440514b81d4d96862476 Mon Sep 17 00:00:00 2001 From: wixoaGit Date: Fri, 17 Jan 2025 01:00:07 -0500 Subject: [PATCH 1/2] Fix var blocks creating an empty type --- .../Compiler/DM/AST/DMAST.ObjectStatements.cs | 6 +++ DMCompiler/Compiler/DM/DMParser.cs | 41 ++++++++++++++----- DMCompiler/DM/Builders/DMCodeTreeBuilder.cs | 2 + 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/DMCompiler/Compiler/DM/AST/DMAST.ObjectStatements.cs b/DMCompiler/Compiler/DM/AST/DMAST.ObjectStatements.cs index a0f4f9dd81..ff3d8319ec 100644 --- a/DMCompiler/Compiler/DM/AST/DMAST.ObjectStatements.cs +++ b/DMCompiler/Compiler/DM/AST/DMAST.ObjectStatements.cs @@ -7,6 +7,12 @@ namespace DMCompiler.Compiler.DM.AST; /// public abstract class DMASTStatement(Location location) : DMASTNode(location); +/// +/// Used when there was an error parsing a statement +/// +/// Emit an error code before creating! +public sealed class DMASTInvalidStatement(Location location) : DMASTStatement(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.
diff --git a/DMCompiler/Compiler/DM/DMParser.cs b/DMCompiler/Compiler/DM/DMParser.cs index c66199337f..b9088c03d8 100644 --- a/DMCompiler/Compiler/DM/DMParser.cs +++ b/DMCompiler/Compiler/DM/DMParser.cs @@ -268,17 +268,28 @@ public DMASTFile File() { return new DMASTProcDefinition(loc, CurrentPath, parameters.ToArray(), procBlock, types); } - //Object definition - if (Block() is { } block) { - Compiler.VerbosePrint($"Parsed object {CurrentPath}"); - return new DMASTObjectDefinition(loc, CurrentPath, block); - } - //Var definition(s) if (CurrentPath.FindElement("var") != -1) { + var isIndented = (CurrentPath.LastElement == "var"); DreamPath varPath = CurrentPath; List varDefinitions = new(); + if (isIndented) { + Newline(); + if (!Check(TokenType.DM_Indent)) { + Emit(WarningCode.BadToken, CurrentLoc, "Expected beginning of a var block"); + return new DMASTInvalidStatement(CurrentLoc); + } + + DMASTPath? newVarPath = Path(); + if (newVarPath == null) { + Emit(WarningCode.InvalidVarDefinition, "Expected a var definition"); + return new DMASTInvalidStatement(CurrentLoc); + } + + varPath = CurrentPath.AddToPath(newVarPath.Path.PathString); + } + while (true) { Whitespace(); @@ -304,24 +315,26 @@ public DMASTFile File() { var varDef = new DMASTObjectVarDefinition(loc, varPath, value, valType); varDefinitions.Add(varDef); - if (Check(TokenType.DM_Comma)) { + if (Check(TokenType.DM_Comma) || (isIndented && Newline())) { Whitespace(); DMASTPath? newVarPath = Path(); if (newVarPath == null) { Emit(WarningCode.InvalidVarDefinition, "Expected a var definition"); break; - } else if (newVarPath.Path.Elements.Length > 1) { // TODO: This is valid DM - Emit(WarningCode.BadToken, newVarPath.Location, "Invalid var name"); - break; } - varPath = CurrentPath.AddToPath("../" + newVarPath.Path.PathString); + varPath = CurrentPath.AddToPath( + isIndented ? newVarPath.Path.PathString + : "../" + newVarPath.Path.PathString); } else { break; } } + if (isIndented) + Consume(TokenType.DM_Dedent, "Expected end of var block"); + return (varDefinitions.Count == 1) ? varDefinitions[0] : new DMASTMultipleObjectVarDefinitions(loc, varDefinitions.ToArray()); @@ -336,6 +349,12 @@ public DMASTFile File() { return new DMASTObjectVarOverride(loc, CurrentPath, value); } + //Object definition + if (Block() is { } block) { + Compiler.VerbosePrint($"Parsed object {CurrentPath}"); + return new DMASTObjectDefinition(loc, CurrentPath, block); + } + //Empty object definition Compiler.VerbosePrint($"Parsed object {CurrentPath} - empty"); return new DMASTObjectDefinition(loc, CurrentPath, null); diff --git a/DMCompiler/DM/Builders/DMCodeTreeBuilder.cs b/DMCompiler/DM/Builders/DMCodeTreeBuilder.cs index c4b558c95d..612576368e 100644 --- a/DMCompiler/DM/Builders/DMCodeTreeBuilder.cs +++ b/DMCompiler/DM/Builders/DMCodeTreeBuilder.cs @@ -40,6 +40,8 @@ private void ProcessStatement(DMASTStatement statement, DreamPath currentType) { } switch (statement) { + case DMASTInvalidStatement: + break; // An error should have been emitted by whatever made this case DMASTObjectDefinition objectDefinition: CodeTree.AddType(objectDefinition.Path); if (objectDefinition.InnerBlock != null) From 1de2d241bb9c1610ebc5be97c7a92c642191104e Mon Sep 17 00:00:00 2001 From: wixoaGit Date: Fri, 17 Jan 2025 14:00:31 -0500 Subject: [PATCH 2/2] Fix `var/type` blocks --- DMCompiler/Compiler/DM/DMParser.cs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/DMCompiler/Compiler/DM/DMParser.cs b/DMCompiler/Compiler/DM/DMParser.cs index b9088c03d8..2949029862 100644 --- a/DMCompiler/Compiler/DM/DMParser.cs +++ b/DMCompiler/Compiler/DM/DMParser.cs @@ -270,24 +270,24 @@ public DMASTFile File() { //Var definition(s) if (CurrentPath.FindElement("var") != -1) { - var isIndented = (CurrentPath.LastElement == "var"); + bool isIndented = false; DreamPath varPath = CurrentPath; List varDefinitions = new(); - if (isIndented) { - Newline(); - if (!Check(TokenType.DM_Indent)) { - Emit(WarningCode.BadToken, CurrentLoc, "Expected beginning of a var block"); - return new DMASTInvalidStatement(CurrentLoc); - } + var possibleNewline = Current(); + if (Newline()) { + if (Check(TokenType.DM_Indent)) { + isIndented = true; + DMASTPath? newVarPath = Path(); + if (newVarPath == null) { + Emit(WarningCode.InvalidVarDefinition, "Expected a var definition"); + return new DMASTInvalidStatement(CurrentLoc); + } - DMASTPath? newVarPath = Path(); - if (newVarPath == null) { - Emit(WarningCode.InvalidVarDefinition, "Expected a var definition"); - return new DMASTInvalidStatement(CurrentLoc); + varPath = CurrentPath.AddToPath(newVarPath.Path.PathString); + } else { + ReuseToken(possibleNewline); } - - varPath = CurrentPath.AddToPath(newVarPath.Path.PathString); } while (true) {