From 2333c88ff290adaa3aabd0582e420b1ef6ec9efb Mon Sep 17 00:00:00 2001 From: jantuomi Date: Fri, 5 Aug 2016 15:36:51 +0300 Subject: Major overhaul of function type checking, allow static and dynamic as well as variadic argument lists Split 'Function' class into abstract superclass 'Function' and child classes 'UserDefinedFunction' and 'BuiltinFunction' --- .../tunkki/core/parser/ast/FunctionDefineNode.java | 7 +- .../core/parser/datatype/BooleanDatatype.java | 10 +-- .../core/parser/datatype/CallableDatatype.java | 11 +-- .../tunkki/core/parser/datatype/Datatype.java | 10 +-- .../tunkki/core/parser/datatype/ListDatatype.java | 6 +- .../tunkki/core/parser/datatype/NadaDatatype.java | 10 +-- .../core/parser/datatype/StringDatatype.java | 10 +-- .../tunkki/core/parser/datatype/VoidDatatype.java | 10 +-- .../com/jantuomi/tunkki/core/runtime/Function.java | 81 ++++++++++++++++++---- .../tunkki/core/runtime/UserDefinedFunction.java | 51 ++++++++++++++ .../core/runtime/builtins/BuiltinManager.java | 1 - .../runtime/builtins/globals/BuiltinFunction.java | 9 ++- .../builtins/globals/ConcatBuiltinFunction.java | 16 +++++ .../builtins/globals/ContainsBuiltinFunction.java | 18 ++++- .../builtins/globals/EqualsBuiltinFunction.java | 21 +++++- .../builtins/globals/GetBuiltinFunction.java | 14 ++++ .../builtins/globals/IfBuiltinFunction.java | 17 +++++ .../builtins/globals/IncludeBuiltinFunction.java | 21 ++++-- .../builtins/globals/InputBuiltinFunction.java | 25 +++++-- .../builtins/globals/ListBuiltinFunction.java | 12 ++++ .../builtins/globals/OutputBuiltinFunction.java | 13 ++++ .../globals/cast/AsBooleanBuiltinFunction.java | 19 +++-- .../globals/cast/AsIntBuiltinFunction.java | 18 ++++- .../builtins/math/PowerBuiltinFunction.java | 14 ++++ 24 files changed, 344 insertions(+), 80 deletions(-) create mode 100644 src/main/com/jantuomi/tunkki/core/runtime/UserDefinedFunction.java (limited to 'src/main/com') diff --git a/src/main/com/jantuomi/tunkki/core/parser/ast/FunctionDefineNode.java b/src/main/com/jantuomi/tunkki/core/parser/ast/FunctionDefineNode.java index 19de2f2..27f3a3c 100644 --- a/src/main/com/jantuomi/tunkki/core/parser/ast/FunctionDefineNode.java +++ b/src/main/com/jantuomi/tunkki/core/parser/ast/FunctionDefineNode.java @@ -2,8 +2,7 @@ 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.runtime.Function; -import com.jantuomi.tunkki.core.runtime.State; +import com.jantuomi.tunkki.core.runtime.UserDefinedFunction; import com.jantuomi.tunkki.core.parser.tokenizer.token.Token; import com.jantuomi.tunkki.exception.types.ExpectedDifferentTokenTunkkiError; import com.jantuomi.tunkki.exception.types.TunkkiError; @@ -38,7 +37,7 @@ public class FunctionDefineNode extends VarargOperatorNode { catch (Exception ex) { throw new ExpectedDifferentTokenTunkkiError(getLine(), getText()); } - Function function = new Function(argumentNames, (BlockBodyNode) body); + UserDefinedFunction function = new UserDefinedFunction(argumentNames, (BlockBodyNode) body); CallableDatatype c = new CallableDatatype(); c.setData(function); @@ -52,7 +51,7 @@ public class FunctionDefineNode extends VarargOperatorNode { System.out.print("\t"); } - System.out.println(String.format("Function")); + System.out.println(String.format("UserDefinedFunction")); for (int i = 0; i < indent + 1; i++) { System.out.print("\t"); diff --git a/src/main/com/jantuomi/tunkki/core/parser/datatype/BooleanDatatype.java b/src/main/com/jantuomi/tunkki/core/parser/datatype/BooleanDatatype.java index d00b42a..df0e572 100644 --- a/src/main/com/jantuomi/tunkki/core/parser/datatype/BooleanDatatype.java +++ b/src/main/com/jantuomi/tunkki/core/parser/datatype/BooleanDatatype.java @@ -23,27 +23,27 @@ public class BooleanDatatype extends Datatype { } @Override - public Datatype add(Datatype other) throws TunkkiError { + public Datatype add(Datatype other) throws TunkkiError { return null; } @Override - public Datatype subtract(Datatype other) throws TunkkiError { + public Datatype subtract(Datatype other) throws TunkkiError { return null; } @Override - public Datatype multiply(Datatype other) throws TunkkiError { + public Datatype multiply(Datatype other) throws TunkkiError { return null; } @Override - public Datatype divide(Datatype other) throws TunkkiError { + public Datatype divide(Datatype other) throws TunkkiError { return null; } @Override - public BooleanDatatype equals(Datatype other) throws TunkkiError { + public BooleanDatatype equals(Datatype other) throws TunkkiError { switch (other.getType()) { case Boolean: return new BooleanDatatype(getData().equals(other.getData())); diff --git a/src/main/com/jantuomi/tunkki/core/parser/datatype/CallableDatatype.java b/src/main/com/jantuomi/tunkki/core/parser/datatype/CallableDatatype.java index f05ee72..8ee4148 100644 --- a/src/main/com/jantuomi/tunkki/core/parser/datatype/CallableDatatype.java +++ b/src/main/com/jantuomi/tunkki/core/parser/datatype/CallableDatatype.java @@ -1,6 +1,7 @@ package com.jantuomi.tunkki.core.parser.datatype; import com.jantuomi.tunkki.core.runtime.Function; +import com.jantuomi.tunkki.core.runtime.UserDefinedFunction; import com.jantuomi.tunkki.exception.types.TunkkiError; import java.util.List; @@ -25,27 +26,27 @@ public class CallableDatatype extends Datatype { } @Override - public Datatype add(Datatype other) throws TunkkiError { + public Datatype add(Datatype other) throws TunkkiError { return null; } @Override - public Datatype subtract(Datatype other) throws TunkkiError { + public Datatype subtract(Datatype other) throws TunkkiError { return null; } @Override - public Datatype multiply(Datatype other) throws TunkkiError { + public Datatype multiply(Datatype other) throws TunkkiError { return null; } @Override - public Datatype divide(Datatype other) throws TunkkiError { + public Datatype divide(Datatype other) throws TunkkiError { return null; } @Override - public BooleanDatatype equals(Datatype other) throws TunkkiError { + public BooleanDatatype equals(Datatype other) throws TunkkiError { switch (other.getType()) { case Nada: return new BooleanDatatype(false); diff --git a/src/main/com/jantuomi/tunkki/core/parser/datatype/Datatype.java b/src/main/com/jantuomi/tunkki/core/parser/datatype/Datatype.java index 928f74b..9983d64 100644 --- a/src/main/com/jantuomi/tunkki/core/parser/datatype/Datatype.java +++ b/src/main/com/jantuomi/tunkki/core/parser/datatype/Datatype.java @@ -37,11 +37,11 @@ abstract public class Datatype { @Override abstract public String toString(); - abstract public Datatype add(Datatype other) throws TunkkiError; - public abstract Datatype subtract(Datatype other) throws TunkkiError; - public abstract Datatype multiply(Datatype other) throws TunkkiError; - public abstract Datatype divide(Datatype other) throws TunkkiError; - public abstract BooleanDatatype equals(Datatype other) throws TunkkiError; + abstract public Datatype add(Datatype other) throws TunkkiError; + public abstract Datatype subtract(Datatype other) throws TunkkiError; + public abstract Datatype multiply(Datatype other) throws TunkkiError; + public abstract Datatype divide(Datatype other) throws TunkkiError; + public abstract BooleanDatatype equals(Datatype other) throws TunkkiError; public static String toString(List variables) { String result = "["; diff --git a/src/main/com/jantuomi/tunkki/core/parser/datatype/ListDatatype.java b/src/main/com/jantuomi/tunkki/core/parser/datatype/ListDatatype.java index f097ee4..a3fb699 100644 --- a/src/main/com/jantuomi/tunkki/core/parser/datatype/ListDatatype.java +++ b/src/main/com/jantuomi/tunkki/core/parser/datatype/ListDatatype.java @@ -25,17 +25,17 @@ public class ListDatatype extends Datatype> { } @Override - public BooleanDatatype equals(Datatype> other) throws TunkkiError { + public BooleanDatatype equals(Datatype other) throws TunkkiError { switch (other.getType()) { case List: boolean found = false; for (int i = 0; i < getData().size(); i++) { - if (!getData().get(i).equals(other.getData().get(i)).getData()) { + if (!getData().get(i).equals(((ListDatatype) other).getData().get(i)).getData()) { found = true; break; } - return new BooleanDatatype(found); } + return new BooleanDatatype(found); case Nada: return new BooleanDatatype(false); } diff --git a/src/main/com/jantuomi/tunkki/core/parser/datatype/NadaDatatype.java b/src/main/com/jantuomi/tunkki/core/parser/datatype/NadaDatatype.java index 880d8ad..7b92f7a 100644 --- a/src/main/com/jantuomi/tunkki/core/parser/datatype/NadaDatatype.java +++ b/src/main/com/jantuomi/tunkki/core/parser/datatype/NadaDatatype.java @@ -18,31 +18,31 @@ public class NadaDatatype extends Datatype { } @Override - public Datatype add(Datatype other) throws TunkkiError { + public Datatype add(Datatype other) throws TunkkiError { doOperation(); return null; } @Override - public Datatype subtract(Datatype other) throws TunkkiError { + public Datatype subtract(Datatype other) throws TunkkiError { doOperation(); return null; } @Override - public Datatype multiply(Datatype other) throws TunkkiError { + public Datatype multiply(Datatype other) throws TunkkiError { doOperation(); return null; } @Override - public Datatype divide(Datatype other) throws TunkkiError { + public Datatype divide(Datatype other) throws TunkkiError { doOperation(); return null; } @Override - public BooleanDatatype equals(Datatype other) throws TunkkiError { + public BooleanDatatype equals(Datatype other) throws TunkkiError { if (other.getType() == Type.Nada) { return new BooleanDatatype(true); } diff --git a/src/main/com/jantuomi/tunkki/core/parser/datatype/StringDatatype.java b/src/main/com/jantuomi/tunkki/core/parser/datatype/StringDatatype.java index 4ffcb49..594de52 100644 --- a/src/main/com/jantuomi/tunkki/core/parser/datatype/StringDatatype.java +++ b/src/main/com/jantuomi/tunkki/core/parser/datatype/StringDatatype.java @@ -23,29 +23,29 @@ public class StringDatatype extends Datatype { } @Override - public Datatype add(Datatype other) { + public Datatype add(Datatype other) { return new StringDatatype( getData() + other.getData() ); } @Override - public Datatype subtract(Datatype other) throws TunkkiError { + public Datatype subtract(Datatype other) throws TunkkiError { return null; } @Override - public Datatype multiply(Datatype other) throws TunkkiError { + public Datatype multiply(Datatype other) throws TunkkiError { return null; } @Override - public Datatype divide(Datatype other) throws TunkkiError { + public Datatype divide(Datatype other) throws TunkkiError { return null; } @Override - public BooleanDatatype equals(Datatype other) throws TunkkiError { + public BooleanDatatype equals(Datatype other) throws TunkkiError { switch (other.getType()) { case String: return new BooleanDatatype(getData().equals(other.getData())); diff --git a/src/main/com/jantuomi/tunkki/core/parser/datatype/VoidDatatype.java b/src/main/com/jantuomi/tunkki/core/parser/datatype/VoidDatatype.java index ae3c8f9..77dd356 100644 --- a/src/main/com/jantuomi/tunkki/core/parser/datatype/VoidDatatype.java +++ b/src/main/com/jantuomi/tunkki/core/parser/datatype/VoidDatatype.java @@ -18,27 +18,27 @@ public class VoidDatatype extends Datatype { } @Override - public Datatype add(Datatype other) { + public Datatype add(Datatype other) { return null; } @Override - public Datatype subtract(Datatype other) { + public Datatype subtract(Datatype other) { return null; } @Override - public Datatype multiply(Datatype other) throws TunkkiError { + public Datatype multiply(Datatype other) throws TunkkiError { return null; } @Override - public Datatype divide(Datatype other) throws TunkkiError { + public Datatype divide(Datatype other) throws TunkkiError { return null; } @Override - public BooleanDatatype equals(Datatype other) throws TunkkiError { + public BooleanDatatype equals(Datatype other) throws TunkkiError { return new BooleanDatatype(false); } } diff --git a/src/main/com/jantuomi/tunkki/core/runtime/Function.java b/src/main/com/jantuomi/tunkki/core/runtime/Function.java index e4c4f0f..b6eab89 100644 --- a/src/main/com/jantuomi/tunkki/core/runtime/Function.java +++ b/src/main/com/jantuomi/tunkki/core/runtime/Function.java @@ -3,17 +3,17 @@ 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.List; +import java.util.*; /** - * Created by jan on 20.6.2016. + * Created by jan on 5.8.2016. */ -public class Function { - - private List argumentNames; - private BlockBodyNode body; +abstract public class Function { + protected List argumentNames; + protected BlockBodyNode body; public Function(List argumentNames, BlockBodyNode body) { this.argumentNames = argumentNames; @@ -23,26 +23,79 @@ public class Function { public Datatype evaluate(List params) throws TunkkiError { State.getInstance().createScope(); - if (params.size() != argumentNames.size()) { - return null; + if (!checkArgumentListValidity(params)) { + throw new FunctionArgumentTunkkiError(-1, Datatype.toString(params)); } - for (int i = 0; i < argumentNames.size(); i++) { - State.getInstance().addSymbolToScope(argumentNames.get(i)); - State.getInstance().setSymbolValueToScope(argumentNames.get(i), params.get(i)); + return null; + } + + protected boolean checkArgumentListValidity(List params) throws FunctionArgumentTunkkiError { + int argumentCount = getArgumentCount(); + boolean isSizeCorrect; + if (!hasVariableArgumentList()) { + isSizeCorrect = (argumentCount == params.size()); + } else { + isSizeCorrect = true; } - Datatype returnValue = body.evaluate(); + if (!isSizeCorrect) { + return false; + } - State.getInstance().popScope(); + if (hasDynamicallyTypedArguments()) { + // do nothing if types can be whatever + } else { + List> argumentTypes = getArgumentTypes(); + Set acceptableTypes; + for (int i = 0; i < params.size(); i++) { + /* The first type set of the list should be tested against for all arguments + if the function's argument list is variable in size + */ + if (hasVariableArgumentList()) { + acceptableTypes = argumentTypes.get(0); + } else { + acceptableTypes = argumentTypes.get(i); + } + if (!acceptableTypes.contains(params.get(i).getType())) { + return false; + } + } + } + + return true; + } - return returnValue; + public int getArgumentCount() { + return argumentNames.size(); } + abstract public boolean hasVariableArgumentList(); + + abstract public boolean hasDynamicallyTypedArguments(); + + /** + * Return a list of possible argument type sets for each positional argument + * If the function has variable arguments, the first (and only) list element set + * is tested against for all parameters + * @return A list of sets of acceptable datatypes for each argument, in order + */ + abstract public List> getArgumentTypes(); + public CallableDatatype makeCallable() { CallableDatatype c = new CallableDatatype(); c.setData(this); return c; } + protected Set createAcceptableTypeSet(Datatype.Type... types) { + return new HashSet<>(Arrays.asList(types)); + } + + final protected Set allTypesSet() { + return new HashSet<>(Arrays.asList( + Datatype.Type.Boolean, Datatype.Type.Double, Datatype.Type.Integer, + Datatype.Type.List, Datatype.Type.Nada, Datatype.Type.Object, Datatype.Type.String + )); + } } diff --git a/src/main/com/jantuomi/tunkki/core/runtime/UserDefinedFunction.java b/src/main/com/jantuomi/tunkki/core/runtime/UserDefinedFunction.java new file mode 100644 index 0000000..2e994a8 --- /dev/null +++ b/src/main/com/jantuomi/tunkki/core/runtime/UserDefinedFunction.java @@ -0,0 +1,51 @@ +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.*; + +/** + * Created by jan on 20.6.2016. + */ +public class UserDefinedFunction extends Function { + + + public UserDefinedFunction(List argumentNames, BlockBodyNode body) { + super(argumentNames, body); + } + + @Override + public Datatype evaluate(List params) throws TunkkiError { + + 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)); + } + + Datatype returnValue = body.evaluate(); + State.getInstance().popScope(); + + return returnValue; + } + + @Override + public boolean hasVariableArgumentList() { + return false; + } + + @Override + public boolean hasDynamicallyTypedArguments() { + return true; + } + + @Override + public List> getArgumentTypes() { + return Collections.emptyList(); + } +} diff --git a/src/main/com/jantuomi/tunkki/core/runtime/builtins/BuiltinManager.java b/src/main/com/jantuomi/tunkki/core/runtime/builtins/BuiltinManager.java index ae66a14..eb7374d 100644 --- a/src/main/com/jantuomi/tunkki/core/runtime/builtins/BuiltinManager.java +++ b/src/main/com/jantuomi/tunkki/core/runtime/builtins/BuiltinManager.java @@ -1,7 +1,6 @@ package com.jantuomi.tunkki.core.runtime.builtins; import com.jantuomi.tunkki.core.parser.datatype.CallableDatatype; -import com.jantuomi.tunkki.core.runtime.Function; import com.jantuomi.tunkki.core.runtime.builtins.globals.*; import com.jantuomi.tunkki.core.runtime.builtins.globals.cast.AsBooleanBuiltinFunction; import com.jantuomi.tunkki.core.runtime.builtins.globals.cast.AsIntBuiltinFunction; diff --git a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/BuiltinFunction.java b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/BuiltinFunction.java index b175525..61d581b 100644 --- a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/BuiltinFunction.java +++ b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/BuiltinFunction.java @@ -2,9 +2,11 @@ package com.jantuomi.tunkki.core.runtime.builtins.globals; import com.jantuomi.tunkki.core.parser.datatype.Datatype; import com.jantuomi.tunkki.core.runtime.Function; +import com.jantuomi.tunkki.core.runtime.UserDefinedFunction; import com.jantuomi.tunkki.exception.types.TunkkiError; import java.util.List; +import java.util.Set; /** * Created by jan on 28.6.2016. @@ -15,5 +17,10 @@ abstract public class BuiltinFunction extends Function { } @Override - abstract public Datatype evaluate(List params) throws TunkkiError; + abstract public List> getArgumentTypes(); + + @Override + public boolean hasDynamicallyTypedArguments() { + return false; + } } diff --git a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/ConcatBuiltinFunction.java b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/ConcatBuiltinFunction.java index 170efed..bd0a627 100644 --- a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/ConcatBuiltinFunction.java +++ b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/ConcatBuiltinFunction.java @@ -4,8 +4,10 @@ import com.jantuomi.tunkki.core.parser.datatype.Datatype; import com.jantuomi.tunkki.core.parser.datatype.StringDatatype; import com.jantuomi.tunkki.exception.types.TunkkiError; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Set; /** * Created by jan on 21.6.2016. @@ -19,6 +21,8 @@ public class ConcatBuiltinFunction extends BuiltinFunction { @Override public Datatype evaluate(List params) throws TunkkiError { + super.evaluate(params); + StringBuilder sb = new StringBuilder(); for (Datatype d : params) { sb.append(d.getData()); @@ -28,4 +32,16 @@ public class ConcatBuiltinFunction extends BuiltinFunction { sb.toString() ); } + + @Override + public boolean hasVariableArgumentList() { + return true; + } + + @Override + public List> getArgumentTypes() { + return Arrays.asList( + createAcceptableTypeSet(Datatype.Type.String) + ); + } } diff --git a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/ContainsBuiltinFunction.java b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/ContainsBuiltinFunction.java index ccb461a..5e1a9b0 100644 --- a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/ContainsBuiltinFunction.java +++ b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/ContainsBuiltinFunction.java @@ -9,6 +9,7 @@ import com.jantuomi.tunkki.exception.types.TunkkiError; import java.util.Arrays; import java.util.List; +import java.util.Set; /** * Created by jan on 27.7.2016. @@ -20,9 +21,7 @@ public class ContainsBuiltinFunction extends BuiltinFunction { @Override public Datatype evaluate(List params) throws TunkkiError { - if (params.size() != 2) { - throw new FunctionArgumentTunkkiError(-1, Datatype.toString(params)); - } + super.evaluate(params); if (params.get(0).getType() == Datatype.Type.List) { return evaluateOnList(params); @@ -33,6 +32,19 @@ public class ContainsBuiltinFunction extends BuiltinFunction { throw new FunctionArgumentTunkkiError(-1, Datatype.toString(params)); } + @Override + public boolean hasVariableArgumentList() { + return false; + } + + @Override + public List> getArgumentTypes() { + return Arrays.asList( + createAcceptableTypeSet(Datatype.Type.List, Datatype.Type.String), + createAcceptableTypeSet() + ); + } + private Datatype evaluateOnList(List params) throws TunkkiError { ListDatatype list = (ListDatatype) params.get(0); Datatype comp = params.get(1); diff --git a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/EqualsBuiltinFunction.java b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/EqualsBuiltinFunction.java index c31759a..20e40fc 100644 --- a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/EqualsBuiltinFunction.java +++ b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/EqualsBuiltinFunction.java @@ -7,7 +7,9 @@ import com.jantuomi.tunkki.exception.types.TunkkiError; import com.jantuomi.tunkki.exception.types.TypeTunkkiError; import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.Set; /** * Created by jan on 31.7.2016. @@ -19,9 +21,7 @@ public class EqualsBuiltinFunction extends BuiltinFunction { @Override public Datatype evaluate(List params) throws TunkkiError { - if (params.size() != 2) { - throw new FunctionArgumentTunkkiError(-1, Datatype.toString(params)); - } + super.evaluate(params); Datatype lhs = params.get(0); Datatype rhs = params.get(1); @@ -33,4 +33,19 @@ public class EqualsBuiltinFunction extends BuiltinFunction { throw new TypeTunkkiError(-1, lhs.getType().toString(), rhs.getType().toString()); } } + + @Override + public boolean hasVariableArgumentList() { + return false; + } + + @Override + public boolean hasDynamicallyTypedArguments() { + return true; + } + + @Override + public List> getArgumentTypes() { + return Collections.emptyList(); + } } diff --git a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/GetBuiltinFunction.java b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/GetBuiltinFunction.java index f936854..33a9170 100644 --- a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/GetBuiltinFunction.java +++ b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/GetBuiltinFunction.java @@ -9,6 +9,7 @@ import com.jantuomi.tunkki.exception.types.TunkkiError; import java.util.Arrays; import java.util.List; +import java.util.Set; /** * Created by jan on 28.7.2016. @@ -42,4 +43,17 @@ public class GetBuiltinFunction extends BuiltinFunction { throw new OutOfBoundsTunkkiError(-1, index.toString()); } } + + @Override + public boolean hasVariableArgumentList() { + return false; + } + + @Override + public List> getArgumentTypes() { + return Arrays.asList( + createAcceptableTypeSet(Datatype.Type.List), + createAcceptableTypeSet(Datatype.Type.Integer) + ); + } } diff --git a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/IfBuiltinFunction.java b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/IfBuiltinFunction.java index f794aa2..1156958 100644 --- a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/IfBuiltinFunction.java +++ b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/IfBuiltinFunction.java @@ -4,12 +4,14 @@ import com.jantuomi.tunkki.core.parser.datatype.BooleanDatatype; import com.jantuomi.tunkki.core.parser.datatype.CallableDatatype; import com.jantuomi.tunkki.core.parser.datatype.Datatype; import com.jantuomi.tunkki.core.parser.datatype.VoidDatatype; +import com.jantuomi.tunkki.core.runtime.Function; import com.jantuomi.tunkki.exception.types.FunctionArgumentTunkkiError; import com.jantuomi.tunkki.exception.types.TunkkiError; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Set; /** * Created by jan on 4.8.2016. @@ -21,6 +23,8 @@ public class IfBuiltinFunction extends BuiltinFunction { @Override public Datatype evaluate(List params) throws TunkkiError { + super.evaluate(params); + if (params.size() != 2) { throw new FunctionArgumentTunkkiError(-1, Datatype.toString(params)); } @@ -38,4 +42,17 @@ public class IfBuiltinFunction extends BuiltinFunction { } return new VoidDatatype(); } + + @Override + public boolean hasVariableArgumentList() { + return false; + } + + @Override + public List> getArgumentTypes() { + return Arrays.asList( + createAcceptableTypeSet(Datatype.Type.Boolean), + createAcceptableTypeSet(Datatype.Type.Callable) + ); + } } 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 fb2f9fc..b3e1a9a 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 @@ -12,6 +12,7 @@ import com.jantuomi.tunkki.exception.types.*; import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -26,13 +27,7 @@ public class IncludeBuiltinFunction extends BuiltinFunction { @Override public Datatype evaluate(List params) throws TunkkiError { - if (params.size() != 1) { - throw new FunctionArgumentTunkkiError(-1, Datatype.toString(params)); - } - - if (params.get(0).getType() != Datatype.Type.String) { - throw new TypeTunkkiError(-1, params.get(0).getType().toString(), "include"); - } + super.evaluate(params); StringDatatype param = (StringDatatype) params.get(0); String filename = param.getData(); @@ -67,4 +62,16 @@ public class IncludeBuiltinFunction extends BuiltinFunction { return new VoidDatatype(); } + + @Override + public boolean hasVariableArgumentList() { + return false; + } + + @Override + public List> getArgumentTypes() { + return Arrays.asList( + createAcceptableTypeSet(Datatype.Type.String) + ); + } } diff --git a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/InputBuiltinFunction.java b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/InputBuiltinFunction.java index 3625541..c7b53f0 100644 --- a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/InputBuiltinFunction.java +++ b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/InputBuiltinFunction.java @@ -7,9 +7,7 @@ import com.jantuomi.tunkki.exception.types.TunkkiError; import com.jantuomi.tunkki.utils.IO; import java.io.IOException; -import java.util.Arrays; -import java.util.List; -import java.util.Scanner; +import java.util.*; /** * Created by jan on 21.6.2016. @@ -23,10 +21,11 @@ public class InputBuiltinFunction extends BuiltinFunction { @Override public Datatype evaluate(List params) throws TunkkiError { - if (params.size() > 0) { - Datatype param = params.get(0); - System.out.print(param.getData().toString()); - } + super.evaluate(params); + + Datatype param = params.get(0); + System.out.print(param.getData().toString()); + String in; try { in = IO.getInstance().readLine(""); @@ -36,4 +35,16 @@ public class InputBuiltinFunction extends BuiltinFunction { return new NadaDatatype(); } } + + @Override + public boolean hasVariableArgumentList() { + return false; + } + + @Override + public List> getArgumentTypes() { + return Collections.singletonList( + createAcceptableTypeSet(Datatype.Type.String) + ); + } } diff --git a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/ListBuiltinFunction.java b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/ListBuiltinFunction.java index 4d82c1a..58629fc 100644 --- a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/ListBuiltinFunction.java +++ b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/ListBuiltinFunction.java @@ -5,7 +5,9 @@ import com.jantuomi.tunkki.core.parser.datatype.ListDatatype; import com.jantuomi.tunkki.exception.types.TunkkiError; import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.Set; /** * Created by jan on 27.7.2016. @@ -20,4 +22,14 @@ public class ListBuiltinFunction extends BuiltinFunction { ListDatatype data = new ListDatatype(params); return data; } + + @Override + public boolean hasVariableArgumentList() { + return true; + } + + @Override + public List> getArgumentTypes() { + return Collections.emptyList(); + } } diff --git a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/OutputBuiltinFunction.java b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/OutputBuiltinFunction.java index e4857c0..ce2aba4 100644 --- a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/OutputBuiltinFunction.java +++ b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/OutputBuiltinFunction.java @@ -7,6 +7,7 @@ import com.jantuomi.tunkki.utils.IO; import java.util.Arrays; import java.util.List; +import java.util.Set; /** * Created by jan on 21.6.2016. @@ -24,4 +25,16 @@ public class OutputBuiltinFunction extends BuiltinFunction { IO.getInstance().printLine(param.getData().toString()); return new VoidDatatype(); } + + @Override + public boolean hasVariableArgumentList() { + return false; + } + + @Override + public List> getArgumentTypes() { + return Arrays.asList( + createAcceptableTypeSet(Datatype.Type.String) + ); + } } diff --git a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/cast/AsBooleanBuiltinFunction.java b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/cast/AsBooleanBuiltinFunction.java index 4432554..e46b88c 100644 --- a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/cast/AsBooleanBuiltinFunction.java +++ b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/cast/AsBooleanBuiltinFunction.java @@ -7,6 +7,7 @@ import com.jantuomi.tunkki.exception.types.TunkkiError; import java.util.Arrays; import java.util.List; +import java.util.Set; /** * Created by jan on 21.6.2016. @@ -20,11 +21,9 @@ public class AsBooleanBuiltinFunction extends BuiltinFunction { @Override public BooleanDatatype evaluate(List params) throws TunkkiError { - if (params.size() != 1) { - return null; - } + super.evaluate(params); + Datatype param = params.get(0); - boolean b; switch (param.getType()) { case Integer: return new BooleanDatatype(((IntegerDatatype) param).getData() != 0); @@ -35,4 +34,16 @@ public class AsBooleanBuiltinFunction extends BuiltinFunction { } } + + @Override + public boolean hasVariableArgumentList() { + return false; + } + + @Override + public List> getArgumentTypes() { + return Arrays.asList( + createAcceptableTypeSet(Datatype.Type.Integer, Datatype.Type.Boolean) + ); + } } diff --git a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/cast/AsIntBuiltinFunction.java b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/cast/AsIntBuiltinFunction.java index 773d480..6bd45ca 100644 --- a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/cast/AsIntBuiltinFunction.java +++ b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/cast/AsIntBuiltinFunction.java @@ -7,6 +7,7 @@ import com.jantuomi.tunkki.exception.types.TunkkiError; import java.util.Arrays; import java.util.List; +import java.util.Set; /** * Created by jan on 21.6.2016. @@ -20,9 +21,8 @@ public class AsIntBuiltinFunction extends BuiltinFunction { @Override public IntegerDatatype evaluate(List params) throws TunkkiError { - if (params.size() != 1) { - return null; - } + super.evaluate(params); + Datatype param = params.get(0); int i; switch (param.getType()) { @@ -45,4 +45,16 @@ public class AsIntBuiltinFunction extends BuiltinFunction { } } + + @Override + public boolean hasVariableArgumentList() { + return false; + } + + @Override + public List> getArgumentTypes() { + return Arrays.asList( + createAcceptableTypeSet(Datatype.Type.String, Datatype.Type.Integer, Datatype.Type.Boolean, Datatype.Type.Double) + ); + } } diff --git a/src/main/com/jantuomi/tunkki/core/runtime/builtins/math/PowerBuiltinFunction.java b/src/main/com/jantuomi/tunkki/core/runtime/builtins/math/PowerBuiltinFunction.java index e56a9b9..f426456 100644 --- a/src/main/com/jantuomi/tunkki/core/runtime/builtins/math/PowerBuiltinFunction.java +++ b/src/main/com/jantuomi/tunkki/core/runtime/builtins/math/PowerBuiltinFunction.java @@ -9,6 +9,7 @@ import com.jantuomi.tunkki.exception.types.TunkkiError; import java.util.Arrays; import java.util.List; +import java.util.Set; /** * Created by jan on 2.8.2016. @@ -39,6 +40,11 @@ public class PowerBuiltinFunction extends BuiltinFunction { } } + @Override + public boolean hasVariableArgumentList() { + return false; + } + private double getDoubleValue(List params, Datatype dt) throws TunkkiError { double number; if (dt.getType() == Datatype.Type.Integer) { @@ -51,4 +57,12 @@ public class PowerBuiltinFunction extends BuiltinFunction { } return number; } + + @Override + public List> getArgumentTypes() { + return Arrays.asList( + createAcceptableTypeSet(Datatype.Type.Integer, Datatype.Type.Double), + createAcceptableTypeSet(Datatype.Type.Integer, Datatype.Type.Double) + ); + } } -- cgit v1.3