Simple Expressions
parent
918b95b7b7
commit
dca55b5c30
2
build.sc
2
build.sc
|
@ -3,7 +3,7 @@ import scalalib._
|
|||
|
||||
object hackdb extends RootModule with ScalaModule
|
||||
{
|
||||
def scalaVersion = "2.13.11"
|
||||
def scalaVersion = "3.3.1"
|
||||
def finalMainClass = "net.okennedy.hackdb.HackDB"
|
||||
|
||||
def ivyDeps = Agg(
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
package net.okennedy.hackdb
|
||||
|
||||
sealed trait Expression
|
||||
{
|
||||
def eval: Constant
|
||||
}
|
||||
|
||||
///////////////////////////////////////////
|
||||
|
||||
sealed trait Constant extends Expression
|
||||
{
|
||||
def eval = this
|
||||
}
|
||||
|
||||
object Constant {
|
||||
case class Int(value: java.lang.Integer) extends Constant
|
||||
case class Double(value: java.lang.Double) extends Constant
|
||||
case class String(value: java.lang.String) extends Constant
|
||||
}
|
||||
|
||||
///////////////////////////////////////////
|
||||
|
||||
object Expression {
|
||||
|
||||
case class Add(a: Expression, b: Expression) extends Expression
|
||||
{
|
||||
def eval: Constant =
|
||||
{
|
||||
(a.eval, b.eval) match {
|
||||
case (Constant.Int(i), Constant.Int(j)) => Constant.Int(i+j)
|
||||
case (Constant.Double(i), Constant.Double(j)) => Constant.Double(i+j)
|
||||
case (Constant.String(i), Constant.String(j)) => Constant.String(i+j)
|
||||
case (i, j) => throw new Exception(s"Invalid expression: $a + $b")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case class Sub(a: Expression, b: Expression) extends Expression
|
||||
{
|
||||
def eval: Constant =
|
||||
{
|
||||
(a.eval, b.eval) match {
|
||||
case (Constant.Int(i), Constant.Int(j)) => Constant.Int(i-j)
|
||||
case (Constant.Double(i), Constant.Double(j)) => Constant.Double(i-j)
|
||||
case (i, j) => throw new Exception(s"Invalid expression: $a - $b")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,9 +1,27 @@
|
|||
package net.okennedy.hackdb
|
||||
|
||||
import fastparse.Parsed
|
||||
|
||||
object HackDB
|
||||
{
|
||||
|
||||
def query(q: String): Unit =
|
||||
{
|
||||
Parser(q) match {
|
||||
case Parsed.Success(expr, _) =>
|
||||
println(s"Parsed: ${expr}")
|
||||
println(s"Value: ${expr.eval}")
|
||||
println("")
|
||||
case Parsed.Failure(msg) =>
|
||||
println(s"Parse Failed: $msg")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
def main(args: Array[String]): Unit =
|
||||
{
|
||||
println(Parser("SELECT 1"))
|
||||
query("SELECT 1")
|
||||
query("SELECT 1+2")
|
||||
query("SELECT 1.1+2.9")
|
||||
}
|
||||
}
|
|
@ -7,14 +7,34 @@ object Parser
|
|||
def apply(str: String) =
|
||||
parse(str, query(_))
|
||||
|
||||
def query[$: P]: P[Int] = P(
|
||||
def query[$: P]: P[Expression] = P(
|
||||
IgnoreCase("select") ~
|
||||
number
|
||||
expression
|
||||
)
|
||||
|
||||
def number[$: P]: P[Int] = P(
|
||||
def expression[$: P]: P[Expression] = P(addSub)
|
||||
|
||||
def addSub[$: P]: P[Expression] = P(
|
||||
constant ~
|
||||
(CharIn("+\\-").! ~/ constant).rep
|
||||
).map { case (head, rest) =>
|
||||
rest.foldLeft(head:Expression) {
|
||||
case (accum, ("+", nextTerm)) =>
|
||||
Expression.Add(accum, nextTerm)
|
||||
case (accum, ("-", nextTerm)) =>
|
||||
Expression.Sub(accum, nextTerm)
|
||||
case (accum, (_, nextTerm)) =>
|
||||
assert(false, "Invalid add/sub op")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
def constant[$: P]: P[Constant] = P(
|
||||
int.map { Constant.Int(_) }
|
||||
)
|
||||
|
||||
def int[$: P]: P[Int] = P(
|
||||
CharIn("0-9").rep(1).!.map(_.toInt)
|
||||
)
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue