Permalink
Browse files

added equality

  • Loading branch information...
edofic committed Aug 27, 2012
1 parent 129e017 commit 97312113282b484fa53357f61fb05990da0cd3ea
@@ -10,19 +10,19 @@ import ScratRuntime.FunctionVarArg
* Time: 10:15 PM
*/
class Evaluator(runtime: ScratRuntime) {
private def binary[L, R](l: Expression, r: Expression)(f: (L, R) => Any) = (apply(l), apply(r)) match {
case (l: L, r: R) => f(l, r)
case other => throw new ScratInvalidTypeError(String.format("in %s got %s", f.toString(), other.toString))
private def binaryDouble(l: Expression, r: Expression)(f: (Double, Double) => Double): Double = (apply(l), apply(r)) match {
case (a: Double, b: Double) => f(a, b)
case other => throw new ScratInvalidTypeError("expected two doubles, got " + other)
}
def apply(e: Expression): Any = e match {
case Number(n) => n
case SString(s) => s
case Add(l, r) => binary(l, r)((_: Double) + (_: Double))
case Subtract(l, r) => binary(l, r)((_: Double) - (_: Double))
case Multiply(l, r) => binary(l, r)((_: Double) * (_: Double))
case Divide(l, r) => binary(l, r)((_: Double) / (_: Double))
case Exponent(l, r) => binary(l, r)(math.pow _)
case Add(l, r) => binaryDouble(l, r)(_ + _)
case Subtract(l, r) => binaryDouble(l, r)(_ - _)
case Multiply(l, r) => binaryDouble(l, r)(_ * _)
case Divide(l, r) => binaryDouble(l, r)(_ / _)
case Exponent(l, r) => binaryDouble(l, r)(math.pow)
case Identifier(name) => {
runtime.get(name) match {
case Some(v) => v
@@ -39,6 +39,12 @@ class Evaluator(runtime: ScratRuntime) {
runtime.put(name.id, e)
e
}
case IfThenElse(pred, then, els) => apply(pred) match {
case d: Double => if (d != 0) apply(then) else apply(els)
case other => throw new ScratInvalidTypeError("expected a number, got " + other)
}
case Equals(l, r) => (if (apply(l) == apply(r)) 1 else 0): Double
case NotEquals(l, r) => (if (apply(l) != apply(r)) 1 else 0): Double
case t => throw new ScratInvalidTokenError(t + " not implemented in evaluator")
}
}
@@ -70,7 +70,24 @@ object Parser extends RegexParsers {
case id ~ "=" ~ exp => Assignment(id, exp)
}
private def expr: Parser[Expression] = sum ||| assignment
private def ifThenElse: Parser[IfThenElse] = "if" ~ expr ~ "then" ~ expr ~ "else" ~ expr ^^ {
case "if" ~ predicate ~ "then" ~ then ~ "else" ~ els => IfThenElse(predicate, then, els)
}
private def equality: Parser[Expression] = noEqExpr ~ rep(("==" | "!=") ~ noEqExpr) ^^ {
case head ~ tail => {
var tree: Expression = head
tail.foreach {
case "==" ~ e => tree = Equals(tree, e)
case "!=" ~ e => tree = NotEquals(tree, e)
}
tree
}
}
private def noEqExpr: Parser[Expression] = sum ||| assignment ||| ifThenElse
private def expr = noEqExpr ||| equality
def apply(s: String): Expression = parseAll(expr, s) match {
case Success(tree, _) => tree
@@ -21,14 +21,14 @@ object Repl {
|
|Language:
|-mathematical expressions containing
| + - * / ( ) ^(exponent) variable-names function application-e.g. ln(10), println(1,2,3)
| == != + - * / ^ ( ) variable-names function application-e.g. ln(10), println(1,2,3)
|-strings
|-assignments
| x = ln(4)
| println("x is ", x)
| println("x is", x)
|-standard library
| constants: pi, e
| functions: ln, log, print, println, readln, mkString
| functions: ln, log, print, println, readln, mkString, toNum
""".stripMargin
def repl() {
@@ -26,7 +26,8 @@ class ScratRuntime {
("mkString" -> functions.mkString),
("print" -> functions.sprint),
("println" -> functions.sprintln),
("readln" -> functions.sreadln)
("readln" -> functions.sreadln),
("toNum" -> functions.toNum)
)
val get: String => Option[Any] = identifiers.get
@@ -63,6 +64,12 @@ class ScratRuntime {
lazy val sreadln: FunctionVarArg = _ => {
readLine()
}
lazy val toNum: FunctionVarArg = {
case (s: String) :: Nil => s.toDouble
case (d: Double) :: Nil => d
case other => throw ScratInvalidTypeError("expected a string or a double but got " + other)
}
}
}
@@ -31,4 +31,10 @@ object Tokens {
case class Assignment(to: Identifier, from: Expression) extends Expression
case class IfThenElse(predicate: Expression, then: Expression, els: Expression) extends Expression
case class Equals(left: Expression, right: Expression) extends Expression
case class NotEquals(left: Expression, right: Expression) extends Expression
}
View
@@ -0,0 +1,4 @@
print("enter passcode")
pass = "password"
state = if readln()==pass then "granted" else "denied"
println("access", state)
View
@@ -1,3 +1,3 @@
print("who are you: ")
name = readln()
print("hello ", name)
print("hello", name)

0 comments on commit 9731211

Please sign in to comment.