aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Kummerlaender2017-04-12 11:45:40 +0200
committerAdrian Kummerlaender2017-04-12 11:45:40 +0200
commitc0bf1dc624f373872d5dd8e67d756d3ec70830e7 (patch)
treeb5978a5cbd8b7040529289e2980af56823a911a4
parent29626d3beaabdc638ed5cb52f2b252bb35e7ec0b (diff)
downloadslang-c0bf1dc624f373872d5dd8e67d756d3ec70830e7.tar
slang-c0bf1dc624f373872d5dd8e67d756d3ec70830e7.tar.gz
slang-c0bf1dc624f373872d5dd8e67d756d3ec70830e7.tar.bz2
slang-c0bf1dc624f373872d5dd8e67d756d3ec70830e7.tar.lz
slang-c0bf1dc624f373872d5dd8e67d756d3ec70830e7.tar.xz
slang-c0bf1dc624f373872d5dd8e67d756d3ec70830e7.tar.zst
slang-c0bf1dc624f373872d5dd8e67d756d3ec70830e7.zip
Implement support for variables, mixed types in data stack
-rw-r--r--repl.d117
1 files changed, 85 insertions, 32 deletions
diff --git a/repl.d b/repl.d
index 9117c28..9f1d131 100644
--- a/repl.d
+++ b/repl.d
@@ -6,37 +6,51 @@ import std.typecons;
import std.container : SList;
import std.container : DList;
-SList!int stack;
-DList!string[string] words;
-Nullable!(DList!string) definition;
+import std.variant;
+
+alias Token = Algebraic!(int, string);
+
+SList!Token stack;
+DList!Token[string] words;
+int[string] variables;
+Nullable!(DList!Token) definition;
void startDefinition()
in { assert( definition.isNull); }
out { assert(!definition.isNull); }
body {
- definition = DList!string();
+ definition = DList!Token();
}
void endDefinition()
in { assert(!definition.isNull); }
out { assert( definition.isNull); }
body {
- auto wordToBeDefined = definition.front;
+ string wordToBeDefined;
+
+ definition.front.visit!(
+ (int x ) => wordToBeDefined = "",
+ (string name) => wordToBeDefined = name
+ );
- if ( wordToBeDefined.isNumeric ) {
+ if ( wordToBeDefined == "" ) {
throw new Exception("words may not be numeric");
- } else {
- definition.removeFront;
- words[wordToBeDefined] = definition;
- definition.nullify;
}
+
+ definition.removeFront;
+ words[wordToBeDefined] = definition;
+ definition.nullify;
}
-void append(ref Nullable!(DList!string) definition, string token) {
- if ( token == ";" ) {
+void append(ref Nullable!(DList!Token) definition, int value) {
+ definition.insertBack(Token(value));
+}
+
+void append(ref Nullable!(DList!Token) definition, string word) {
+ if ( word == ";" ) {
endDefinition();
} else {
- definition.insertBack(token);
+ definition.insertBack(Token(word));
}
}
@@ -45,15 +59,28 @@ void evaluate(string word) {
case "ยง":
startDefinition();
break;
+ case "$":
+ string name = stack.pop().get!string;
+ int value = stack.pop().get!int;
+
+ variables[name] = value;
+ break;
+ case "@":
+ string name = stack.pop().get!string;
+
+ if ( name in variables ) {
+ stack.push(variables[name]);
+ }
+ break;
case "+":
- auto a = stack.pop();
- auto b = stack.pop();
+ int a = stack.pop().get!int;
+ int b = stack.pop().get!int;
stack.push(a + b);
break;
case "*":
- auto a = stack.pop();
- auto b = stack.pop();
+ int a = stack.pop().get!int;
+ int b = stack.pop().get!int;
stack.push(a * b);
break;
@@ -61,42 +88,68 @@ void evaluate(string word) {
writeln(stack.front);
break;
default:
- foreach ( token; words[word] ) {
- process(token);
+ if ( word in words ) {
+ foreach ( token; words[word] ) {
+ process(token);
+ }
+ } else {
+ stack.push(word);
}
}
}
-void process(string token) {
- if ( token.isNumeric ) {
- stack.push(parse!int(token));
+void process(Token token) {
+ token.visit!(
+ (int x ) => process(x),
+ (string word) => process(word)
+ );
+}
+
+void process(int x) {
+ stack.push(x);
+}
+
+void process(string word) {
+ evaluate(word);
+}
+
+void push(ref SList!Token stack, int value) {
+ if ( definition.isNull ) {
+ stack.insertFront(Token(value));
} else {
- evaluate(token);
+ definition.append(value);
}
}
-void push(ref SList!int stack, int value) {
+void push(ref SList!Token stack, string word) {
if ( definition.isNull ) {
- stack.insertFront(value);
+ stack.insertFront(Token(word));
} else {
- definition.append(to!string(value));
+ definition.append(word);
}
}
-int pop(ref SList!int stack) {
- auto x = stack.front;
+Token pop(ref SList!Token stack) {
+ Token token = stack.front;
stack.removeFront;
-
- return x;
+ return token;
}
void main() {
while ( !stdin.eof ) {
foreach ( token; stdin.readln.split ) {
if ( definition.isNull ) {
- process(token);
+ if ( token.isNumeric ) {
+ process(parse!int(token));
+ } else {
+ process(token);
+ }
} else {
- definition.append(token);
+ if ( token.isNumeric ) {
+ definition.append(parse!int(token));
+ } else {
+ definition.append(token);
+ }
}
}
}