mirror of
https://github.com/aNNiMON/Own-Programming-Language-Tutorial.git
synced 2024-09-20 00:34:20 +03:00
Урок 13. Шаблон проектирования «Посетитель»
This commit is contained in:
parent
5144524ba2
commit
ebed6c56d2
@ -4,6 +4,9 @@ import com.annimon.ownlang.parser.Lexer;
|
|||||||
import com.annimon.ownlang.parser.Parser;
|
import com.annimon.ownlang.parser.Parser;
|
||||||
import com.annimon.ownlang.parser.Token;
|
import com.annimon.ownlang.parser.Token;
|
||||||
import com.annimon.ownlang.parser.ast.Statement;
|
import com.annimon.ownlang.parser.ast.Statement;
|
||||||
|
import com.annimon.ownlang.parser.visitors.AssignValidator;
|
||||||
|
import com.annimon.ownlang.parser.visitors.FunctionAdder;
|
||||||
|
import com.annimon.ownlang.parser.visitors.VariablePrinter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
@ -15,7 +18,7 @@ import java.util.List;
|
|||||||
public final class Main {
|
public final class Main {
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
final String input = new String( Files.readAllBytes(Paths.get("program.own")), "UTF-8");
|
final String input = new String( Files.readAllBytes(Paths.get("visitor.own")), "UTF-8");
|
||||||
final List<Token> tokens = new Lexer(input).tokenize();
|
final List<Token> tokens = new Lexer(input).tokenize();
|
||||||
for (Token token : tokens) {
|
for (Token token : tokens) {
|
||||||
System.out.println(token);
|
System.out.println(token);
|
||||||
@ -23,6 +26,9 @@ public final class Main {
|
|||||||
|
|
||||||
final Statement program = new Parser(tokens).parse();
|
final Statement program = new Parser(tokens).parse();
|
||||||
System.out.println(program.toString());
|
System.out.println(program.toString());
|
||||||
|
program.accept(new FunctionAdder());
|
||||||
|
program.accept(new VariablePrinter());
|
||||||
|
program.accept(new AssignValidator());
|
||||||
program.execute();
|
program.execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,8 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public final class ArrayAccessExpression implements Expression {
|
public final class ArrayAccessExpression implements Expression {
|
||||||
|
|
||||||
private final String variable;
|
public final String variable;
|
||||||
private final List<Expression> indices;
|
public final List<Expression> indices;
|
||||||
|
|
||||||
public ArrayAccessExpression(String variable, List<Expression> indices) {
|
public ArrayAccessExpression(String variable, List<Expression> indices) {
|
||||||
this.variable = variable;
|
this.variable = variable;
|
||||||
@ -48,6 +48,11 @@ public final class ArrayAccessExpression implements Expression {
|
|||||||
throw new RuntimeException("Array expected");
|
throw new RuntimeException("Array expected");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -6,8 +6,8 @@ package com.annimon.ownlang.parser.ast;
|
|||||||
*/
|
*/
|
||||||
public final class ArrayAssignmentStatement implements Statement {
|
public final class ArrayAssignmentStatement implements Statement {
|
||||||
|
|
||||||
private final ArrayAccessExpression array;
|
public final ArrayAccessExpression array;
|
||||||
private final Expression expression;
|
public final Expression expression;
|
||||||
|
|
||||||
public ArrayAssignmentStatement(ArrayAccessExpression array, Expression expression) {
|
public ArrayAssignmentStatement(ArrayAccessExpression array, Expression expression) {
|
||||||
this.array = array;
|
this.array = array;
|
||||||
@ -18,6 +18,11 @@ public final class ArrayAssignmentStatement implements Statement {
|
|||||||
public void execute() {
|
public void execute() {
|
||||||
array.getArray().set(array.lastIndex(), expression.eval());
|
array.getArray().set(array.lastIndex(), expression.eval());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -10,7 +10,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public final class ArrayExpression implements Expression {
|
public final class ArrayExpression implements Expression {
|
||||||
|
|
||||||
private final List<Expression> elements;
|
public final List<Expression> elements;
|
||||||
|
|
||||||
public ArrayExpression(List<Expression> arguments) {
|
public ArrayExpression(List<Expression> arguments) {
|
||||||
this.elements = arguments;
|
this.elements = arguments;
|
||||||
@ -25,6 +25,11 @@ public final class ArrayExpression implements Expression {
|
|||||||
}
|
}
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -9,8 +9,8 @@ import com.annimon.ownlang.lib.Variables;
|
|||||||
*/
|
*/
|
||||||
public final class AssignmentStatement implements Statement {
|
public final class AssignmentStatement implements Statement {
|
||||||
|
|
||||||
private final String variable;
|
public final String variable;
|
||||||
private final Expression expression;
|
public final Expression expression;
|
||||||
|
|
||||||
public AssignmentStatement(String variable, Expression expression) {
|
public AssignmentStatement(String variable, Expression expression) {
|
||||||
this.variable = variable;
|
this.variable = variable;
|
||||||
@ -22,6 +22,11 @@ public final class AssignmentStatement implements Statement {
|
|||||||
final Value result = expression.eval();
|
final Value result = expression.eval();
|
||||||
Variables.set(variable, result);
|
Variables.set(variable, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -11,8 +11,8 @@ import com.annimon.ownlang.lib.Value;
|
|||||||
*/
|
*/
|
||||||
public final class BinaryExpression implements Expression {
|
public final class BinaryExpression implements Expression {
|
||||||
|
|
||||||
private final Expression expr1, expr2;
|
public final Expression expr1, expr2;
|
||||||
private final char operation;
|
public final char operation;
|
||||||
|
|
||||||
public BinaryExpression(char operation, Expression expr1, Expression expr2) {
|
public BinaryExpression(char operation, Expression expr1, Expression expr2) {
|
||||||
this.operation = operation;
|
this.operation = operation;
|
||||||
@ -52,6 +52,11 @@ public final class BinaryExpression implements Expression {
|
|||||||
return new NumberValue(number1 + number2);
|
return new NumberValue(number1 + number2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -9,7 +9,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public final class BlockStatement implements Statement {
|
public final class BlockStatement implements Statement {
|
||||||
|
|
||||||
private final List<Statement> statements;
|
public final List<Statement> statements;
|
||||||
|
|
||||||
public BlockStatement() {
|
public BlockStatement() {
|
||||||
statements = new ArrayList<>();
|
statements = new ArrayList<>();
|
||||||
@ -25,6 +25,11 @@ public final class BlockStatement implements Statement {
|
|||||||
statement.execute();
|
statement.execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -10,6 +10,11 @@ public final class BreakStatement extends RuntimeException implements Statement
|
|||||||
public void execute() {
|
public void execute() {
|
||||||
throw this;
|
throw this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -38,8 +38,8 @@ public final class ConditionalExpression implements Expression {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Expression expr1, expr2;
|
public final Expression expr1, expr2;
|
||||||
private final Operator operation;
|
public final Operator operation;
|
||||||
|
|
||||||
public ConditionalExpression(Operator operation, Expression expr1, Expression expr2) {
|
public ConditionalExpression(Operator operation, Expression expr1, Expression expr2) {
|
||||||
this.operation = operation;
|
this.operation = operation;
|
||||||
@ -78,6 +78,11 @@ public final class ConditionalExpression implements Expression {
|
|||||||
}
|
}
|
||||||
return new NumberValue(result);
|
return new NumberValue(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -10,6 +10,11 @@ public final class ContinueStatement extends RuntimeException implements Stateme
|
|||||||
public void execute() {
|
public void execute() {
|
||||||
throw this;
|
throw this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -6,8 +6,8 @@ package com.annimon.ownlang.parser.ast;
|
|||||||
*/
|
*/
|
||||||
public final class DoWhileStatement implements Statement {
|
public final class DoWhileStatement implements Statement {
|
||||||
|
|
||||||
private final Expression condition;
|
public final Expression condition;
|
||||||
private final Statement statement;
|
public final Statement statement;
|
||||||
|
|
||||||
public DoWhileStatement(Expression condition, Statement statement) {
|
public DoWhileStatement(Expression condition, Statement statement) {
|
||||||
this.condition = condition;
|
this.condition = condition;
|
||||||
@ -27,6 +27,11 @@ public final class DoWhileStatement implements Statement {
|
|||||||
}
|
}
|
||||||
while (condition.eval().asNumber() != 0);
|
while (condition.eval().asNumber() != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -6,7 +6,7 @@ import com.annimon.ownlang.lib.Value;
|
|||||||
*
|
*
|
||||||
* @author aNNiMON
|
* @author aNNiMON
|
||||||
*/
|
*/
|
||||||
public interface Expression {
|
public interface Expression extends Node {
|
||||||
|
|
||||||
Value eval();
|
Value eval();
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,10 @@ package com.annimon.ownlang.parser.ast;
|
|||||||
*/
|
*/
|
||||||
public final class ForStatement implements Statement {
|
public final class ForStatement implements Statement {
|
||||||
|
|
||||||
private final Statement initialization;
|
public final Statement initialization;
|
||||||
private final Expression termination;
|
public final Expression termination;
|
||||||
private final Statement increment;
|
public final Statement increment;
|
||||||
private final Statement statement;
|
public final Statement statement;
|
||||||
|
|
||||||
public ForStatement(Statement initialization, Expression termination, Statement increment, Statement block) {
|
public ForStatement(Statement initialization, Expression termination, Statement increment, Statement block) {
|
||||||
this.initialization = initialization;
|
this.initialization = initialization;
|
||||||
@ -30,6 +30,11 @@ public final class ForStatement implements Statement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -10,9 +10,9 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public final class FunctionDefineStatement implements Statement {
|
public final class FunctionDefineStatement implements Statement {
|
||||||
|
|
||||||
private final String name;
|
public final String name;
|
||||||
private final List<String> argNames;
|
public final List<String> argNames;
|
||||||
private final Statement body;
|
public final Statement body;
|
||||||
|
|
||||||
public FunctionDefineStatement(String name, List<String> argNames, Statement body) {
|
public FunctionDefineStatement(String name, List<String> argNames, Statement body) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@ -24,6 +24,11 @@ public final class FunctionDefineStatement implements Statement {
|
|||||||
public void execute() {
|
public void execute() {
|
||||||
Functions.set(name, new UserDefinedFunction(argNames, body));
|
Functions.set(name, new UserDefinedFunction(argNames, body));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -6,7 +6,7 @@ package com.annimon.ownlang.parser.ast;
|
|||||||
*/
|
*/
|
||||||
public final class FunctionStatement implements Statement {
|
public final class FunctionStatement implements Statement {
|
||||||
|
|
||||||
private final FunctionalExpression function;
|
public final FunctionalExpression function;
|
||||||
|
|
||||||
public FunctionStatement(FunctionalExpression function) {
|
public FunctionStatement(FunctionalExpression function) {
|
||||||
this.function = function;
|
this.function = function;
|
||||||
@ -16,6 +16,11 @@ public final class FunctionStatement implements Statement {
|
|||||||
public void execute() {
|
public void execute() {
|
||||||
function.eval();
|
function.eval();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -14,8 +14,8 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public final class FunctionalExpression implements Expression {
|
public final class FunctionalExpression implements Expression {
|
||||||
|
|
||||||
private final String name;
|
public final String name;
|
||||||
private final List<Expression> arguments;
|
public final List<Expression> arguments;
|
||||||
|
|
||||||
public FunctionalExpression(String name) {
|
public FunctionalExpression(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@ -30,7 +30,7 @@ public final class FunctionalExpression implements Expression {
|
|||||||
public void addArgument(Expression arg) {
|
public void addArgument(Expression arg) {
|
||||||
arguments.add(arg);
|
arguments.add(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value eval() {
|
public Value eval() {
|
||||||
final int size = arguments.size();
|
final int size = arguments.size();
|
||||||
@ -54,6 +54,11 @@ public final class FunctionalExpression implements Expression {
|
|||||||
}
|
}
|
||||||
return function.execute(values);
|
return function.execute(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -6,8 +6,8 @@ package com.annimon.ownlang.parser.ast;
|
|||||||
*/
|
*/
|
||||||
public final class IfStatement implements Statement {
|
public final class IfStatement implements Statement {
|
||||||
|
|
||||||
private final Expression expression;
|
public final Expression expression;
|
||||||
private final Statement ifStatement, elseStatement;
|
public final Statement ifStatement, elseStatement;
|
||||||
|
|
||||||
public IfStatement(Expression expression, Statement ifStatement, Statement elseStatement) {
|
public IfStatement(Expression expression, Statement ifStatement, Statement elseStatement) {
|
||||||
this.expression = expression;
|
this.expression = expression;
|
||||||
@ -24,6 +24,11 @@ public final class IfStatement implements Statement {
|
|||||||
elseStatement.execute();
|
elseStatement.execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
10
src/com/annimon/ownlang/parser/ast/Node.java
Normal file
10
src/com/annimon/ownlang/parser/ast/Node.java
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package com.annimon.ownlang.parser.ast;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author aNNiMON
|
||||||
|
*/
|
||||||
|
public interface Node {
|
||||||
|
|
||||||
|
void accept(Visitor visitor);
|
||||||
|
}
|
@ -6,7 +6,7 @@ package com.annimon.ownlang.parser.ast;
|
|||||||
*/
|
*/
|
||||||
public final class PrintStatement implements Statement {
|
public final class PrintStatement implements Statement {
|
||||||
|
|
||||||
private final Expression expression;
|
public final Expression expression;
|
||||||
|
|
||||||
public PrintStatement(Expression expression) {
|
public PrintStatement(Expression expression) {
|
||||||
this.expression = expression;
|
this.expression = expression;
|
||||||
@ -16,6 +16,11 @@ public final class PrintStatement implements Statement {
|
|||||||
public void execute() {
|
public void execute() {
|
||||||
System.out.print(expression.eval());
|
System.out.print(expression.eval());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -8,7 +8,7 @@ import com.annimon.ownlang.lib.Value;
|
|||||||
*/
|
*/
|
||||||
public final class ReturnStatement extends RuntimeException implements Statement {
|
public final class ReturnStatement extends RuntimeException implements Statement {
|
||||||
|
|
||||||
private final Expression expression;
|
public final Expression expression;
|
||||||
private Value result;
|
private Value result;
|
||||||
|
|
||||||
public ReturnStatement(Expression expression) {
|
public ReturnStatement(Expression expression) {
|
||||||
@ -24,6 +24,11 @@ public final class ReturnStatement extends RuntimeException implements Statement
|
|||||||
result = expression.eval();
|
result = expression.eval();
|
||||||
throw this;
|
throw this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -4,7 +4,7 @@ package com.annimon.ownlang.parser.ast;
|
|||||||
*
|
*
|
||||||
* @author aNNiMON
|
* @author aNNiMON
|
||||||
*/
|
*/
|
||||||
public interface Statement {
|
public interface Statement extends Node {
|
||||||
|
|
||||||
void execute();
|
void execute();
|
||||||
}
|
}
|
||||||
|
@ -9,14 +9,14 @@ import com.annimon.ownlang.lib.Value;
|
|||||||
*/
|
*/
|
||||||
public final class UnaryExpression implements Expression {
|
public final class UnaryExpression implements Expression {
|
||||||
|
|
||||||
private final Expression expr1;
|
public final Expression expr1;
|
||||||
private final char operation;
|
public final char operation;
|
||||||
|
|
||||||
public UnaryExpression(char operation, Expression expr1) {
|
public UnaryExpression(char operation, Expression expr1) {
|
||||||
this.operation = operation;
|
this.operation = operation;
|
||||||
this.expr1 = expr1;
|
this.expr1 = expr1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value eval() {
|
public Value eval() {
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
@ -27,6 +27,11 @@ public final class UnaryExpression implements Expression {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("%c %s", operation, expr1);
|
return String.format("%c %s", operation, expr1);
|
||||||
|
@ -10,7 +10,7 @@ import com.annimon.ownlang.lib.Value;
|
|||||||
*/
|
*/
|
||||||
public final class ValueExpression implements Expression {
|
public final class ValueExpression implements Expression {
|
||||||
|
|
||||||
private final Value value;
|
public final Value value;
|
||||||
|
|
||||||
public ValueExpression(double value) {
|
public ValueExpression(double value) {
|
||||||
this.value = new NumberValue(value);
|
this.value = new NumberValue(value);
|
||||||
@ -24,6 +24,11 @@ public final class ValueExpression implements Expression {
|
|||||||
public Value eval() {
|
public Value eval() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -9,7 +9,7 @@ import com.annimon.ownlang.lib.Variables;
|
|||||||
*/
|
*/
|
||||||
public final class VariableExpression implements Expression {
|
public final class VariableExpression implements Expression {
|
||||||
|
|
||||||
private final String name;
|
public final String name;
|
||||||
|
|
||||||
public VariableExpression(String name) {
|
public VariableExpression(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@ -20,6 +20,11 @@ public final class VariableExpression implements Expression {
|
|||||||
if (!Variables.isExists(name)) throw new RuntimeException("Variable does not exists");
|
if (!Variables.isExists(name)) throw new RuntimeException("Variable does not exists");
|
||||||
return Variables.get(name);
|
return Variables.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
30
src/com/annimon/ownlang/parser/ast/Visitor.java
Normal file
30
src/com/annimon/ownlang/parser/ast/Visitor.java
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package com.annimon.ownlang.parser.ast;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author aNNiMON
|
||||||
|
*/
|
||||||
|
public interface Visitor {
|
||||||
|
|
||||||
|
void visit(ArrayAccessExpression s);
|
||||||
|
void visit(ArrayAssignmentStatement s);
|
||||||
|
void visit(ArrayExpression s);
|
||||||
|
void visit(AssignmentStatement s);
|
||||||
|
void visit(BinaryExpression s);
|
||||||
|
void visit(BlockStatement s);
|
||||||
|
void visit(BreakStatement s);
|
||||||
|
void visit(ConditionalExpression s);
|
||||||
|
void visit(ContinueStatement s);
|
||||||
|
void visit(DoWhileStatement s);
|
||||||
|
void visit(ForStatement s);
|
||||||
|
void visit(FunctionDefineStatement s);
|
||||||
|
void visit(FunctionStatement s);
|
||||||
|
void visit(FunctionalExpression s);
|
||||||
|
void visit(IfStatement s);
|
||||||
|
void visit(PrintStatement s);
|
||||||
|
void visit(ReturnStatement s);
|
||||||
|
void visit(UnaryExpression s);
|
||||||
|
void visit(ValueExpression s);
|
||||||
|
void visit(VariableExpression s);
|
||||||
|
void visit(WhileStatement st);
|
||||||
|
}
|
@ -6,8 +6,8 @@ package com.annimon.ownlang.parser.ast;
|
|||||||
*/
|
*/
|
||||||
public final class WhileStatement implements Statement {
|
public final class WhileStatement implements Statement {
|
||||||
|
|
||||||
private final Expression condition;
|
public final Expression condition;
|
||||||
private final Statement statement;
|
public final Statement statement;
|
||||||
|
|
||||||
public WhileStatement(Expression condition, Statement statement) {
|
public WhileStatement(Expression condition, Statement statement) {
|
||||||
this.condition = condition;
|
this.condition = condition;
|
||||||
@ -26,6 +26,11 @@ public final class WhileStatement implements Statement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Visitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
132
src/com/annimon/ownlang/parser/visitors/AbstractVisitor.java
Normal file
132
src/com/annimon/ownlang/parser/visitors/AbstractVisitor.java
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
package com.annimon.ownlang.parser.visitors;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.parser.ast.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author aNNiMON
|
||||||
|
*/
|
||||||
|
public abstract class AbstractVisitor implements Visitor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ArrayAccessExpression s) {
|
||||||
|
for (Expression index : s.indices) {
|
||||||
|
index.accept(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ArrayAssignmentStatement s) {
|
||||||
|
s.array.accept(this);
|
||||||
|
s.expression.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ArrayExpression s) {
|
||||||
|
for (Expression index : s.elements) {
|
||||||
|
index.accept(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(AssignmentStatement s) {
|
||||||
|
s.expression.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(BinaryExpression s) {
|
||||||
|
s.expr1.accept(this);
|
||||||
|
s.expr2.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(BlockStatement s) {
|
||||||
|
for (Statement statement : s.statements) {
|
||||||
|
statement.accept(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(BreakStatement s) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ConditionalExpression s) {
|
||||||
|
s.expr1.accept(this);
|
||||||
|
s.expr2.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ContinueStatement s) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(DoWhileStatement s) {
|
||||||
|
s.condition.accept(this);
|
||||||
|
s.statement.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ForStatement s) {
|
||||||
|
s.initialization.accept(this);
|
||||||
|
s.termination.accept(this);
|
||||||
|
s.increment.accept(this);
|
||||||
|
s.statement.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(FunctionDefineStatement s) {
|
||||||
|
s.body.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(FunctionStatement s) {
|
||||||
|
s.function.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(FunctionalExpression s) {
|
||||||
|
for (Expression argument : s.arguments) {
|
||||||
|
argument.accept(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(IfStatement s) {
|
||||||
|
s.expression.accept(this);
|
||||||
|
s.ifStatement.accept(this);
|
||||||
|
if (s.elseStatement != null) {
|
||||||
|
s.elseStatement.accept(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(PrintStatement s) {
|
||||||
|
s.expression.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ReturnStatement s) {
|
||||||
|
s.expression.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(UnaryExpression s) {
|
||||||
|
s.expr1.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ValueExpression s) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(VariableExpression s) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(WhileStatement st) {
|
||||||
|
st.condition.accept(this);
|
||||||
|
st.statement.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
19
src/com/annimon/ownlang/parser/visitors/AssignValidator.java
Normal file
19
src/com/annimon/ownlang/parser/visitors/AssignValidator.java
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package com.annimon.ownlang.parser.visitors;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.lib.Variables;
|
||||||
|
import com.annimon.ownlang.parser.ast.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author aNNiMON
|
||||||
|
*/
|
||||||
|
public final class AssignValidator extends AbstractVisitor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(AssignmentStatement s) {
|
||||||
|
super.visit(s);
|
||||||
|
if (Variables.isExists(s.variable)) {
|
||||||
|
throw new RuntimeException("Cannot assign value to constant");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
16
src/com/annimon/ownlang/parser/visitors/FunctionAdder.java
Normal file
16
src/com/annimon/ownlang/parser/visitors/FunctionAdder.java
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package com.annimon.ownlang.parser.visitors;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.parser.ast.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author aNNiMON
|
||||||
|
*/
|
||||||
|
public final class FunctionAdder extends AbstractVisitor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(FunctionDefineStatement s) {
|
||||||
|
super.visit(s);
|
||||||
|
s.execute();
|
||||||
|
}
|
||||||
|
}
|
28
src/com/annimon/ownlang/parser/visitors/VariablePrinter.java
Normal file
28
src/com/annimon/ownlang/parser/visitors/VariablePrinter.java
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package com.annimon.ownlang.parser.visitors;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.parser.ast.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author aNNiMON
|
||||||
|
*/
|
||||||
|
public final class VariablePrinter extends AbstractVisitor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ArrayAccessExpression s) {
|
||||||
|
super.visit(s);
|
||||||
|
System.out.println(s.variable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(AssignmentStatement s) {
|
||||||
|
super.visit(s);
|
||||||
|
System.out.println(s.variable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(VariableExpression s) {
|
||||||
|
super.visit(s);
|
||||||
|
System.out.println(s.name);
|
||||||
|
}
|
||||||
|
}
|
5
visitor.own
Normal file
5
visitor.own
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
func()
|
||||||
|
def func() print "function\n"
|
||||||
|
|
||||||
|
a = 2 + 3 * 4
|
||||||
|
print a
|
Loading…
Reference in New Issue
Block a user