Remove unnecessary abstraction Expression, use Statement only as marker

This commit is contained in:
aNNiMON 2023-10-14 18:47:27 +03:00 committed by Victor Melnik
parent f6d4ff5cc9
commit 1535e86472
61 changed files with 355 additions and 353 deletions

View File

@ -65,7 +65,7 @@ public class UserDefinedFunction implements Function, SourceLocation {
final Argument arg = arguments.get(i);
ScopeHandler.defineVariableInCurrentScope(arg.name(), arg.valueExpr().eval());
}
body.execute();
body.eval();
return NumberValue.ZERO;
} catch (ReturnStatement rt) {
return rt.getResult();

View File

@ -20,9 +20,9 @@ import java.util.stream.Collectors;
*/
public final class Parser {
public static Statement parse(List<Token> tokens) {
public static Node parse(List<Token> tokens) {
final Parser parser = new Parser(tokens);
final Statement program = parser.parse();
final Node program = parser.parse();
if (parser.getParseErrors().hasErrors()) {
throw new OwnLangParserException(parser.getParseErrors());
}
@ -71,7 +71,7 @@ public final class Parser {
return parseErrors;
}
public Statement parse() {
public Node parse() {
parseErrors.clear();
final BlockStatement result = new BlockStatement();
while (!match(TokenType.EOF)) {
@ -180,7 +180,7 @@ public final class Parser {
if (match(TokenType.EXTRACT)) {
return destructuringAssignment();
}
final Expression expression = expression();
final Node expression = expression();
if (expression instanceof Statement statement) {
return statement;
}
@ -209,7 +209,7 @@ public final class Parser {
}
private Statement ifElse() {
final Expression condition = expression();
final Node condition = expression();
final Statement ifStatement = statementOrBlock();
final Statement elseStatement;
if (match(TokenType.ELSE)) {
@ -221,7 +221,7 @@ public final class Parser {
}
private Statement whileStatement() {
final Expression condition = expression();
final Node condition = expression();
final Statement statement = statementOrBlock();
return new WhileStatement(condition, statement);
}
@ -229,7 +229,7 @@ public final class Parser {
private Statement doWhileStatement() {
final Statement statement = statementOrBlock();
consume(TokenType.WHILE);
final Expression condition = expression();
final Node condition = expression();
return new DoWhileStatement(condition, statement);
}
@ -252,7 +252,7 @@ public final class Parser {
boolean optParentheses = match(TokenType.LPAREN);
final Statement initialization = assignmentStatement();
consume(TokenType.COMMA);
final Expression termination = expression();
final Node termination = expression();
consume(TokenType.COMMA);
final Statement increment = assignmentStatement();
if (optParentheses) consume(TokenType.RPAREN); // close opt parentheses
@ -265,7 +265,7 @@ public final class Parser {
boolean optParentheses = match(TokenType.LPAREN);
final String variable = consume(TokenType.WORD).text();
consume(TokenType.COLON);
final Expression container = expression();
final Node container = expression();
if (optParentheses) {
consume(TokenType.RPAREN); // close opt parentheses
}
@ -280,7 +280,7 @@ public final class Parser {
consume(TokenType.COMMA);
final String value = consume(TokenType.WORD).text();
consume(TokenType.COLON);
final Expression container = expression();
final Node container = expression();
if (optParentheses) {
consume(TokenType.RPAREN); // close opt parentheses
}
@ -332,14 +332,14 @@ public final class Parser {
);
}
private Expression functionChain(Expression qualifiedNameExpr) {
private Node functionChain(Node qualifiedNameExpr) {
// f1()()() || f1().f2().f3() || f1().key
final Expression expr = function(qualifiedNameExpr);
final Node expr = function(qualifiedNameExpr);
if (lookMatch(0, TokenType.LPAREN)) {
return functionChain(expr);
}
if (lookMatch(0, TokenType.DOT)) {
final List<Expression> indices = variableSuffix();
final List<Node> indices = variableSuffix();
if (indices == null || indices.isEmpty()) {
return expr;
}
@ -354,7 +354,7 @@ public final class Parser {
return expr;
}
private FunctionalExpression function(Expression qualifiedNameExpr) {
private FunctionalExpression function(Node qualifiedNameExpr) {
// function(arg1, arg2, ...)
final var startTokenIndex = index - 1;
consume(TokenType.LPAREN);
@ -367,10 +367,10 @@ public final class Parser {
return function;
}
private Expression array() {
private Node array() {
// [value1, value2, ...]
consume(TokenType.LBRACKET);
final List<Expression> elements = new ArrayList<>();
final List<Node> elements = new ArrayList<>();
while (!match(TokenType.RBRACKET)) {
elements.add(expression());
match(TokenType.COMMA);
@ -378,14 +378,14 @@ public final class Parser {
return new ArrayExpression(elements);
}
private Expression map() {
private Node map() {
// {key1 : value1, key2 : value2, ...}
consume(TokenType.LBRACE);
final Map<Expression, Expression> elements = new HashMap<>();
final Map<Node, Node> elements = new HashMap<>();
while (!match(TokenType.RBRACE)) {
final Expression key = primary();
final Node key = primary();
consume(TokenType.COLON);
final Expression value = expression();
final Node value = expression();
elements.put(key, value);
match(TokenType.COMMA);
}
@ -397,7 +397,7 @@ public final class Parser {
// case pattern1: result1
// case pattern2 if expr: result2
// }
final Expression expression = expression();
final Node expression = expression();
consume(TokenType.LBRACE);
final List<MatchExpression.Pattern> patterns = new ArrayList<>();
do {
@ -494,12 +494,12 @@ public final class Parser {
return classDeclaration;
}
private Expression expression() {
private Node expression() {
return assignment();
}
private Expression assignment() {
final Expression assignment = assignmentStrict();
private Node assignment() {
final Node assignment = assignmentStrict();
if (assignment != null) {
return assignment;
}
@ -509,7 +509,7 @@ public final class Parser {
private AssignmentExpression assignmentStrict() {
// x[0].prop += ...
final int position = index;
final Expression targetExpr = qualifiedName();
final Node targetExpr = qualifiedName();
if (!(targetExpr instanceof Accessible)) {
index = position;
return null;
@ -523,18 +523,18 @@ public final class Parser {
match(currentType);
final BinaryExpression.Operator op = ASSIGN_OPERATORS.get(currentType);
final Expression expression = expression();
final Node expression = expression();
return new AssignmentExpression(op, (Accessible) targetExpr, expression);
}
private Expression ternary() {
Expression result = nullCoalesce();
private Node ternary() {
Node result = nullCoalesce();
if (match(TokenType.QUESTION)) {
final Expression trueExpr = expression();
final Node trueExpr = expression();
consume(TokenType.COLON);
final Expression falseExpr = expression();
final Node falseExpr = expression();
return new TernaryExpression(result, trueExpr, falseExpr);
}
if (match(TokenType.QUESTIONCOLON)) {
@ -543,8 +543,8 @@ public final class Parser {
return result;
}
private Expression nullCoalesce() {
Expression result = logicalOr();
private Node nullCoalesce() {
Node result = logicalOr();
while (true) {
if (match(TokenType.QUESTIONQUESTION)) {
@ -557,8 +557,8 @@ public final class Parser {
return result;
}
private Expression logicalOr() {
Expression result = logicalAnd();
private Node logicalOr() {
Node result = logicalAnd();
while (true) {
if (match(TokenType.BARBAR)) {
@ -571,8 +571,8 @@ public final class Parser {
return result;
}
private Expression logicalAnd() {
Expression result = bitwiseOr();
private Node logicalAnd() {
Node result = bitwiseOr();
while (true) {
if (match(TokenType.AMPAMP)) {
@ -585,8 +585,8 @@ public final class Parser {
return result;
}
private Expression bitwiseOr() {
Expression expression = bitwiseXor();
private Node bitwiseOr() {
Node expression = bitwiseXor();
while (true) {
if (match(TokenType.BAR)) {
@ -599,8 +599,8 @@ public final class Parser {
return expression;
}
private Expression bitwiseXor() {
Expression expression = bitwiseAnd();
private Node bitwiseXor() {
Node expression = bitwiseAnd();
while (true) {
if (match(TokenType.CARET)) {
@ -613,8 +613,8 @@ public final class Parser {
return expression;
}
private Expression bitwiseAnd() {
Expression expression = equality();
private Node bitwiseAnd() {
Node expression = equality();
while (true) {
if (match(TokenType.AMP)) {
@ -627,8 +627,8 @@ public final class Parser {
return expression;
}
private Expression equality() {
Expression result = conditional();
private Node equality() {
Node result = conditional();
if (match(TokenType.EQEQ)) {
return new ConditionalExpression(ConditionalExpression.Operator.EQUALS, result, conditional());
@ -640,8 +640,8 @@ public final class Parser {
return result;
}
private Expression conditional() {
Expression result = shift();
private Node conditional() {
Node result = shift();
while (true) {
if (match(TokenType.LT)) {
@ -666,8 +666,8 @@ public final class Parser {
return result;
}
private Expression shift() {
Expression expression = additive();
private Node shift() {
Node expression = additive();
while (true) {
if (match(TokenType.LTLT)) {
@ -692,8 +692,8 @@ public final class Parser {
return expression;
}
private Expression additive() {
Expression result = multiplicative();
private Node additive() {
Node result = multiplicative();
while (true) {
if (match(TokenType.PLUS)) {
@ -722,8 +722,8 @@ public final class Parser {
return result;
}
private Expression multiplicative() {
Expression result = objectCreation();
private Node multiplicative() {
Node result = objectCreation();
while (true) {
if (match(TokenType.STAR)) {
@ -748,11 +748,11 @@ public final class Parser {
return result;
}
private Expression objectCreation() {
private Node objectCreation() {
if (match(TokenType.NEW)) {
final var startTokenIndex = index - 1;
final String className = consume(TokenType.WORD).text();
final List<Expression> args = new ArrayList<>();
final List<Node> args = new ArrayList<>();
consume(TokenType.LPAREN);
while (!match(TokenType.RPAREN)) {
args.add(expression());
@ -766,7 +766,7 @@ public final class Parser {
return unary();
}
private Expression unary() {
private Node unary() {
if (match(TokenType.PLUSPLUS)) {
return new UnaryExpression(UnaryExpression.Operator.INCREMENT_PREFIX, primary());
}
@ -788,9 +788,9 @@ public final class Parser {
return primary();
}
private Expression primary() {
private Node primary() {
if (match(TokenType.LPAREN)) {
Expression result = expression();
Node result = expression();
consume(TokenType.RPAREN);
return result;
}
@ -813,13 +813,13 @@ public final class Parser {
return variable();
}
private Expression variable() {
private Node variable() {
// function(...
if (lookMatch(0, TokenType.WORD) && lookMatch(1, TokenType.LPAREN)) {
return functionChain(new ValueExpression(consume(TokenType.WORD).text()));
}
final Expression qualifiedNameExpr = qualifiedName();
final Node qualifiedNameExpr = qualifiedName();
if (qualifiedNameExpr != null) {
// variable(args) || arr["key"](args) || obj.key(args)
if (lookMatch(0, TokenType.LPAREN)) {
@ -844,28 +844,28 @@ public final class Parser {
return value();
}
private Expression qualifiedName() {
private Node qualifiedName() {
// var || var.key[index].key2
final Token current = get(0);
if (!match(TokenType.WORD)) return null;
final List<Expression> indices = variableSuffix();
final List<Node> indices = variableSuffix();
if (indices == null || indices.isEmpty()) {
return new VariableExpression(current.text());
}
return new ContainerAccessExpression(current.text(), indices);
}
private List<Expression> variableSuffix() {
private List<Node> variableSuffix() {
// .key1.arr1[expr1][expr2].key2
if (!lookMatch(0, TokenType.DOT) && !lookMatch(0, TokenType.LBRACKET)) {
return null;
}
final List<Expression> indices = new ArrayList<>();
final List<Node> indices = new ArrayList<>();
while (lookMatch(0, TokenType.DOT) || lookMatch(0, TokenType.LBRACKET)) {
if (match(TokenType.DOT)) {
final String fieldName = consume(TokenType.WORD).text();
final Expression key = new ValueExpression(fieldName);
final Node key = new ValueExpression(fieldName);
indices.add(key);
}
if (match(TokenType.LBRACKET)) {
@ -876,7 +876,7 @@ public final class Parser {
return indices;
}
private Expression value() {
private Node value() {
final Token current = get(0);
if (match(TokenType.NUMBER)) {
return new ValueExpression(createNumber(current.text(), 10));
@ -898,7 +898,7 @@ public final class Parser {
new ValueExpression(consume(TokenType.WORD).text())
)));
}
final List<Expression> indices = variableSuffix();
final List<Node> indices = variableSuffix();
if (indices == null || indices.isEmpty()) {
return strExpr;
}

View File

@ -1,6 +1,6 @@
package com.annimon.ownlang.parser.ast;
public record Argument(String name, Expression valueExpr) {
public record Argument(String name, Node valueExpr) {
public Argument(String name) {
this(name, null);

View File

@ -22,7 +22,7 @@ public final class Arguments implements Iterable<Argument>, SourceLocation {
requiredArgumentsCount++;
}
public void addOptional(String name, Expression expr) {
public void addOptional(String name, Node expr) {
arguments.add(new Argument(name, expr));
}

View File

@ -8,11 +8,11 @@ import java.util.List;
*
* @author aNNiMON
*/
public final class ArrayExpression implements Expression {
public final class ArrayExpression implements Node {
public final List<Expression> elements;
public final List<Node> elements;
public ArrayExpression(List<Expression> arguments) {
public ArrayExpression(List<Node> arguments) {
this.elements = arguments;
}

View File

@ -6,22 +6,17 @@ import com.annimon.ownlang.lib.Value;
*
* @author aNNiMON
*/
public final class AssignmentExpression extends InterruptableNode implements Expression, Statement {
public final class AssignmentExpression extends InterruptableNode implements Statement {
public final Accessible target;
public final BinaryExpression.Operator operation;
public final Expression expression;
public final Node expression;
public AssignmentExpression(BinaryExpression.Operator operation, Accessible target, Expression expr) {
public AssignmentExpression(BinaryExpression.Operator operation, Accessible target, Node expr) {
this.operation = operation;
this.target = target;
this.expression = expr;
}
@Override
public void execute() {
eval();
}
@Override
public Value eval() {
@ -30,8 +25,8 @@ public final class AssignmentExpression extends InterruptableNode implements Exp
// Simple assignment
return target.set(expression.eval());
}
final Expression expr1 = new ValueExpression(target.get());
final Expression expr2 = new ValueExpression(expression.eval());
final Node expr1 = new ValueExpression(target.get());
final Node expr2 = new ValueExpression(expression.eval());
return target.set(new BinaryExpression(operation, expr1, expr2).eval());
}

View File

@ -8,7 +8,7 @@ import com.annimon.ownlang.lib.*;
*
* @author aNNiMON
*/
public final class BinaryExpression implements Expression {
public final class BinaryExpression implements Node {
public enum Operator {
ADD("+"),
@ -45,9 +45,9 @@ public final class BinaryExpression implements Expression {
}
public final Operator operation;
public final Expression expr1, expr2;
public final Node expr1, expr2;
public BinaryExpression(Operator operation, Expression expr1, Expression expr2) {
public BinaryExpression(Operator operation, Node expr1, Node expr2) {
this.operation = operation;
this.expr1 = expr1;
this.expr2 = expr2;

View File

@ -1,6 +1,8 @@
package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.Console;
import com.annimon.ownlang.lib.NumberValue;
import com.annimon.ownlang.lib.Value;
import java.util.ArrayList;
import java.util.List;
@ -10,22 +12,23 @@ import java.util.List;
*/
public final class BlockStatement extends InterruptableNode implements Statement {
public final List<Statement> statements;
public final List<Node> statements;
public BlockStatement() {
statements = new ArrayList<>();
}
public void add(Statement statement) {
public void add(Node statement) {
statements.add(statement);
}
@Override
public void execute() {
public Value eval() {
super.interruptionCheck();
for (Statement statement : statements) {
statement.execute();
for (Node statement : statements) {
statement.eval();
}
return NumberValue.ZERO;
}
@Override
@ -41,7 +44,7 @@ public final class BlockStatement extends InterruptableNode implements Statement
@Override
public String toString() {
final StringBuilder result = new StringBuilder();
for (Statement statement : statements) {
for (Node statement : statements) {
result.append(statement.toString()).append(Console.newline());
}
return result.toString();

View File

@ -1,5 +1,7 @@
package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.lib.Value;
/**
*
* @author aNNiMON
@ -7,7 +9,7 @@ package com.annimon.ownlang.parser.ast;
public final class BreakStatement extends RuntimeException implements Statement {
@Override
public void execute() {
public Value eval() {
throw this;
}

View File

@ -1,6 +1,8 @@
package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.lib.ClassDeclarations;
import com.annimon.ownlang.lib.NumberValue;
import com.annimon.ownlang.lib.Value;
import java.util.ArrayList;
import java.util.List;
@ -25,8 +27,9 @@ public final class ClassDeclarationStatement implements Statement {
}
@Override
public void execute() {
public Value eval() {
ClassDeclarations.set(name, this);
return NumberValue.ZERO;
}
@Override

View File

@ -9,7 +9,7 @@ import com.annimon.ownlang.lib.Value;
*
* @author aNNiMON
*/
public final class ConditionalExpression implements Expression {
public final class ConditionalExpression implements Node {
public enum Operator {
EQUALS("=="),
@ -36,10 +36,10 @@ public final class ConditionalExpression implements Expression {
}
}
public final Expression expr1, expr2;
public final Node expr1, expr2;
public final Operator operation;
public ConditionalExpression(Operator operation, Expression expr1, Expression expr2) {
public ConditionalExpression(Operator operation, Node expr1, Node expr2) {
this.operation = operation;
this.expr1 = expr1;
this.expr2 = expr2;

View File

@ -9,20 +9,20 @@ import java.util.regex.Pattern;
*
* @author aNNiMON
*/
public final class ContainerAccessExpression implements Expression, Accessible {
public final class ContainerAccessExpression implements Node, Accessible {
private static final Pattern PATTERN_SIMPLE_INDEX = Pattern.compile("^\"[a-zA-Z$_]\\w*\"");
public final Expression root;
public final List<Expression> indices;
public final Node root;
public final List<Node> indices;
private final boolean[] simpleIndices;
private final boolean rootIsVariable;
public ContainerAccessExpression(String variable, List<Expression> indices) {
public ContainerAccessExpression(String variable, List<Node> indices) {
this(new VariableExpression(variable), indices);
}
public ContainerAccessExpression(Expression root, List<Expression> indices) {
public ContainerAccessExpression(Node root, List<Node> indices) {
rootIsVariable = root instanceof VariableExpression;
this.root = root;
this.indices = indices;
@ -33,7 +33,7 @@ public final class ContainerAccessExpression implements Expression, Accessible {
return rootIsVariable;
}
public Expression getRoot() {
public Node getRoot() {
return root;
}
@ -110,7 +110,7 @@ public final class ContainerAccessExpression implements Expression, Accessible {
private boolean[] precomputeSimpleIndices() {
final boolean[] result = new boolean[indices.size()];
int i = 0;
for (Expression index : indices) {
for (Node index : indices) {
String indexStr = index.toString();
result[i] = PATTERN_SIMPLE_INDEX.matcher(indexStr).matches();
i++;
@ -122,7 +122,7 @@ public final class ContainerAccessExpression implements Expression, Accessible {
public String toString() {
final var sb = new StringBuilder(root.toString());
int i = 0;
for (Expression index : indices) {
for (Node index : indices) {
String indexStr = index.toString();
if (simpleIndices[i]) {
sb.append('.').append(indexStr, 1, indexStr.length() - 1);

View File

@ -1,5 +1,7 @@
package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.lib.Value;
/**
*
* @author aNNiMON
@ -7,7 +9,7 @@ package com.annimon.ownlang.parser.ast;
public final class ContinueStatement extends RuntimeException implements Statement {
@Override
public void execute() {
public Value eval() {
throw this;
}

View File

@ -13,21 +13,22 @@ import java.util.Map;
public final class DestructuringAssignmentStatement extends InterruptableNode implements Statement {
public final List<String> variables;
public final Expression containerExpression;
public final Node containerExpression;
public DestructuringAssignmentStatement(List<String> arguments, Expression container) {
public DestructuringAssignmentStatement(List<String> arguments, Node container) {
this.variables = arguments;
this.containerExpression = container;
}
@Override
public void execute() {
public Value eval() {
super.interruptionCheck();
final Value container = containerExpression.eval();
switch (container.type()) {
case Types.ARRAY -> execute((ArrayValue) container);
case Types.MAP -> execute((MapValue) container);
}
return NumberValue.ZERO;
}
private void execute(ArrayValue array) {

View File

@ -1,25 +1,28 @@
package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.lib.NumberValue;
import com.annimon.ownlang.lib.Value;
/**
*
* @author aNNiMON
*/
public final class DoWhileStatement extends InterruptableNode implements Statement {
public final Expression condition;
public final Node condition;
public final Statement statement;
public DoWhileStatement(Expression condition, Statement statement) {
public DoWhileStatement(Node condition, Statement statement) {
this.condition = condition;
this.statement = statement;
}
@Override
public void execute() {
public Value eval() {
super.interruptionCheck();
do {
try {
statement.execute();
statement.eval();
} catch (BreakStatement bs) {
break;
} catch (ContinueStatement cs) {
@ -27,6 +30,7 @@ public final class DoWhileStatement extends InterruptableNode implements Stateme
}
}
while (condition.eval().asInt() != 0);
return NumberValue.ZERO;
}
@Override

View File

@ -7,22 +7,17 @@ import com.annimon.ownlang.lib.Value;
*
* @author aNNiMON
*/
public final class ExprStatement extends InterruptableNode implements Expression, Statement {
public final class ExprStatement extends InterruptableNode implements Statement {
public final Expression expr;
public final Node expr;
public ExprStatement(Expression function) {
public ExprStatement(Node function) {
this.expr = function;
}
@Override
public void execute() {
super.interruptionCheck();
expr.eval();
}
@Override
public Value eval() {
super.interruptionCheck();
return expr.eval();
}

View File

@ -1,12 +0,0 @@
package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.lib.Value;
/**
*
* @author aNNiMON
*/
public interface Expression extends Node {
Value eval();
}

View File

@ -1,5 +1,8 @@
package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.lib.NumberValue;
import com.annimon.ownlang.lib.Value;
/**
*
* @author aNNiMON
@ -7,11 +10,11 @@ package com.annimon.ownlang.parser.ast;
public final class ForStatement extends InterruptableNode implements Statement {
public final Statement initialization;
public final Expression termination;
public final Node termination;
public final Statement increment;
public final Statement statement;
public ForStatement(Statement initialization, Expression termination, Statement increment, Statement block) {
public ForStatement(Statement initialization, Node termination, Statement increment, Statement block) {
this.initialization = initialization;
this.termination = termination;
this.increment = increment;
@ -19,17 +22,18 @@ public final class ForStatement extends InterruptableNode implements Statement {
}
@Override
public void execute() {
public Value eval() {
super.interruptionCheck();
for (initialization.execute(); termination.eval().asInt() != 0; increment.execute()) {
for (initialization.eval(); termination.eval().asInt() != 0; increment.eval()) {
try {
statement.execute();
statement.eval();
} catch (BreakStatement bs) {
break;
} catch (ContinueStatement cs) {
// continue;
}
}
return NumberValue.ZERO;
}
@Override

View File

@ -11,17 +11,17 @@ import java.util.Map;
public final class ForeachArrayStatement extends InterruptableNode implements Statement {
public final String variable;
public final Expression container;
public final Node container;
public final Statement body;
public ForeachArrayStatement(String variable, Expression container, Statement body) {
public ForeachArrayStatement(String variable, Node container, Statement body) {
this.variable = variable;
this.container = container;
this.body = body;
}
@Override
public void execute() {
public Value eval() {
super.interruptionCheck();
try (final var ignored = ScopeHandler.closeableScope()) {
final Value containerValue = container.eval();
@ -32,13 +32,14 @@ public final class ForeachArrayStatement extends InterruptableNode implements St
default -> throw new TypeException("Cannot iterate " + Types.typeToString(containerValue.type()));
}
}
return NumberValue.ZERO;
}
private void iterateString(String str) {
for (char ch : str.toCharArray()) {
ScopeHandler.setVariable(variable, new StringValue(String.valueOf(ch)));
try {
body.execute();
body.eval();
} catch (BreakStatement bs) {
break;
} catch (ContinueStatement cs) {
@ -51,7 +52,7 @@ public final class ForeachArrayStatement extends InterruptableNode implements St
for (Value value : containerValue) {
ScopeHandler.setVariable(variable, value);
try {
body.execute();
body.eval();
} catch (BreakStatement bs) {
break;
} catch (ContinueStatement cs) {
@ -67,7 +68,7 @@ public final class ForeachArrayStatement extends InterruptableNode implements St
entry.getValue()
}));
try {
body.execute();
body.eval();
} catch (BreakStatement bs) {
break;
} catch (ContinueStatement cs) {

View File

@ -11,10 +11,10 @@ import java.util.Map;
public final class ForeachMapStatement extends InterruptableNode implements Statement {
public final String key, value;
public final Expression container;
public final Node container;
public final Statement body;
public ForeachMapStatement(String key, String value, Expression container, Statement body) {
public ForeachMapStatement(String key, String value, Node container, Statement body) {
this.key = key;
this.value = value;
this.container = container;
@ -22,7 +22,7 @@ public final class ForeachMapStatement extends InterruptableNode implements Stat
}
@Override
public void execute() {
public Value eval() {
super.interruptionCheck();
try (final var ignored = ScopeHandler.closeableScope()) {
final Value containerValue = container.eval();
@ -33,6 +33,7 @@ public final class ForeachMapStatement extends InterruptableNode implements Stat
default -> throw new TypeException("Cannot iterate " + Types.typeToString(containerValue.type()) + " as key, value pair");
}
}
return NumberValue.ZERO;
}
private void iterateString(String str) {
@ -40,7 +41,7 @@ public final class ForeachMapStatement extends InterruptableNode implements Stat
ScopeHandler.setVariable(key, new StringValue(String.valueOf(ch)));
ScopeHandler.setVariable(value, NumberValue.of(ch));
try {
body.execute();
body.eval();
} catch (BreakStatement bs) {
break;
} catch (ContinueStatement cs) {
@ -55,7 +56,7 @@ public final class ForeachMapStatement extends InterruptableNode implements Stat
ScopeHandler.setVariable(key, v);
ScopeHandler.setVariable(value, NumberValue.of(index++));
try {
body.execute();
body.eval();
} catch (BreakStatement bs) {
break;
} catch (ContinueStatement cs) {
@ -69,7 +70,7 @@ public final class ForeachMapStatement extends InterruptableNode implements Stat
ScopeHandler.setVariable(key, entry.getKey());
ScopeHandler.setVariable(value, entry.getValue());
try {
body.execute();
body.eval();
} catch (BreakStatement bs) {
break;
} catch (ContinueStatement cs) {

View File

@ -1,7 +1,9 @@
package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.lib.NumberValue;
import com.annimon.ownlang.lib.ScopeHandler;
import com.annimon.ownlang.lib.UserDefinedFunction;
import com.annimon.ownlang.lib.Value;
import com.annimon.ownlang.util.Range;
import com.annimon.ownlang.util.SourceLocation;
@ -29,8 +31,9 @@ public final class FunctionDefineStatement implements Statement, SourceLocation
}
@Override
public void execute() {
public Value eval() {
ScopeHandler.setFunction(name, new UserDefinedFunction(arguments, body, range));
return NumberValue.ZERO;
}
@Override

View File

@ -6,7 +6,7 @@ import com.annimon.ownlang.lib.*;
*
* @author aNNiMON
*/
public final class FunctionReferenceExpression extends InterruptableNode implements Expression {
public final class FunctionReferenceExpression extends InterruptableNode {
public final String name;

View File

@ -13,18 +13,18 @@ import java.util.List;
* @author aNNiMON
*/
public final class FunctionalExpression extends InterruptableNode
implements Expression, Statement, SourceLocation {
implements Statement, SourceLocation {
public final Expression functionExpr;
public final List<Expression> arguments;
public final Node functionExpr;
public final List<Node> arguments;
private Range range;
public FunctionalExpression(Expression functionExpr) {
public FunctionalExpression(Node functionExpr) {
this.functionExpr = functionExpr;
arguments = new ArrayList<>();
}
public void addArgument(Expression arg) {
public void addArgument(Node arg) {
arguments.add(arg);
}
@ -36,11 +36,6 @@ public final class FunctionalExpression extends InterruptableNode
public Range getRange() {
return range;
}
@Override
public void execute() {
eval();
}
@Override
public Value eval() {
@ -57,7 +52,7 @@ public final class FunctionalExpression extends InterruptableNode
return result;
}
private Function consumeFunction(Expression expr) {
private Function consumeFunction(Node expr) {
final Value value = expr.eval();
if (value.type() == Types.FUNCTION) {
return ((FunctionValue) value).getValue();
@ -96,7 +91,7 @@ public final class FunctionalExpression extends InterruptableNode
} else {
sb.append(functionExpr).append('(');
}
final Iterator<Expression> it = arguments.iterator();
final Iterator<Node> it = arguments.iterator();
if (it.hasNext()) {
sb.append(it.next());
while (it.hasNext()) {

View File

@ -1,29 +1,33 @@
package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.lib.NumberValue;
import com.annimon.ownlang.lib.Value;
/**
*
* @author aNNiMON
*/
public final class IfStatement extends InterruptableNode implements Statement {
public final Expression expression;
public final Node expression;
public final Statement ifStatement, elseStatement;
public IfStatement(Expression expression, Statement ifStatement, Statement elseStatement) {
public IfStatement(Node expression, Statement ifStatement, Statement elseStatement) {
this.expression = expression;
this.ifStatement = ifStatement;
this.elseStatement = elseStatement;
}
@Override
public void execute() {
public Value eval() {
super.interruptionCheck();
final int result = expression.eval().asInt();
if (result != 0) {
ifStatement.execute();
ifStatement.eval();
} else if (elseStatement != null) {
elseStatement.execute();
elseStatement.eval();
}
return NumberValue.ZERO;
}
@Override

View File

@ -2,6 +2,8 @@ package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.exceptions.OwnLangParserException;
import com.annimon.ownlang.exceptions.OwnLangRuntimeException;
import com.annimon.ownlang.lib.NumberValue;
import com.annimon.ownlang.lib.Value;
import com.annimon.ownlang.parser.error.ParseErrorsFormatterStage;
import com.annimon.ownlang.stages.*;
import com.annimon.ownlang.util.input.InputSourceFile;
@ -13,14 +15,14 @@ import com.annimon.ownlang.util.input.SourceLoaderStage;
*/
public final class IncludeStatement extends InterruptableNode implements Statement {
public final Expression expression;
public final Node expression;
public IncludeStatement(Expression expression) {
public IncludeStatement(Node expression) {
this.expression = expression;
}
@Override
public void execute() {
public Value eval() {
super.interruptionCheck();
final var stagesData = new StagesDataMap();
@ -37,6 +39,7 @@ public final class IncludeStatement extends InterruptableNode implements Stateme
.perform(stagesData, ex.getParseErrors());
throw new OwnLangRuntimeException(error, ex);
}
return NumberValue.ZERO;
}
@Override

View File

@ -9,11 +9,11 @@ import java.util.Map;
*
* @author aNNiMON
*/
public final class MapExpression implements Expression {
public final class MapExpression implements Node {
public final Map<Expression, Expression> elements;
public final Map<Node, Node> elements;
public MapExpression(Map<Expression, Expression> arguments) {
public MapExpression(Map<Node, Node> arguments) {
this.elements = arguments;
}
@ -21,7 +21,7 @@ public final class MapExpression implements Expression {
public Value eval() {
final int size = elements.size();
final MapValue map = new MapValue(size);
for (Map.Entry<Expression, Expression> entry : elements.entrySet()) {
for (Map.Entry<Node, Node> entry : elements.entrySet()) {
map.set(entry.getKey().eval(), entry.getValue().eval());
}
return map;
@ -41,9 +41,9 @@ public final class MapExpression implements Expression {
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append('{');
Iterator<Map.Entry<Expression, Expression>> it = elements.entrySet().iterator();
Iterator<Map.Entry<Node, Node>> it = elements.entrySet().iterator();
if (it.hasNext()) {
Map.Entry<Expression, Expression> entry = it.next();
Map.Entry<Node, Node> entry = it.next();
sb.append(entry.getKey()).append(" : ").append(entry.getValue());
while (it.hasNext()) {
entry = it.next();

View File

@ -11,21 +11,16 @@ import java.util.List;
*
* @author aNNiMON
*/
public final class MatchExpression extends InterruptableNode implements Expression, Statement {
public final class MatchExpression extends InterruptableNode implements Statement {
public final Expression expression;
public final Node expression;
public final List<Pattern> patterns;
public MatchExpression(Expression expression, List<Pattern> patterns) {
public MatchExpression(Node expression, List<Pattern> patterns) {
this.expression = expression;
this.patterns = patterns;
}
@Override
public void execute() {
eval();
}
@Override
public Value eval() {
super.interruptionCheck();
@ -73,7 +68,7 @@ public final class MatchExpression extends InterruptableNode implements Expressi
final int size = array.size();
for (int i = 0; i < size; i++) {
final Expression expr = p.values.get(i);
final Node expr = p.values.get(i);
if ( (expr != ANY) && (expr.eval().compareTo(array.get(i)) != 0) ) {
return false;
}
@ -146,7 +141,7 @@ public final class MatchExpression extends InterruptableNode implements Expressi
private Value evalResult(Statement s) {
try {
s.execute();
s.eval();
} catch (ReturnStatement ret) {
return ret.getResult();
}
@ -176,7 +171,7 @@ public final class MatchExpression extends InterruptableNode implements Expressi
public abstract static sealed class Pattern {
public Statement result;
public Expression optCondition;
public Node optCondition;
@Override
public String toString() {
@ -247,13 +242,13 @@ public final class MatchExpression extends InterruptableNode implements Expressi
}
public static final class TuplePattern extends Pattern {
public final List<Expression> values;
public final List<Node> values;
public TuplePattern() {
this(new ArrayList<>());
}
public TuplePattern(List<Expression> parts) {
public TuplePattern(List<Node> parts) {
this.values = parts;
}
@ -261,13 +256,13 @@ public final class MatchExpression extends InterruptableNode implements Expressi
values.add(ANY);
}
public void add(Expression value) {
public void add(Node value) {
values.add(value);
}
@Override
public String toString() {
final Iterator<Expression> it = values.iterator();
final Iterator<Node> it = values.iterator();
if (it.hasNext()) {
final StringBuilder sb = new StringBuilder();
sb.append('(').append(it.next());
@ -281,7 +276,7 @@ public final class MatchExpression extends InterruptableNode implements Expressi
}
}
public static final Expression ANY = new Expression() {
public static final Node ANY = new Node() {
@Override
public Value eval() {
return NumberValue.ONE;

View File

@ -1,10 +1,14 @@
package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.lib.Value;
/**
*
* @author aNNiMON
*/
public interface Node {
Value eval();
void accept(Visitor visitor);

View File

@ -7,13 +7,13 @@ import com.annimon.ownlang.util.SourceLocation;
import java.util.Iterator;
import java.util.List;
public final class ObjectCreationExpression implements Expression, SourceLocation {
public final class ObjectCreationExpression implements Node, SourceLocation {
public final String className;
public final List<Expression> constructorArguments;
public final List<Node> constructorArguments;
private Range range;
public ObjectCreationExpression(String className, List<Expression> constructorArguments) {
public ObjectCreationExpression(String className, List<Node> constructorArguments) {
this.className = className;
this.constructorArguments = constructorArguments;
}
@ -80,7 +80,7 @@ public final class ObjectCreationExpression implements Expression, SourceLocatio
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("new ").append(className).append(' ');
final Iterator<Expression> it = constructorArguments.iterator();
final Iterator<Node> it = constructorArguments.iterator();
if (it.hasNext()) {
sb.append(it.next());
while (it.hasNext()) {

View File

@ -1,6 +1,8 @@
package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.Console;
import com.annimon.ownlang.lib.NumberValue;
import com.annimon.ownlang.lib.Value;
/**
*
@ -8,16 +10,17 @@ import com.annimon.ownlang.Console;
*/
public final class PrintStatement extends InterruptableNode implements Statement {
public final Expression expression;
public final Node expression;
public PrintStatement(Expression expression) {
public PrintStatement(Node expression) {
this.expression = expression;
}
@Override
public void execute() {
public Value eval() {
super.interruptionCheck();
Console.print(expression.eval().asString());
return NumberValue.ZERO;
}
@Override

View File

@ -1,6 +1,8 @@
package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.Console;
import com.annimon.ownlang.lib.NumberValue;
import com.annimon.ownlang.lib.Value;
/**
*
@ -8,16 +10,17 @@ import com.annimon.ownlang.Console;
*/
public final class PrintlnStatement extends InterruptableNode implements Statement {
public final Expression expression;
public final Node expression;
public PrintlnStatement(Expression expression) {
public PrintlnStatement(Node expression) {
this.expression = expression;
}
@Override
public void execute() {
public Value eval() {
super.interruptionCheck();
Console.println(expression.eval().asString());
return NumberValue.ZERO;
}
@Override

View File

@ -8,10 +8,10 @@ import com.annimon.ownlang.lib.Value;
*/
public final class ReturnStatement extends RuntimeException implements Statement {
public final Expression expression;
public final Node expression;
private Value result;
public ReturnStatement(Expression expression) {
public ReturnStatement(Node expression) {
this.expression = expression;
}
@ -20,7 +20,7 @@ public final class ReturnStatement extends RuntimeException implements Statement
}
@Override
public void execute() {
public Value eval() {
result = expression.eval();
throw this;
}

View File

@ -5,6 +5,5 @@ package com.annimon.ownlang.parser.ast;
* @author aNNiMON
*/
public interface Statement extends Node {
void execute();
}

View File

@ -6,12 +6,12 @@ import com.annimon.ownlang.lib.Value;
*
* @author aNNiMON
*/
public final class TernaryExpression implements Expression {
public final class TernaryExpression implements Node {
public final Expression condition;
public final Expression trueExpr, falseExpr;
public final Node condition;
public final Node trueExpr, falseExpr;
public TernaryExpression(Expression condition, Expression trueExpr, Expression falseExpr) {
public TernaryExpression(Node condition, Node trueExpr, Node falseExpr) {
this.condition = condition;
this.trueExpr = trueExpr;
this.falseExpr = falseExpr;

View File

@ -10,7 +10,7 @@ import com.annimon.ownlang.lib.Value;
*
* @author aNNiMON
*/
public final class UnaryExpression implements Expression, Statement {
public final class UnaryExpression implements Statement {
public enum Operator {
INCREMENT_PREFIX("++"),
@ -35,19 +35,14 @@ public final class UnaryExpression implements Expression, Statement {
}
}
public final Expression expr1;
public final Node expr1;
public final Operator operation;
public UnaryExpression(Operator operation, Expression expr1) {
public UnaryExpression(Operator operation, Node expr1) {
this.operation = operation;
this.expr1 = expr1;
}
@Override
public void execute() {
eval();
}
@Override
public Value eval() {
final Value value = expr1.eval();

View File

@ -2,6 +2,7 @@ package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.lib.Function;
import com.annimon.ownlang.lib.ModuleLoader;
import com.annimon.ownlang.lib.NumberValue;
import com.annimon.ownlang.lib.Value;
import com.annimon.ownlang.modules.Module;
import java.util.Collection;
@ -20,11 +21,12 @@ public final class UseStatement extends InterruptableNode implements Statement {
}
@Override
public void execute() {
public Value eval() {
super.interruptionCheck();
for (String module : modules) {
ModuleLoader.loadAndUse(module);
}
return NumberValue.ZERO;
}
public Map<String, Value> loadConstants() {

View File

@ -11,7 +11,7 @@ import com.annimon.ownlang.lib.Value;
*
* @author aNNiMON
*/
public final class ValueExpression extends InterruptableNode implements Expression {
public final class ValueExpression extends InterruptableNode {
public final Value value;

View File

@ -8,7 +8,7 @@ import com.annimon.ownlang.lib.Value;
*
* @author aNNiMON
*/
public final class VariableExpression extends InterruptableNode implements Expression, Accessible {
public final class VariableExpression extends InterruptableNode implements Accessible {
public final String name;
@ -24,7 +24,9 @@ public final class VariableExpression extends InterruptableNode implements Expre
@Override
public Value get() {
if (!ScopeHandler.isVariableOrConstantExists(name)) throw new VariableDoesNotExistsException(name);
if (!ScopeHandler.isVariableOrConstantExists(name)) {
throw new VariableDoesNotExistsException(name);
}
return ScopeHandler.getVariableOrConstant(name);
}

View File

@ -1,31 +1,35 @@
package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.lib.NumberValue;
import com.annimon.ownlang.lib.Value;
/**
*
* @author aNNiMON
*/
public final class WhileStatement extends InterruptableNode implements Statement {
public final Expression condition;
public final Node condition;
public final Statement statement;
public WhileStatement(Expression condition, Statement statement) {
public WhileStatement(Node condition, Statement statement) {
this.condition = condition;
this.statement = statement;
}
@Override
public void execute() {
public Value eval() {
super.interruptionCheck();
while (condition.eval().asInt() != 0) {
try {
statement.execute();
statement.eval();
} catch (BreakStatement bs) {
break;
} catch (ContinueStatement cs) {
// continue;
}
}
return NumberValue.ZERO;
}
@Override

View File

@ -1,7 +1,7 @@
package com.annimon.ownlang.parser.linters;
import com.annimon.ownlang.parser.ast.IncludeStatement;
import com.annimon.ownlang.parser.ast.Statement;
import com.annimon.ownlang.parser.ast.Node;
import com.annimon.ownlang.parser.ast.Visitor;
import com.annimon.ownlang.parser.visitors.AbstractVisitor;
import com.annimon.ownlang.parser.visitors.VisitorUtils;
@ -15,7 +15,7 @@ abstract class LintVisitor extends AbstractVisitor {
}
protected void applyVisitor(IncludeStatement s, Visitor visitor) {
final Statement program = VisitorUtils.includeProgram(s);
final Node program = VisitorUtils.includeProgram(s);
if (program != null) {
program.accept(visitor);
}

View File

@ -2,7 +2,7 @@ package com.annimon.ownlang.parser.linters;
import com.annimon.ownlang.Console;
import com.annimon.ownlang.lib.ScopeHandler;
import com.annimon.ownlang.parser.ast.Statement;
import com.annimon.ownlang.parser.ast.Node;
import com.annimon.ownlang.parser.ast.Visitor;
import com.annimon.ownlang.stages.Stage;
import com.annimon.ownlang.stages.StagesData;
@ -10,10 +10,10 @@ import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class LinterStage implements Stage<Statement, Statement> {
public class LinterStage implements Stage<Node, Node> {
@Override
public Statement perform(StagesData stagesData, Statement input) {
public Node perform(StagesData stagesData, Node input) {
final List<LinterResult> results = new ArrayList<>();
final Visitor[] validators = new Visitor[] {
new AssignValidator(results),

View File

@ -4,7 +4,6 @@ import com.annimon.ownlang.lib.Types;
import com.annimon.ownlang.parser.ast.AssignmentExpression;
import com.annimon.ownlang.parser.ast.BlockStatement;
import com.annimon.ownlang.parser.ast.ExprStatement;
import com.annimon.ownlang.parser.ast.Expression;
import com.annimon.ownlang.parser.ast.IfStatement;
import com.annimon.ownlang.parser.ast.Node;
import com.annimon.ownlang.parser.ast.Statement;
@ -123,7 +122,7 @@ public class DeadCodeElimination extends OptimizationVisitor<Map<String, Variabl
public Node visit(BlockStatement s, Map<String, VariableInfo> t) {
final BlockStatement result = new BlockStatement();
boolean changed = false;
for (Statement statement : s.statements) {
for (Node statement : s.statements) {
final Node node = statement.accept(this, t);
if (node != statement) {
changed = true;
@ -135,8 +134,8 @@ public class DeadCodeElimination extends OptimizationVisitor<Map<String, Variabl
if (node instanceof Statement stmt) {
result.add(stmt);
} else if (node instanceof Expression expr) {
result.add(new ExprStatement(expr));
} else if (node != null) {
result.add(new ExprStatement(node));
}
}
if (changed) {

View File

@ -2,11 +2,9 @@ package com.annimon.ownlang.parser.optimization;
import com.annimon.ownlang.Console;
import com.annimon.ownlang.parser.ast.BlockStatement;
import com.annimon.ownlang.parser.ast.Expression;
import com.annimon.ownlang.parser.ast.Node;
import com.annimon.ownlang.parser.ast.PrintStatement;
import com.annimon.ownlang.parser.ast.PrintlnStatement;
import com.annimon.ownlang.parser.ast.Statement;
import com.annimon.ownlang.parser.ast.ValueExpression;
import static com.annimon.ownlang.parser.visitors.VisitorUtils.isConstantValue;
@ -48,8 +46,8 @@ public class InstructionCombining extends OptimizationVisitor<Void> implements O
final BlockStatement result = new BlockStatement();
int i;
for (i = 1; i < size; i++) {
Statement s1 = s.statements.get(i - 1);
Statement s2 = s.statements.get(i);
Node s1 = s.statements.get(i - 1);
Node s2 = s.statements.get(i);
Node n1 = s1.accept(this, t);
Node n2 = s2.accept(this, t);
if (n1 != s1 || n2 != s2) {
@ -57,7 +55,7 @@ public class InstructionCombining extends OptimizationVisitor<Void> implements O
}
final Node combined = tryCombine(n1, n2);
if (combined == null) {
result.add((Statement) n1);
result.add(n1);
} else {
changed = true;
result.add(consumeStatement(combined));
@ -66,12 +64,12 @@ public class InstructionCombining extends OptimizationVisitor<Void> implements O
}
if (i == size) {
// Last node
Statement s2 = s.statements.get(size - 1);
Node s2 = s.statements.get(size - 1);
Node n2 = s2.accept(this, t);
if (n2 != s2) {
changed = true;
}
result.add((Statement) n2);
result.add(n2);
}
if (changed) {
return result;
@ -91,10 +89,10 @@ public class InstructionCombining extends OptimizationVisitor<Void> implements O
else n2Type = 0;
if (n1Type != 0 && n2Type != 0) {
final Expression e1 = (n1Type == 1)
final Node e1 = (n1Type == 1)
? ((PrintStatement) n1).expression
: ((PrintlnStatement) n1).expression;
final Expression e2 = (n2Type == 1)
final Node e2 = (n2Type == 1)
? ((PrintStatement) n2).expression
: ((PrintlnStatement) n2).expression;
if (isConstantValue(e1) && isConstantValue(e2)) {

View File

@ -1,11 +1,10 @@
package com.annimon.ownlang.parser.optimization;
import com.annimon.ownlang.parser.ast.Node;
import com.annimon.ownlang.parser.ast.Statement;
import com.annimon.ownlang.stages.Stage;
import com.annimon.ownlang.stages.StagesData;
public class OptimizationStage implements Stage<Statement, Statement> {
public class OptimizationStage implements Stage<Node, Node> {
public static final String TAG_OPTIMIZATION_SUMMARY = "optimizationSummary";
@ -30,7 +29,7 @@ public class OptimizationStage implements Stage<Statement, Statement> {
}
@Override
public Statement perform(StagesData stagesData, Statement input) {
public Node perform(StagesData stagesData, Node input) {
if (level == 0) return input;
Node result = input;
@ -51,6 +50,6 @@ public class OptimizationStage implements Stage<Statement, Statement> {
);
}
return (Statement) result;
return result;
}
}

View File

@ -14,14 +14,14 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
@Override
public Node visit(ArrayExpression s, T t) {
final List<Expression> elements = new ArrayList<>(s.elements.size());
final List<Node> elements = new ArrayList<>(s.elements.size());
boolean changed = false;
for (Expression expression : s.elements) {
for (Node expression : s.elements) {
final Node node = expression.accept(this, t);
if (node != expression) {
changed = true;
}
elements.add((Expression) node);
elements.add(node);
}
if (changed) {
return new ArrayExpression(elements);
@ -34,7 +34,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
final Node exprNode = s.expression.accept(this, t);
final Node targetNode = s.target.accept(this, t);
if ( (exprNode != s.expression || targetNode != s.target) && (targetNode instanceof Accessible) ) {
return new AssignmentExpression(s.operation, (Accessible) targetNode, (Expression) exprNode);
return new AssignmentExpression(s.operation, (Accessible) targetNode, exprNode);
}
return s;
}
@ -44,7 +44,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
final Node expr1 = s.expr1.accept(this, t);
final Node expr2 = s.expr2.accept(this, t);
if (expr1 != s.expr1 || expr2 != s.expr2) {
return new BinaryExpression(s.operation, (Expression) expr1, (Expression) expr2);
return new BinaryExpression(s.operation, expr1, expr2);
}
return s;
}
@ -53,15 +53,13 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
public Node visit(BlockStatement s, T t) {
boolean changed = false;
final BlockStatement result = new BlockStatement();
for (Statement statement : s.statements) {
for (Node statement : s.statements) {
final Node node = statement.accept(this, t);
if (node != statement) {
changed = true;
}
if (node instanceof Statement) {
result.add((Statement) node);
} else if (node instanceof Expression) {
result.add(new ExprStatement((Expression) node));
if (node != null) {
result.add(consumeStatement(node));
}
}
if (changed) {
@ -85,7 +83,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
final Node expr1 = s.expr1.accept(this, t);
final Node expr2 = s.expr2.accept(this, t);
if (expr1 != s.expr1 || expr2 != s.expr2) {
return new ConditionalExpression(s.operation, (Expression) expr1, (Expression) expr2);
return new ConditionalExpression(s.operation, expr1, expr2);
}
return s;
}
@ -95,16 +93,16 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
final Node root = s.root.accept(this, t);
boolean changed = (root != s.root);
final List<Expression> indices = new ArrayList<>(s.indices.size());
for (Expression expression : s.indices) {
final List<Node> indices = new ArrayList<>(s.indices.size());
for (Node expression : s.indices) {
final Node node = expression.accept(this, t);
if (node != expression) {
changed = true;
}
indices.add((Expression) node);
indices.add(node);
}
if (changed) {
return new ContainerAccessExpression((Expression) root, indices);
return new ContainerAccessExpression(root, indices);
}
return s;
}
@ -119,7 +117,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
final Node condition = s.condition.accept(this, t);
final Node statement = s.statement.accept(this, t);
if (condition != s.condition || statement != s.statement) {
return new DoWhileStatement((Expression) condition, consumeStatement(statement));
return new DoWhileStatement(condition, consumeStatement(statement));
}
return s;
}
@ -128,7 +126,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
public Node visit(DestructuringAssignmentStatement s, T t) {
final Node expr = s.containerExpression.accept(this, t);
if (expr != s.containerExpression) {
return new DestructuringAssignmentStatement(s.variables, (Expression) expr);
return new DestructuringAssignmentStatement(s.variables, expr);
}
return s;
}
@ -142,7 +140,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
if (initialization != s.initialization || termination != s.termination
|| increment != s.increment || statement != s.statement) {
return new ForStatement(consumeStatement(initialization),
(Expression) termination, consumeStatement(increment), consumeStatement(statement));
termination, consumeStatement(increment), consumeStatement(statement));
}
return s;
}
@ -152,7 +150,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
final Node container = s.container.accept(this, t);
final Node body = s.body.accept(this, t);
if (container != s.container || body != s.body) {
return new ForeachArrayStatement(s.variable, (Expression) container, consumeStatement(body));
return new ForeachArrayStatement(s.variable, container, consumeStatement(body));
}
return s;
}
@ -162,7 +160,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
final Node container = s.container.accept(this, t);
final Node body = s.body.accept(this, t);
if (container != s.container || body != s.body) {
return new ForeachMapStatement(s.key, s.value, (Expression) container, consumeStatement(body));
return new ForeachMapStatement(s.key, s.value, container, consumeStatement(body));
}
return s;
}
@ -188,7 +186,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
public Node visit(ExprStatement s, T t) {
final Node expr = s.expr.accept(this, t);
if (expr != s.expr) {
return new ExprStatement((Expression) expr);
return new ExprStatement(expr);
}
return s;
}
@ -196,14 +194,14 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
@Override
public Node visit(FunctionalExpression s, T t) {
final Node functionExpr = s.functionExpr.accept(this, t);
final FunctionalExpression result = new FunctionalExpression((Expression) functionExpr);
final FunctionalExpression result = new FunctionalExpression(functionExpr);
boolean changed = functionExpr != s.functionExpr;
for (Expression argument : s.arguments) {
for (Node argument : s.arguments) {
final Node expr = argument.accept(this, t);
if (expr != argument) {
changed = true;
}
result.addArgument((Expression) expr);
result.addArgument(expr);
}
if (changed) {
return result;
@ -222,7 +220,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
elseStatement = null;
}
if (expression != s.expression || ifStatement != s.ifStatement || elseStatement != s.elseStatement) {
return new IfStatement((Expression) expression, consumeStatement(ifStatement),
return new IfStatement(expression, consumeStatement(ifStatement),
(elseStatement == null ? null : consumeStatement(elseStatement)) );
}
return s;
@ -232,22 +230,22 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
public Node visit(IncludeStatement s, T t) {
final Node expression = s.expression.accept(this, t);
if (expression != s.expression) {
return new IncludeStatement((Expression) expression);
return new IncludeStatement(expression);
}
return s;
}
@Override
public Node visit(MapExpression s, T t) {
final Map<Expression, Expression> elements = new HashMap<>(s.elements.size());
final Map<Node, Node> elements = new HashMap<>(s.elements.size());
boolean changed = false;
for (Map.Entry<Expression, Expression> entry : s.elements.entrySet()) {
for (Map.Entry<Node, Node> entry : s.elements.entrySet()) {
final Node key = entry.getKey().accept(this, t);
final Node value = entry.getValue().accept(this, t);
if (key != entry.getKey() || value != entry.getValue()) {
changed = true;
}
elements.put((Expression) key, (Expression) value);
elements.put(key, value);
}
if (changed) {
return new MapExpression(elements);
@ -268,7 +266,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
if ((node != expr) && isValue(node)) {
changed = true;
final Value value = ((ValueExpression) node).value;
final Expression optCondition = pattern.optCondition;
final Node optCondition = pattern.optCondition;
final Statement result = pattern.result;
pattern = new MatchExpression.ConstantPattern(value);
pattern.optCondition = optCondition;
@ -277,21 +275,21 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
}
if (pattern instanceof MatchExpression.TuplePattern tuple) {
final List<Expression> newValues = new ArrayList<>(tuple.values.size());
final List<Node> newValues = new ArrayList<>(tuple.values.size());
boolean valuesChanged = false;
for (Expression value : tuple.values) {
for (Node value : tuple.values) {
if (value != MatchExpression.ANY) {
final Node node = value.accept(this, t);
if (node != value) {
valuesChanged = true;
value = (Expression) node;
value = node;
}
}
newValues.add(value);
}
if (valuesChanged) {
changed = true;
final Expression optCondition = pattern.optCondition;
final Node optCondition = pattern.optCondition;
final Statement result = pattern.result;
pattern = new MatchExpression.TuplePattern(newValues);
pattern.optCondition = optCondition;
@ -309,28 +307,28 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
Node optCond = pattern.optCondition.accept(this, t);
if (optCond != pattern.optCondition) {
changed = true;
pattern.optCondition = (Expression) optCond;
pattern.optCondition = optCond;
}
}
patterns.add(pattern);
}
if (changed) {
return new MatchExpression((Expression) expression, patterns);
return new MatchExpression(expression, patterns);
}
return s;
}
@Override
public Node visit(ObjectCreationExpression s, T t) {
final List<Expression> args = new ArrayList<>();
final List<Node> args = new ArrayList<>();
boolean changed = false;
for (Expression argument : s.constructorArguments) {
for (Node argument : s.constructorArguments) {
final Node expr = argument.accept(this, t);
if (expr != argument) {
changed = true;
}
args.add((Expression) expr);
args.add(expr);
}
if (changed) {
@ -343,7 +341,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
public Node visit(PrintStatement s, T t) {
final Node expression = s.expression.accept(this, t);
if (expression != s.expression) {
return new PrintStatement((Expression) expression);
return new PrintStatement(expression);
}
return s;
}
@ -352,7 +350,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
public Node visit(PrintlnStatement s, T t) {
final Node expression = s.expression.accept(this, t);
if (expression != s.expression) {
return new PrintlnStatement((Expression) expression);
return new PrintlnStatement(expression);
}
return s;
}
@ -361,7 +359,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
public Node visit(ReturnStatement s, T t) {
final Node expression = s.expression.accept(this, t);
if (expression != s.expression) {
return new ReturnStatement((Expression) expression);
return new ReturnStatement(expression);
}
return s;
}
@ -372,7 +370,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
final Node trueExpr = s.trueExpr.accept(this, t);
final Node falseExpr = s.falseExpr.accept(this, t);
if (condition != s.condition || trueExpr != s.trueExpr || falseExpr != s.falseExpr) {
return new TernaryExpression((Expression) condition, (Expression) trueExpr, (Expression) falseExpr);
return new TernaryExpression(condition, trueExpr, falseExpr);
}
return s;
}
@ -381,7 +379,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
public Node visit(UnaryExpression s, T t) {
final Node expr1 = s.expr1.accept(this, t);
if (expr1 != s.expr1) {
return new UnaryExpression(s.operation, (Expression) expr1);
return new UnaryExpression(s.operation, expr1);
}
return s;
}
@ -407,7 +405,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
final Node condition = s.condition.accept(this, t);
final Node statement = s.statement.accept(this, t);
if (condition != s.condition || statement != s.statement) {
return new WhileStatement((Expression) condition, consumeStatement(statement));
return new WhileStatement(condition, consumeStatement(statement));
}
return s;
}
@ -434,7 +432,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
boolean changed = false;
out.setRange(in.getRange());
for (Argument argument : in) {
final Expression valueExpr = argument.valueExpr();
final Node valueExpr = argument.valueExpr();
if (valueExpr == null) {
out.addRequired(argument.name());
} else {
@ -442,7 +440,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
if (expr != valueExpr) {
changed = true;
}
out.addOptional(argument.name(), (Expression) expr);
out.addOptional(argument.name(), expr);
}
}
return changed;
@ -452,6 +450,6 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
if (node instanceof Statement statement) {
return statement;
}
return new ExprStatement((Expression) node);
return new ExprStatement(node);
}
}

View File

@ -110,7 +110,7 @@ public class VariablesGrabber extends OptimizationVisitor<Map<String, VariableIn
final String variableName = argument.name();
grabVariableInfo(t, variableName);
/* No need to add value - it is optional arguments
final Expression expr = argument.getValueExpr();
final Node expr = argument.getValueExpr();
if (expr != null && isValue(expr)) {
var.value = ((ValueExpression) expr).value;
}*/

View File

@ -12,7 +12,7 @@ public abstract class AbstractVisitor implements Visitor {
@Override
public void visit(ArrayExpression s) {
for (Expression index : s.elements) {
for (Node index : s.elements) {
index.accept(this);
}
}
@ -30,7 +30,7 @@ public abstract class AbstractVisitor implements Visitor {
@Override
public void visit(BlockStatement s) {
for (Statement statement : s.statements) {
for (Node statement : s.statements) {
statement.accept(this);
}
}
@ -53,7 +53,7 @@ public abstract class AbstractVisitor implements Visitor {
@Override
public void visit(ContainerAccessExpression s) {
s.root.accept(this);
for (Expression index : s.indices) {
for (Node index : s.indices) {
index.accept(this);
}
}
@ -110,7 +110,7 @@ public abstract class AbstractVisitor implements Visitor {
@Override
public void visit(FunctionalExpression s) {
s.functionExpr.accept(this);
for (Expression argument : s.arguments) {
for (Node argument : s.arguments) {
argument.accept(this);
}
}
@ -131,7 +131,7 @@ public abstract class AbstractVisitor implements Visitor {
@Override
public void visit(MapExpression s) {
for (Map.Entry<Expression, Expression> entry : s.elements.entrySet()) {
for (Map.Entry<Node, Node> entry : s.elements.entrySet()) {
entry.getKey().accept(this);
entry.getValue().accept(this);
}
@ -144,7 +144,7 @@ public abstract class AbstractVisitor implements Visitor {
@Override
public void visit(ObjectCreationExpression s) {
for (Expression argument : s.constructorArguments) {
for (Node argument : s.constructorArguments) {
argument.accept(this);
}
}

View File

@ -11,6 +11,6 @@ public final class FunctionAdder extends AbstractVisitor {
@Override
public void visit(FunctionDefineStatement s) {
super.visit(s);
s.execute();
s.eval();
}
}

View File

@ -1,10 +1,7 @@
package com.annimon.ownlang.parser.visitors;
import com.annimon.ownlang.parser.ast.ArrayExpression;
import com.annimon.ownlang.parser.ast.Expression;
import com.annimon.ownlang.parser.ast.Statement;
import com.annimon.ownlang.parser.ast.Node;
import com.annimon.ownlang.parser.ast.UseStatement;
import com.annimon.ownlang.parser.ast.ValueExpression;
import java.util.HashSet;
import java.util.Set;
@ -16,7 +13,7 @@ public class ModuleDetector extends AbstractVisitor {
modules = new HashSet<>();
}
public Set<String> detect(Statement s) {
public Set<String> detect(Node s) {
s.accept(this);
return modules;
}

View File

@ -21,7 +21,7 @@ public class PrintVisitor implements ResultVisitor<StringBuilder, StringBuilder>
@Override
public StringBuilder visit(ArrayExpression s, StringBuilder t) {
t.append('[');
final Iterator<Expression> it = s.elements.iterator();
final Iterator<Node> it = s.elements.iterator();
if (it.hasNext()) {
it.next().accept(this, t);
while (it.hasNext()) {
@ -58,7 +58,7 @@ public class PrintVisitor implements ResultVisitor<StringBuilder, StringBuilder>
}
increaseIndent();
for (Statement statement : s.statements) {
for (Node statement : s.statements) {
newLine(t);
printIndent(t);
statement.accept(this, t);
@ -108,7 +108,7 @@ public class PrintVisitor implements ResultVisitor<StringBuilder, StringBuilder>
@Override
public StringBuilder visit(ContainerAccessExpression s, StringBuilder t) {
s.root.accept(this, t);
for (Expression index : s.indices) {
for (Node index : s.indices) {
t.append('[');
index.accept(this, t);
t.append(']');
@ -266,7 +266,7 @@ public class PrintVisitor implements ResultVisitor<StringBuilder, StringBuilder>
t.append('{');
increaseIndent();
boolean firstElement = true;
for (Map.Entry<Expression, Expression> entry : s.elements.entrySet()) {
for (Map.Entry<Node, Node> entry : s.elements.entrySet()) {
if (firstElement) firstElement = false;
else t.append(",");
newLine(t);
@ -440,10 +440,10 @@ public class PrintVisitor implements ResultVisitor<StringBuilder, StringBuilder>
return t;
}
private void printArgs(StringBuilder t, List<Expression> args) {
private void printArgs(StringBuilder t, List<Node> args) {
t.append("(");
boolean firstElement = true;
for (Expression expr : args) {
for (Node expr : args) {
if (firstElement) firstElement = false;
else t.append(", ");
expr.accept(this, t);

View File

@ -11,7 +11,6 @@ import com.annimon.ownlang.parser.ast.BinaryExpression;
import com.annimon.ownlang.parser.ast.ConditionalExpression;
import com.annimon.ownlang.parser.ast.IncludeStatement;
import com.annimon.ownlang.parser.ast.Node;
import com.annimon.ownlang.parser.ast.Statement;
import com.annimon.ownlang.parser.ast.UnaryExpression;
import com.annimon.ownlang.parser.ast.ValueExpression;
import com.annimon.ownlang.parser.ast.VariableExpression;
@ -32,7 +31,7 @@ public final class VisitorUtils {
return (node instanceof VariableExpression);
}
public static Statement includeProgram(IncludeStatement s) {
public static Node includeProgram(IncludeStatement s) {
if (!isValue(s.expression)) return null;
try {
final String path = s.expression.eval().asString();

View File

@ -1,12 +1,12 @@
package com.annimon.ownlang.stages;
import com.annimon.ownlang.parser.ast.Statement;
import com.annimon.ownlang.parser.ast.Node;
public class ExecutionStage implements Stage<Statement, Statement> {
public class ExecutionStage implements Stage<Node, Node> {
@Override
public Statement perform(StagesData stagesData, Statement input) {
input.execute();
public Node perform(StagesData stagesData, Node input) {
input.eval();
return input;
}
}

View File

@ -1,12 +1,12 @@
package com.annimon.ownlang.stages;
import com.annimon.ownlang.parser.ast.Statement;
import com.annimon.ownlang.parser.ast.Node;
import com.annimon.ownlang.parser.visitors.FunctionAdder;
public class FunctionAddingStage implements Stage<Statement, Statement> {
public class FunctionAddingStage implements Stage<Node, Node> {
@Override
public Statement perform(StagesData stagesData, Statement input) {
public Node perform(StagesData stagesData, Node input) {
input.accept(new FunctionAdder());
return input;
}

View File

@ -3,18 +3,18 @@ package com.annimon.ownlang.stages;
import com.annimon.ownlang.exceptions.OwnLangParserException;
import com.annimon.ownlang.parser.Parser;
import com.annimon.ownlang.parser.Token;
import com.annimon.ownlang.parser.ast.Statement;
import com.annimon.ownlang.parser.ast.Node;
import java.util.List;
public class ParserStage implements Stage<List<Token>, Statement> {
public class ParserStage implements Stage<List<Token>, Node> {
public static final String TAG_PROGRAM = "program";
public static final String TAG_HAS_PARSE_ERRORS = "hasParseErrors";
@Override
public Statement perform(StagesData stagesData, List<Token> input) {
public Node perform(StagesData stagesData, List<Token> input) {
final Parser parser = new Parser(input);
final Statement program = parser.parse();
final Node program = parser.parse();
final var parseErrors = parser.getParseErrors();
stagesData.put(TAG_PROGRAM, program);
stagesData.put(TAG_HAS_PARSE_ERRORS, parseErrors.hasErrors());

View File

@ -32,9 +32,9 @@ public class ParserTest {
assertEval( number(2), "12 % 5", operator(BinaryExpression.Operator.REMAINDER, value(12), value(5)) );
}
private static void assertEval(Value expectedValue, String input, Expression expected) {
private static void assertEval(Value expectedValue, String input, Node expected) {
BlockStatement program = assertExpression(input, expected);
program.execute();
program.eval();
final Value actual = ScopeHandler.getVariable("a");
try {
assertEquals(expectedValue.asNumber(), actual.asNumber(), 0.001);
@ -43,7 +43,7 @@ public class ParserTest {
}
}
private static BlockStatement assertExpression(String input, Expression expected) {
private static BlockStatement assertExpression(String input, Node expected) {
return assertProgram("a = " + input, block(assign("a", expected)));
}
@ -60,7 +60,7 @@ public class ParserTest {
}
}
private static Statement parse(String input) {
private static Node parse(String input) {
return Parser.parse(Lexer.tokenize(input));
}
}

View File

@ -1,6 +1,6 @@
package com.annimon.ownlang.parser;
import com.annimon.ownlang.parser.ast.Statement;
import com.annimon.ownlang.parser.ast.Node;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openjdk.jmh.annotations.*;
@ -28,7 +28,7 @@ public class ProgramsBenchmarkTest {
@Param({"-"})
private String path;
private Statement program;
private Node program;
@Setup(Level.Trial)
public void initializeTrial() throws IOException {
@ -41,7 +41,7 @@ public class ProgramsBenchmarkTest {
@Benchmark
public void programBenchmark() {
for (int i = 0; i < iterations; i++) {
program.execute();
program.eval();
}
}

View File

@ -6,7 +6,7 @@ import com.annimon.ownlang.lib.FunctionValue;
import com.annimon.ownlang.lib.NumberValue;
import com.annimon.ownlang.lib.ScopeHandler;
import com.annimon.ownlang.parser.ast.FunctionDefineStatement;
import com.annimon.ownlang.parser.ast.Statement;
import com.annimon.ownlang.parser.ast.Node;
import com.annimon.ownlang.parser.ast.Visitor;
import com.annimon.ownlang.parser.error.ParseErrorsFormatterStage;
import com.annimon.ownlang.parser.optimization.OptimizationStage;
@ -26,7 +26,7 @@ import static org.junit.jupiter.api.Assertions.*;
public class ProgramsTest {
private static final String RES_DIR = "src/test/resources";
private static Stage<InputSource, Statement> testPipeline;
private static Stage<InputSource, Node> testPipeline;
public static Stream<InputSource> data() {
return scanDirectory(RES_DIR)

View File

@ -35,19 +35,19 @@ public final class ASTHelper {
return result;
}
public static AssignmentExpression assign(String variable, Expression expr) {
public static AssignmentExpression assign(String variable, Node expr) {
return assign(var(variable), expr);
}
public static AssignmentExpression assign(Accessible accessible, Expression expr) {
public static AssignmentExpression assign(Accessible accessible, Node expr) {
return assign(null, accessible, expr);
}
public static AssignmentExpression assign(BinaryExpression.Operator op, Accessible accessible, Expression expr) {
public static AssignmentExpression assign(BinaryExpression.Operator op, Accessible accessible, Node expr) {
return new AssignmentExpression(op, accessible, expr);
}
public static BinaryExpression operator(BinaryExpression.Operator op, Expression left, Expression right) {
public static BinaryExpression operator(BinaryExpression.Operator op, Node left, Node right) {
return new BinaryExpression(op, left, right);
}

View File

@ -21,8 +21,8 @@ public class VariableExpressionTest {
@Test
public void testVariable() {
assign("a", value(4)).execute();
assign("b", value("ABCD")).execute();
assign("a", value(4)).eval();
assign("b", value("ABCD")).eval();
assertValue(number(4), var("a").eval());
assertValue(string("ABCD"), var("b").eval());
@ -30,8 +30,8 @@ public class VariableExpressionTest {
@Test
public void testVariableReplace() {
assign("a", value(4)).execute();
assign("a", value(8)).execute();
assign("a", value(4)).eval();
assign("a", value(8)).eval();
assertValue(number(8), var("a").eval());
}

View File

@ -7,7 +7,7 @@ import com.annimon.ownlang.exceptions.StoppedException;
import com.annimon.ownlang.lib.*;
import com.annimon.ownlang.parser.*;
import com.annimon.ownlang.parser.ast.BlockStatement;
import com.annimon.ownlang.parser.ast.Statement;
import com.annimon.ownlang.parser.ast.Node;
import com.annimon.ownlang.util.Pos;
import com.annimon.ownlang.parser.visitors.PrintVisitor;
import com.annimon.ownlang.utils.repl.JLineConsole;
@ -66,7 +66,7 @@ public final class Repl {
}
buffer.append(line).append(Console.newline());
Statement program = null;
Node program = null;
try {
final List<Token> tokens = Lexer.tokenize(buffer.toString());
final Parser parser = new Parser(tokens);
@ -82,7 +82,7 @@ public final class Repl {
continue;
}
}
program.execute();
program.eval();
} catch (OwnLangParserException lex) {
continue;
} catch (StoppedException ex) {

View File

@ -8,6 +8,7 @@ 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.Node;
import com.annimon.ownlang.parser.ast.Statement;
import com.annimon.ownlang.parser.visitors.FunctionAdder;
import java.io.File;
@ -31,7 +32,7 @@ public final class Sandbox {
final List<Token> tokens = Lexer.tokenize(input);
final Parser parser = new Parser(tokens);
final Statement program = parser.parse();
final Node program = parser.parse();
if (parser.getParseErrors().hasErrors()) {
System.out.print(parser.getParseErrors());
return;
@ -40,7 +41,7 @@ public final class Sandbox {
program.accept(new FunctionAdder());
try {
program.execute();
program.eval();
} catch (StoppedException ex) {
// skip
} catch (Exception ex) {