Skip to content

Commit

Permalink
added variables
Browse files Browse the repository at this point in the history
  • Loading branch information
edofic committed Aug 26, 2012
1 parent dad2f2a commit 5100820
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 11 deletions.
18 changes: 11 additions & 7 deletions main/src/com/edofic/scrat/Evaluator.scala
@@ -1,17 +1,16 @@
package com.edofic.scrat package com.edofic.scrat


import com.edofic.scrat.Util.Exceptions._ import com.edofic.scrat.Util.Exceptions._
import com.edofic.scrat.StdLib.FunctionVarArg import Tokens._

import ScratRuntime.FunctionVarArg


/** /**
* User: andraz * User: andraz
* Date: 8/25/12 * Date: 8/25/12
* Time: 10:15 PM * Time: 10:15 PM
*/ */
object Evaluator { object Evaluator {

val runtime = new ScratRuntime
import Tokens._


private def binary[L, R](l: Expression, r: Expression)(f: (L, R) => Any) = (apply(l), apply(r)) match { 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 (l: L, r: R) => f(l, r)
Expand All @@ -27,20 +26,25 @@ object Evaluator {
case Divide(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 Exponent(l, r) => binary(l, r)(math.pow _)
case Identifier(name) => { case Identifier(name) => {
//lookup standard library runtime(name) match {
StdLib(name) match {
case Some(v) => v case Some(v) => v
case _ => throw new ScratSemanticError(name + " not found") case _ => throw new ScratSemanticError(name + " not found")
} }
} }
case ExpList(lst) => lst map apply case ExpList(lst) => lst map apply
case FunctionCall(name, args) => { case FunctionCall(name, args) => {

//lookup standard lib //lookup standard lib
StdLib(name.id) match { runtime(name.id) match {
case Some(f: FunctionVarArg) => f.apply(apply(args)) case Some(f: FunctionVarArg) => f.apply(apply(args))
case None => throw new ScratSemanticError("function " + name + "not found") 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") case t => throw new ScratInvalidTokenError(t + " not implemented in evaluator")
} }
} }
8 changes: 7 additions & 1 deletion main/src/com/edofic/scrat/Parser.scala
Expand Up @@ -55,7 +55,7 @@ object Parser extends RegexParsers {


private def parenExpr: Parser[Expression] = "(" ~> expr <~ ")" 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 => { case head ~ tail => {
var tree: Expression = head var tree: Expression = head
tail.foreach { tail.foreach {
Expand All @@ -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 { def apply(s: String): Expression = parseAll(expr, s) match {
case Success(tree, _) => tree case Success(tree, _) => tree
case e: NoSuccess => throw new ScratSyntaxError("parsing error") case e: NoSuccess => throw new ScratSyntaxError("parsing error")
Expand Down
Expand Up @@ -7,16 +7,22 @@ import com.edofic.scrat.Util.Exceptions._
* Date: 8/25/12 * Date: 8/25/12
* Time: 10:25 PM * Time: 10:25 PM
*/ */
object StdLib { object ScratRuntime {
type FunctionVarArg = Any => Any 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), ("pi" -> math.Pi),
("e" -> math.E), ("e" -> math.E),
("ln" -> functions.ln), ("ln" -> functions.ln),
("log" -> functions.log), ("log" -> functions.log),
("print" -> functions.sprint), ("print" -> functions.sprint),
("println" -> functions.sprintln) ("println" -> functions.sprintln),
("readln" -> functions.sreadln)
) )


def apply(key: String): Option[Any] = identifiers.get(key) def apply(key: String): Option[Any] = identifiers.get(key)
Expand All @@ -41,6 +47,10 @@ object StdLib {
case lst: List[_] => println(lst.mkString(" ")) case lst: List[_] => println(lst.mkString(" "))
case other => throw ScratInvalidTypeError("expected a list but got " + other) case other => throw ScratInvalidTypeError("expected a list but got " + other)
} }

lazy val sreadln: FunctionVarArg = _ => {
readLine()
}
} }


} }
2 changes: 2 additions & 0 deletions main/src/com/edofic/scrat/Tokens.scala
Expand Up @@ -29,4 +29,6 @@ object Tokens {


case class FunctionCall(name: Identifier, args: ExpList) extends Expression 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.