Parse error highlighting for include statement

This commit is contained in:
aNNiMON 2023-10-14 14:34:05 +03:00 committed by Victor Melnik
parent a05e9e55e3
commit f6d4ff5cc9
5 changed files with 62 additions and 55 deletions

View File

@ -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<Token> 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

View File

@ -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);

View File

@ -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<Token> tokens = Lexer.tokenize(input);
return Parser.parse(tokens);
} catch (IOException ex) {
return null;
}

View File

@ -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)
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)

View File

@ -1,4 +1,4 @@
use std, yaml, ounit
use std, yaml
yml = yamlencode({
"name": "Yaml Example",
@ -10,11 +10,11 @@ yml = yamlencode({
"key": "value",
10: "1000"
}
})
obj = yamldecode(yml)
})
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"])
assertEquals("Yaml Example", obj.name)
assertEquals(1, obj.version)
assertEquals(4, length(obj.arrayData))
assertEquals("value", obj.objectData.key)
assertEquals("1000", obj.objectData["10"])