diff options
author | Adrian Kummerlaender | 2017-04-11 21:35:17 +0200 |
---|---|---|
committer | Adrian Kummerlaender | 2017-04-11 21:35:17 +0200 |
commit | 9fa3bcf8d3d8801ae01530afa3cff9a31e22a0a7 (patch) | |
tree | a5c30f158d139c3313c1fd1238d0b94cffe174be | |
parent | 57ab42eabb5a9a7ddf7d6a416bf18eca63336a87 (diff) | |
download | slang-9fa3bcf8d3d8801ae01530afa3cff9a31e22a0a7.tar slang-9fa3bcf8d3d8801ae01530afa3cff9a31e22a0a7.tar.gz slang-9fa3bcf8d3d8801ae01530afa3cff9a31e22a0a7.tar.bz2 slang-9fa3bcf8d3d8801ae01530afa3cff9a31e22a0a7.tar.lz slang-9fa3bcf8d3d8801ae01530afa3cff9a31e22a0a7.tar.xz slang-9fa3bcf8d3d8801ae01530afa3cff9a31e22a0a7.tar.zst slang-9fa3bcf8d3d8801ae01530afa3cff9a31e22a0a7.zip |
Simplify word definition, evaluation
-rw-r--r-- | repl.d | 133 |
1 files changed, 59 insertions, 74 deletions
@@ -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); } } } |