aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--repl.d133
1 files changed, 59 insertions, 74 deletions
diff --git a/repl.d b/repl.d
index 9ea36d6..7026b30 100644
--- a/repl.d
+++ b/repl.d
@@ -1,103 +1,88 @@
import std.stdio;
import std.string;
import std.conv;
+import std.typecons;
+
import std.container : SList;
import std.container : DList;
-import std.variant;
-
-alias Token = Algebraic!(int, string);
-
-auto dataStack = SList!int();
-bool defMode = false;
-string defModeWord = "";
+SList!int stack;
+DList!string[string] words;
+Nullable!(DList!string) definition;
-DList!Token[string] wordMap;
-
-void push(ref DList!Token stack, int value) {
- stack.insertBack(Token(value));
+void push(ref SList!int stack, int value) {
+ if ( definition.isNull ) {
+ stack.insertFront(value);
+ } else {
+ definition.insertBack(to!string(value));
+ }
}
-void push(ref DList!Token stack, string word) {
- stack.insertBack(Token(word));
-}
+int pop(ref SList!int stack) {
+ auto x = stack.front;
+ stack.removeFront;
-void push(ref DList!Token[string] map, int value) {
- map[defModeWord].push(value);
+ return x;
}
-void push(ref DList!Token[string] map, string word) {
- if ( defModeWord == "" ) {
- defModeWord = word;
- map[defModeWord] = DList!Token();
- } else {
- map[defModeWord].push(word);
- }
-}
+void append(ref Nullable!(DList!string) definition, string token) {
+ if ( token == ";" ) {
+ auto wordToBeDefined = definition.front;
-void push(ref SList!int stack, int value) {
- if ( defMode ) {
- wordMap.push(value);
+ if ( wordToBeDefined.isNumeric ) {
+ throw new Exception("words may not be numeric");
+ } else {
+ definition.removeFront;
+ words[wordToBeDefined] = definition;
+ definition.nullify;
+ }
} else {
- stack.insertFront(value);
+ definition.insertBack(token);
}
}
-void push(ref SList!int stack, string word) {
- if ( defMode ) {
- if ( word == ";" ) {
- defMode = false;
- defModeWord = "";
- } else {
- wordMap.push(word);
- }
- } else {
- switch ( word ) {
- case "§":
- defMode = true;
- defModeWord = "";
- break;
- case "+":
- auto a = stack.pop();
- auto b = stack.pop();
+void evaluate(string word) {
+ switch ( word ) {
+ case "§":
+ definition = DList!string();
+ break;
+ case "+":
+ auto a = stack.pop();
+ auto b = stack.pop();
- stack.push(a + b);
- break;
- case "*":
- auto a = stack.pop();
- auto b = stack.pop();
+ stack.push(a + b);
+ break;
+ case "*":
+ auto a = stack.pop();
+ auto b = stack.pop();
- stack.push(a * b);
- break;
- case ".":
- writeln(stack.front);
- break;
- default:
- foreach ( token; wordMap[word] ) {
- if ( token.type == typeid(int) ) {
- stack.push(*token.peek!int);
- } else {
- stack.push(*token.peek!string);
- }
+ stack.push(a * b);
+ break;
+ case ".":
+ writeln(stack.front);
+ break;
+ default:
+ foreach ( token; words[word] ) {
+ if ( token.isNumeric ) {
+ stack.push(parse!int(token));
+ } else {
+ evaluate(token);
}
- }
+ }
}
}
-int pop(ref SList!int stack) {
- auto x = stack.front;
- stack.removeFront;
-
- return x;
-}
-
void main() {
while ( !stdin.eof ) {
- foreach ( word; stdin.readln.split ) {
- if ( word.isNumeric ) {
- dataStack.push(parse!int(word));
+ foreach ( token; stdin.readln.split ) {
+ if ( definition.isNull ) {
+ if ( token.isNumeric ) {
+ stack.push(parse!int(token));
+ } else {
+ evaluate(token);
+ }
} else {
- dataStack.push(word);
+ definition.append(token);
}
}
}