diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-11-19 12:47:50 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-11-19 12:47:50 +0000 |
| commit | 6d71b87e4be3de27432e9efa4d601a0351d68cc4 (patch) | |
| tree | 6c8b09775f2555e773e5ae0a35c35f060177e653 /src/main/java/org | |
| parent | 9a89c6c410dcdced542438a955becea587a07862 (diff) | |
Check for consistency in compilation unit elements
Diffstat (limited to 'src/main/java/org')
4 files changed, 55 insertions, 5 deletions
diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenContext.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenContext.java index da417cf5..c6f9b11d 100644 --- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenContext.java +++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenContext.java @@ -11,6 +11,7 @@ import org.shedlang.compiler.patio.ast.instructions.PatioLocalStore; import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; import org.shedlang.compiler.patio.ast.types.PatioDataLayout; import org.shedlang.compiler.patio.ast.types.PatioType; +import org.shedlang.compiler.patio.errors.DuplicateCompilationUnitElementName; import org.shedlang.compiler.sources.Source; import org.shedlang.compiler.typechecker.TypeInfos; import org.shedlang.compiler.types.*; @@ -150,11 +151,33 @@ public record PatioCodeGenContext( public CompilationUnitContext addCompilationUnitElement( PatioCompilationUnitElement element ) { + if (this.elementsByName.containsKey(element.name())) { + throw new DuplicateCompilationUnitElementName(element.name(), element.source()); + } + return new CompilationUnitContext( this.elementsByName.plus(element.name(), element) ); } + @CheckReturnValue + public CompilationUnitContext ensureCompilationUnitElement( + PatioCompilationUnitElement element + ) { + var existingElement = this.elementsByName.get(element.name()); + + if (existingElement == null) { + return new CompilationUnitContext( + this.elementsByName.plus(element.name(), element) + ); + } else if (existingElement.equals(element)) { + return this; + } else { + throw new DuplicateCompilationUnitElementName(element.name(), element.source()); + } + + } + public record Result<T>(T value, CompilationUnitContext context) {} } @@ -389,6 +412,15 @@ public record PatioCodeGenContext( } @CheckReturnValue + public PatioCodeGenContext ensureCompilationUnitElement( + PatioCompilationUnitElement element + ) { + return withCompilationUnitContext( + this.compilationUnitContext.ensureCompilationUnitElement(element) + ); + } + + @CheckReturnValue public PatioCodeGenResult<PatioLocalRef> temporaryPop() { var result = this.functionContext.temporaryPop(); diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenEffects.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenEffects.java index dd1f414b..6d6e0476 100644 --- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenEffects.java +++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenEffects.java @@ -11,6 +11,7 @@ import org.shedlang.compiler.patio.ast.types.PatioDataLayouts; import org.shedlang.compiler.patio.ast.types.PatioType; import org.shedlang.compiler.patio.ast.types.PatioTypes; import org.shedlang.compiler.sources.Source; +import org.shedlang.compiler.sources.Sources; import org.shedlang.compiler.stackir.instructions.DefineFunctionInstruction; import org.shedlang.compiler.types.UserDefinedEffect; import org.shedlang.compiler.util.Lists; @@ -75,15 +76,14 @@ public class PatioCodeGenEffects { bodyContext -> { var runtimeFindHandlerMethodName = "shed__runtime__effects_find_handler_method"; - // TODO: check if element already exists? - bodyContext = bodyContext.addCompilationUnitElement(new PatioFunctionDeclaration( + bodyContext = bodyContext.ensureCompilationUnitElement(new PatioFunctionDeclaration( runtimeFindHandlerMethodName, List.of( new PatioLocal.Param("effectTag", EFFECT_TAG_TYPE), new PatioLocal.Param("methodIndex", EFFECT_METHOD_INDEX_TYPE) ), PatioCodeGenTypes.VALUE_TYPE, - source + Sources.RUNTIME )); var handlerMethodResult = bodyContext.allocateVal( diff --git a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenStrings.java b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenStrings.java index a1de8092..2e62202d 100644 --- a/src/main/java/org/shedlang/compiler/patio/PatioCodeGenStrings.java +++ b/src/main/java/org/shedlang/compiler/patio/PatioCodeGenStrings.java @@ -10,6 +10,7 @@ import org.shedlang.compiler.patio.ast.types.PatioDataLayouts; import org.shedlang.compiler.patio.ast.types.PatioDataValue; import org.shedlang.compiler.patio.ast.types.PatioDataValues; import org.shedlang.compiler.sources.Source; +import org.shedlang.compiler.sources.Sources; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -60,14 +61,14 @@ public class PatioCodeGenStrings { ) { var runtimeAddName = "shed__runtime__string_add"; - context = context.addCompilationUnitElement(new PatioFunctionDeclaration( + context = context.ensureCompilationUnitElement(new PatioFunctionDeclaration( runtimeAddName, List.of( new PatioLocal.Param("left", PatioCodeGenTypes.VALUE_TYPE), new PatioLocal.Param("right", PatioCodeGenTypes.VALUE_TYPE) ), PatioCodeGenTypes.VALUE_TYPE, - source + Sources.RUNTIME )); context = context.addInstruction(new PatioCall( diff --git a/src/main/java/org/shedlang/compiler/patio/errors/DuplicateCompilationUnitElementName.java b/src/main/java/org/shedlang/compiler/patio/errors/DuplicateCompilationUnitElementName.java new file mode 100644 index 00000000..264d7da8 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/patio/errors/DuplicateCompilationUnitElementName.java @@ -0,0 +1,17 @@ +package org.shedlang.compiler.patio.errors; + +import org.shedlang.compiler.errors.InternalCompilerError; +import org.shedlang.compiler.sources.Source; + +public class DuplicateCompilationUnitElementName extends InternalCompilerError { + private final String elementName; + + public DuplicateCompilationUnitElementName(String elementName, Source source) { + super("Duplicate compilation unit element name: " + elementName, source); + this.elementName = elementName; + } + + public String elementName() { + return elementName; + } +} |
