diff options
| author | Adrian Kummerlaender | 2017-04-12 11:45:40 +0200 | 
|---|---|---|
| committer | Adrian Kummerlaender | 2017-04-12 11:45:40 +0200 | 
| commit | c0bf1dc624f373872d5dd8e67d756d3ec70830e7 (patch) | |
| tree | b5978a5cbd8b7040529289e2980af56823a911a4 | |
| parent | 29626d3beaabdc638ed5cb52f2b252bb35e7ec0b (diff) | |
| download | slang-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.d | 117 | 
1 files changed, 85 insertions, 32 deletions
@@ -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); +				}  			}  		}  	}  | 
