diff options
-rw-r--r-- | repl.d | 24 | ||||
-rw-r--r-- | src/definition.d | 30 | ||||
-rw-r--r-- | src/primitives/eval.d | 8 | ||||
-rw-r--r-- | src/primitives/impl.d | 27 | ||||
-rw-r--r-- | src/stack.d | 18 |
5 files changed, 62 insertions, 45 deletions
@@ -11,14 +11,17 @@ import src.stack; static import definition = src.definition; static import primitives = src.primitives.eval; -void process(int x) { - try { - if ( !primitives.evaluate(x) ) { - stack.push(x); +template process(T) +if ( is(T == int) || is(T == bool) ) { + void process(T value) { + try { + if ( !primitives.evaluate(value) ) { + stack.push(value); + } + } + catch (Exception ex) { + writeln("Error: ", ex.msg); } - } - catch (Exception ex) { - writeln("Error: ", ex.msg); } } @@ -41,8 +44,9 @@ void process(string word) { void process(Token token) { token.visit!( - (int x ) => process(x), - (string word) => process(word) + (int value) => process(value), + (bool value) => process(value), + (string word ) => process(word) ); } @@ -50,7 +54,7 @@ void main() { while ( !stdin.eof ) { foreach ( token; stdin.readln.split ) { if ( token.isNumeric ) { - immutable int value = parse!int(token); + auto value = parse!int(token); if ( !definition.handle(value) ) { process(value); diff --git a/src/definition.d b/src/definition.d index dd4dddc..e6a7789 100644 --- a/src/definition.d +++ b/src/definition.d @@ -20,12 +20,13 @@ void end() { string wordToBeDefined; definition.front.visit!( - (int x ) => wordToBeDefined = "", - (string name) => wordToBeDefined = name + (int value) => wordToBeDefined = "", + (bool value) => wordToBeDefined = "", + (string name ) => wordToBeDefined = name ); if ( wordToBeDefined == "" ) { - throw new Exception("words may not be numeric"); + throw new Exception("words may not be numeric or boolean"); } definition.removeFront; @@ -33,12 +34,15 @@ void end() { definition.nullify; } -bool handle(int value) { - if ( definition.isNull ) { - return false; - } else { - definition.insertBack(Token(value)); - return true; +template handle(T) +if ( is(T == int) || is(T == bool) ) { + bool handle(T value) { + if ( definition.isNull ) { + return false; + } else { + definition.insertBack(Token(value)); + return true; + } } } @@ -55,3 +59,11 @@ bool handle(string word) { return true; } } + +bool handle(Token token) { + return token.visit!( + (int value) => handle(value), + (bool value) => handle(value), + (string word ) => handle(word) + ); +} diff --git a/src/primitives/eval.d b/src/primitives/eval.d index 533f491..d62fdb8 100644 --- a/src/primitives/eval.d +++ b/src/primitives/eval.d @@ -6,6 +6,10 @@ bool evaluate(int value) { return drop_mode; } +bool evaluate(bool value) { + return drop_mode; +} + bool evaluate(string word) { if ( drop_mode ) { switch ( word ) { @@ -47,6 +51,10 @@ bool evaluate(string word) { return unary_op_stack_dup; case "swp": return binary_op_stack_swp; + case "true": + return integral_value_bool(true); + case "false": + return integral_value_bool(false); case "<": return binary_cond_lt; case "=": diff --git a/src/primitives/impl.d b/src/primitives/impl.d index cac3e64..dd257cc 100644 --- a/src/primitives/impl.d +++ b/src/primitives/impl.d @@ -5,8 +5,8 @@ import std.stdio; import src.stack; import src.definition; -int[string] variables; -bool drop_mode; +Token[string] variables; +bool drop_mode; bool definition_start() { src.definition.start; @@ -15,7 +15,7 @@ bool definition_start() { bool binary_op_variable_bind() { string name = stack.pop.get!string; - int value = stack.pop.get!int; + Token value = stack.pop; variables[name] = value; return true; @@ -32,16 +32,8 @@ bool unary_op_variable_resolve() { } bool conditional_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"); - } + drop_mode = !stack.pop.get!bool; + return true; } bool conditional_then() { @@ -132,9 +124,14 @@ bool binary_cond_lt() { } bool binary_cond_eq() { - int b = stack.pop.get!int; - int a = stack.pop.get!int; + auto b = stack.pop; + auto a = stack.pop; stack.push(a == b); return true; } + +bool integral_value_bool(bool value) { + stack.push(Token(value)); + return true; +} diff --git a/src/stack.d b/src/stack.d index 6805873..2fb602b 100644 --- a/src/stack.d +++ b/src/stack.d @@ -6,7 +6,7 @@ import std.container : SList; static import src.definition; -alias Token = Algebraic!(int, string); +alias Token = Algebraic!(int, bool, string); alias Stack = SList; Stack!Token stack; @@ -26,18 +26,14 @@ Token pop(ref Stack!Token stack) { } void push(ref Stack!Token stack, Token token) { - if ( !token.visit!( - (int x ) => src.definition.handle(x), - (string word) => src.definition.handle(word) - ) ) { + if ( !src.definition.handle(token) ) { stack.insertFront(token); } } -void push(ref Stack!Token stack, int value) { - stack.push(Token(value)); -} - -void push(ref Stack!Token stack, string word) { - stack.push(Token(word)); +template push(T) +if ( is(T == int) || is(T == bool) || is (T == string) ) { + void push(ref Stack!Token stack, T value) { + stack.push(Token(value)); + } } |