104 lines
2.1 KiB
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(" ");
|
|
}
|
|
}
|