diff options
| author | jantuomi <jans.tuomi@gmail.com> | 2016-08-29 14:25:24 +0300 |
|---|---|---|
| committer | jantuomi <jans.tuomi@gmail.com> | 2016-08-29 14:25:24 +0300 |
| commit | 5ccfb2931c9ed97798857e97d521ce31ad104c65 (patch) | |
| tree | 1e5e2d5a8a9fdbb69c28ff96c10d77aa34159ec8 /src | |
| parent | b4469f872286f8563ec805ef32798bb9608c29e4 (diff) | |
Implement object definition with 'obj' keyword
Diffstat (limited to 'src')
16 files changed, 171 insertions, 33 deletions
diff --git a/src/main/com/jantuomi/tunkki/core/parser/Parser.java b/src/main/com/jantuomi/tunkki/core/parser/Parser.java index 9cb183f..ebd8eac 100644 --- a/src/main/com/jantuomi/tunkki/core/parser/Parser.java +++ b/src/main/com/jantuomi/tunkki/core/parser/Parser.java @@ -17,30 +17,22 @@ import java.util.Stack; public class Parser { private static final Parser instance = new Parser(); - private List<Token> tokens; - private List<ASTNode> statementSequence; - public static Parser getInstance() { return instance; } - private Parser() { - - } + private Parser() {} private Stack<Token> stack; public List<Token> parse(List<Token> tokens) throws TunkkiError { - this.tokens = tokens; this.stack = new Stack<>(); List<Token> args; List<Token> output = new ArrayList<>(); for (Token t : tokens) { + /* Skip newline tokens */ if (t.getTokenType() == Token.Type.NewlineToken) { -// if (stack.size() > 0) { -// output.add(stack.pop()); -// } continue; } @@ -88,6 +80,7 @@ public class Parser { stack.push(result); } + /* When the token list is empty, pop all remaining tokens from the stack */ while (stack.size() > 0) { output.add(stack.pop()); } diff --git a/src/main/com/jantuomi/tunkki/core/parser/ast/AssignmentNode.java b/src/main/com/jantuomi/tunkki/core/parser/ast/AssignmentNode.java index 38bb269..95ab77c 100644 --- a/src/main/com/jantuomi/tunkki/core/parser/ast/AssignmentNode.java +++ b/src/main/com/jantuomi/tunkki/core/parser/ast/AssignmentNode.java @@ -20,7 +20,7 @@ public class AssignmentNode extends BinaryOperatorNode { public Datatype evaluate() throws TunkkiError { SymbolNode symbol = (SymbolNode) lhs; Datatype rValue = rhs.evaluate(); - State.getInstance().setSymbolValueToScope( + State.getGlobalState().setSymbolValueToScope( symbol.getName(), rValue ); diff --git a/src/main/com/jantuomi/tunkki/core/parser/ast/DeclareAssignNode.java b/src/main/com/jantuomi/tunkki/core/parser/ast/DeclareAssignNode.java index 206bbd9..1d2d31a 100644 --- a/src/main/com/jantuomi/tunkki/core/parser/ast/DeclareAssignNode.java +++ b/src/main/com/jantuomi/tunkki/core/parser/ast/DeclareAssignNode.java @@ -27,10 +27,10 @@ public class DeclareAssignNode extends BinaryOperatorNode { throw new ExpectedDifferentTokenTunkkiError(getLine(), getText()); } - State.getInstance().addSymbolToScope(var.getName()); + State.getGlobalState().addSymbolToScope(var.getName()); Datatype rValue = rhs.evaluate(); - State.getInstance().setSymbolValueToScope( + State.getGlobalState().setSymbolValueToScope( var.getName(), rValue ); diff --git a/src/main/com/jantuomi/tunkki/core/parser/ast/NullaryOperatorNode.java b/src/main/com/jantuomi/tunkki/core/parser/ast/NullaryOperatorNode.java new file mode 100644 index 0000000..d2d25b9 --- /dev/null +++ b/src/main/com/jantuomi/tunkki/core/parser/ast/NullaryOperatorNode.java @@ -0,0 +1,22 @@ +package com.jantuomi.tunkki.core.parser.ast; + +import com.jantuomi.tunkki.core.parser.datatype.Datatype; +import com.jantuomi.tunkki.core.parser.tokenizer.token.Token; +import com.jantuomi.tunkki.exception.types.TunkkiError; + +import java.util.Collections; +import java.util.List; + +/** + * Created by jan on 8.8.2016. + */ +abstract public class NullaryOperatorNode extends ASTNode { + public NullaryOperatorNode(Token token) { + super(token); + } + + @Override + List<ASTNode> getChildren() { + return Collections.emptyList(); + } +} diff --git a/src/main/com/jantuomi/tunkki/core/parser/ast/ObjectDefinitionNode.java b/src/main/com/jantuomi/tunkki/core/parser/ast/ObjectDefinitionNode.java new file mode 100644 index 0000000..2a9a19d --- /dev/null +++ b/src/main/com/jantuomi/tunkki/core/parser/ast/ObjectDefinitionNode.java @@ -0,0 +1,42 @@ +package com.jantuomi.tunkki.core.parser.ast; + +import com.jantuomi.tunkki.core.parser.datatype.CallableDatatype; +import com.jantuomi.tunkki.core.parser.datatype.Datatype; +import com.jantuomi.tunkki.core.parser.datatype.ObjectDatatype; +import com.jantuomi.tunkki.core.parser.tokenizer.token.Token; +import com.jantuomi.tunkki.core.runtime.Function; +import com.jantuomi.tunkki.core.runtime.State; +import com.jantuomi.tunkki.exception.types.TunkkiError; + +import java.util.Collections; + +/** + * Created by jan on 8.8.2016. + */ +public class ObjectDefinitionNode extends NullaryOperatorNode { + public ObjectDefinitionNode(Token token, String name, CallableDatatype constructor) { + super(token); + this.name = name; + this.constructor = constructor; + } + + private String name; + private CallableDatatype constructor; + + public void setName(String name) { + this.name = name; + } + + @Override + public Datatype evaluate() throws TunkkiError { + ObjectDatatype obj = new ObjectDatatype(); + + State state = new State(); + constructor.call(Collections.emptyList()); + Function func = constructor.getData(); + func.setState(state); + + obj.setData(func.getState().getGlobalScope()); + return obj; + } +} diff --git a/src/main/com/jantuomi/tunkki/core/parser/ast/ObjectMemberNode.java b/src/main/com/jantuomi/tunkki/core/parser/ast/ObjectMemberNode.java index c2eb637..c982db2 100644 --- a/src/main/com/jantuomi/tunkki/core/parser/ast/ObjectMemberNode.java +++ b/src/main/com/jantuomi/tunkki/core/parser/ast/ObjectMemberNode.java @@ -21,7 +21,7 @@ public class ObjectMemberNode extends UnaryOperatorNode { public Datatype evaluate() throws TunkkiError { Datatype d; try { - d = State.getInstance().resolveSymbol(getText()); + d = State.getGlobalState().resolveSymbol(getText()); } catch (TunkkiError ex) { ex.setLine(getLine()); throw ex; diff --git a/src/main/com/jantuomi/tunkki/core/parser/ast/SymbolNode.java b/src/main/com/jantuomi/tunkki/core/parser/ast/SymbolNode.java index 7fb5e64..21d37f5 100644 --- a/src/main/com/jantuomi/tunkki/core/parser/ast/SymbolNode.java +++ b/src/main/com/jantuomi/tunkki/core/parser/ast/SymbolNode.java @@ -44,7 +44,7 @@ public class SymbolNode extends ASTNode { Datatype returnValue; try { - returnValue = State.getInstance().resolveSymbol(name); + returnValue = State.getGlobalState().resolveSymbol(name); } /* If a TunkkiError is caught, pass it on with line information */ diff --git a/src/main/com/jantuomi/tunkki/core/parser/ast/VariableDeclareNode.java b/src/main/com/jantuomi/tunkki/core/parser/ast/VariableDeclareNode.java index b53438a..38590f0 100644 --- a/src/main/com/jantuomi/tunkki/core/parser/ast/VariableDeclareNode.java +++ b/src/main/com/jantuomi/tunkki/core/parser/ast/VariableDeclareNode.java @@ -21,7 +21,7 @@ public class VariableDeclareNode extends ASTNode { @Override public Datatype evaluate() { - State.getInstance().addSymbolToScope(variable.getName()); + State.getGlobalState().addSymbolToScope(variable.getName()); return new StringDatatype(variable.getName()); } diff --git a/src/main/com/jantuomi/tunkki/core/parser/tokenizer/Tokenizer.java b/src/main/com/jantuomi/tunkki/core/parser/tokenizer/Tokenizer.java index 2449e0a..9515abf 100644 --- a/src/main/com/jantuomi/tunkki/core/parser/tokenizer/Tokenizer.java +++ b/src/main/com/jantuomi/tunkki/core/parser/tokenizer/Tokenizer.java @@ -61,6 +61,7 @@ public class Tokenizer { tokenRegexes.put(Token.Type.NegationToken, "^(not)\\b"); tokenRegexes.put(Token.Type.DeclarationToken, "^(decl)\\b"); + tokenRegexes.put(Token.Type.ObjectDefinitionToken, "^(obj)\\b"); tokenRegexes.put(Token.Type.CallToken, "^([a-öA-Ö]+\\w*)\\?[\\s|\\!]"); tokenRegexes.put(Token.Type.ObjectMemberToken, "^([a-öA-Ö]+)\\:"); tokenRegexes.put(Token.Type.SymbolToken, "^([a-öA-Ö]+\\w*)\\b"); diff --git a/src/main/com/jantuomi/tunkki/core/parser/tokenizer/token/Token.java b/src/main/com/jantuomi/tunkki/core/parser/tokenizer/token/Token.java index d53ea68..21ccbaf 100644 --- a/src/main/com/jantuomi/tunkki/core/parser/tokenizer/token/Token.java +++ b/src/main/com/jantuomi/tunkki/core/parser/tokenizer/token/Token.java @@ -70,6 +70,7 @@ abstract public class Token { DeclareAssignToken, ObjectMemberToken, + ObjectDefinitionToken, NotAToken } diff --git a/src/main/com/jantuomi/tunkki/core/parser/tokenizer/token/TokenFactory.java b/src/main/com/jantuomi/tunkki/core/parser/tokenizer/token/TokenFactory.java index 588af63..326958d 100644 --- a/src/main/com/jantuomi/tunkki/core/parser/tokenizer/token/TokenFactory.java +++ b/src/main/com/jantuomi/tunkki/core/parser/tokenizer/token/TokenFactory.java @@ -56,6 +56,8 @@ public class TokenFactory { return new SymbolToken(text); case CallToken: return new CallToken(text, rawText); + case ObjectDefinitionToken: + return new ObjectDefinitionToken(); case BlockEndToken: return new BlockEndToken(); case ObjectMemberToken: diff --git a/src/main/com/jantuomi/tunkki/core/parser/tokenizer/token/types/ObjectDefinitionToken.java b/src/main/com/jantuomi/tunkki/core/parser/tokenizer/token/types/ObjectDefinitionToken.java new file mode 100644 index 0000000..8215c26 --- /dev/null +++ b/src/main/com/jantuomi/tunkki/core/parser/tokenizer/token/types/ObjectDefinitionToken.java @@ -0,0 +1,56 @@ +package com.jantuomi.tunkki.core.parser.tokenizer.token.types; + +import com.jantuomi.tunkki.core.parser.ast.ASTNode; +import com.jantuomi.tunkki.core.parser.ast.FunctionDefineNode; +import com.jantuomi.tunkki.core.parser.ast.ObjectDefinitionNode; +import com.jantuomi.tunkki.core.parser.ast.SymbolNode; +import com.jantuomi.tunkki.core.parser.datatype.CallableDatatype; +import com.jantuomi.tunkki.core.parser.tokenizer.token.Token; +import com.jantuomi.tunkki.exception.types.ExpectedDifferentTokenTunkkiError; +import com.jantuomi.tunkki.exception.types.TunkkiError; + +/** + * Created by jan on 8.8.2016. + */ +public class ObjectDefinitionToken extends VarargOperatorToken { + public ObjectDefinitionToken() { + super(Type.ObjectDefinitionToken, "obj"); + } + + @Override + public ASTNode generateNode() throws TunkkiError { + if (args.size() < 2 || args.size() > 3) { + throw new ExpectedDifferentTokenTunkkiError(getLine(), getText()); + } + + Token arg1 = args.get(0); + if (!(arg1 instanceof SymbolToken)) { + throw new ExpectedDifferentTokenTunkkiError(getLine(), getText()); + } + + Token funcArg; + if (args.size() == 2) { + funcArg = args.get(1); + } else { + funcArg = args.get(2); + } + + if (!(funcArg instanceof FunctionDefineToken)) { + throw new ExpectedDifferentTokenTunkkiError(getLine(), getText()); + } + + SymbolNode symbol = (SymbolNode) arg1.generateNode(); + String name = symbol.getName(); + + FunctionDefineNode constructor = (FunctionDefineNode) funcArg.generateNode(); + CallableDatatype constructorCallable = (CallableDatatype) constructor.evaluate(); + ObjectDefinitionNode node = new ObjectDefinitionNode(this, name, constructorCallable); + node.setName(name); + return node; + } + + @Override + public Type getTerminatorTokenType() { + return Type.FunctionDefineToken; + } +} diff --git a/src/main/com/jantuomi/tunkki/core/runtime/Function.java b/src/main/com/jantuomi/tunkki/core/runtime/Function.java index b6eab89..2c60bd0 100644 --- a/src/main/com/jantuomi/tunkki/core/runtime/Function.java +++ b/src/main/com/jantuomi/tunkki/core/runtime/Function.java @@ -15,13 +15,27 @@ abstract public class Function { protected List<String> argumentNames; protected BlockBodyNode body; + private State state = null; + + public void setState(State state) { + this.state = state; + } + + public State getState() { + if (this.state != null) { + return this.state; + } else { + return State.getGlobalState(); + } + } + public Function(List<String> argumentNames, BlockBodyNode body) { this.argumentNames = argumentNames; this.body = body; } public Datatype evaluate(List<Datatype> params) throws TunkkiError { - State.getInstance().createScope(); + Scope scope = getState().createScope(); if (!checkArgumentListValidity(params)) { throw new FunctionArgumentTunkkiError(-1, Datatype.toString(params)); diff --git a/src/main/com/jantuomi/tunkki/core/runtime/State.java b/src/main/com/jantuomi/tunkki/core/runtime/State.java index 2cbd94a..3bf214c 100644 --- a/src/main/com/jantuomi/tunkki/core/runtime/State.java +++ b/src/main/com/jantuomi/tunkki/core/runtime/State.java @@ -6,8 +6,6 @@ import com.jantuomi.tunkki.core.parser.datatype.NadaDatatype; import com.jantuomi.tunkki.core.runtime.builtins.BuiltinManager; import com.jantuomi.tunkki.exception.types.TunkkiError; -import java.util.Arrays; -import java.util.List; import java.util.Map; import java.util.Stack; @@ -15,15 +13,24 @@ import java.util.Stack; * Created by jan on 11.6.2016. */ public class State { - private static final State instance = new State(); + private static final State globalState = new State(); - public static State getInstance() { - return instance; + public static State getGlobalState() { + return globalState; } private Stack<Scope> scopes = new Stack<>(); - private State() { + static { + globalState.replaceBaseScopeWithGlobal(); + } + + public State() { + Scope baseScope = new Scope(); + scopes.push(baseScope); + } + + public void replaceBaseScopeWithGlobal() { /* Push global scope onto the stack */ Scope globalScope = new Scope(); @@ -37,7 +44,7 @@ public class State { globalScope.addVariable("nada"); globalScope.setVariableValue("nada", new NadaDatatype()); - scopes.push(globalScope); + scopes.set(0, globalScope); } public Datatype resolveSymbol(String symbol) throws TunkkiError { @@ -55,6 +62,10 @@ public class State { return scope; } + public Scope getGlobalScope() { + return scopes.get(0); + } + public void addSymbolToScope(String symbol) { scopes.peek().addVariable(symbol); } diff --git a/src/main/com/jantuomi/tunkki/core/runtime/UserDefinedFunction.java b/src/main/com/jantuomi/tunkki/core/runtime/UserDefinedFunction.java index 2e994a8..c094d91 100644 --- a/src/main/com/jantuomi/tunkki/core/runtime/UserDefinedFunction.java +++ b/src/main/com/jantuomi/tunkki/core/runtime/UserDefinedFunction.java @@ -1,9 +1,7 @@ package com.jantuomi.tunkki.core.runtime; import com.jantuomi.tunkki.core.parser.ast.BlockBodyNode; -import com.jantuomi.tunkki.core.parser.datatype.CallableDatatype; import com.jantuomi.tunkki.core.parser.datatype.Datatype; -import com.jantuomi.tunkki.exception.types.FunctionArgumentTunkkiError; import com.jantuomi.tunkki.exception.types.TunkkiError; import java.util.*; @@ -13,7 +11,6 @@ import java.util.*; */ public class UserDefinedFunction extends Function { - public UserDefinedFunction(List<String> argumentNames, BlockBodyNode body) { super(argumentNames, body); } @@ -24,12 +21,12 @@ public class UserDefinedFunction extends Function { super.evaluate(params); for (int i = 0; i < argumentNames.size(); i++) { - State.getInstance().addSymbolToScope(argumentNames.get(i)); - State.getInstance().setSymbolValueToScope(argumentNames.get(i), params.get(i)); + State.getGlobalState().addSymbolToScope(argumentNames.get(i)); + State.getGlobalState().setSymbolValueToScope(argumentNames.get(i), params.get(i)); } Datatype returnValue = body.evaluate(); - State.getInstance().popScope(); + State.getGlobalState().popScope(); return returnValue; } diff --git a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/IncludeBuiltinFunction.java b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/IncludeBuiltinFunction.java index b3e1a9a..d2c6f31 100644 --- a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/IncludeBuiltinFunction.java +++ b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/IncludeBuiltinFunction.java @@ -6,7 +6,6 @@ import com.jantuomi.tunkki.core.CommandLineArgumentContainer; import com.jantuomi.tunkki.core.parser.datatype.*; import com.jantuomi.tunkki.core.runtime.State; import com.jantuomi.tunkki.core.runtime.builtins.BuiltinManager; -import com.jantuomi.tunkki.exception.ExceptionManager; import com.jantuomi.tunkki.exception.types.*; import java.util.Arrays; @@ -39,8 +38,8 @@ public class IncludeBuiltinFunction extends BuiltinFunction { for (String funcName : funcs.keySet()) { namespace.getData().addAndSetVariable(funcName, funcs.get(funcName)); } - State.getInstance().addSymbolToScope(filename); - State.getInstance().setSymbolValueToScope(filename, namespace); + State.getGlobalState().addSymbolToScope(filename); + State.getGlobalState().setSymbolValueToScope(filename, namespace); } else { |
