Skip to content

Commit

Permalink
Error positions
Browse files Browse the repository at this point in the history
  • Loading branch information
Villane committed Jul 2, 2013
1 parent c92c9a4 commit 35c3b04
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 8 deletions.
4 changes: 3 additions & 1 deletion src/lambda/AST.scala
@@ -1,6 +1,8 @@
package lambda

sealed trait Expr
import scala.util.parsing.input.Positional

sealed trait Expr extends Positional

case class Lambda(arg: Var, body: Expr) extends Expr

Expand Down
10 changes: 5 additions & 5 deletions src/lambda/LambdaParser.scala
Expand Up @@ -12,11 +12,11 @@ class LambdaParser extends StdTokenParsers with PackratParsers {
type P[+T] = PackratParser[T]
lazy val expr: P[Expr] = application | notApp
lazy val notApp = variable | parens | lambda
lazy val lambda: P[Lambda] = ("λ" | "\\") ~> variable ~ "." ~ expr ^^
{ case v ~ "." ~ e => Lambda(v, e) }
lazy val application: P[Apply] = expr ~ notApp ^^
{ case left ~ right => Apply(left, right) }
lazy val variable: P[Var] = ident ^^ Var.apply
lazy val lambda: P[Lambda] = positioned(("λ" | "\\") ~> variable ~ "." ~ expr ^^
{ case v ~ "." ~ e => Lambda(v, e) })
lazy val application: P[Apply] = positioned(expr ~ notApp ^^
{ case left ~ right => Apply(left, right) })
lazy val variable: P[Var] = positioned(ident ^^ Var.apply)
lazy val parens: P[Expr] = "(" ~> expr <~ ")"

def parse(str: String): ParseResult[Expr] = {
Expand Down
10 changes: 9 additions & 1 deletion src/lambda/LambdaREPL.scala
Expand Up @@ -13,7 +13,15 @@ object LambdaREPL {
val exprSrc = readLine("λ> ")
import parser.{Success, NoSuccess}
parser.parse(exprSrc) match {
case Success(expr, _) => println(pretty(eval(bind(expr))))
case Success(expr, _) =>
val bound = bind(expr)
if (bind.messages.isEmpty)
println(pretty(eval(bound)))
else {
for (m <- bind.messages)
println(m.pos.longString + m.msg)
bind.messages.clear()
}
case err: NoSuccess => println(err)
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/lambda/Message.scala
@@ -0,0 +1,5 @@
package lambda

import scala.util.parsing.input.Position

case class Message(pos: Position, msg: String)
7 changes: 6 additions & 1 deletion src/lambda/Scope.scala
@@ -1,5 +1,7 @@
package lambda

import scala.collection.mutable.ListBuffer

object Scope {
var id = 0
def nextId = { val i = id; id += 1; i }
Expand All @@ -19,6 +21,7 @@ class Scope(val parent: Option[Scope], val boundNames: Set[String]) {
}

class Binder() {
val messages = ListBuffer[Message]()

def apply(term: Expr) = bind(term, Scope.TOP)

Expand All @@ -29,7 +32,9 @@ class Binder() {
case v @ Var(name, _) =>
(parent closestBinding name) match {
case Some(scope) => v.copy(scope = scope)
case None => sys.error("Undefined variable: " + name)
case None =>
messages += Message(v.pos, "Unbound variable: " + name)
v
}
case Apply(fun, arg) =>
Apply(bind(fun, parent), bind(arg, parent))
Expand Down

0 comments on commit 35c3b04

Please sign in to comment.