mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Refactor and reformat scala example
This commit is contained in:
parent
434a3dd207
commit
46ebc2d694
|
@ -3,7 +3,7 @@ package org.teavm.samples.scala
|
|||
import org.teavm.samples.scala.Grammar._
|
||||
|
||||
object Calculator {
|
||||
def eval(expr : Expr) : BigInt = expr match {
|
||||
def eval(expr: Expr): BigInt = expr match {
|
||||
case Add(a, b) => eval(a) + eval(b)
|
||||
case Subtract(a, b) => eval(a) - eval(b)
|
||||
case Multiply(a, b) => eval(a) * eval(b)
|
||||
|
@ -12,16 +12,16 @@ object Calculator {
|
|||
case Number(v) => v
|
||||
}
|
||||
|
||||
def print(expr : Expr) : String = expr match {
|
||||
def print(expr: Expr): String = expr match {
|
||||
case Add(a, b) => "(" + print(a) + " + " + print(b) + ")"
|
||||
case Subtract(a, b) => "(" + print(a) + " - " + print(b) + ")"
|
||||
case Multiply(a, b) => "(" + print(a) + " * " + print(b) + ")"
|
||||
case Divide(a, b) => "(" + print(a) + " / " + print(b) + ")"
|
||||
case Negate(n) => "-" + print(n)
|
||||
case Number(v) => v.toString()
|
||||
case Number(v) => v.toString
|
||||
}
|
||||
|
||||
def parse(str : Seq[Char]) = additive.parse(str)
|
||||
def parse(str: Seq[Char]) = additive.parse(str)
|
||||
|
||||
def additive = multiplicative ~ ((keyword("+") | keyword("-")) ~ multiplicative).* >> {
|
||||
case (h, t) => t.foldLeft(h) {
|
||||
|
@ -29,31 +29,42 @@ object Calculator {
|
|||
case (left, ("-", right)) => Subtract(left, right)
|
||||
}
|
||||
}
|
||||
|
||||
def multiplicative = unary ~ ((keyword("*") | keyword("/")) ~ unary).* >> {
|
||||
case (h, t) => t.foldLeft(h) {
|
||||
case (left, ("*", right)) => Multiply(left, right)
|
||||
case (left, ("/", right)) => Divide(left, right)
|
||||
}
|
||||
}
|
||||
def unary : Rule[Expr] = keyword("-").? ~ primitive >> {
|
||||
|
||||
def unary: Rule[Expr] = keyword("-").? ~ primitive >> {
|
||||
case (Some(_), v) => Negate(v)
|
||||
case (None, v) => v
|
||||
}
|
||||
def primitive : Rule[Expr] = Rule.firstOf(number >> Number, group)
|
||||
def group : Rule[Expr] = keyword("(") ~ additive ~ keyword(")") >> { case ((_, result), _) => result }
|
||||
|
||||
def number : Rule[Int] = range('1', '9') ~ range('0', '9').* ~ ws >> {
|
||||
def primitive: Rule[Expr] = Rule.firstOf(number >> Number, group)
|
||||
|
||||
def group: Rule[Expr] = keyword("(") ~ additive ~ keyword(")") >> { case ((_, result), _) => result }
|
||||
|
||||
def number: Rule[Int] = range('1', '9') ~ range('0', '9').* ~ ws >> {
|
||||
case ((h, t), _) => t.foldLeft(h - '0')((n, c) => n * 10 + (c - '0'))
|
||||
}
|
||||
|
||||
def keyword(str : String) = s(str) ~ ws >> { case (s, _) => s }
|
||||
def ws = s(" ").* >> { case _ => Unit }
|
||||
def keyword(str: String) = s(str) ~ ws >> { case (s, _) => s }
|
||||
|
||||
def ws = s(" ").* >> (_ => Unit)
|
||||
}
|
||||
|
||||
sealed abstract class Expr
|
||||
case class Number(value : Int) extends Expr
|
||||
case class Add(left : Expr, right : Expr) extends Expr
|
||||
case class Subtract(left : Expr, right : Expr) extends Expr
|
||||
case class Multiply(left : Expr, right : Expr) extends Expr
|
||||
case class Divide(left : Expr, right : Expr) extends Expr
|
||||
case class Negate(argument : Expr) extends Expr
|
||||
|
||||
case class Number(value: Int) extends Expr
|
||||
|
||||
case class Add(left: Expr, right: Expr) extends Expr
|
||||
|
||||
case class Subtract(left: Expr, right: Expr) extends Expr
|
||||
|
||||
case class Multiply(left: Expr, right: Expr) extends Expr
|
||||
|
||||
case class Divide(left: Expr, right: Expr) extends Expr
|
||||
|
||||
case class Negate(argument: Expr) extends Expr
|
|
@ -1,30 +1,26 @@
|
|||
package org.teavm.samples.scala
|
||||
|
||||
import org.teavm.samples.scala.DOM._
|
||||
import org.teavm.samples.scala.Calculator.parse
|
||||
import org.teavm.samples.scala.Calculator.print
|
||||
import org.teavm.samples.scala.Calculator.eval
|
||||
import org.teavm.jso.browser.Window
|
||||
import org.teavm.jso.dom.html._
|
||||
import org.teavm.jso.dom.events._
|
||||
import org.teavm.jso.dom.html._
|
||||
import org.teavm.samples.scala.Calculator.{eval, parse, print}
|
||||
|
||||
object Client {
|
||||
def main(args: Array[String]) {
|
||||
var doc = HTMLDocument.current
|
||||
var exprElem = doc.getElementById("expr").asInstanceOf[HTMLInputElement]
|
||||
var calcElem = doc.getElementById("calculate")
|
||||
var resultList = doc.getElementById("result-list");
|
||||
calcElem.listenClick((e : MouseEvent) => {
|
||||
parse(exprElem.getValue().toSeq) match {
|
||||
val doc = HTMLDocument.current
|
||||
val exprElem = doc.getElementById("expr").asInstanceOf[HTMLInputElement]
|
||||
val calcElem = doc.getElementById("calculate")
|
||||
val resultList = doc.getElementById("result-list")
|
||||
calcElem.listenClick((e: MouseEvent) => {
|
||||
parse(exprElem.getValue.toSeq) match {
|
||||
case (None, _) => Window.alert("Error parsing expression");
|
||||
case (Some(x), Nil) => {
|
||||
resultList.insertBefore(doc.createElement("div", (elem : HTMLElement) => {
|
||||
elem.withChild("span", (child : HTMLElement) =>
|
||||
case (Some(x), Nil) =>
|
||||
resultList.insertBefore(doc.createElement("div", (elem: HTMLElement) => {
|
||||
elem.withChild("span", (child: HTMLElement) =>
|
||||
child.withAttr("class", "plan").withText(print(x) + " = "))
|
||||
elem.withChild("span", (child : HTMLElement) =>
|
||||
elem.withChild("span", (child: HTMLElement) =>
|
||||
child.withAttr("class", "result").withText(eval(x).toString))
|
||||
}), resultList.getFirstChild)
|
||||
}
|
||||
case (_, err) => Window.alert("Error parsing expression: " + err);
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
package org.teavm.samples.scala
|
||||
|
||||
import org.teavm.jso.dom.events._
|
||||
import java.util.function.Consumer
|
||||
|
||||
object DOM {
|
||||
implicit def toEventListener[T <: Event](f : T => Any) : EventListener[T] = {
|
||||
new EventListener[T]() {
|
||||
def handleEvent(e : T) = f(e)
|
||||
}
|
||||
}
|
||||
|
||||
implicit def toConsumer[T](f : T => Any) : Consumer[T] = {
|
||||
new Consumer[T]() {
|
||||
def accept(e : T) = f(e)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,56 +1,65 @@
|
|||
package org.teavm.samples.scala
|
||||
|
||||
object Grammar {
|
||||
def rule[T](f : Seq[Char] => (Option[T], Seq[Char])) : Rule[T] = Rule.rule(f)
|
||||
def s(str : String) : Rule[String] = Rule.expect(str)
|
||||
def range(first : Char, last : Char) : Rule[Char] = Rule.range(first, last)
|
||||
def rule[T](f: Seq[Char] => (Option[T], Seq[Char])): Rule[T] = Rule.rule(f)
|
||||
|
||||
def s(str: String): Rule[String] = Rule.expect(str)
|
||||
|
||||
def range(first: Char, last: Char): Rule[Char] = Rule.range(first, last)
|
||||
}
|
||||
|
||||
trait Rule[T] {
|
||||
def parse(chars : Seq[Char]) : (Option[T], Seq[Char])
|
||||
def ~[S](other : Rule[S]) : Rule[(T, S)] = Rule.concat(this, other)
|
||||
def ~(other : => String) : Rule[(T, String)] = Rule.concat(this, Rule.expect(other))
|
||||
def |(other : => Rule[T]) : Rule[T] = Rule.firstOf(this, other)
|
||||
def *() : Rule[List[T]] = Rule.unlimited(this)
|
||||
def >>[S](f : T => S) : Rule[S] = Rule.andThen(this, f)
|
||||
def ?() : Rule[Option[T]] = Rule.optional(this)
|
||||
def parse(chars: Seq[Char]): (Option[T], Seq[Char])
|
||||
|
||||
def debug(str : String) = Rule.rule { x =>
|
||||
var (result, rem) = parse(x)
|
||||
def ~[S](other: Rule[S]): Rule[(T, S)] = Rule.concat(this, other)
|
||||
|
||||
def ~(other: => String): Rule[(T, String)] = Rule.concat(this, Rule.expect(other))
|
||||
|
||||
def |(other: => Rule[T]): Rule[T] = Rule.firstOf(this, other)
|
||||
|
||||
def *(): Rule[List[T]] = Rule.unlimited(this)
|
||||
|
||||
def >>[S](f: T => S): Rule[S] = Rule.andThen(this, f)
|
||||
|
||||
def ?(): Rule[Option[T]] = Rule.optional(this)
|
||||
|
||||
def debug(str: String) = Rule.rule { x =>
|
||||
val (result, rem) = parse(x)
|
||||
println(str + ":" + result + ":" + rem)
|
||||
(result, rem)
|
||||
}
|
||||
}
|
||||
|
||||
object Rule {
|
||||
def rule[T](f : Seq[Char] => (Option[T], Seq[Char])) : Rule[T] = new Rule[T]() {
|
||||
def parse(chars : Seq[Char]) : (Option[T], Seq[Char]) = f(chars)
|
||||
}
|
||||
def concat[S, T](left : Rule[S], right : => Rule[T]) : Rule[(S, T)] = {
|
||||
def rule[T](f: Seq[Char] => (Option[T], Seq[Char])): Rule[T] = (chars: Seq[Char]) => f(chars)
|
||||
|
||||
def concat[S, T](left: Rule[S], right: => Rule[T]): Rule[(S, T)] = {
|
||||
rule(chars => left.parse(chars) match {
|
||||
case (Some(leftResult), rem) => right.parse(rem) match {
|
||||
case (Some(rightResult), rem2) => (Some((leftResult, rightResult)), rem2)
|
||||
case (None, rem2) => (None, rem)
|
||||
case (None, _) => (None, rem)
|
||||
}
|
||||
case (None, rem) => (None, rem)
|
||||
})
|
||||
}
|
||||
def unlimited[T](inner : Rule[T]) : Rule[List[T]] = {
|
||||
def iter(chars : Seq[Char]) : (List[T], Seq[Char]) = {
|
||||
|
||||
def unlimited[T](inner: Rule[T]): Rule[List[T]] = {
|
||||
def iter(chars: Seq[Char]): (List[T], Seq[Char]) = {
|
||||
inner.parse(chars) match {
|
||||
case (Some(result), rem) => {
|
||||
case (Some(result), rem) =>
|
||||
val (tail, rem2) = iter(rem)
|
||||
(result :: tail, rem2)
|
||||
}
|
||||
case (None, rem) => (Nil, rem)
|
||||
}
|
||||
}
|
||||
|
||||
rule(chars => {
|
||||
val (result, rem) = iter(chars)
|
||||
(Some(result), rem)
|
||||
})
|
||||
}
|
||||
def firstOf[T](first : Rule[T], second : => Rule[T]) : Rule[T] = {
|
||||
|
||||
def firstOf[T](first: Rule[T], second: => Rule[T]): Rule[T] = {
|
||||
rule(chars => first.parse(chars) match {
|
||||
case (Some(result), rem) => (Some(result), rem)
|
||||
case (None, _) => second.parse(chars) match {
|
||||
|
@ -59,14 +68,16 @@ object Rule {
|
|||
}
|
||||
})
|
||||
}
|
||||
def optional[T](inner : Rule[T]) : Rule[Option[T]] = {
|
||||
|
||||
def optional[T](inner: Rule[T]): Rule[Option[T]] = {
|
||||
rule(chars => inner.parse(chars) match {
|
||||
case (Some(result), rem) => (Some(Some(result)), rem)
|
||||
case (None, rem) => (Some(None), chars)
|
||||
})
|
||||
}
|
||||
implicit def expect(str : String) : Rule[String] = {
|
||||
def iter(chars : Seq[Char], index : Int) : (Boolean, Seq[Char]) = {
|
||||
|
||||
implicit def expect(str: String): Rule[String] = {
|
||||
def iter(chars: Seq[Char], index: Int): (Boolean, Seq[Char]) = {
|
||||
if (index == str.length())
|
||||
(true, chars)
|
||||
else chars match {
|
||||
|
@ -75,24 +86,24 @@ object Rule {
|
|||
case _ => (false, chars)
|
||||
}
|
||||
}
|
||||
|
||||
rule(chars => {
|
||||
val (matched, rem) = iter(chars, 0)
|
||||
(matched match {
|
||||
case true => Some(str)
|
||||
case false => None
|
||||
}, rem)
|
||||
(if (matched) Some(str) else None, rem)
|
||||
})
|
||||
}
|
||||
def andThen[T, S](inner : Rule[T], f : T => S) : Rule[S] = {
|
||||
|
||||
def andThen[T, S](inner: Rule[T], f: T => S): Rule[S] = {
|
||||
rule(chars => inner.parse(chars) match {
|
||||
case (Some(result), rem) => (Some(f(result)), rem)
|
||||
case (None, rem) => (None, rem)
|
||||
})
|
||||
}
|
||||
def range(first : Char, last : Char) : Rule[Char] = {
|
||||
rule(chars => chars match {
|
||||
|
||||
def range(first: Char, last: Char): Rule[Char] = {
|
||||
rule {
|
||||
case c +: rem if c >= first && c <= last => (Some(c), rem)
|
||||
case _ => (None, chars)
|
||||
})
|
||||
case chars => (None, chars)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user