aboutsummaryrefslogtreecommitdiffstats
path: root/main/core
diff options
context:
space:
mode:
Diffstat (limited to 'main/core')
-rw-r--r--main/core/parser/ASTGenerator.java3
-rw-r--r--main/core/parser/ast/AssignmentNode.java33
-rw-r--r--main/core/parser/ast/FunctionDefineNode.java17
-rw-r--r--main/core/parser/ast/SymbolNode.java13
-rw-r--r--main/core/parser/ast/VariableDeclareNode.java32
-rw-r--r--main/core/runtime/Function.java41
-rw-r--r--main/core/runtime/Scope.java48
-rw-r--r--main/core/runtime/State.java47
-rw-r--r--main/core/tokenizer/Tokenizer.java2
-rw-r--r--main/core/tokenizer/token/Token.java6
-rw-r--r--main/core/tokenizer/token/types/AdditionToken.java3
-rw-r--r--main/core/tokenizer/token/types/AssignmentToken.java55
-rw-r--r--main/core/tokenizer/token/types/FunctionBodyToken.java3
-rw-r--r--main/core/tokenizer/token/types/FunctionDefineToken.java3
-rw-r--r--main/core/tokenizer/token/types/OpenParenToken.java3
-rw-r--r--main/core/tokenizer/token/types/SubtractionToken.java3
-rw-r--r--main/core/tokenizer/token/types/SymbolToken.java3
-rw-r--r--main/core/tokenizer/token/types/VariableDeclareToken.java42
18 files changed, 333 insertions, 24 deletions
diff --git a/main/core/parser/ASTGenerator.java b/main/core/parser/ASTGenerator.java
index 548735b..3d19a8c 100644
--- a/main/core/parser/ASTGenerator.java
+++ b/main/core/parser/ASTGenerator.java
@@ -2,6 +2,7 @@ package com.jantuomi.interpreter.main.core.parser;
import com.jantuomi.interpreter.main.core.parser.ast.ASTNode;
import com.jantuomi.interpreter.main.core.tokenizer.token.Token;
+import com.jantuomi.interpreter.main.exception.InterpreterException;
import java.util.ArrayList;
import java.util.List;
@@ -18,7 +19,7 @@ public class ASTGenerator {
return instance;
}
- public List<ASTNode> generate(List<Token> trees) {
+ public List<ASTNode> generate(List<Token> trees) throws InterpreterException {
List<ASTNode> list = new ArrayList<>();
for (Token root : trees) {
diff --git a/main/core/parser/ast/AssignmentNode.java b/main/core/parser/ast/AssignmentNode.java
new file mode 100644
index 0000000..bcbff1c
--- /dev/null
+++ b/main/core/parser/ast/AssignmentNode.java
@@ -0,0 +1,33 @@
+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 java.util.Arrays;
+import java.util.List;
+
+/**
+ * Created by jan on 21.6.2016.
+ */
+public class AssignmentNode extends BinaryOperatorNode {
+ public AssignmentNode(Token token, SymbolNode lhs, ASTNode rhs) {
+ super(token, lhs, rhs);
+ }
+
+ @Override
+ public DataContainer evaluate() {
+ SymbolNode symbol = (SymbolNode) lhs;
+ DataContainer rValue = rhs.evaluate();
+ State.getInstance().setSymbolValueToScope(
+ symbol.getName(),
+ rValue
+ );
+ return rValue;
+ }
+
+ @Override
+ List<ASTNode> getChildren() {
+ return Arrays.asList(lhs, rhs);
+ }
+}
diff --git a/main/core/parser/ast/FunctionDefineNode.java b/main/core/parser/ast/FunctionDefineNode.java
index e867f78..2402bed 100644
--- a/main/core/parser/ast/FunctionDefineNode.java
+++ b/main/core/parser/ast/FunctionDefineNode.java
@@ -1,8 +1,14 @@
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.StringDataContainer;
+import com.jantuomi.interpreter.main.core.runtime.Function;
+import com.jantuomi.interpreter.main.core.runtime.State;
import com.jantuomi.interpreter.main.core.tokenizer.token.Token;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* Created by jan on 17.6.2016.
*/
@@ -26,8 +32,15 @@ public class FunctionDefineNode extends VarargOperatorNode {
@Override
public DataContainer evaluate() {
- // TODO add function in State
- return null;
+ List<String> argumentNames = new ArrayList<>();
+ for (ASTNode arg : args) {
+ SymbolNode argSym = (SymbolNode) arg;
+ argumentNames.add(argSym.getName());
+ }
+ Function function = new Function(argumentNames, (FunctionBodyNode) body);
+ State.getInstance().addFunctionToScope(name, function);
+
+ return new StringDataContainer("function " + name);
}
@Override
diff --git a/main/core/parser/ast/SymbolNode.java b/main/core/parser/ast/SymbolNode.java
index 7ea8d96..4dfb403 100644
--- a/main/core/parser/ast/SymbolNode.java
+++ b/main/core/parser/ast/SymbolNode.java
@@ -4,6 +4,7 @@ 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 java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -26,6 +27,10 @@ public class SymbolNode extends ASTNode {
this.name = name;
}
+ public String getName() {
+ return name;
+ }
+
private String name;
public SymbolNode(Token token) {
@@ -34,7 +39,13 @@ public class SymbolNode extends ASTNode {
@Override
public DataContainer evaluate() {
- return State.getInstance().getSymbolValue(name, parameterListNode.getParameters());
+ List<DataContainer> paramValues = new ArrayList<>();
+ if (parameterListNode != null) {
+ for (ASTNode param : parameterListNode.getChildren()) {
+ paramValues.add(param.evaluate());
+ }
+ }
+ return State.getInstance().getSymbolValue(name, paramValues);
}
@Override
diff --git a/main/core/parser/ast/VariableDeclareNode.java b/main/core/parser/ast/VariableDeclareNode.java
new file mode 100644
index 0000000..185edda
--- /dev/null
+++ b/main/core/parser/ast/VariableDeclareNode.java
@@ -0,0 +1,32 @@
+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.StringDataContainer;
+import com.jantuomi.interpreter.main.core.runtime.State;
+import com.jantuomi.interpreter.main.core.tokenizer.token.Token;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Created by jan on 20.6.2016.
+ */
+public class VariableDeclareNode extends ASTNode {
+ private SymbolNode variable;
+
+ public VariableDeclareNode(Token source, SymbolNode variable) {
+ super(source);
+ this.variable = variable;
+ }
+
+ @Override
+ public DataContainer evaluate() {
+ State.getInstance().addSymbolToScope(variable.getName());
+ return new StringDataContainer(variable.getName());
+ }
+
+ @Override
+ List<ASTNode> getChildren() {
+ return Arrays.asList();
+ }
+}
diff --git a/main/core/runtime/Function.java b/main/core/runtime/Function.java
new file mode 100644
index 0000000..cf6422f
--- /dev/null
+++ b/main/core/runtime/Function.java
@@ -0,0 +1,41 @@
+package com.jantuomi.interpreter.main.core.runtime;
+
+import com.jantuomi.interpreter.main.core.parser.ast.FunctionBodyNode;
+import com.jantuomi.interpreter.main.core.parser.datatype.DataContainer;
+
+import java.util.List;
+
+/**
+ * Created by jan on 20.6.2016.
+ */
+public class Function {
+
+ private List<String> argumentNames;
+
+ private FunctionBodyNode body;
+
+ public Function(List<String> argumentNames, FunctionBodyNode body) {
+ this.argumentNames = argumentNames;
+ this.body = body;
+ }
+
+ public DataContainer evaluate(List<DataContainer> params) {
+ State.getInstance().createScope();
+
+ if (params.size() != argumentNames.size()) {
+ return null;
+ }
+
+ for (int i = 0; i < argumentNames.size(); i++) {
+ State.getInstance().addSymbolToScope(argumentNames.get(i));
+ State.getInstance().setSymbolValueToScope(argumentNames.get(i), params.get(i));
+ }
+
+ DataContainer returnValue = body.evaluate();
+
+ State.getInstance().popScope();
+
+ return returnValue;
+ }
+
+}
diff --git a/main/core/runtime/Scope.java b/main/core/runtime/Scope.java
new file mode 100644
index 0000000..a45cdd7
--- /dev/null
+++ b/main/core/runtime/Scope.java
@@ -0,0 +1,48 @@
+package com.jantuomi.interpreter.main.core.runtime;
+
+import com.jantuomi.interpreter.main.core.parser.datatype.DataContainer;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by jan on 20.6.2016.
+ */
+public class Scope {
+ private Scope parent = null;
+
+ private Map<String, DataContainer> variables = new HashMap<>();
+ private Map<String, Function> functions = new HashMap<>();
+
+ public void addVariable(String symbol) {
+ variables.put(symbol, null);
+ }
+
+ public void setVariableValue(String symbol, DataContainer value) {
+ variables.replace(symbol, value);
+ }
+
+ public DataContainer resolveSymbol(String symbol, List<DataContainer> params) {
+ if (functions.containsKey(symbol)) {
+ return functions.get(symbol).evaluate(params);
+ }
+ if (variables.containsKey(symbol)) {
+ return variables.get(symbol);
+ }
+ else if (parent != null) {
+ return parent.resolveSymbol(symbol, params);
+ }
+ else {
+ return null;
+ }
+ }
+
+ public void setParent(Scope parent) {
+ this.parent = parent;
+ }
+
+ public void addFunction(String symbol, Function func) {
+ functions.put(symbol, func);
+ }
+}
diff --git a/main/core/runtime/State.java b/main/core/runtime/State.java
index 7d1a2fa..72a268b 100644
--- a/main/core/runtime/State.java
+++ b/main/core/runtime/State.java
@@ -1,11 +1,10 @@
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 java.util.HashMap;
+import java.util.Arrays;
import java.util.List;
-import java.util.Map;
+import java.util.Stack;
/**
* Created by jan on 11.6.2016.
@@ -17,26 +16,50 @@ public class State {
return instance;
}
- private Map<String, DataContainer> variables = new HashMap<>();
+ private Stack<Scope> scopes = new Stack<>();
private State() {
+ /* Push global scope onto the stack */
+ scopes.push(new Scope());
+ }
+ private DataContainer resolveSymbol(String symbol) {
+ return scopes.peek().resolveSymbol(symbol, Arrays.asList());
}
public DataContainer getSymbolValue(String symbol) {
- if (variables.keySet().contains(symbol)) {
- return variables.get(symbol);
+ DataContainer d = resolveSymbol(symbol);
+ return d;
+ }
+
+ public DataContainer getSymbolValue(String symbol, List<DataContainer> parameters) {
+ return scopes.peek().resolveSymbol(symbol, parameters);
+ }
+
+ public Scope createScope() {
+ Scope scope = new Scope();
+ if (scopes.size() > 0) {
+ scope.setParent(scopes.peek());
} else {
- return null;
+ scope.setParent(null);
}
+ scopes.push(scope);
+ return scope;
+ }
+
+ public void addSymbolToScope(String symbol) {
+ scopes.peek().addVariable(symbol);
+ }
+
+ public void addFunctionToScope(String symbol, Function func) {
+ scopes.peek().addFunction(symbol, func);
}
- public DataContainer getSymbolValue(String symbol, List<ASTNode> parameters) {
- // TODO
- return null;
+ public void setSymbolValueToScope(String symbol, DataContainer value) {
+ scopes.peek().setVariableValue(symbol, value);
}
- public void setSymbolValue(String symbol, DataContainer value) {
- variables.put(symbol, value);
+ public Scope popScope() {
+ return scopes.pop();
}
}
diff --git a/main/core/tokenizer/Tokenizer.java b/main/core/tokenizer/Tokenizer.java
index 9aed09c..30bc86e 100644
--- a/main/core/tokenizer/Tokenizer.java
+++ b/main/core/tokenizer/Tokenizer.java
@@ -41,7 +41,7 @@ public class Tokenizer {
tokenRegexes.put(Token.Type.SubtractionToken, "^(\\-)");
tokenRegexes.put(Token.Type.DivisionToken, "^(\\/)");
tokenRegexes.put(Token.Type.MultiplicationToken, "^(\\*)");
- tokenRegexes.put(Token.Type.AssignmentToken, "^(\\<\\-)");
+ tokenRegexes.put(Token.Type.AssignmentToken, "^(set)\\b");
tokenRegexes.put(Token.Type.LessThanToken, "^(\\<)");
tokenRegexes.put(Token.Type.GreaterThanToken, "^(\\>)");
tokenRegexes.put(Token.Type.LessOrEqualThanToken, "^(\\<\\=)");
diff --git a/main/core/tokenizer/token/Token.java b/main/core/tokenizer/token/Token.java
index 5248799..2582590 100644
--- a/main/core/tokenizer/token/Token.java
+++ b/main/core/tokenizer/token/Token.java
@@ -28,7 +28,7 @@ abstract public class Token {
}
}
- abstract public ASTNode generateNode();
+ abstract public ASTNode generateNode() throws InterpreterException;
/* Token types, ordered by precedence */
public enum Type {
@@ -165,6 +165,10 @@ abstract public class Token {
return new EndFunctionDefineToken();
case FunctionBodyToken:
return new FunctionBodyToken();
+ case DeclarationToken:
+ return new VariableDeclareToken();
+ case AssignmentToken:
+ return new AssignmentToken();
case SymbolToken:
return new SymbolToken(text);
case OpenParenToken:
diff --git a/main/core/tokenizer/token/types/AdditionToken.java b/main/core/tokenizer/token/types/AdditionToken.java
index 2d77b46..4623d73 100644
--- a/main/core/tokenizer/token/types/AdditionToken.java
+++ b/main/core/tokenizer/token/types/AdditionToken.java
@@ -2,6 +2,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.AdditionNode;
+import com.jantuomi.interpreter.main.exception.InterpreterException;
/**
* Created by jan on 15.6.2016.
@@ -12,7 +13,7 @@ public class AdditionToken extends BinaryOperatorToken {
}
@Override
- public ASTNode generateNode() {
+ public ASTNode generateNode() throws InterpreterException {
return new AdditionNode(this,
lhs.generateNode(),
rhs.generateNode()
diff --git a/main/core/tokenizer/token/types/AssignmentToken.java b/main/core/tokenizer/token/types/AssignmentToken.java
new file mode 100644
index 0000000..57f404c
--- /dev/null
+++ b/main/core/tokenizer/token/types/AssignmentToken.java
@@ -0,0 +1,55 @@
+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.AssignmentNode;
+import com.jantuomi.interpreter.main.core.parser.ast.SymbolNode;
+import com.jantuomi.interpreter.main.core.tokenizer.token.Token;
+import com.jantuomi.interpreter.main.exception.ExceptionManager;
+import com.jantuomi.interpreter.main.exception.InterpreterException;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Created by jan on 20.6.2016.
+ */
+public class AssignmentToken extends Token {
+
+ private Token lhs;
+ private Token rhs;
+
+ public AssignmentToken() {
+ super(Type.AssignmentToken, "set");
+ }
+
+ // TODO this and the node
+
+ @Override
+ public ASTNode generateNode() throws InterpreterException {
+ ASTNode lhsNode = lhs.generateNode();
+
+ if (!(lhsNode instanceof SymbolNode)) {
+ ExceptionManager.raise(InterpreterException.ExceptionType.SyntaxError, getLine(), "non-symbol " + toString());
+ return null;
+ }
+
+ AssignmentNode node = new AssignmentNode(this,
+ (SymbolNode) lhsNode,
+ rhs.generateNode()
+ );
+
+ return node;
+ }
+
+ @Override
+ public Token setArguments(List<Token> args) {
+ this.lhs = args.get(0);
+ this.rhs = args.get(1);
+ return this;
+ }
+
+ @Override
+ public List<Token> getChildren() {
+ return Arrays.asList(lhs, rhs);
+ }
+}
diff --git a/main/core/tokenizer/token/types/FunctionBodyToken.java b/main/core/tokenizer/token/types/FunctionBodyToken.java
index 647ed55..f71e8a0 100644
--- a/main/core/tokenizer/token/types/FunctionBodyToken.java
+++ b/main/core/tokenizer/token/types/FunctionBodyToken.java
@@ -3,6 +3,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.tokenizer.token.Token;
+import com.jantuomi.interpreter.main.exception.InterpreterException;
import java.util.ArrayList;
import java.util.List;
@@ -16,7 +17,7 @@ public class FunctionBodyToken extends VarargOperatorToken {
}
@Override
- public ASTNode generateNode() {
+ public ASTNode generateNode() throws InterpreterException {
FunctionBodyNode node = new FunctionBodyNode(this);
List<ASTNode> statements = new ArrayList<>();
for (int i = 0; i < args.size() - 1; i++) {
diff --git a/main/core/tokenizer/token/types/FunctionDefineToken.java b/main/core/tokenizer/token/types/FunctionDefineToken.java
index 6bbfd84..116d3db 100644
--- a/main/core/tokenizer/token/types/FunctionDefineToken.java
+++ b/main/core/tokenizer/token/types/FunctionDefineToken.java
@@ -3,6 +3,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.FunctionDefineNode;
+import com.jantuomi.interpreter.main.exception.InterpreterException;
import java.util.ArrayList;
import java.util.List;
@@ -16,7 +17,7 @@ public class FunctionDefineToken extends VarargOperatorToken {
}
@Override
- public ASTNode generateNode() {
+ public ASTNode generateNode() throws InterpreterException {
FunctionDefineNode node = new FunctionDefineNode(this);
node.setName(args.get(0).getText());
diff --git a/main/core/tokenizer/token/types/OpenParenToken.java b/main/core/tokenizer/token/types/OpenParenToken.java
index 07385c9..80b507c 100644
--- a/main/core/tokenizer/token/types/OpenParenToken.java
+++ b/main/core/tokenizer/token/types/OpenParenToken.java
@@ -3,6 +3,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.ParameterListNode;
import com.jantuomi.interpreter.main.core.tokenizer.token.Token;
+import com.jantuomi.interpreter.main.exception.InterpreterException;
/**
* Created by jan on 19.6.2016.
@@ -13,7 +14,7 @@ public class OpenParenToken extends VarargOperatorToken {
}
@Override
- public ASTNode generateNode() {
+ public ASTNode generateNode() throws InterpreterException {
ParameterListNode node = new ParameterListNode(this);
for (Token token : args) {
diff --git a/main/core/tokenizer/token/types/SubtractionToken.java b/main/core/tokenizer/token/types/SubtractionToken.java
index a1b9a83..9f7ff10 100644
--- a/main/core/tokenizer/token/types/SubtractionToken.java
+++ b/main/core/tokenizer/token/types/SubtractionToken.java
@@ -2,6 +2,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.SubtractionNode;
+import com.jantuomi.interpreter.main.exception.InterpreterException;
/**
* Created by jan on 16.6.2016.
@@ -12,7 +13,7 @@ public class SubtractionToken extends BinaryOperatorToken {
}
@Override
- public ASTNode generateNode() {
+ public ASTNode generateNode() throws InterpreterException {
return new SubtractionNode(this,
lhs.generateNode(),
rhs.generateNode()
diff --git a/main/core/tokenizer/token/types/SymbolToken.java b/main/core/tokenizer/token/types/SymbolToken.java
index b091ac9..d750921 100644
--- a/main/core/tokenizer/token/types/SymbolToken.java
+++ b/main/core/tokenizer/token/types/SymbolToken.java
@@ -4,6 +4,7 @@ import com.jantuomi.interpreter.main.core.parser.ast.ASTNode;
import com.jantuomi.interpreter.main.core.parser.ast.ParameterListNode;
import com.jantuomi.interpreter.main.core.parser.ast.SymbolNode;
import com.jantuomi.interpreter.main.core.tokenizer.token.Token;
+import com.jantuomi.interpreter.main.exception.InterpreterException;
import java.util.Arrays;
import java.util.List;
@@ -24,7 +25,7 @@ public class SymbolToken extends Token {
}
@Override
- public ASTNode generateNode() {
+ public ASTNode generateNode() throws InterpreterException {
SymbolNode node = new SymbolNode(this);
node.setName(this.getText());
if (callArgumentList != null) {
diff --git a/main/core/tokenizer/token/types/VariableDeclareToken.java b/main/core/tokenizer/token/types/VariableDeclareToken.java
new file mode 100644
index 0000000..1ec0826
--- /dev/null
+++ b/main/core/tokenizer/token/types/VariableDeclareToken.java
@@ -0,0 +1,42 @@
+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.SymbolNode;
+import com.jantuomi.interpreter.main.core.parser.ast.VariableDeclareNode;
+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 20.6.2016.
+ */
+public class VariableDeclareToken extends Token {
+
+ private SymbolToken variable;
+
+ public VariableDeclareToken() {
+ super(Type.DeclarationToken, "decl");
+ }
+
+ @Override
+ public ASTNode generateNode() throws InterpreterException {
+ VariableDeclareNode node = new VariableDeclareNode(this,
+ (SymbolNode) variable.generateNode());
+ return node;
+ }
+
+ @Override
+ public Token setArguments(List<Token> args) {
+ if (args.size() > 0) {
+ this.variable = (SymbolToken) args.get(0);
+ }
+ return this;
+ }
+
+ @Override
+ public List<Token> getChildren() {
+ return Arrays.asList(variable);
+ }
+}