From f9dafe8f87b00fc158e5c3be0ab03eafdc1b53d4 Mon Sep 17 00:00:00 2001 From: Stan Hebben Date: Fri, 12 Apr 2024 20:59:10 +0200 Subject: [PATCH] WIP to implement proper try/catch --- .../codemodel/compilation/StatementCompiler.java | 2 ++ .../impl/compiler/ExpressionCompilerImpl.java | 2 +- .../impl/compiler/MemberCompilerImpl.java | 2 +- .../impl/compiler/StatementCompilerImpl.java | 15 +++++++++++---- .../zenscript/parser/ParsedFileCompiler.java | 2 +- .../parser/statements/ParsedStatementThrow.java | 4 ++-- .../zencode-tests/statements/try-catch-3.zc | 16 ++++++++++++++++ 7 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 ScriptingEngineTester/src/main/resources/zencode-tests/statements/try-catch-3.zc diff --git a/CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/StatementCompiler.java b/CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/StatementCompiler.java index 824e8e19d..affb740cd 100644 --- a/CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/StatementCompiler.java +++ b/CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/StatementCompiler.java @@ -25,5 +25,7 @@ public interface StatementCompiler { Optional getFunctionHeader(); + Optional getThrownType(); + void addLocalVariable(CompilingVariable variable); } diff --git a/CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/impl/compiler/ExpressionCompilerImpl.java b/CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/impl/compiler/ExpressionCompilerImpl.java index c695b00f4..a2d404661 100644 --- a/CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/impl/compiler/ExpressionCompilerImpl.java +++ b/CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/impl/compiler/ExpressionCompilerImpl.java @@ -138,7 +138,7 @@ public ExpressionCompiler withLocalVariables(List variables) @Override public StatementCompiler forLambda(LambdaClosure closure, FunctionHeader header) { LocalSymbols newLocals = locals.forLambda(closure, header); - return new StatementCompilerImpl(context, localType, types, header, newLocals); + return new StatementCompilerImpl(context, localType, types, header, newLocals, null); } @Override diff --git a/CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/impl/compiler/MemberCompilerImpl.java b/CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/impl/compiler/MemberCompilerImpl.java index ae1e4f72c..203fe9b11 100644 --- a/CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/impl/compiler/MemberCompilerImpl.java +++ b/CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/impl/compiler/MemberCompilerImpl.java @@ -35,7 +35,7 @@ public ExpressionCompiler forFieldInitializers() { @Override public StatementCompiler forMethod(FunctionHeader header) { - return new StatementCompilerImpl(context, localType, types, header, new LocalSymbols(header)); + return new StatementCompilerImpl(context, localType, types, header, new LocalSymbols(header), null); } @Override diff --git a/CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/impl/compiler/StatementCompilerImpl.java b/CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/impl/compiler/StatementCompilerImpl.java index 11e6766db..ba40a954f 100644 --- a/CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/impl/compiler/StatementCompilerImpl.java +++ b/CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/impl/compiler/StatementCompilerImpl.java @@ -20,14 +20,16 @@ public class StatementCompilerImpl implements StatementCompiler { private final LocalType localType; private final LocalSymbols locals; private final FunctionHeader functionHeader; + private final TypeID thrownType; private final TypeBuilder types; - public StatementCompilerImpl(CompileContext context, LocalType localType, TypeBuilder types, FunctionHeader functionHeader, LocalSymbols locals) { + public StatementCompilerImpl(CompileContext context, LocalType localType, TypeBuilder types, FunctionHeader functionHeader, LocalSymbols locals, TypeID thrownType) { this.context = context; this.localType = localType; this.functionHeader = functionHeader; this.locals = locals; this.types = types.withGeneric(functionHeader.typeParameters); + this.thrownType = thrownType; expressionCompiler = new ExpressionCompilerImpl(context, localType, this.types, functionHeader.thrownType, locals, functionHeader); } @@ -48,19 +50,19 @@ public ResolvedType resolve(TypeID type) { @Override public StatementCompiler forBlock() { - return new StatementCompilerImpl(context, localType, types, functionHeader, locals.forBlock()); + return new StatementCompilerImpl(context, localType, types, functionHeader, locals.forBlock(), thrownType); } @Override public StatementCompiler forLoop(CompilingLoopStatement loop) { - return new StatementCompilerImpl(context, localType, types, functionHeader, locals.forLoop(loop, loop.getLabels().toArray(new String[0]))); + return new StatementCompilerImpl(context, localType, types, functionHeader, locals.forLoop(loop, loop.getLabels().toArray(new String[0])), thrownType); } @Override public StatementCompiler forCatch(CompilingVariable exceptionVariable) { LocalSymbols locals = this.locals.forBlock(); locals.add(exceptionVariable); - return new StatementCompilerImpl(context, localType, types, functionHeader.withThrownType(exceptionVariable.getActualType()), locals); + return new StatementCompilerImpl(context, localType, types, functionHeader.withThrownType(exceptionVariable.getActualType()), locals, null); } @Override @@ -73,6 +75,11 @@ public Optional getFunctionHeader() { return Optional.ofNullable(functionHeader); } + @Override + public Optional getThrownType() { + return thrownType == null ? Optional.ofNullable(functionHeader).map(header -> header.thrownType) : Optional.of(thrownType); + } + @Override public void addLocalVariable(CompilingVariable variable) { locals.add(variable); diff --git a/Parser/src/main/java/org/openzen/zenscript/parser/ParsedFileCompiler.java b/Parser/src/main/java/org/openzen/zenscript/parser/ParsedFileCompiler.java index 3bb528a3e..28593d87c 100644 --- a/Parser/src/main/java/org/openzen/zenscript/parser/ParsedFileCompiler.java +++ b/Parser/src/main/java/org/openzen/zenscript/parser/ParsedFileCompiler.java @@ -63,7 +63,7 @@ public MemberCompiler forExpansionMembers(TypeID extended, TypeSymbol expansion) @Override public StatementCompiler forScripts(FunctionHeader scriptHeader) { - return new StatementCompilerImpl(context, null, localTypeBuilder, scriptHeader, new LocalSymbols(scriptHeader)); + return new StatementCompilerImpl(context, null, localTypeBuilder, scriptHeader, new LocalSymbols(scriptHeader), null); } private class FileTypeBuilder extends AbstractTypeBuilder { diff --git a/Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementThrow.java b/Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementThrow.java index 8eb09ee96..8747987b2 100644 --- a/Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementThrow.java +++ b/Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementThrow.java @@ -29,10 +29,10 @@ public ParsedStatementThrow(CodePosition position, ParsedAnnotation[] annotation @Override public CompilingStatement compile(StatementCompiler compiler, CodeBlock lastBlock) { Optional maybeHeader = compiler.getFunctionHeader(); - if (!maybeHeader.isPresent()) + if (!compiler.getThrownType().isPresent()) return new InvalidCompilingStatement(position, lastBlock, CompileErrors.cannotThrowHere()); - FunctionHeader header = maybeHeader.get(); + FunctionHeader header = maybeHeader.orElse(null); return new Compiling(compiler, expression.compile(compiler.expressions()), lastBlock, header); } diff --git a/ScriptingEngineTester/src/main/resources/zencode-tests/statements/try-catch-3.zc b/ScriptingEngineTester/src/main/resources/zencode-tests/statements/try-catch-3.zc new file mode 100644 index 000000000..6a950acdf --- /dev/null +++ b/ScriptingEngineTester/src/main/resources/zencode-tests/statements/try-catch-3.zc @@ -0,0 +1,16 @@ +#output: TestException +#output: test + +try { + if true { + throw new TestException1("test"); + } else { + throw new TestException2("test"); + } +} catch ex as TestException1 { + println(typeof(ex)); + println(ex.message); +} catch ex as TestException2 { + println(typeof(ex)); + println(ex.message); +}