From 45a2b88d584fc8bdee1fbaf0def1d9b55ba26eff Mon Sep 17 00:00:00 2001 From: Jan Tuomi Date: Tue, 21 Jun 2016 20:07:32 +0300 Subject: Added scopes, variables and functions --- main/core/runtime/Function.java | 41 +++++++++++++++++++++++++++++++++++ main/core/runtime/Scope.java | 48 +++++++++++++++++++++++++++++++++++++++++ main/core/runtime/State.java | 47 +++++++++++++++++++++++++++++----------- 3 files changed, 124 insertions(+), 12 deletions(-) create mode 100644 main/core/runtime/Function.java create mode 100644 main/core/runtime/Scope.java (limited to 'main/core/runtime') 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 argumentNames; + + private FunctionBodyNode body; + + public Function(List argumentNames, FunctionBodyNode body) { + this.argumentNames = argumentNames; + this.body = body; + } + + public DataContainer evaluate(List 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 variables = new HashMap<>(); + private Map 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 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 variables = new HashMap<>(); + private Stack 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 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 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(); } } -- cgit v1.3