diff options
20 files changed, 171 insertions, 34 deletions
diff --git a/main/core/parser/ast/ASTNode.java b/main/core/parser/ast/ASTNode.java index 99bdc06..311314f 100644 --- a/main/core/parser/ast/ASTNode.java +++ b/main/core/parser/ast/ASTNode.java @@ -2,6 +2,7 @@ package com.jantuomi.interpreter.main.core.parser.ast; import com.jantuomi.interpreter.main.core.parser.datatype.DataContainer; import com.jantuomi.interpreter.main.core.tokenizer.token.Token; +import com.jantuomi.interpreter.main.exception.InterpreterException; import java.util.List; @@ -10,7 +11,7 @@ import java.util.List; */ abstract public class ASTNode { - public abstract DataContainer evaluate(); + public abstract DataContainer evaluate() throws InterpreterException; protected Token source; diff --git a/main/core/parser/ast/AdditionNode.java b/main/core/parser/ast/AdditionNode.java index a6406ae..0820370 100644 --- a/main/core/parser/ast/AdditionNode.java +++ b/main/core/parser/ast/AdditionNode.java @@ -2,6 +2,7 @@ package com.jantuomi.interpreter.main.core.parser.ast; import com.jantuomi.interpreter.main.core.parser.datatype.DataContainer; import com.jantuomi.interpreter.main.core.tokenizer.token.Token; +import com.jantuomi.interpreter.main.exception.InterpreterException; import java.util.Arrays; import java.util.List; @@ -16,7 +17,7 @@ public class AdditionNode extends BinaryOperatorNode { } @Override - public DataContainer evaluate() { + public DataContainer evaluate() throws InterpreterException { DataContainer operand1 = lhs.evaluate(); DataContainer operand2 = rhs.evaluate(); diff --git a/main/core/parser/ast/AssignmentNode.java b/main/core/parser/ast/AssignmentNode.java index bcbff1c..f2e7b8d 100644 --- a/main/core/parser/ast/AssignmentNode.java +++ b/main/core/parser/ast/AssignmentNode.java @@ -3,6 +3,7 @@ package com.jantuomi.interpreter.main.core.parser.ast; import com.jantuomi.interpreter.main.core.parser.datatype.DataContainer; import com.jantuomi.interpreter.main.core.runtime.State; import com.jantuomi.interpreter.main.core.tokenizer.token.Token; +import com.jantuomi.interpreter.main.exception.InterpreterException; import java.util.Arrays; import java.util.List; @@ -16,7 +17,7 @@ public class AssignmentNode extends BinaryOperatorNode { } @Override - public DataContainer evaluate() { + public DataContainer evaluate() throws InterpreterException { SymbolNode symbol = (SymbolNode) lhs; DataContainer rValue = rhs.evaluate(); State.getInstance().setSymbolValueToScope( diff --git a/main/core/parser/ast/FunctionBodyNode.java b/main/core/parser/ast/BlockBodyNode.java index 394710c..671f847 100644 --- a/main/core/parser/ast/FunctionBodyNode.java +++ b/main/core/parser/ast/BlockBodyNode.java @@ -3,17 +3,18 @@ package com.jantuomi.interpreter.main.core.parser.ast; import com.jantuomi.interpreter.main.core.parser.datatype.DataContainer; import com.jantuomi.interpreter.main.core.parser.datatype.VoidDataContainer; import com.jantuomi.interpreter.main.core.tokenizer.token.Token; +import com.jantuomi.interpreter.main.exception.InterpreterException; /** * Created by jan on 17.6.2016. */ -public class FunctionBodyNode extends VarargOperatorNode { - public FunctionBodyNode(Token token) { +public class BlockBodyNode extends VarargOperatorNode { + public BlockBodyNode(Token token) { super(token); } @Override - public DataContainer evaluate() { + public DataContainer evaluate() throws InterpreterException { DataContainer returnValue = new VoidDataContainer(); for (ASTNode node : args) { diff --git a/main/core/parser/ast/BranchNode.java b/main/core/parser/ast/BranchNode.java new file mode 100644 index 0000000..d6fb4cf --- /dev/null +++ b/main/core/parser/ast/BranchNode.java @@ -0,0 +1,42 @@ +package com.jantuomi.interpreter.main.core.parser.ast; + +import com.jantuomi.interpreter.main.core.parser.datatype.BooleanDataContainer; +import com.jantuomi.interpreter.main.core.parser.datatype.DataContainer; +import com.jantuomi.interpreter.main.core.tokenizer.token.Token; +import com.jantuomi.interpreter.main.exception.InterpreterException; + +import java.util.Arrays; +import java.util.List; + +/** + * Created by jan on 17.6.2016. + */ +public class BranchNode extends ASTNode { + + private ASTNode expression; + private BlockBodyNode branch; + + public BranchNode(Token token, ASTNode expression, BlockBodyNode branch) { + super(token); + this.expression = expression; + this.branch = branch; + } + + @Override + public DataContainer evaluate() throws InterpreterException { + DataContainer ev = expression.evaluate(); + boolean returnValue = false; + if (ev instanceof BooleanDataContainer) { + returnValue = ((BooleanDataContainer) ev).getData(); + if (returnValue) { + branch.evaluate(); + } + } + return new BooleanDataContainer(returnValue); + } + + @Override + List<ASTNode> getChildren() { + return Arrays.asList(expression, branch); + } +} diff --git a/main/core/parser/ast/FunctionDefineNode.java b/main/core/parser/ast/FunctionDefineNode.java index 2402bed..482551f 100644 --- a/main/core/parser/ast/FunctionDefineNode.java +++ b/main/core/parser/ast/FunctionDefineNode.java @@ -37,7 +37,7 @@ public class FunctionDefineNode extends VarargOperatorNode { SymbolNode argSym = (SymbolNode) arg; argumentNames.add(argSym.getName()); } - Function function = new Function(argumentNames, (FunctionBodyNode) body); + Function function = new Function(argumentNames, (BlockBodyNode) body); State.getInstance().addFunctionToScope(name, function); return new StringDataContainer("function " + name); diff --git a/main/core/parser/ast/SubtractionNode.java b/main/core/parser/ast/SubtractionNode.java index 0865ab1..b234d0d 100644 --- a/main/core/parser/ast/SubtractionNode.java +++ b/main/core/parser/ast/SubtractionNode.java @@ -2,6 +2,7 @@ package com.jantuomi.interpreter.main.core.parser.ast; import com.jantuomi.interpreter.main.core.parser.datatype.DataContainer; import com.jantuomi.interpreter.main.core.tokenizer.token.Token; +import com.jantuomi.interpreter.main.exception.InterpreterException; import java.util.Arrays; import java.util.List; @@ -15,7 +16,7 @@ public class SubtractionNode extends BinaryOperatorNode { } @Override - public DataContainer evaluate() { + public DataContainer evaluate() throws InterpreterException { DataContainer operand1 = lhs.evaluate(); DataContainer operand2 = rhs.evaluate(); diff --git a/main/core/parser/ast/SymbolNode.java b/main/core/parser/ast/SymbolNode.java index 4dfb403..c44d41b 100644 --- a/main/core/parser/ast/SymbolNode.java +++ b/main/core/parser/ast/SymbolNode.java @@ -3,6 +3,7 @@ package com.jantuomi.interpreter.main.core.parser.ast; import com.jantuomi.interpreter.main.core.parser.datatype.DataContainer; import com.jantuomi.interpreter.main.core.runtime.State; import com.jantuomi.interpreter.main.core.tokenizer.token.Token; +import com.jantuomi.interpreter.main.exception.InterpreterException; import java.util.ArrayList; import java.util.Arrays; @@ -38,7 +39,7 @@ public class SymbolNode extends ASTNode { } @Override - public DataContainer evaluate() { + public DataContainer evaluate() throws InterpreterException { List<DataContainer> paramValues = new ArrayList<>(); if (parameterListNode != null) { for (ASTNode param : parameterListNode.getChildren()) { diff --git a/main/core/parser/datatype/BooleanDataContainer.java b/main/core/parser/datatype/BooleanDataContainer.java new file mode 100644 index 0000000..1536fca --- /dev/null +++ b/main/core/parser/datatype/BooleanDataContainer.java @@ -0,0 +1,33 @@ +package com.jantuomi.interpreter.main.core.parser.datatype; + +import com.jantuomi.interpreter.main.exception.ExceptionManager; +import com.jantuomi.interpreter.main.exception.InterpreterException; + +/** + * Created by jan on 16.6.2016. + */ +public class BooleanDataContainer extends DataContainer<Boolean> { + + private boolean value; + + public BooleanDataContainer(boolean value) { + this.value = value; + } + + @Override + public String toString() { + return Boolean.toString(value); + } + + @Override + public DataContainer<Boolean> add(DataContainer<Boolean> other) throws InterpreterException { + ExceptionManager.raise(InterpreterException.ExceptionType.TypeError, -1, "boolean", "boolean"); + return null; + } + + @Override + public DataContainer<Boolean> subtract(DataContainer<Boolean> other) throws InterpreterException { + ExceptionManager.raise(InterpreterException.ExceptionType.TypeError, -1, "boolean", "boolean"); + return null; + } +} diff --git a/main/core/parser/datatype/DataContainer.java b/main/core/parser/datatype/DataContainer.java index b504bd6..2214d80 100644 --- a/main/core/parser/datatype/DataContainer.java +++ b/main/core/parser/datatype/DataContainer.java @@ -1,5 +1,7 @@ package com.jantuomi.interpreter.main.core.parser.datatype; +import com.jantuomi.interpreter.main.exception.InterpreterException; + /** * Created by jan on 11.6.2016. */ @@ -24,6 +26,6 @@ abstract public class DataContainer<T> { @Override abstract public String toString(); - abstract public DataContainer<T> add(DataContainer<T> other); - public abstract DataContainer<T> subtract(DataContainer<T> other); + abstract public DataContainer<T> add(DataContainer<T> other) throws InterpreterException; + public abstract DataContainer<T> subtract(DataContainer<T> other) throws InterpreterException; } diff --git a/main/core/runtime/Function.java b/main/core/runtime/Function.java index cf6422f..cc4f56f 100644 --- a/main/core/runtime/Function.java +++ b/main/core/runtime/Function.java @@ -1,7 +1,8 @@ package com.jantuomi.interpreter.main.core.runtime; -import com.jantuomi.interpreter.main.core.parser.ast.FunctionBodyNode; +import com.jantuomi.interpreter.main.core.parser.ast.BlockBodyNode; import com.jantuomi.interpreter.main.core.parser.datatype.DataContainer; +import com.jantuomi.interpreter.main.exception.InterpreterException; import java.util.List; @@ -12,14 +13,14 @@ public class Function { private List<String> argumentNames; - private FunctionBodyNode body; + private BlockBodyNode body; - public Function(List<String> argumentNames, FunctionBodyNode body) { + public Function(List<String> argumentNames, BlockBodyNode body) { this.argumentNames = argumentNames; this.body = body; } - public DataContainer evaluate(List<DataContainer> params) { + public DataContainer evaluate(List<DataContainer> params) throws InterpreterException { State.getInstance().createScope(); if (params.size() != argumentNames.size()) { diff --git a/main/core/runtime/Interpreter.java b/main/core/runtime/Interpreter.java index f84e7e7..6877ac3 100644 --- a/main/core/runtime/Interpreter.java +++ b/main/core/runtime/Interpreter.java @@ -2,6 +2,7 @@ package com.jantuomi.interpreter.main.core.runtime; import com.jantuomi.interpreter.main.core.parser.ast.ASTNode; import com.jantuomi.interpreter.main.core.parser.datatype.DataContainer; +import com.jantuomi.interpreter.main.exception.InterpreterException; import java.util.List; @@ -18,7 +19,7 @@ public class Interpreter { private Interpreter() { } - public static String execute(List<ASTNode> sequence) { + public static String execute(List<ASTNode> sequence) throws InterpreterException { String output = ""; for (ASTNode node : sequence) { DataContainer data = node.evaluate(); diff --git a/main/core/runtime/Scope.java b/main/core/runtime/Scope.java index a45cdd7..e3bf899 100644 --- a/main/core/runtime/Scope.java +++ b/main/core/runtime/Scope.java @@ -1,6 +1,7 @@ package com.jantuomi.interpreter.main.core.runtime; import com.jantuomi.interpreter.main.core.parser.datatype.DataContainer; +import com.jantuomi.interpreter.main.exception.InterpreterException; import java.util.HashMap; import java.util.List; @@ -23,7 +24,7 @@ public class Scope { variables.replace(symbol, value); } - public DataContainer resolveSymbol(String symbol, List<DataContainer> params) { + public DataContainer resolveSymbol(String symbol, List<DataContainer> params) throws InterpreterException { if (functions.containsKey(symbol)) { return functions.get(symbol).evaluate(params); } diff --git a/main/core/runtime/State.java b/main/core/runtime/State.java index 72a268b..d825a3a 100644 --- a/main/core/runtime/State.java +++ b/main/core/runtime/State.java @@ -1,6 +1,7 @@ package com.jantuomi.interpreter.main.core.runtime; import com.jantuomi.interpreter.main.core.parser.datatype.DataContainer; +import com.jantuomi.interpreter.main.exception.InterpreterException; import java.util.Arrays; import java.util.List; @@ -23,16 +24,16 @@ public class State { scopes.push(new Scope()); } - private DataContainer resolveSymbol(String symbol) { + private DataContainer resolveSymbol(String symbol) throws InterpreterException { return scopes.peek().resolveSymbol(symbol, Arrays.asList()); } - public DataContainer getSymbolValue(String symbol) { + public DataContainer getSymbolValue(String symbol) throws InterpreterException { DataContainer d = resolveSymbol(symbol); return d; } - public DataContainer getSymbolValue(String symbol, List<DataContainer> parameters) { + public DataContainer getSymbolValue(String symbol, List<DataContainer> parameters) throws InterpreterException { return scopes.peek().resolveSymbol(symbol, parameters); } diff --git a/main/core/tokenizer/Tokenizer.java b/main/core/tokenizer/Tokenizer.java index 30bc86e..78acd1b 100644 --- a/main/core/tokenizer/Tokenizer.java +++ b/main/core/tokenizer/Tokenizer.java @@ -52,7 +52,7 @@ public class Tokenizer { tokenRegexes.put(Token.Type.ClosedParenToken, "^(\\))"); tokenRegexes.put(Token.Type.FunctionDefineToken, "^(func)\\b"); tokenRegexes.put(Token.Type.FunctionBodyToken, "^(as)\\b"); - tokenRegexes.put(Token.Type.EndFunctionDefineToken, "^(end)\\b"); + tokenRegexes.put(Token.Type.EndBlockToken, "^(end)\\b"); tokenRegexes.put(Token.Type.DeclarationToken, "^(decl)\\b"); tokenRegexes.put(Token.Type.IntegerLiteralToken, "^(\\d+)"); tokenRegexes.put(Token.Type.SymbolToken, "^([a-zA-Z]+\\w*)"); diff --git a/main/core/tokenizer/token/Token.java b/main/core/tokenizer/token/Token.java index f058391..9fce412 100644 --- a/main/core/tokenizer/token/Token.java +++ b/main/core/tokenizer/token/Token.java @@ -52,10 +52,11 @@ abstract public class Token { IntegerLiteralToken, WhitespaceToken, NewlineToken, - EndStatementToken, + BranchToken, SymbolToken, - EndFunctionDefineToken, + EndBlockToken, FunctionBodyToken, + BranchBodyToken, NotAToken } @@ -163,10 +164,12 @@ abstract public class Token { return new SubtractionToken(); case FunctionDefineToken: return new FunctionDefineToken(); - case EndFunctionDefineToken: + case EndBlockToken: return new EndFunctionDefineToken(); case FunctionBodyToken: - return new FunctionBodyToken(); + return new BlockBodyToken("as"); + case BranchBodyToken: + return new BlockBodyToken("then"); case DeclarationToken: return new VariableDeclareToken(); case AssignmentToken: @@ -177,6 +180,8 @@ abstract public class Token { return new OpenParenToken(); case ClosedParenToken: return new ClosedParenToken(); + case BranchToken: + return new BranchToken(); default: ExceptionManager.raise(InterpreterException.ExceptionType.IllegalTokenError, line, type.toString() @@ -195,10 +200,11 @@ abstract public class Token { fdai.setVariable(true); fdai.setTerminator(Type.FunctionBodyToken); return fdai; + case BranchBodyToken: case FunctionBodyToken: ArgumentInfo fbai = new ArgumentInfo(); fbai.setVariable(true); - fbai.setTerminator(Type.EndFunctionDefineToken); + fbai.setTerminator(Type.EndBlockToken); return fbai; case OpenParenToken: ArgumentInfo opai = new ArgumentInfo(); @@ -220,6 +226,7 @@ abstract public class Token { case GreaterOrEqualThanToken: case EqualsToken: case NotEqualsToken: + case BranchToken: return new ArgumentInfo(2); case DeclarationToken: return new ArgumentInfo(1); diff --git a/main/core/tokenizer/token/types/FunctionBodyToken.java b/main/core/tokenizer/token/types/BlockBodyToken.java index f71e8a0..444ea1f 100644 --- a/main/core/tokenizer/token/types/FunctionBodyToken.java +++ b/main/core/tokenizer/token/types/BlockBodyToken.java @@ -1,7 +1,7 @@ package com.jantuomi.interpreter.main.core.tokenizer.token.types; import com.jantuomi.interpreter.main.core.parser.ast.ASTNode; -import com.jantuomi.interpreter.main.core.parser.ast.FunctionBodyNode; +import com.jantuomi.interpreter.main.core.parser.ast.BlockBodyNode; import com.jantuomi.interpreter.main.core.tokenizer.token.Token; import com.jantuomi.interpreter.main.exception.InterpreterException; @@ -11,14 +11,14 @@ import java.util.List; /** * Created by jan on 16.6.2016. */ -public class FunctionBodyToken extends VarargOperatorToken { - public FunctionBodyToken() { - super(Type.FunctionBodyToken, "as"); +public class BlockBodyToken extends VarargOperatorToken { + public BlockBodyToken(String keyword) { + super(Type.FunctionBodyToken, keyword); } @Override public ASTNode generateNode() throws InterpreterException { - FunctionBodyNode node = new FunctionBodyNode(this); + BlockBodyNode node = new BlockBodyNode(this); List<ASTNode> statements = new ArrayList<>(); for (int i = 0; i < args.size() - 1; i++) { Token arg = args.get(i); diff --git a/main/core/tokenizer/token/types/BranchToken.java b/main/core/tokenizer/token/types/BranchToken.java new file mode 100644 index 0000000..84aeabb --- /dev/null +++ b/main/core/tokenizer/token/types/BranchToken.java @@ -0,0 +1,43 @@ +package com.jantuomi.interpreter.main.core.tokenizer.token.types; + +import com.jantuomi.interpreter.main.core.parser.ast.ASTNode; +import com.jantuomi.interpreter.main.core.parser.ast.BlockBodyNode; +import com.jantuomi.interpreter.main.core.parser.ast.BranchNode; +import com.jantuomi.interpreter.main.core.tokenizer.token.Token; +import com.jantuomi.interpreter.main.exception.InterpreterException; + +import java.util.Arrays; +import java.util.List; + +/** + * Created by jan on 21.6.2016. + */ +public class BranchToken extends Token { + + private Token expression; + private BlockBodyToken branch; + + public BranchToken() { + super(Type.BranchToken, "if"); + } + + @Override + public ASTNode generateNode() throws InterpreterException { + return new BranchNode(this, + expression.generateNode(), + (BlockBodyNode) branch.generateNode() + ); + } + + @Override + public Token setArguments(List<Token> args) { + expression = args.get(0); + branch = (BlockBodyToken) args.get(1); + return this; + } + + @Override + public List<Token> getChildren() { + return Arrays.asList(expression, branch); + } +} diff --git a/main/core/tokenizer/token/types/EndFunctionDefineToken.java b/main/core/tokenizer/token/types/EndFunctionDefineToken.java index ffd33c5..14b21f8 100644 --- a/main/core/tokenizer/token/types/EndFunctionDefineToken.java +++ b/main/core/tokenizer/token/types/EndFunctionDefineToken.java @@ -11,7 +11,7 @@ import java.util.List; */ public class EndFunctionDefineToken extends Token { public EndFunctionDefineToken() { - super(Type.EndFunctionDefineToken, "end"); + super(Type.EndBlockToken, "end"); } @Override diff --git a/main/core/tokenizer/token/types/FunctionDefineToken.java b/main/core/tokenizer/token/types/FunctionDefineToken.java index 116d3db..7d715a9 100644 --- a/main/core/tokenizer/token/types/FunctionDefineToken.java +++ b/main/core/tokenizer/token/types/FunctionDefineToken.java @@ -1,7 +1,7 @@ package com.jantuomi.interpreter.main.core.tokenizer.token.types; import com.jantuomi.interpreter.main.core.parser.ast.ASTNode; -import com.jantuomi.interpreter.main.core.parser.ast.FunctionBodyNode; +import com.jantuomi.interpreter.main.core.parser.ast.BlockBodyNode; import com.jantuomi.interpreter.main.core.parser.ast.FunctionDefineNode; import com.jantuomi.interpreter.main.exception.InterpreterException; @@ -27,7 +27,7 @@ public class FunctionDefineToken extends VarargOperatorToken { } node.setArgs(funcArgs); - FunctionBodyNode bodyNode = (FunctionBodyNode) args.get(args.size() - 1).generateNode(); + BlockBodyNode bodyNode = (BlockBodyNode) args.get(args.size() - 1).generateNode(); node.setBody(bodyNode); return node; } |
