Skip to content

Instantly share code, notes, and snippets.

@FeepingCreature
Created July 6, 2022 10:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FeepingCreature/2fcc82cecdf27b4301d3feed06fcc5bf to your computer and use it in GitHub Desktop.
Save FeepingCreature/2fcc82cecdf27b4301d3feed06fcc5bf to your computer and use it in GitHub Desktop.
module rpn;
macro import std.macro.assert;
import std.algorithm;
import std.stdio;
import std.string;
alias Token = (:add|:sub|:mul|:div|:mod|int);
void main(string[] args) {
auto rpn = args.map(a => a.parse).array.rpn;
rpn.case {
string error: print("failed: $error");
int i: print("> $i");
}
}
(int | string) rpn(Token[] tokens) {
mut int[] stack;
int pop() {
int ret = stack[$ - 1];
stack = stack[0 .. $ - 1];
return ret;
}
for (op in tokens) op.case {
int i: stack ~= i;
default:
if (stack.length < 2) return "not enough tokens for $(op.repr)";
auto b = pop;
auto a = pop;
op.case {
:add: stack ~= a + b;
:sub: stack ~= a - b;
:mul: stack ~= a * b;
:div: stack ~= a / b;
:mod: stack ~= a % b;
default: assert(false);
}
// print("$a $(op.repr) $b = $(stack[$ - 1])");
}
return pop;
}
Token parse(string arg) {
if (arg == "+") return :add;
if (arg == "-") return :sub;
if (arg == "*") return :mul;
if (arg == "/") return :div;
if (arg == "%") return :mod;
return arg.atoi;
}
string repr(Token token) {
return token.case(
:add: "+", :sub: "-", :mul: "*", :div: "/", :mod: "%",
int i: "$i");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment