Permalink
Browse files

added variables

  • Loading branch information...
edofic committed Aug 26, 2012
1 parent dad2f2a commit 51008205be59ec325dcb1de2f1058071c1703f4a
@@ -1,17 +1,16 @@
package com.edofic.scrat
import com.edofic.scrat.Util.Exceptions._
import com.edofic.scrat.StdLib.FunctionVarArg
import Tokens._
import ScratRuntime.FunctionVarArg
/**
* User: andraz
* Date: 8/25/12
* Time: 10:15 PM
*/
object Evaluator {
import Tokens._
val runtime = new 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)
@@ -27,20 +26,25 @@ object Evaluator {
case Divide(l, r) => binary(l, r)((_: Double) / (_: Double))
case Exponent(l, r) => binary(l, r)(math.pow _)
case Identifier(name) => {
//lookup standard library
StdLib(name) match {
runtime(name) match {
case Some(v) => v
case _ => throw new ScratSemanticError(name + " not found")
}
}
case ExpList(lst) => lst map apply
case FunctionCall(name, args) => {
//lookup standard lib
StdLib(name.id) match {
runtime(name.id) match {
case Some(f: FunctionVarArg) => f.apply(apply(args))
case None => throw new ScratSemanticError("function " + name + "not found")
}
}
case Assignment(name, exp) => {
val e = apply(exp)
runtime.identifiers.put(name.id, e)
e
}
case t => throw new ScratInvalidTokenError(t + " not implemented in evaluator")
}
}
@@ -55,7 +55,7 @@ object Parser extends RegexParsers {
private def parenExpr: Parser[Expression] = "(" ~> expr <~ ")"
private def expr: Parser[Expression] = term ~ rep(("+" | "-") ~ term) ^^ {
private def sum: Parser[Expression] = term ~ rep(("+" | "-") ~ term) ^^ {
case head ~ tail => {
var tree: Expression = head
tail.foreach {
@@ -66,6 +66,12 @@ object Parser extends RegexParsers {
}
}
private def assignment: Parser[Assignment] = identifier ~ "=" ~ expr ^^ {
case id ~ "=" ~ exp => Assignment(id, exp)
}
private def expr: Parser[Expression] = sum ||| assignment
def apply(s: String): Expression = parseAll(expr, s) match {
case Success(tree, _) => tree
case e: NoSuccess => throw new ScratSyntaxError("parsing error")
@@ -7,16 +7,22 @@ import com.edofic.scrat.Util.Exceptions._
* Date: 8/25/12
* Time: 10:25 PM
*/
object StdLib {
object ScratRuntime {
type FunctionVarArg = Any => Any
}
class ScratRuntime {
import ScratRuntime.FunctionVarArg
val identifiers: Map[String, Any] = Map(
val identifiers: collection.mutable.Map[String, Any] = collection.mutable.Map(
("pi" -> math.Pi),
("e" -> math.E),
("ln" -> functions.ln),
("log" -> functions.log),
("print" -> functions.sprint),
("println" -> functions.sprintln)
("println" -> functions.sprintln),
("readln" -> functions.sreadln)
)
def apply(key: String): Option[Any] = identifiers.get(key)
@@ -41,6 +47,10 @@ object StdLib {
case lst: List[_] => println(lst.mkString(" "))
case other => throw ScratInvalidTypeError("expected a list but got " + other)
}
lazy val sreadln: FunctionVarArg = _ => {
readLine()
}
}
}
@@ -29,4 +29,6 @@ object Tokens {
case class FunctionCall(name: Identifier, args: ExpList) extends Expression
case class Assignment(to: Identifier, from: Expression) extends Expression
}

0 comments on commit 5100820

Please sign in to comment.