Skip to content

Instantly share code, notes, and snippets.

@martintrojer
Last active December 18, 2015 01:59
Show Gist options
  • Save martintrojer/5707573 to your computer and use it in GitHub Desktop.
Save martintrojer/5707573 to your computer and use it in GitHub Desktop.
Scheme Scala
def eval(env: Env, expr: ExprT): (Env, ExprT) = expr match {
case NullExpr() => throw new IllegalStateException("invalid interpreter state")
case Comb(List()) => throw new IllegalStateException("invalid combination")
case Comb(h :: t) =>
eval(env, h) match {
case (_, Proc(f)) => apply(f, t, env)
case (nEnv, Func(args, body)) => {
if (args.length != t.length) throw new IllegalArgumentException("invalid number or arguments")
val newEnv = (args zip t).foldLeft(nEnv.expand())((acc, av) => bindArg(acc, av._1, av._2))
evalAll(newEnv, body)
}
case (nEnv, expr) => (nEnv, expr)
}
case Proc(f) => (env, Proc(f))
case Func(args, body) => throw new IllegalArgumentException("invalid function call")
case v @ Value(_) => (env, v)
case l @ List(_) => (env, l)
case Symbol(s) =>
env.lookUp(s) match {
case Some(e) => (env, e)
case None => throw new IllegalArgumentException("unbound symbol '" + s +"'")
}
}
private def apply(f: ((Env, List[ExprT]) => (Env, ExprT)),
args: List[ExprT], env: Env) =
f(env, args)
import scala.util.parsing.combinator._
object Parser extends JavaTokenParsers {
def value: Parser[ValueT] = stringLiteral ^^ (x => Name(x.tail.init)) |
floatingPointNumber ^^ (x => Num(BigDecimal(x)))
def expression: Parser[ExprT] = value ^^ (x => Value(x)) |
"""[^()\s]+""".r ^^ (x => Symbol(x)) |
combination
def combination: Parser[Comb] = "(" ~> rep(expression) <~ ")" ^^ (x => Comb(x))
def program: Parser[List[ExprT]] = rep(expression)
// ---
def parse(source: String) = parseAll(program, source).get
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment