aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Kummerlaender2017-04-12 16:58:18 +0200
committerAdrian Kummerlaender2017-04-12 17:24:09 +0200
commit4804893a6616a312ac8028e42d2aa990018ffbe6 (patch)
tree7eabf5638dd29580dae9c0197804b739301885a9
parent900c223ed40e36ffedce95e9a987d9a3c0309271 (diff)
downloadslang-4804893a6616a312ac8028e42d2aa990018ffbe6.tar
slang-4804893a6616a312ac8028e42d2aa990018ffbe6.tar.gz
slang-4804893a6616a312ac8028e42d2aa990018ffbe6.tar.bz2
slang-4804893a6616a312ac8028e42d2aa990018ffbe6.tar.lz
slang-4804893a6616a312ac8028e42d2aa990018ffbe6.tar.xz
slang-4804893a6616a312ac8028e42d2aa990018ffbe6.tar.zst
slang-4804893a6616a312ac8028e42d2aa990018ffbe6.zip
Modularize primitives implementation, add stack manipulators
-rw-r--r--repl.d16
-rw-r--r--src/primitives.d96
-rw-r--r--src/primitives/eval.d48
-rw-r--r--src/primitives/impl.d119
-rw-r--r--src/stack.d17
5 files changed, 186 insertions, 110 deletions
diff --git a/repl.d b/repl.d
index 4938a11..e3aef2b 100644
--- a/repl.d
+++ b/repl.d
@@ -8,12 +8,12 @@ import std.container : SList;
import src.stack;
-static import src.definition;
-static import src.primitives;
+static import definition = src.definition;
+static import primitives = src.primitives.eval;
void process(int x) {
try {
- if ( !src.primitives.evaluate(x) ) {
+ if ( !primitives.evaluate(x) ) {
stack.push(x);
}
}
@@ -24,9 +24,9 @@ void process(int x) {
void process(string word) {
try {
- if ( !src.primitives.evaluate(word) ) {
- if ( word in src.definition.words ) {
- foreach ( token; src.definition.words[word] ) {
+ if ( !primitives.evaluate(word) ) {
+ if ( word in definition.words ) {
+ foreach ( token; definition.words[word] ) {
process(token);
}
} else {
@@ -52,11 +52,11 @@ void main() {
if ( token.isNumeric ) {
immutable int value = parse!int(token);
- if ( !src.definition.handle(value) ) {
+ if ( !definition.handle(value) ) {
process(value);
}
} else {
- if ( !src.definition.handle(token) ) {
+ if ( !definition.handle(token) ) {
process(token);
}
}
diff --git a/src/primitives.d b/src/primitives.d
deleted file mode 100644
index f577713..0000000
--- a/src/primitives.d
+++ /dev/null
@@ -1,96 +0,0 @@
-module src.primitives;
-
-import std.stdio;
-
-import src.stack;
-import src.definition;
-
-int[string] variables;
-bool drop_mode;
-
-bool evaluate(int value) {
- return drop_mode;
-}
-
-bool evaluate(string word) {
- if ( drop_mode ) {
- if ( word == "then" ) {
- drop_mode = false;
- }
-
- return true;
- }
-
- switch ( word ) {
- case "§":
- src.definition.start;
- return true;
- case "$":
- string name = stack.pop.get!string;
- int value = stack.pop.get!int;
-
- variables[name] = value;
- return true;
- case "@":
- string name = stack.pop.get!string;
-
- if ( name in variables ) {
- stack.push(variables[name]);
- }
- return true;
- case "if":
- switch ( stack.pop.get!int ) {
- case 0:
- drop_mode = true;
- return true;
- case 1:
- drop_mode = false;
- return true;
- default:
- throw new Exception("invalid logic value");
- }
- case "then":
- drop_mode = false;
- return true;
- case "+":
- int b = stack.pop.get!int;
- int a = stack.pop.get!int;
-
- stack.push(a + b);
- return true;
- case "*":
- int b = stack.pop.get!int;
- int a = stack.pop.get!int;
-
- stack.push(a * b);
- return true;
- case "/":
- int b = stack.pop.get!int;
- int a = stack.pop.get!int;
-
- if ( b == 0 ) {
- throw new Exception("division by 0 undefined");
- } else {
- stack.push(a / b);
- }
- return true;
- case "%":
- int b = stack.pop.get!int;
- int a = stack.pop.get!int;
-
- if ( b == 0 ) {
- throw new Exception("modulo 0 undefined");
- } else {
- stack.push(a % b);
- }
- return true;
- case ".":
- stack.pop;
- return true;
- case "'":
- writeln(stack.top);
- return true;
- default:
- return false;
- }
-}
diff --git a/src/primitives/eval.d b/src/primitives/eval.d
new file mode 100644
index 0000000..3f91e80
--- /dev/null
+++ b/src/primitives/eval.d
@@ -0,0 +1,48 @@
+module src.primitives.eval;
+
+import src.primitives.impl;
+
+bool evaluate(int value) {
+ return drop_mode;
+}
+
+bool evaluate(string word) {
+ if ( drop_mode ) {
+ if ( word == "then" ) {
+ return conditional_end;
+ } else {
+ return true;
+ }
+ }
+
+ switch ( word ) {
+ case "§":
+ return definition_start;
+ case "$":
+ return binary_op_variable_bind;
+ case "@":
+ return unary_op_variable_resolve;
+ case "if":
+ return conditional_start;
+ case "then":
+ return conditional_end;
+ case "+":
+ return binary_op_add;
+ case "*":
+ return binary_op_multiply;
+ case "/":
+ return binary_op_divide;
+ case "%":
+ return binary_op_modulo;
+ case ".":
+ return unary_op_io_print;
+ case "pop":
+ return unary_op_stack_pop;
+ case "dup":
+ return unary_op_stack_dup;
+ case "swp":
+ return binary_op_stack_swp;
+ default:
+ return false;
+ }
+}
diff --git a/src/primitives/impl.d b/src/primitives/impl.d
new file mode 100644
index 0000000..4ec9019
--- /dev/null
+++ b/src/primitives/impl.d
@@ -0,0 +1,119 @@
+module src.primitives.impl;
+
+import std.stdio;
+
+import src.stack;
+import src.definition;
+
+int[string] variables;
+bool drop_mode;
+
+bool definition_start() {
+ src.definition.start;
+ return true;
+}
+
+bool binary_op_variable_bind() {
+ string name = stack.pop.get!string;
+ int value = stack.pop.get!int;
+
+ variables[name] = value;
+ return true;
+}
+
+bool unary_op_variable_resolve() {
+ string name = stack.pop.get!string;
+
+ if ( name in variables ) {
+ stack.push(variables[name]);
+ }
+
+ return true;
+}
+
+bool conditional_start() {
+ switch ( stack.pop.get!int ) {
+ case 0:
+ drop_mode = true;
+ return true;
+ case 1:
+ drop_mode = false;
+ return true;
+ default:
+ throw new Exception("invalid logic value");
+ }
+}
+
+bool conditional_end() {
+ drop_mode = false;
+ return true;
+}
+
+bool binary_op_add() {
+ int b = stack.pop.get!int;
+ int a = stack.pop.get!int;
+
+ stack.push(a + b);
+
+ return true;
+}
+
+bool binary_op_multiply() {
+ int b = stack.pop.get!int;
+ int a = stack.pop.get!int;
+
+ stack.push(a * b);
+
+ return true;
+}
+
+bool binary_op_divide() {
+ int b = stack.pop.get!int;
+ int a = stack.pop.get!int;
+
+ if ( b == 0 ) {
+ throw new Exception("division by 0 undefined");
+ } else {
+ stack.push(a / b);
+ }
+
+ return true;
+}
+
+bool binary_op_modulo() {
+ int b = stack.pop.get!int;
+ int a = stack.pop.get!int;
+
+ if ( b == 0 ) {
+ throw new Exception("modulo 0 undefined");
+ } else {
+ stack.push(a % b);
+ }
+
+ return true;
+}
+
+bool unary_op_io_print() {
+ writeln(stack.top);
+ return true;
+}
+
+bool unary_op_stack_pop() {
+ stack.pop;
+ return true;
+}
+
+bool unary_op_stack_dup() {
+ stack.push(stack.top);
+ return true;
+}
+
+bool binary_op_stack_swp() {
+ auto b = stack.pop;
+ auto a = stack.pop;
+
+ stack.push(b);
+ stack.push(a);
+
+ return true;
+}
diff --git a/src/stack.d b/src/stack.d
index 756dafc..6805873 100644
--- a/src/stack.d
+++ b/src/stack.d
@@ -25,14 +25,19 @@ Token pop(ref Stack!Token stack) {
return token;
}
-void push(ref Stack!Token stack, int value) {
- if ( !src.definition.handle(value) ) {
- stack.insertFront(Token(value));
+void push(ref Stack!Token stack, Token token) {
+ if ( !token.visit!(
+ (int x ) => src.definition.handle(x),
+ (string word) => src.definition.handle(word)
+ ) ) {
+ stack.insertFront(token);
}
}
+void push(ref Stack!Token stack, int value) {
+ stack.push(Token(value));
+}
+
void push(ref Stack!Token stack, string word) {
- if ( !src.definition.handle(word) ) {
- stack.insertFront(Token(word));
- }
+ stack.push(Token(word));
}