exercism/dart/forth/lib/forth.dart

104 lines
2.1 KiB
Dart

class Forth {
List<int> stack = <int>[];
Map customCmds = Map<String, String>.of({});
List<int> evaluate(String input) {
List<String> pts = input.toLowerCase().split(" ");
for(int i = 0; i < pts.length; i++) {
int? val = int.tryParse(pts[i]);
if(val == null) {
if(customCmds.containsKey(pts[i])) {
return evaluate(customCmds[pts[i]]);
} else {
switch(pts[i]) {
case ':': {
_addCommand(pts.sublist(1));
} break;
case '+': {
_add();
} break;
case '-': {
_sub();
} break;
case '*': {
_mult();
} break;
case '/': {
_div();
} break;
case 'dup': {
_dup();
} break;
case 'drop': {
_drop();
} break;
case 'swap': {
_swap();
} break;
case 'over': {
_over();
} break;
default: {
throw Exception('Unknown command');
} break;
}
}
} else {
_push(val);
}
}
return stack;
}
int _pop() {
if(stack.length > 0) {
int wrk = stack.last;
stack.removeLast();
return wrk;
} else {
throw Exception('Stack empty');
}
}
_push(int v) => stack.add(v);
_add() => _push(_pop() + _pop());
_sub() {
int v2 = _pop();
int v1 = _pop();
_push(v1 - v2);
}
_mult() => _push(_pop() * _pop());
_div() {
int v2 = _pop();
int v1 = _pop();
if(v2 == 0) {
throw Exception('Division by zero');
}
_push((v1 / v2).toInt());
}
_dup() {
int v1 = _pop();
_push(v1);
_push(v1);
}
_drop() => _pop();
_swap() {
int v2 = _pop();
int v1 = _pop();
_push(v2);
_push(v1);
}
_over() {
int v2 = _pop();
int v1 = _pop();
_push(v1);
_push(v2);
_push(v1);
}
_addCommand(List<String> pts) {
String keyword = pts[0];
customCmds[keyword] = pts.sublist(1, pts.length-2).join(" ");
}
}