Skip to content

Commit f6d4ff5

Browse files
committed
Parse error highlighting for include statement
1 parent a05e9e5 commit f6d4ff5

File tree

5 files changed

+61
-54
lines changed

5 files changed

+61
-54
lines changed

ownlang-parser/src/main/java/com/annimon/ownlang/parser/ast/IncludeStatement.java

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
package com.annimon.ownlang.parser.ast;
22

3-
import com.annimon.ownlang.parser.Lexer;
4-
import com.annimon.ownlang.parser.Parser;
5-
import com.annimon.ownlang.parser.SourceLoader;
6-
import com.annimon.ownlang.parser.Token;
7-
import com.annimon.ownlang.parser.visitors.FunctionAdder;
8-
import java.io.IOException;
9-
import java.util.List;
3+
import com.annimon.ownlang.exceptions.OwnLangParserException;
4+
import com.annimon.ownlang.exceptions.OwnLangRuntimeException;
5+
import com.annimon.ownlang.parser.error.ParseErrorsFormatterStage;
6+
import com.annimon.ownlang.stages.*;
7+
import com.annimon.ownlang.util.input.InputSourceFile;
8+
import com.annimon.ownlang.util.input.SourceLoaderStage;
109

1110
/**
1211
*
@@ -23,22 +22,22 @@ public IncludeStatement(Expression expression) {
2322
@Override
2423
public void execute() {
2524
super.interruptionCheck();
25+
26+
final var stagesData = new StagesDataMap();
2627
try {
27-
final Statement program = loadProgram(expression.eval().asString());
28-
if (program != null) {
29-
program.accept(new FunctionAdder());
30-
program.execute();
31-
}
32-
} catch (Exception ex) {
33-
throw new RuntimeException(ex);
28+
final String path = expression.eval().asString();
29+
new SourceLoaderStage()
30+
.then(new LexerStage())
31+
.then(new ParserStage())
32+
.then(new FunctionAddingStage())
33+
.then(new ExecutionStage())
34+
.perform(stagesData, new InputSourceFile(path));
35+
} catch (OwnLangParserException ex) {
36+
final var error = new ParseErrorsFormatterStage()
37+
.perform(stagesData, ex.getParseErrors());
38+
throw new OwnLangRuntimeException(error, ex);
3439
}
3540
}
36-
37-
public Statement loadProgram(String path) throws IOException {
38-
final String input = SourceLoader.readSource(path);
39-
final List<Token> tokens = Lexer.tokenize(input);
40-
return Parser.parse(tokens);
41-
}
4241

4342
@Override
4443
public void accept(Visitor visitor) {

ownlang-parser/src/main/java/com/annimon/ownlang/parser/ast/UnaryExpression.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,27 +53,27 @@ public Value eval() {
5353
final Value value = expr1.eval();
5454
switch (operation) {
5555
case INCREMENT_PREFIX: {
56-
if (expr1 instanceof Accessible) {
57-
return ((Accessible) expr1).set(increment(value));
56+
if (expr1 instanceof Accessible accessible) {
57+
return accessible.set(increment(value));
5858
}
5959
return increment(value);
6060
}
6161
case DECREMENT_PREFIX: {
62-
if (expr1 instanceof Accessible) {
63-
return ((Accessible) expr1).set(decrement(value));
62+
if (expr1 instanceof Accessible accessible) {
63+
return accessible.set(decrement(value));
6464
}
6565
return decrement(value);
6666
}
6767
case INCREMENT_POSTFIX: {
68-
if (expr1 instanceof Accessible) {
69-
((Accessible) expr1).set(increment(value));
68+
if (expr1 instanceof Accessible accessible) {
69+
accessible.set(increment(value));
7070
return value;
7171
}
7272
return increment(value);
7373
}
7474
case DECREMENT_POSTFIX: {
75-
if (expr1 instanceof Accessible) {
76-
((Accessible) expr1).set(decrement(value));
75+
if (expr1 instanceof Accessible accessible) {
76+
accessible.set(decrement(value));
7777
return value;
7878
}
7979
return decrement(value);

ownlang-parser/src/main/java/com/annimon/ownlang/parser/visitors/VisitorUtils.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
import com.annimon.ownlang.lib.NumberValue;
44
import com.annimon.ownlang.lib.Types;
55
import com.annimon.ownlang.lib.Value;
6+
import com.annimon.ownlang.parser.Lexer;
7+
import com.annimon.ownlang.parser.Parser;
8+
import com.annimon.ownlang.parser.SourceLoader;
9+
import com.annimon.ownlang.parser.Token;
610
import com.annimon.ownlang.parser.ast.BinaryExpression;
711
import com.annimon.ownlang.parser.ast.ConditionalExpression;
812
import com.annimon.ownlang.parser.ast.IncludeStatement;
@@ -13,6 +17,7 @@
1317
import com.annimon.ownlang.parser.ast.VariableExpression;
1418
import java.io.IOException;
1519
import java.util.HashSet;
20+
import java.util.List;
1621
import java.util.Set;
1722

1823
public final class VisitorUtils {
@@ -28,9 +33,12 @@ public static boolean isVariable(Node node) {
2833
}
2934

3035
public static Statement includeProgram(IncludeStatement s) {
31-
if (!isValue(s)) return null;
36+
if (!isValue(s.expression)) return null;
3237
try {
33-
return s.loadProgram(s.expression.eval().asString());
38+
final String path = s.expression.eval().asString();
39+
final String input = SourceLoader.readSource(path);
40+
final List<Token> tokens = Lexer.tokenize(input);
41+
return Parser.parse(tokens);
3442
} catch (IOException ex) {
3543
return null;
3644
}

ownlang-parser/src/test/resources/modules/yaml/yamldecode.own

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std, yaml, ounit
1+
use std, yaml
22

33
x = yamldecode("
44
name: \"std\"
@@ -23,9 +23,9 @@ x = yamldecode("
2323
print typeof([]) // 3 (ARRAY)
2424
")
2525

26-
assertEquals("std", x.name)
27-
assertEquals("both", x.scope)
28-
assertEquals(0, length(x.constants))
29-
assertEquals(2, length(x.functions))
30-
assertEquals("arrayCombine", x.functions[0].name)
31-
assertEquals("возвращает тип переданного значения", x.functions[1].desc_ru)
26+
assertEquals("std", x.name)
27+
assertEquals("both", x.scope)
28+
assertEquals(0, x.constants.length)
29+
assertEquals(2, x.functions.length)
30+
assertEquals("arrayCombine", x.functions[0].name)
31+
assertEquals("возвращает тип переданного значения", x.functions[1].desc_ru)
Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
use std, yaml, ounit
1+
use std, yaml
22

33
yml = yamlencode({
4-
"name": "Yaml Example",
5-
"version": 1,
6-
"arrayData": [
7-
1, 2, 3, 4
8-
],
9-
"objectData": {
10-
"key": "value",
11-
10: "1000"
12-
}
13-
})
14-
obj = yamldecode(yml)
4+
"name": "Yaml Example",
5+
"version": 1,
6+
"arrayData": [
7+
1, 2, 3, 4
8+
],
9+
"objectData": {
10+
"key": "value",
11+
10: "1000"
12+
}
13+
})
14+
obj = yamldecode(yml)
1515

16-
assertEquals("Yaml Example", obj.name)
17-
assertEquals(1, obj.version)
18-
assertEquals(4, length(obj.arrayData))
19-
assertEquals("value", obj.objectData.key)
20-
assertEquals("1000", obj.objectData["10"])
16+
assertEquals("Yaml Example", obj.name)
17+
assertEquals(1, obj.version)
18+
assertEquals(4, length(obj.arrayData))
19+
assertEquals("value", obj.objectData.key)
20+
assertEquals("1000", obj.objectData["10"])

0 commit comments

Comments
 (0)