Simple Expressions

main
Oliver Kennedy 2023-11-01 11:39:23 -04:00
parent 918b95b7b7
commit dca55b5c30
Signed by: okennedy
GPG Key ID: 3E5F9B3ABD3FDB60
4 changed files with 93 additions and 6 deletions

View File

@ -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(

View File

@ -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")
}
}
}
}

View File

@ -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")
}
}

View File

@ -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)
)
}