Skip to content

Instantly share code, notes, and snippets.

@icejoywoo
Last active June 25, 2019 06:14
Show Gist options
  • Save icejoywoo/706edf1a7e9d277f5349c44990b4e81a to your computer and use it in GitHub Desktop.
Save icejoywoo/706edf1a7e9d277f5349c44990b4e81a to your computer and use it in GitHub Desktop.

Revisions

  1. icejoywoo revised this gist Jun 25, 2019. 1 changed file with 14 additions and 0 deletions.
    14 changes: 14 additions & 0 deletions EvalDemo.scala
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,14 @@
    import com.twitter.util.Eval

    object EvalDemo {
    def main(args: Array[String]): Unit = {
    val eval = new Eval
    eval.compile(
    """
    |object Env {
    | val a = 5
    |}
    """.stripMargin)
    println(eval.inPlace[Int]("import Env._; a"))
    }
    }
  2. icejoywoo revised this gist Jun 25, 2019. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion calculator.scala
    Original file line number Diff line number Diff line change
    @@ -25,7 +25,7 @@ class Arith extends JavaTokenParsers {
    case "+"~v => v.toDouble
    }, { i => s"unexpected error [$i]" })
    | ident ^? ({ case i if env.contains(i) => env(i) }, { i => s"$i is not found in context"})
    | ("-" | "+")~identifier ^? ({
    | ("-" | "+")~ident ^? ({
    case "-"~v if env.contains(v) => -env(v)
    case "+"~v if env.contains(v) => env(v)
    }, { case _~i => s"$i is not found in context" })
  3. icejoywoo revised this gist Jun 25, 2019. 1 changed file with 2 additions and 6 deletions.
    8 changes: 2 additions & 6 deletions calculator.scala
    Original file line number Diff line number Diff line change
    @@ -4,8 +4,6 @@ import scala.util.parsing.combinator._
    class Arith extends JavaTokenParsers {
    var env: mutable.Map[String, Double] = mutable.Map.empty

    def identifier: Parser[String] = """[a-zA-Z_]+""".r

    def expr: Parser[Double] = term~rep("+"~term | "-"~term) ^^ {
    case term~ops =>
    ops.foldLeft(term) {
    @@ -26,14 +24,12 @@ class Arith extends JavaTokenParsers {
    case "-"~v => -v.toDouble
    case "+"~v => v.toDouble
    }, { i => s"unexpected error [$i]" })
    | identifier ^? ({ case i if env.contains(i) => env(i) }, { i => s"$i is not found in context"})
    | ident ^? ({ case i if env.contains(i) => env(i) }, { i => s"$i is not found in context"})
    | ("-" | "+")~identifier ^? ({
    case "-"~v if env.contains(v) => -env(v)
    case "+"~v if env.contains(v) => env(v)
    }, { case _~i => s"$i is not found in context" })
    | "("~expr~")" ^? ({
    case "("~v~")" => v
    }, { i => s"unexpected error [$i]"})
    | "(" ~> expr <~ ")"
    )
    }

  4. icejoywoo revised this gist Jun 13, 2019. 1 changed file with 3 additions and 4 deletions.
    7 changes: 3 additions & 4 deletions calculator.scala
    Original file line number Diff line number Diff line change
    @@ -22,16 +22,15 @@ class Arith extends JavaTokenParsers {
    }
    def factor: Parser[Double] = (
    floatingPointNumber ^^ { _.toDouble }
    | ("-" | "+")~floatingPointNumber ^^ {
    | ("-" | "+")~floatingPointNumber ^? ({
    case "-"~v => -v.toDouble
    case "+"~v => v.toDouble
    case _ => sys.error("unexpected error")
    }
    }, { i => s"unexpected error [$i]" })
    | identifier ^? ({ case i if env.contains(i) => env(i) }, { i => s"$i is not found in context"})
    | ("-" | "+")~identifier ^? ({
    case "-"~v if env.contains(v) => -env(v)
    case "+"~v if env.contains(v) => env(v)
    }, { i => s"$i is not found in context"})
    }, { case _~i => s"$i is not found in context" })
    | "("~expr~")" ^? ({
    case "("~v~")" => v
    }, { i => s"unexpected error [$i]"})
  5. icejoywoo revised this gist Jun 13, 2019. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion calculator.scala
    Original file line number Diff line number Diff line change
    @@ -31,7 +31,7 @@ class Arith extends JavaTokenParsers {
    | ("-" | "+")~identifier ^? ({
    case "-"~v if env.contains(v) => -env(v)
    case "+"~v if env.contains(v) => env(v)
    }, { i => s"unexpected error [$i]"})
    }, { i => s"$i is not found in context"})
    | "("~expr~")" ^? ({
    case "("~v~")" => v
    }, { i => s"unexpected error [$i]"})
  6. icejoywoo revised this gist Jun 13, 2019. 1 changed file with 7 additions and 9 deletions.
    16 changes: 7 additions & 9 deletions calculator.scala
    Original file line number Diff line number Diff line change
    @@ -27,16 +27,14 @@ class Arith extends JavaTokenParsers {
    case "+"~v => v.toDouble
    case _ => sys.error("unexpected error")
    }
    | identifier ^^ { env(_) }
    | ("-" | "+")~identifier ^^ {
    case "-"~v => -env(v)
    case "+"~v => env(v)
    case _ => sys.error("unexpected error")
    }
    | "("~expr~")" ^^ {
    | identifier ^? ({ case i if env.contains(i) => env(i) }, { i => s"$i is not found in context"})
    | ("-" | "+")~identifier ^? ({
    case "-"~v if env.contains(v) => -env(v)
    case "+"~v if env.contains(v) => env(v)
    }, { i => s"unexpected error [$i]"})
    | "("~expr~")" ^? ({
    case "("~v~")" => v
    case _ => sys.error("unexpected error")
    }
    }, { i => s"unexpected error [$i]"})
    )
    }

  7. icejoywoo created this gist Jun 13, 2019.
    92 changes: 92 additions & 0 deletions calculator.scala
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,92 @@
    import scala.collection.mutable
    import scala.util.parsing.combinator._

    class Arith extends JavaTokenParsers {
    var env: mutable.Map[String, Double] = mutable.Map.empty

    def identifier: Parser[String] = """[a-zA-Z_]+""".r

    def expr: Parser[Double] = term~rep("+"~term | "-"~term) ^^ {
    case term~ops =>
    ops.foldLeft(term) {
    case (a, "+"~b) => a + b
    case (a, "-"~b) => a - b
    }
    }
    def term: Parser[Double] = factor~rep("*"~factor | "/"~factor) ^^ {
    case factor~ops =>
    ops.foldLeft(factor) {
    case (a, "*"~b) => a * b
    case (a, "/"~b) => a / b
    }
    }
    def factor: Parser[Double] = (
    floatingPointNumber ^^ { _.toDouble }
    | ("-" | "+")~floatingPointNumber ^^ {
    case "-"~v => -v.toDouble
    case "+"~v => v.toDouble
    case _ => sys.error("unexpected error")
    }
    | identifier ^^ { env(_) }
    | ("-" | "+")~identifier ^^ {
    case "-"~v => -env(v)
    case "+"~v => env(v)
    case _ => sys.error("unexpected error")
    }
    | "("~expr~")" ^^ {
    case "("~v~")" => v
    case _ => sys.error("unexpected error")
    }
    )
    }

    object TestArith extends Arith {
    def main(args: Array[String]): Unit = {
    env += "a" -> 5
    env += "b" -> 6
    env += "c" -> 7

    assert(parseAll(expr, "2 * (3 + 7) * a + (b + c) * c").get == 191.0)
    assert(parseAll(expr, "2 * (3 + 7) * (a + (b + c) * c)").get == 1920.0)
    assert(parseAll(expr, "a + 4").get == 9.0)
    assert(parseAll(expr, "((a) + (4))").get == 9.0)
    assert(parseAll(expr, "a / 20 + 10 + a * b + c * 10").get == 110.25)
    assert(parseAll(expr, "+5").get == 5.0)
    assert(parseAll(expr, "-a").get == -5.0)

    parseAll(expr, "2 * (3 + 7)") match {
    case Success(matched,_) => println(matched)
    case Failure(msg,_) => println("FAILURE: " + msg)
    case Error(msg,_) => println("ERROR: " + msg)
    }

    parseAll(expr, "2 * (3 + 7))") match {
    case Success(matched,_) => println(matched)
    case Failure(msg,_) => println("FAILURE: " + msg)
    case Error(msg,_) => println("ERROR: " + msg)
    }

    assert(!parseAll(expr, "2 * (3 + 7))").successful)
    assert(!parseAll(expr, "(2 * (3 + 7)").successful)
    }
    }

    object TestArith2 {
    def main(args: Array[String]): Unit = {
    val a = new Arith
    a.env ++= Map(
    "a" -> 5,
    "b" -> 6,
    "c" -> 7
    )

    assert(a.parseAll(a.expr, "2 * (3 + 7) * a + (b + c) * c").get == 191.0)
    assert(a.parseAll(a.expr, "2 * (3 + 7) * (a + (b + c) * c)").get == 1920.0)
    assert(a.parseAll(a.expr, "a + 4").get == 9.0)
    assert(a.parseAll(a.expr, "((a) + (4))").get == 9.0)
    assert(a.parseAll(a.expr, "a / 20 + 10 + a * b + c * 10").get == 110.25)

    assert(!a.parseAll(a.expr, "2 * (3 + 7))").successful)
    assert(!a.parseAll(a.expr, "(2 * (3 + 7)").successful)
    }
    }