aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Tuomi <jans.tuomi@gmail.com>2016-06-22 22:33:33 +0300
committerJan Tuomi <jans.tuomi@gmail.com>2016-07-26 19:47:10 +0300
commitfa02123ab00be8b8fe212c5d34ed021f1b63de74 (patch)
treea16534cafb01cf7e7dc12713815a2bc7188834b1
parent695f7f3e2613d96a597e15a8c6142019098745c8 (diff)
Add double type and fix exception types
-rw-r--r--main/core/parser/ast/AdditionNode.java9
-rw-r--r--main/core/parser/ast/NegationNode.java2
-rw-r--r--main/core/parser/ast/SubtractionNode.java9
-rw-r--r--main/core/parser/ast/SymbolNode.java12
-rw-r--r--main/core/parser/datatype/BooleanDataContainer.java18
-rw-r--r--main/core/parser/datatype/DataContainer.java10
-rw-r--r--main/core/parser/datatype/DoubleDataContainer.java50
-rw-r--r--main/core/parser/datatype/IntegerDataContainer.java77
-rw-r--r--main/core/parser/datatype/StringDataContainer.java17
-rw-r--r--main/core/parser/datatype/VoidDataContainer.java17
-rw-r--r--main/core/runtime/Scope.java3
-rw-r--r--main/core/runtime/builtins/AsIntBuiltinFunction.java5
-rw-r--r--main/exception/InterpreterException.java16
-rw-r--r--test/MainTest.java22
-rw-r--r--test/resources/program.bork14
15 files changed, 244 insertions, 37 deletions
diff --git a/main/core/parser/ast/AdditionNode.java b/main/core/parser/ast/AdditionNode.java
index 0820370..00db230 100644
--- a/main/core/parser/ast/AdditionNode.java
+++ b/main/core/parser/ast/AdditionNode.java
@@ -2,6 +2,7 @@ package com.jantuomi.interpreter.main.core.parser.ast;
import com.jantuomi.interpreter.main.core.parser.datatype.DataContainer;
import com.jantuomi.interpreter.main.core.tokenizer.token.Token;
+import com.jantuomi.interpreter.main.exception.ExceptionManager;
import com.jantuomi.interpreter.main.exception.InterpreterException;
import java.util.Arrays;
@@ -22,7 +23,13 @@ public class AdditionNode extends BinaryOperatorNode {
DataContainer operand2 = rhs.evaluate();
DataContainer result = operand1.add(operand2);
- return result;
+ if (result != null) {
+ return result;
+ } else {
+ ExceptionManager.raise(InterpreterException.ExceptionType.TypeError, source.getLine(),
+ operand1.getType().toString(), operand2.getType().toString());
+ return null;
+ }
}
@Override
diff --git a/main/core/parser/ast/NegationNode.java b/main/core/parser/ast/NegationNode.java
index ec3be2a..1d381cb 100644
--- a/main/core/parser/ast/NegationNode.java
+++ b/main/core/parser/ast/NegationNode.java
@@ -27,7 +27,7 @@ public class NegationNode extends UnaryOperatorNode {
((IntegerDataContainer) d).getData() != 0
);
}
- ExceptionManager.raise(InterpreterException.ExceptionType.TypeError, -1, "not", d.toString());
+ ExceptionManager.raise(InterpreterException.ExceptionType.TypeError, source.getLine(), "not", d.toString());
return null;
}
diff --git a/main/core/parser/ast/SubtractionNode.java b/main/core/parser/ast/SubtractionNode.java
index b234d0d..6b05073 100644
--- a/main/core/parser/ast/SubtractionNode.java
+++ b/main/core/parser/ast/SubtractionNode.java
@@ -2,6 +2,7 @@ package com.jantuomi.interpreter.main.core.parser.ast;
import com.jantuomi.interpreter.main.core.parser.datatype.DataContainer;
import com.jantuomi.interpreter.main.core.tokenizer.token.Token;
+import com.jantuomi.interpreter.main.exception.ExceptionManager;
import com.jantuomi.interpreter.main.exception.InterpreterException;
import java.util.Arrays;
@@ -21,7 +22,13 @@ public class SubtractionNode extends BinaryOperatorNode {
DataContainer operand2 = rhs.evaluate();
DataContainer result = operand1.subtract(operand2);
- return result;
+ if (result != null) {
+ return result;
+ } else {
+ ExceptionManager.raise(InterpreterException.ExceptionType.TypeError, source.getLine(),
+ operand1.getType().toString(), operand2.getType().toString());
+ return null;
+ }
}
@Override
diff --git a/main/core/parser/ast/SymbolNode.java b/main/core/parser/ast/SymbolNode.java
index c44d41b..5a4346a 100644
--- a/main/core/parser/ast/SymbolNode.java
+++ b/main/core/parser/ast/SymbolNode.java
@@ -3,11 +3,14 @@ package com.jantuomi.interpreter.main.core.parser.ast;
import com.jantuomi.interpreter.main.core.parser.datatype.DataContainer;
import com.jantuomi.interpreter.main.core.runtime.State;
import com.jantuomi.interpreter.main.core.tokenizer.token.Token;
+import com.jantuomi.interpreter.main.exception.ExceptionManager;
import com.jantuomi.interpreter.main.exception.InterpreterException;
+import com.sun.deploy.util.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.stream.Collectors;
/**
* Created by jan on 17.6.2016.
@@ -46,7 +49,14 @@ public class SymbolNode extends ASTNode {
paramValues.add(param.evaluate());
}
}
- return State.getInstance().getSymbolValue(name, paramValues);
+ DataContainer returnValue = State.getInstance().getSymbolValue(name, paramValues);
+ if (returnValue != null) {
+ return returnValue;
+ } else {
+ ExceptionManager.raise(InterpreterException.ExceptionType.UndeclaredSymbolError, source.getLine(), name,
+ StringUtils.join(paramValues.stream().map(dataContainer -> dataContainer.toString()).collect(Collectors.toList()), ","));
+ return null;
+ }
}
@Override
diff --git a/main/core/parser/datatype/BooleanDataContainer.java b/main/core/parser/datatype/BooleanDataContainer.java
index af814bb..e21ed96 100644
--- a/main/core/parser/datatype/BooleanDataContainer.java
+++ b/main/core/parser/datatype/BooleanDataContainer.java
@@ -1,6 +1,5 @@
package com.jantuomi.interpreter.main.core.parser.datatype;
-import com.jantuomi.interpreter.main.exception.ExceptionManager;
import com.jantuomi.interpreter.main.exception.InterpreterException;
/**
@@ -14,19 +13,32 @@ public class BooleanDataContainer extends DataContainer<Boolean> {
}
@Override
+ public Type getType() {
+ return Type.Boolean;
+ }
+
+ @Override
public String toString() {
return Boolean.toString(getData());
}
@Override
public DataContainer<Boolean> add(DataContainer<Boolean> other) throws InterpreterException {
- ExceptionManager.raise(InterpreterException.ExceptionType.TypeError, -1, "boolean", "boolean");
return null;
}
@Override
public DataContainer<Boolean> subtract(DataContainer<Boolean> other) throws InterpreterException {
- ExceptionManager.raise(InterpreterException.ExceptionType.TypeError, -1, "boolean", "boolean");
+ return null;
+ }
+
+ @Override
+ public DataContainer<Boolean> multiply(DataContainer<Boolean> other) throws InterpreterException {
+ return null;
+ }
+
+ @Override
+ public DataContainer<Boolean> divide(DataContainer<Boolean> other) throws InterpreterException {
return null;
}
}
diff --git a/main/core/parser/datatype/DataContainer.java b/main/core/parser/datatype/DataContainer.java
index 2214d80..5f46640 100644
--- a/main/core/parser/datatype/DataContainer.java
+++ b/main/core/parser/datatype/DataContainer.java
@@ -8,10 +8,14 @@ import com.jantuomi.interpreter.main.exception.InterpreterException;
abstract public class DataContainer<T> {
public enum Type {
- Integer
+ Integer,
+ Double,
+ String,
+ Boolean,
+ Void
}
- private Type type;
+ abstract public Type getType();
private T data;
@@ -28,4 +32,6 @@ abstract public class DataContainer<T> {
abstract public DataContainer<T> add(DataContainer<T> other) throws InterpreterException;
public abstract DataContainer<T> subtract(DataContainer<T> other) throws InterpreterException;
+ public abstract DataContainer<T> multiply(DataContainer<T> other) throws InterpreterException;
+ public abstract DataContainer<T> divide(DataContainer<T> other) throws InterpreterException;
}
diff --git a/main/core/parser/datatype/DoubleDataContainer.java b/main/core/parser/datatype/DoubleDataContainer.java
new file mode 100644
index 0000000..76849c2
--- /dev/null
+++ b/main/core/parser/datatype/DoubleDataContainer.java
@@ -0,0 +1,50 @@
+package com.jantuomi.interpreter.main.core.parser.datatype;
+
+import com.jantuomi.interpreter.main.exception.InterpreterException;
+
+/**
+ * Created by jan on 22.6.2016.
+ */
+public class DoubleDataContainer extends DataContainer<Double> {
+ public DoubleDataContainer(double value) {
+ setData(value);
+ }
+
+ @Override
+ public Type getType() {
+ return Type.Double;
+ }
+
+ @Override
+ public String toString() {
+ return getData().toString();
+ }
+
+ @Override
+ public DataContainer<Double> add(DataContainer<Double> other) throws InterpreterException {
+ return new DoubleDataContainer(
+ getData() + other.getData()
+ );
+ }
+
+ @Override
+ public DataContainer<Double> subtract(DataContainer<Double> other) throws InterpreterException {
+ return new DoubleDataContainer(
+ getData() - other.getData()
+ );
+ }
+
+ @Override
+ public DataContainer<Double> multiply(DataContainer<Double> other) throws InterpreterException {
+ return new DoubleDataContainer(
+ getData() * other.getData()
+ );
+ }
+
+ @Override
+ public DataContainer<Double> divide(DataContainer<Double> other) throws InterpreterException {
+ return new DoubleDataContainer(
+ getData() / other.getData()
+ );
+ }
+}
diff --git a/main/core/parser/datatype/IntegerDataContainer.java b/main/core/parser/datatype/IntegerDataContainer.java
index 1999131..4f71e2b 100644
--- a/main/core/parser/datatype/IntegerDataContainer.java
+++ b/main/core/parser/datatype/IntegerDataContainer.java
@@ -1,5 +1,7 @@
package com.jantuomi.interpreter.main.core.parser.datatype;
+import com.jantuomi.interpreter.main.exception.InterpreterException;
+
/**
* Created by jan on 16.6.2016.
*/
@@ -10,21 +12,80 @@ public class IntegerDataContainer extends DataContainer<Integer> {
}
@Override
+ public Type getType() {
+ return Type.Integer;
+ }
+
+ @Override
public String toString() {
return Integer.toString(getData());
}
@Override
- public DataContainer<Integer> add(DataContainer<Integer> other) {
- return new IntegerDataContainer(
- this.getData() + other.getData()
- );
+ public DataContainer add(DataContainer other) {
+ switch (other.getType()) {
+ case Integer:
+ return new IntegerDataContainer(
+ this.getData() + ((IntegerDataContainer) other).getData()
+ );
+ case Double:
+ return new DoubleDataContainer(
+ (double) getData() + ((DoubleDataContainer) other).getData()
+ );
+ default:
+ return null;
+
+ }
+ }
+
+ @Override
+ public DataContainer subtract(DataContainer other) {
+ switch (other.getType()) {
+ case Integer:
+ return new IntegerDataContainer(
+ this.getData() - ((IntegerDataContainer) other).getData()
+ );
+ case Double:
+ return new DoubleDataContainer(
+ (double) getData() - ((DoubleDataContainer) other).getData()
+ );
+ default:
+ return null;
+
+ }
}
@Override
- public DataContainer<Integer> subtract(DataContainer<Integer> other) {
- return new IntegerDataContainer(
- this.getData() - other.getData()
- );
+ public DataContainer multiply(DataContainer other) throws InterpreterException {
+ switch (other.getType()) {
+ case Integer:
+ return new IntegerDataContainer(
+ this.getData() * ((IntegerDataContainer) other).getData()
+ );
+ case Double:
+ return new DoubleDataContainer(
+ (double) getData() * ((DoubleDataContainer) other).getData()
+ );
+ default:
+ return null;
+
+ }
+ }
+
+ @Override
+ public DataContainer divide(DataContainer other) throws InterpreterException {
+ switch (other.getType()) {
+ case Integer:
+ return new IntegerDataContainer(
+ this.getData() / ((IntegerDataContainer) other).getData()
+ );
+ case Double:
+ return new DoubleDataContainer(
+ (double) getData() / ((DoubleDataContainer) other).getData()
+ );
+ default:
+ return null;
+
+ }
}
}
diff --git a/main/core/parser/datatype/StringDataContainer.java b/main/core/parser/datatype/StringDataContainer.java
index bbc9b29..68f41d9 100644
--- a/main/core/parser/datatype/StringDataContainer.java
+++ b/main/core/parser/datatype/StringDataContainer.java
@@ -1,6 +1,5 @@
package com.jantuomi.interpreter.main.core.parser.datatype;
-import com.jantuomi.interpreter.main.exception.ExceptionManager;
import com.jantuomi.interpreter.main.exception.InterpreterException;
/**
@@ -14,6 +13,11 @@ public class StringDataContainer extends DataContainer<String> {
}
@Override
+ public Type getType() {
+ return Type.String;
+ }
+
+ @Override
public String toString() {
return getData();
}
@@ -27,7 +31,16 @@ public class StringDataContainer extends DataContainer<String> {
@Override
public DataContainer<String> subtract(DataContainer<String> other) throws InterpreterException {
- ExceptionManager.raise(InterpreterException.ExceptionType.TypeError, -1, "string", "string");
+ return null;
+ }
+
+ @Override
+ public DataContainer<String> multiply(DataContainer<String> other) throws InterpreterException {
+ return null;
+ }
+
+ @Override
+ public DataContainer<String> divide(DataContainer<String> other) throws InterpreterException {
return null;
}
}
diff --git a/main/core/parser/datatype/VoidDataContainer.java b/main/core/parser/datatype/VoidDataContainer.java
index 8e078d9..098de8d 100644
--- a/main/core/parser/datatype/VoidDataContainer.java
+++ b/main/core/parser/datatype/VoidDataContainer.java
@@ -1,11 +1,18 @@
package com.jantuomi.interpreter.main.core.parser.datatype;
+import com.jantuomi.interpreter.main.exception.InterpreterException;
+
/**
* Created by jan on 17.6.2016.
*/
public class VoidDataContainer extends DataContainer<Integer> {
@Override
+ public Type getType() {
+ return Type.Void;
+ }
+
+ @Override
public String toString() {
return "";
}
@@ -19,4 +26,14 @@ public class VoidDataContainer extends DataContainer<Integer> {
public DataContainer<Integer> subtract(DataContainer<Integer> other) {
return null;
}
+
+ @Override
+ public DataContainer<Integer> multiply(DataContainer<Integer> other) throws InterpreterException {
+ return null;
+ }
+
+ @Override
+ public DataContainer<Integer> divide(DataContainer<Integer> other) throws InterpreterException {
+ return null;
+ }
}
diff --git a/main/core/runtime/Scope.java b/main/core/runtime/Scope.java
index e3bf899..0bf8907 100644
--- a/main/core/runtime/Scope.java
+++ b/main/core/runtime/Scope.java
@@ -26,7 +26,8 @@ public class Scope {
public DataContainer resolveSymbol(String symbol, List<DataContainer> params) throws InterpreterException {
if (functions.containsKey(symbol)) {
- return functions.get(symbol).evaluate(params);
+ DataContainer r = functions.get(symbol).evaluate(params);
+ return r;
}
if (variables.containsKey(symbol)) {
return variables.get(symbol);
diff --git a/main/core/runtime/builtins/AsIntBuiltinFunction.java b/main/core/runtime/builtins/AsIntBuiltinFunction.java
index 3e1c71c..210e1e4 100644
--- a/main/core/runtime/builtins/AsIntBuiltinFunction.java
+++ b/main/core/runtime/builtins/AsIntBuiltinFunction.java
@@ -5,7 +5,6 @@ import com.jantuomi.interpreter.main.core.parser.datatype.DataContainer;
import com.jantuomi.interpreter.main.core.parser.datatype.IntegerDataContainer;
import com.jantuomi.interpreter.main.core.parser.datatype.StringDataContainer;
import com.jantuomi.interpreter.main.core.runtime.Function;
-import com.jantuomi.interpreter.main.exception.ExceptionManager;
import com.jantuomi.interpreter.main.exception.InterpreterException;
import java.util.Arrays;
@@ -30,7 +29,7 @@ public class AsIntBuiltinFunction extends Function {
@Override
public DataContainer evaluate(List<DataContainer> params) throws InterpreterException {
if (params.size() != 1) {
- ExceptionManager.raise(InterpreterException.ExceptionType.SyntaxError, -1, "amount of parameters to as_int");
+ return null;
}
DataContainer param = params.get(0);
int i = 0;
@@ -39,8 +38,6 @@ public class AsIntBuiltinFunction extends Function {
i = Integer.parseInt(((StringDataContainer) param).getData());
}
catch (NumberFormatException ex) {
- ExceptionManager.raise(InterpreterException.ExceptionType.SyntaxError, -1,
- String.format("parameter %s to as_int", param.toString()));
return null;
}
}
diff --git a/main/exception/InterpreterException.java b/main/exception/InterpreterException.java
index 8421edc..ac021c0 100644
--- a/main/exception/InterpreterException.java
+++ b/main/exception/InterpreterException.java
@@ -21,19 +21,20 @@ public class InterpreterException extends Exception {
public static Map<ExceptionType, String> errorTexts = new HashMap<>();
static {
- errorTexts.put(ExceptionType.IllegalTokenError, "Illegal token %s found.");
- errorTexts.put(ExceptionType.UnknownOperatorError, "Unexpected operator %s found.");
+ errorTexts.put(ExceptionType.IllegalTokenError, "Unknown or illegal token %s found.");
errorTexts.put(ExceptionType.SyntaxError, "Unexpected %s.");
errorTexts.put(ExceptionType.TypeError, "Incompatible types %s and %s.");
- errorTexts.put(ExceptionType.ArgumentError, "Function %s requires %s arguments.");
- errorTexts.put(ExceptionType.UndeclaredSymbolError, "No symbol %s defined.");
+ errorTexts.put(ExceptionType.ArgumentError, "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, parameters: [%s].");
}
private ExceptionType exceptionType;
+ private String completeMessage;
public InterpreterException(ExceptionType exceptionType, int line, String... args) {
- super(formatMessage(exceptionType.toString() + ": " + what(exceptionType), line, args), null, false, false);
+ super(exceptionType.toString(), null, false, false);
this.exceptionType = exceptionType;
+ this.completeMessage = formatMessage(exceptionType.toString() + ": " + what(exceptionType), line, args);
}
private static String formatMessage(String message, int line, String... args) {
@@ -45,4 +46,9 @@ public class InterpreterException extends Exception {
public static String what(ExceptionType type) {
return errorTexts.get(type);
}
+
+ @Override
+ public void printStackTrace() {
+ System.err.println(completeMessage);
+ }
}
diff --git a/test/MainTest.java b/test/MainTest.java
index 1730a6b..f90e367 100644
--- a/test/MainTest.java
+++ b/test/MainTest.java
@@ -2,8 +2,13 @@ package com.jantuomi.interpreter.test;
import com.jantuomi.interpreter.main.Main;
import com.jantuomi.interpreter.main.exception.InterpreterException;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -11,6 +16,21 @@ import static org.junit.Assert.assertTrue;
* Created by jan on 10.6.2016.
*/
public class MainTest {
+
+ private final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ private PrintStream originalOut;
+
+ @Before
+ public void setupStreams() {
+ originalOut = System.out;
+ System.setOut(new PrintStream(out));
+ }
+
+ @After
+ public void cleanStreams() {
+ System.setOut(originalOut);
+ }
+
@Test
public void testParseArguments1() {
String[] notAnArgument = {"--not-an-argument"};
@@ -26,6 +46,8 @@ public class MainTest {
@Test
public void testWholeProcedure() throws InterpreterException {
String input = "- + 2 5 1";
+
Main.run(input);
+ assertTrue(out.toString().contains("6"));
}
} \ No newline at end of file
diff --git a/test/resources/program.bork b/test/resources/program.bork
index 52cee38..7034625 100644
--- a/test/resources/program.bork
+++ b/test/resources/program.bork
@@ -1,15 +1,13 @@
/* get an integer from the user */
-decl user_input
-set user_input in("give integer: ")
-out( concat("your input was: " user_input "!") )
-
-/* add 10 to the integer */
-decl operand set operand 10
+decl lhs decl rhs
+set lhs in("give an integer: ")
+set rhs in("give another: ")
+/* add the inputs together */
decl sum
-set sum + as_int(user_input) operand
+set sum + as_int(lhs) as_int(rhs)
/* print the sum */
-out( concat(user_input " + " operand " = " sum) )
+out( concat(lhs " + " rhs " = " sum) )
"done" \ No newline at end of file