diff --git a/src/main/java/dev/tenfont/cpmm/elements/statements/FunctionDeclarationStatement.java b/src/main/java/dev/tenfont/cpmm/elements/statements/FunctionDeclarationStatement.java index ff40191..77cde9d 100644 --- a/src/main/java/dev/tenfont/cpmm/elements/statements/FunctionDeclarationStatement.java +++ b/src/main/java/dev/tenfont/cpmm/elements/statements/FunctionDeclarationStatement.java @@ -5,16 +5,21 @@ import dev.tenfont.cpmm.lang.components.Context; import dev.tenfont.cpmm.lang.components.Statement; import dev.tenfont.cpmm.lang.components.TokenType; +import lombok.RequiredArgsConstructor; +@RequiredArgsConstructor public class FunctionDeclarationStatement extends Statement { + private final BlockStatement body; + private String identifier; + @Override public void execute(Interpreter interpreter) { - System.out.println("Function declaration statement executing test."); } @Override public boolean init(Parser parser, Context context) { parser.eat(TokenType.FUNCTION); + identifier = parser.eat(TokenType.IDENTIFIER, String.class); return true; } } diff --git a/src/main/java/dev/tenfont/cpmm/elements/statements/IfStatement.java b/src/main/java/dev/tenfont/cpmm/elements/statements/IfStatement.java index f548bc5..e90fea6 100644 --- a/src/main/java/dev/tenfont/cpmm/elements/statements/IfStatement.java +++ b/src/main/java/dev/tenfont/cpmm/elements/statements/IfStatement.java @@ -6,19 +6,17 @@ import dev.tenfont.cpmm.lang.components.Expression; import dev.tenfont.cpmm.lang.components.Statement; import dev.tenfont.cpmm.lang.components.TokenType; +import lombok.RequiredArgsConstructor; +@RequiredArgsConstructor public class IfStatement extends Statement { - private final BlockStatement blockStatement; + private final BlockStatement body; private Expression test; - public IfStatement(BlockStatement blockStatement) { - this.blockStatement = blockStatement; - } - @Override public void execute(Interpreter interpreter) { var value = test.get(interpreter.getCurrentContext()); - if (value != null && (boolean) value) blockStatement.execute(interpreter); + if (value != null && (boolean) value) body.execute(interpreter); } @Override diff --git a/src/main/java/dev/tenfont/cpmm/lang/FunctionRegistry.java b/src/main/java/dev/tenfont/cpmm/lang/FunctionRegistry.java new file mode 100644 index 0000000..24024e1 --- /dev/null +++ b/src/main/java/dev/tenfont/cpmm/lang/FunctionRegistry.java @@ -0,0 +1,21 @@ +package dev.tenfont.cpmm.lang; + +import dev.tenfont.cpmm.lang.components.Function; + +import java.util.HashMap; +import java.util.Map; + +public class FunctionRegistry { + private final Map map = new HashMap<>(); + + public boolean declareFunction(String name, Function function) { + if (map.containsKey(name)) + return false; + map.put(name, function); + return true; + } + + public boolean functionExists(String name) { + return map.containsKey(name); + } +} diff --git a/src/main/java/dev/tenfont/cpmm/lang/Parser.java b/src/main/java/dev/tenfont/cpmm/lang/Parser.java index 2c8e209..0963254 100644 --- a/src/main/java/dev/tenfont/cpmm/lang/Parser.java +++ b/src/main/java/dev/tenfont/cpmm/lang/Parser.java @@ -58,7 +58,6 @@ public Statement parseStatement(Context context) { return this.parseBlockStatement(context); } case REVERSE -> statement = new ReverseStatement(); - case FUNCTION -> statement = new FunctionDeclarationStatement(); case VARIABLE_DECLARATION -> statement = new VariableDeclarationStatement(); default -> statement = new ExpressionStatement(); } @@ -123,6 +122,9 @@ public Statement parseBlockStatement(Context context) { statement = new IfStatement(block); statement.init(this, context); eat(TokenType.END_STATEMENT); + } case FUNCTION -> { + statement.init(this, context); + eat(TokenType.END_STATEMENT); } } } diff --git a/src/main/java/dev/tenfont/cpmm/lang/components/Context.java b/src/main/java/dev/tenfont/cpmm/lang/components/Context.java index 79fc2bf..594de8b 100644 --- a/src/main/java/dev/tenfont/cpmm/lang/components/Context.java +++ b/src/main/java/dev/tenfont/cpmm/lang/components/Context.java @@ -1,5 +1,6 @@ package dev.tenfont.cpmm.lang.components; +import dev.tenfont.cpmm.lang.FunctionRegistry; import dev.tenfont.cpmm.lang.VariableMap; import lombok.AccessLevel; import lombok.Getter; @@ -11,9 +12,10 @@ @RequiredArgsConstructor(access = AccessLevel.PRIVATE) @Getter public class Context { - // TODO include optional script object, variable map and function registry + // TODO include optional script object private final @Nullable Context parentContext; private final VariableMap variableMap; + private final FunctionRegistry functionRegistry; public Context() { this(new VariableMap()); @@ -21,11 +23,12 @@ public Context() { public Context(VariableMap variableMap) { this.parentContext = null; + this.functionRegistry = new FunctionRegistry(); this.variableMap = variableMap; } public Context enterScope() { - return new Context(this, new VariableMap(variableMap)); + return new Context(this, new VariableMap(variableMap), functionRegistry); } public Context exitScope() { diff --git a/src/main/java/dev/tenfont/cpmm/lang/components/Function.java b/src/main/java/dev/tenfont/cpmm/lang/components/Function.java new file mode 100644 index 0000000..4456891 --- /dev/null +++ b/src/main/java/dev/tenfont/cpmm/lang/components/Function.java @@ -0,0 +1,5 @@ +package dev.tenfont.cpmm.lang.components; + +public interface Function { + void execute(Object[] arguments); +} diff --git a/src/main/java/dev/tenfont/cpmm/lang/components/ScriptFunction.java b/src/main/java/dev/tenfont/cpmm/lang/components/ScriptFunction.java new file mode 100644 index 0000000..38f2c1d --- /dev/null +++ b/src/main/java/dev/tenfont/cpmm/lang/components/ScriptFunction.java @@ -0,0 +1,16 @@ +package dev.tenfont.cpmm.lang.components; + +import dev.tenfont.cpmm.lang.Interpreter; +import lombok.RequiredArgsConstructor; + +import java.util.LinkedList; + +@RequiredArgsConstructor +public class ScriptFunction implements Function { + private final LinkedList statements; + + @Override + public void execute(Object[] arguments) { + new Interpreter(statements).execute(); + } +}