diff --git a/ownlang-parser/src/main/java/com/annimon/ownlang/parser/ast/IncludeStatement.java b/ownlang-parser/src/main/java/com/annimon/ownlang/parser/ast/IncludeStatement.java index 3b2c5de..8963de6 100644 --- a/ownlang-parser/src/main/java/com/annimon/ownlang/parser/ast/IncludeStatement.java +++ b/ownlang-parser/src/main/java/com/annimon/ownlang/parser/ast/IncludeStatement.java @@ -1,12 +1,11 @@ package com.annimon.ownlang.parser.ast; -import com.annimon.ownlang.parser.Lexer; -import com.annimon.ownlang.parser.Parser; -import com.annimon.ownlang.parser.SourceLoader; -import com.annimon.ownlang.parser.Token; -import com.annimon.ownlang.parser.visitors.FunctionAdder; -import java.io.IOException; -import java.util.List; +import com.annimon.ownlang.exceptions.OwnLangParserException; +import com.annimon.ownlang.exceptions.OwnLangRuntimeException; +import com.annimon.ownlang.parser.error.ParseErrorsFormatterStage; +import com.annimon.ownlang.stages.*; +import com.annimon.ownlang.util.input.InputSourceFile; +import com.annimon.ownlang.util.input.SourceLoaderStage; /** * @@ -23,21 +22,21 @@ public final class IncludeStatement extends InterruptableNode implements Stateme @Override public void execute() { super.interruptionCheck(); - try { - final Statement program = loadProgram(expression.eval().asString()); - if (program != null) { - program.accept(new FunctionAdder()); - program.execute(); - } - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - public Statement loadProgram(String path) throws IOException { - final String input = SourceLoader.readSource(path); - final List tokens = Lexer.tokenize(input); - return Parser.parse(tokens); + final var stagesData = new StagesDataMap(); + try { + final String path = expression.eval().asString(); + new SourceLoaderStage() + .then(new LexerStage()) + .then(new ParserStage()) + .then(new FunctionAddingStage()) + .then(new ExecutionStage()) + .perform(stagesData, new InputSourceFile(path)); + } catch (OwnLangParserException ex) { + final var error = new ParseErrorsFormatterStage() + .perform(stagesData, ex.getParseErrors()); + throw new OwnLangRuntimeException(error, ex); + } } @Override diff --git a/ownlang-parser/src/main/java/com/annimon/ownlang/parser/ast/UnaryExpression.java b/ownlang-parser/src/main/java/com/annimon/ownlang/parser/ast/UnaryExpression.java index 551ba6a..20d35b1 100644 --- a/ownlang-parser/src/main/java/com/annimon/ownlang/parser/ast/UnaryExpression.java +++ b/ownlang-parser/src/main/java/com/annimon/ownlang/parser/ast/UnaryExpression.java @@ -53,27 +53,27 @@ public final class UnaryExpression implements Expression, Statement { final Value value = expr1.eval(); switch (operation) { case INCREMENT_PREFIX: { - if (expr1 instanceof Accessible) { - return ((Accessible) expr1).set(increment(value)); + if (expr1 instanceof Accessible accessible) { + return accessible.set(increment(value)); } return increment(value); } case DECREMENT_PREFIX: { - if (expr1 instanceof Accessible) { - return ((Accessible) expr1).set(decrement(value)); + if (expr1 instanceof Accessible accessible) { + return accessible.set(decrement(value)); } return decrement(value); } case INCREMENT_POSTFIX: { - if (expr1 instanceof Accessible) { - ((Accessible) expr1).set(increment(value)); + if (expr1 instanceof Accessible accessible) { + accessible.set(increment(value)); return value; } return increment(value); } case DECREMENT_POSTFIX: { - if (expr1 instanceof Accessible) { - ((Accessible) expr1).set(decrement(value)); + if (expr1 instanceof Accessible accessible) { + accessible.set(decrement(value)); return value; } return decrement(value); diff --git a/ownlang-parser/src/main/java/com/annimon/ownlang/parser/visitors/VisitorUtils.java b/ownlang-parser/src/main/java/com/annimon/ownlang/parser/visitors/VisitorUtils.java index 1c593b8..007f764 100644 --- a/ownlang-parser/src/main/java/com/annimon/ownlang/parser/visitors/VisitorUtils.java +++ b/ownlang-parser/src/main/java/com/annimon/ownlang/parser/visitors/VisitorUtils.java @@ -3,6 +3,10 @@ package com.annimon.ownlang.parser.visitors; import com.annimon.ownlang.lib.NumberValue; import com.annimon.ownlang.lib.Types; import com.annimon.ownlang.lib.Value; +import com.annimon.ownlang.parser.Lexer; +import com.annimon.ownlang.parser.Parser; +import com.annimon.ownlang.parser.SourceLoader; +import com.annimon.ownlang.parser.Token; import com.annimon.ownlang.parser.ast.BinaryExpression; import com.annimon.ownlang.parser.ast.ConditionalExpression; import com.annimon.ownlang.parser.ast.IncludeStatement; @@ -13,6 +17,7 @@ import com.annimon.ownlang.parser.ast.ValueExpression; import com.annimon.ownlang.parser.ast.VariableExpression; import java.io.IOException; import java.util.HashSet; +import java.util.List; import java.util.Set; public final class VisitorUtils { @@ -28,9 +33,12 @@ public final class VisitorUtils { } public static Statement includeProgram(IncludeStatement s) { - if (!isValue(s)) return null; + if (!isValue(s.expression)) return null; try { - return s.loadProgram(s.expression.eval().asString()); + final String path = s.expression.eval().asString(); + final String input = SourceLoader.readSource(path); + final List tokens = Lexer.tokenize(input); + return Parser.parse(tokens); } catch (IOException ex) { return null; } diff --git a/ownlang-parser/src/test/resources/modules/yaml/yamldecode.own b/ownlang-parser/src/test/resources/modules/yaml/yamldecode.own index 7906f2e..4deea1a 100644 --- a/ownlang-parser/src/test/resources/modules/yaml/yamldecode.own +++ b/ownlang-parser/src/test/resources/modules/yaml/yamldecode.own @@ -1,4 +1,4 @@ -use std, yaml, ounit +use std, yaml x = yamldecode(" name: \"std\" @@ -23,9 +23,9 @@ x = yamldecode(" print typeof([]) // 3 (ARRAY) ") -assertEquals("std", x.name) -assertEquals("both", x.scope) -assertEquals(0, length(x.constants)) -assertEquals(2, length(x.functions)) -assertEquals("arrayCombine", x.functions[0].name) -assertEquals("возвращает тип переданного значения", x.functions[1].desc_ru) \ No newline at end of file + assertEquals("std", x.name) + assertEquals("both", x.scope) + assertEquals(0, x.constants.length) + assertEquals(2, x.functions.length) + assertEquals("arrayCombine", x.functions[0].name) + assertEquals("возвращает тип переданного значения", x.functions[1].desc_ru) diff --git a/ownlang-parser/src/test/resources/modules/yaml/yamlencode.own b/ownlang-parser/src/test/resources/modules/yaml/yamlencode.own index 77e2e3b..7ee5609 100644 --- a/ownlang-parser/src/test/resources/modules/yaml/yamlencode.own +++ b/ownlang-parser/src/test/resources/modules/yaml/yamlencode.own @@ -1,20 +1,20 @@ -use std, yaml, ounit +use std, yaml yml = yamlencode({ - "name": "Yaml Example", - "version": 1, - "arrayData": [ - 1, 2, 3, 4 - ], - "objectData": { - "key": "value", - 10: "1000" - } -}) -obj = yamldecode(yml) + "name": "Yaml Example", + "version": 1, + "arrayData": [ + 1, 2, 3, 4 + ], + "objectData": { + "key": "value", + 10: "1000" + } + }) + obj = yamldecode(yml) -assertEquals("Yaml Example", obj.name) -assertEquals(1, obj.version) -assertEquals(4, length(obj.arrayData)) -assertEquals("value", obj.objectData.key) -assertEquals("1000", obj.objectData["10"]) \ No newline at end of file + assertEquals("Yaml Example", obj.name) + assertEquals(1, obj.version) + assertEquals(4, length(obj.arrayData)) + assertEquals("value", obj.objectData.key) + assertEquals("1000", obj.objectData["10"]) \ No newline at end of file