mirror of
https://github.com/aNNiMON/Own-Programming-Language-Tutorial.git
synced 2024-09-20 00:34:20 +03:00
Parse error highlighting for include statement
This commit is contained in:
parent
a05e9e55e3
commit
f6d4ff5cc9
@ -1,12 +1,11 @@
|
|||||||
package com.annimon.ownlang.parser.ast;
|
package com.annimon.ownlang.parser.ast;
|
||||||
|
|
||||||
import com.annimon.ownlang.parser.Lexer;
|
import com.annimon.ownlang.exceptions.OwnLangParserException;
|
||||||
import com.annimon.ownlang.parser.Parser;
|
import com.annimon.ownlang.exceptions.OwnLangRuntimeException;
|
||||||
import com.annimon.ownlang.parser.SourceLoader;
|
import com.annimon.ownlang.parser.error.ParseErrorsFormatterStage;
|
||||||
import com.annimon.ownlang.parser.Token;
|
import com.annimon.ownlang.stages.*;
|
||||||
import com.annimon.ownlang.parser.visitors.FunctionAdder;
|
import com.annimon.ownlang.util.input.InputSourceFile;
|
||||||
import java.io.IOException;
|
import com.annimon.ownlang.util.input.SourceLoaderStage;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -23,21 +22,21 @@ public final class IncludeStatement extends InterruptableNode implements Stateme
|
|||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
super.interruptionCheck();
|
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 var stagesData = new StagesDataMap();
|
||||||
final String input = SourceLoader.readSource(path);
|
try {
|
||||||
final List<Token> tokens = Lexer.tokenize(input);
|
final String path = expression.eval().asString();
|
||||||
return Parser.parse(tokens);
|
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
|
@Override
|
||||||
|
@ -53,27 +53,27 @@ public final class UnaryExpression implements Expression, Statement {
|
|||||||
final Value value = expr1.eval();
|
final Value value = expr1.eval();
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
case INCREMENT_PREFIX: {
|
case INCREMENT_PREFIX: {
|
||||||
if (expr1 instanceof Accessible) {
|
if (expr1 instanceof Accessible accessible) {
|
||||||
return ((Accessible) expr1).set(increment(value));
|
return accessible.set(increment(value));
|
||||||
}
|
}
|
||||||
return increment(value);
|
return increment(value);
|
||||||
}
|
}
|
||||||
case DECREMENT_PREFIX: {
|
case DECREMENT_PREFIX: {
|
||||||
if (expr1 instanceof Accessible) {
|
if (expr1 instanceof Accessible accessible) {
|
||||||
return ((Accessible) expr1).set(decrement(value));
|
return accessible.set(decrement(value));
|
||||||
}
|
}
|
||||||
return decrement(value);
|
return decrement(value);
|
||||||
}
|
}
|
||||||
case INCREMENT_POSTFIX: {
|
case INCREMENT_POSTFIX: {
|
||||||
if (expr1 instanceof Accessible) {
|
if (expr1 instanceof Accessible accessible) {
|
||||||
((Accessible) expr1).set(increment(value));
|
accessible.set(increment(value));
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
return increment(value);
|
return increment(value);
|
||||||
}
|
}
|
||||||
case DECREMENT_POSTFIX: {
|
case DECREMENT_POSTFIX: {
|
||||||
if (expr1 instanceof Accessible) {
|
if (expr1 instanceof Accessible accessible) {
|
||||||
((Accessible) expr1).set(decrement(value));
|
accessible.set(decrement(value));
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
return decrement(value);
|
return decrement(value);
|
||||||
|
@ -3,6 +3,10 @@ package com.annimon.ownlang.parser.visitors;
|
|||||||
import com.annimon.ownlang.lib.NumberValue;
|
import com.annimon.ownlang.lib.NumberValue;
|
||||||
import com.annimon.ownlang.lib.Types;
|
import com.annimon.ownlang.lib.Types;
|
||||||
import com.annimon.ownlang.lib.Value;
|
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.BinaryExpression;
|
||||||
import com.annimon.ownlang.parser.ast.ConditionalExpression;
|
import com.annimon.ownlang.parser.ast.ConditionalExpression;
|
||||||
import com.annimon.ownlang.parser.ast.IncludeStatement;
|
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 com.annimon.ownlang.parser.ast.VariableExpression;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public final class VisitorUtils {
|
public final class VisitorUtils {
|
||||||
@ -28,9 +33,12 @@ public final class VisitorUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Statement includeProgram(IncludeStatement s) {
|
public static Statement includeProgram(IncludeStatement s) {
|
||||||
if (!isValue(s)) return null;
|
if (!isValue(s.expression)) return null;
|
||||||
try {
|
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) {
|
} catch (IOException ex) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std, yaml, ounit
|
use std, yaml
|
||||||
|
|
||||||
x = yamldecode("
|
x = yamldecode("
|
||||||
name: \"std\"
|
name: \"std\"
|
||||||
@ -23,9 +23,9 @@ x = yamldecode("
|
|||||||
print typeof([]) // 3 (ARRAY)
|
print typeof([]) // 3 (ARRAY)
|
||||||
")
|
")
|
||||||
|
|
||||||
assertEquals("std", x.name)
|
assertEquals("std", x.name)
|
||||||
assertEquals("both", x.scope)
|
assertEquals("both", x.scope)
|
||||||
assertEquals(0, length(x.constants))
|
assertEquals(0, x.constants.length)
|
||||||
assertEquals(2, length(x.functions))
|
assertEquals(2, x.functions.length)
|
||||||
assertEquals("arrayCombine", x.functions[0].name)
|
assertEquals("arrayCombine", x.functions[0].name)
|
||||||
assertEquals("возвращает тип переданного значения", x.functions[1].desc_ru)
|
assertEquals("возвращает тип переданного значения", x.functions[1].desc_ru)
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
use std, yaml, ounit
|
use std, yaml
|
||||||
|
|
||||||
yml = yamlencode({
|
yml = yamlencode({
|
||||||
"name": "Yaml Example",
|
"name": "Yaml Example",
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"arrayData": [
|
"arrayData": [
|
||||||
1, 2, 3, 4
|
1, 2, 3, 4
|
||||||
],
|
],
|
||||||
"objectData": {
|
"objectData": {
|
||||||
"key": "value",
|
"key": "value",
|
||||||
10: "1000"
|
10: "1000"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
obj = yamldecode(yml)
|
obj = yamldecode(yml)
|
||||||
|
|
||||||
assertEquals("Yaml Example", obj.name)
|
assertEquals("Yaml Example", obj.name)
|
||||||
assertEquals(1, obj.version)
|
assertEquals(1, obj.version)
|
||||||
assertEquals(4, length(obj.arrayData))
|
assertEquals(4, length(obj.arrayData))
|
||||||
assertEquals("value", obj.objectData.key)
|
assertEquals("value", obj.objectData.key)
|
||||||
assertEquals("1000", obj.objectData["10"])
|
assertEquals("1000", obj.objectData["10"])
|
Loading…
Reference in New Issue
Block a user