No longer in development
9. Examples

9. Examples

This example is for a Reverse Polish Notation (RPN) calculator. The Squiggle version contains more exception throwing, which is automatically generated by Squiggle.

If you're not familiar with RPN, here's a quick translation:

RPN: 2 3 4 * 3 - +

Normal: 2 + ((3 * 4) - 3)

rpn.js

var text = "2 3 4 * 3 - +";

function tokenize(text) {
  return text.split(" ").map(tokenValue);
}

var table = {
  "+": function(a, b) { return a + b; },
  "-": function(a, b) { return a - b; },
  "*": function(a, b) { return a * b; },
  "/": function(a, b) { return a / b; }
};

function tokenValue(token) {
  if (table.hasOwnProperty(token)) {
    return table[token];
  } else {
    return Number(token);
  }
}

function evaluate_(stack, values) {
  if (values.length === 0) {
    return stack[0];
  }
  var i = stack.length;
  var x = values[0];
  var v = values.slice(1);
  if (typeof x === "function") {
    var a = stack[i - 1];
    var b = stack[i - 2];
    var y = x(a, b);
    var newStack = stack.slice(0, i - 2).concat([y]);
  } else {
    var newStack = stack.concat([x]);
  }
  return evaluate_(newStack, v);
}

function evaluate(text) {
  return evaluate_([], tokenize(text));
}

console.log(evaluate(text));

rpn.squiggle

let {Number, console} = global

let text = "2 3 4 * 3 - +"

def tokenize(text) do
  text.split(" ").map(fn(x, ...) tokenValue(x))
end

def tokenValue(token) do
  match token
  case "+" then ["Func", fn(a, b) a + b]
  case "-" then ["Func", fn(a, b) a - b]
  case "*" then ["Func", fn(a, b) a * b]
  case "/" then ["Func", fn(a, b) a / b]
  case num then ["Num", Number(num)]
  end
end

def evaluate_(stack, values) do
  match [stack, values]
  case [[first, second, ...rest], [["Func", f], ...xs]] then
    evaluate_([f(first, second)] ++ rest, xs)
  case [stack, [["Num", n], ...xs]] then
    evaluate_([n] ++ stack, xs)
  case [[value, ...], _] then
    value
  end
end

def evaluate(text) do
  evaluate_([], tokenize(text))
end

console.log(evaluate(text))