diff options
Diffstat (limited to 'src/main')
8 files changed, 155 insertions, 56 deletions
diff --git a/src/main/com/jantuomi/tunkki/core/parser/datatype/IntegerDatatype.java b/src/main/com/jantuomi/tunkki/core/parser/datatype/IntegerDatatype.java index 1891326..51d9d4e 100644 --- a/src/main/com/jantuomi/tunkki/core/parser/datatype/IntegerDatatype.java +++ b/src/main/com/jantuomi/tunkki/core/parser/datatype/IntegerDatatype.java @@ -103,4 +103,8 @@ public class IntegerDatatype extends Datatype<Integer> { } } + + public DoubleDatatype asDouble() { + return new DoubleDatatype(getData().doubleValue()); + } } diff --git a/src/main/com/jantuomi/tunkki/core/runtime/State.java b/src/main/com/jantuomi/tunkki/core/runtime/State.java index cdcbacd..742e603 100644 --- a/src/main/com/jantuomi/tunkki/core/runtime/State.java +++ b/src/main/com/jantuomi/tunkki/core/runtime/State.java @@ -2,7 +2,7 @@ package com.jantuomi.tunkki.core.runtime; import com.jantuomi.tunkki.core.parser.datatype.Datatype; import com.jantuomi.tunkki.core.parser.datatype.NadaDatatype; -import com.jantuomi.tunkki.core.runtime.builtins.globals.BuiltinManager; +import com.jantuomi.tunkki.core.runtime.builtins.BuiltinManager; import com.jantuomi.tunkki.exception.TunkkiError; import java.util.Arrays; diff --git a/src/main/com/jantuomi/tunkki/core/runtime/builtins/BuiltinManager.java b/src/main/com/jantuomi/tunkki/core/runtime/builtins/BuiltinManager.java new file mode 100644 index 0000000..f139025 --- /dev/null +++ b/src/main/com/jantuomi/tunkki/core/runtime/builtins/BuiltinManager.java @@ -0,0 +1,67 @@ +package com.jantuomi.tunkki.core.runtime.builtins; + +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; +import com.jantuomi.tunkki.core.runtime.builtins.math.PowerBuiltinFunction; +import com.jantuomi.tunkki.exception.TunkkiError; + +import java.util.*; + +/** + * Created by jan on 21.6.2016. + */ +public class BuiltinManager { + private static BuiltinManager instance = new BuiltinManager(); + + public static BuiltinManager getInstance() { + return instance; + } + + private List<BuiltinFunction> builtins; + + public final Set<String> BUILTIN_MODULES = new HashSet<>(Arrays.asList( + "math" + )); + + private BuiltinManager() { + instance = this; + builtins = new ArrayList<>(); + initializeGlobals(); + } + + private void initializeGlobals() { + builtins.add(new OutputBuiltinFunction()); + builtins.add(new InputBuiltinFunction()); + builtins.add(new ConcatBuiltinFunction()); + builtins.add(new AsIntBuiltinFunction()); + builtins.add(new AsBooleanBuiltinFunction()); + builtins.add(new IncludeBuiltinFunction()); + builtins.add(new ListBuiltinFunction()); + builtins.add(new ContainsBuiltinFunction()); + builtins.add(new GetBuiltinFunction()); + builtins.add(new EqualsBuiltinFunction()); + } + + private List<Function> getFunctionsFromMathModule() { + return Arrays.asList(new PowerBuiltinFunction()); + } + + public List<Function> getFunctionsFromModule(String name) throws TunkkiError { + if (name.equals("math")) { + return getFunctionsFromMathModule(); + } + else { + throw new TunkkiError(TunkkiError.ExceptionType.IncludeError, -1, name); + } + } + + public void addBuiltin(BuiltinFunction func) { + builtins.add(func); + } + + public List<BuiltinFunction> getBuiltins() { + return builtins; + } +} 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 4efa1da..96c9ebe 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,6 +2,7 @@ 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.builtins.BuiltinManager; import com.jantuomi.tunkki.exception.TunkkiError; import java.util.List; @@ -12,7 +13,6 @@ import java.util.List; abstract public class BuiltinFunction extends Function{ public BuiltinFunction(List<String> argumentNames) { super(argumentNames, null); - BuiltinManager.getInstance().addBuiltin(this); } @Override diff --git a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/BuiltinManager.java b/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/BuiltinManager.java deleted file mode 100644 index 76b4916..0000000 --- a/src/main/com/jantuomi/tunkki/core/runtime/builtins/globals/BuiltinManager.java +++ /dev/null @@ -1,43 +0,0 @@ -package 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; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by jan on 21.6.2016. - */ -public class BuiltinManager { - private static BuiltinManager instance = new BuiltinManager(); - - public static BuiltinManager getInstance() { - return instance; - } - - private List<BuiltinFunction> builtins; - - private BuiltinManager() { - instance = this; - builtins = new ArrayList<>(); - new OutputBuiltinFunction(); - new InputBuiltinFunction(); - new ConcatBuiltinFunction(); - new AsIntBuiltinFunction(); - new AsBooleanBuiltinFunction(); - new IncludeBuiltinFunction(); - new ListBuiltinFunction(); - new ContainsBuiltinFunction(); - new GetBuiltinFunction(); - new EqualsBuiltinFunction(); - } - - public void addBuiltin(BuiltinFunction func) { - builtins.add(func); - } - - public List<BuiltinFunction> getBuiltins() { - return builtins; - } -} 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 c3965e5..6c200e5 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,6 +6,9 @@ import com.jantuomi.tunkki.core.CommandLineArgumentContainer; import com.jantuomi.tunkki.core.parser.datatype.Datatype; import com.jantuomi.tunkki.core.parser.datatype.StringDatatype; import com.jantuomi.tunkki.core.parser.datatype.VoidDatatype; +import com.jantuomi.tunkki.core.runtime.Function; +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.TunkkiError; @@ -13,6 +16,7 @@ import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; /** * Created by jan on 28.6.2016. @@ -33,21 +37,30 @@ public class IncludeBuiltinFunction extends BuiltinFunction { return null; } - String contents = CommandLineArgumentContainer.getInstance().readFileContents(filename); + if (BuiltinManager.getInstance().BUILTIN_MODULES.contains(filename)) { + + BuiltinManager.getInstance().getFunctionsFromModule(filename).stream() + .forEach( f -> State.getInstance().addFunctionToScope(f.getName(), f) ); - if (contents == null) { - return null; } + else { + String contents = CommandLineArgumentContainer.getInstance().readFileContents(filename); - String regex = String.format(".*include\\?\\s+\"\\s?%s\\s?\"\\s?\\!.*", Pattern.quote(filename)); - Pattern pattern = Pattern.compile(regex, Pattern.DOTALL); - Matcher matcher = pattern.matcher(contents); - if (matcher.matches()) { - ExceptionManager.raise(TunkkiError.ExceptionType.GeneralError, -1, "Recursive include detected, aborting."); - return null; + if (contents == null) { + return null; + } + + String regex = String.format(".*include\\?\\s+\"\\s?%s\\s?\"\\s?\\!.*", Pattern.quote(filename)); + Pattern pattern = Pattern.compile(regex, Pattern.DOTALL); + Matcher matcher = pattern.matcher(contents); + if (matcher.matches()) { + ExceptionManager.raise(TunkkiError.ExceptionType.GeneralError, -1, "Recursive include detected, aborting."); + return null; + } + + Tunkki.getInstance().run(contents); } - Tunkki.getInstance().run(contents); return new VoidDatatype(); } 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 new file mode 100644 index 0000000..9c4db2b --- /dev/null +++ b/src/main/com/jantuomi/tunkki/core/runtime/builtins/math/PowerBuiltinFunction.java @@ -0,0 +1,58 @@ +package com.jantuomi.tunkki.core.runtime.builtins.math; + +import com.jantuomi.tunkki.core.parser.datatype.Datatype; +import com.jantuomi.tunkki.core.parser.datatype.DoubleDatatype; +import com.jantuomi.tunkki.core.parser.datatype.IntegerDatatype; +import com.jantuomi.tunkki.core.runtime.builtins.globals.BuiltinFunction; +import com.jantuomi.tunkki.exception.TunkkiError; + +import java.util.Arrays; +import java.util.List; + +/** + * Created by jan on 2.8.2016. + */ +public class PowerBuiltinFunction extends BuiltinFunction { + public PowerBuiltinFunction() { + super(Arrays.asList("number", "exponent")); + } + + @Override + public Datatype evaluate(List<Datatype> params) throws TunkkiError { + if (params.size() != 2) { + throw new TunkkiError(TunkkiError.ExceptionType.FunctionArgumentError, -1, getName(), Datatype.toString(params)); + } + + Datatype lhs = params.get(0); + Datatype rhs = params.get(1); + + double number = getDoubleValue(params, lhs); + double exponent = getDoubleValue(params, rhs); + + try { + double result = Math.pow(number, exponent); + return new DoubleDatatype(result); + } + catch (Exception ex) { + throw new TunkkiError(TunkkiError.ExceptionType.FunctionArgumentError, -1, getName(), Datatype.toString(params)); + } + } + + private double getDoubleValue(List<Datatype> params, Datatype dt) throws TunkkiError { + double number; + if (dt.getType() == Datatype.Type.Integer) { + number = ((IntegerDatatype) dt).asDouble().getData(); + } else if (dt.getType() == Datatype.Type.Double) { + number = ((DoubleDatatype) dt).getData(); + } + else { + throw new TunkkiError(TunkkiError.ExceptionType.FunctionArgumentError, -1, getName(), Datatype.toString(params)); + } + return number; + } + + @Override + public String getName() { + return "pow"; + } +} diff --git a/src/main/com/jantuomi/tunkki/exception/TunkkiError.java b/src/main/com/jantuomi/tunkki/exception/TunkkiError.java index 2f133e6..affc353 100644 --- a/src/main/com/jantuomi/tunkki/exception/TunkkiError.java +++ b/src/main/com/jantuomi/tunkki/exception/TunkkiError.java @@ -32,7 +32,7 @@ public class TunkkiError extends Exception { errorTexts.put(ExceptionType.ExpectedDifferentTokenError, "Token '%s' expects a different token stack."); errorTexts.put(ExceptionType.FunctionArgumentError, "The parameter list given to function %s is either of wrong length or the parameters are of wrong type. Actual: %s"); errorTexts.put(ExceptionType.UndeclaredSymbolError, "No symbol %s defined in the current scope."); - errorTexts.put(ExceptionType.IncludeError, "File %s could not be included."); + errorTexts.put(ExceptionType.IncludeError, "File or module %s could not be included."); errorTexts.put(ExceptionType.GeneralError, "%s"); errorTexts.put(ExceptionType.NadaError, "Can't do operation with a nada value."); errorTexts.put(ExceptionType.CastError, "Illegal cast to type %s from value %s."); |
