mirror of
https://github.com/fluencelabs/aqua.git
synced 2025-04-24 22:42:13 +00:00
Literals parsing
This commit is contained in:
parent
103203bab0
commit
215866baf0
@ -3,11 +3,7 @@ package aqua.parse
|
||||
import aqua.parse.Token._
|
||||
import cats.data.NonEmptyList
|
||||
import cats.parse.{Parser ⇒ P}
|
||||
|
||||
// TODO could be const
|
||||
sealed trait Value
|
||||
case class VarLambda(name: String, lambda: Option[String]) extends Value
|
||||
case class Literal(value: String, ts: List[BasicType]) extends Value
|
||||
import Value.`value`
|
||||
|
||||
sealed trait FuncOp
|
||||
sealed trait InstrOp extends FuncOp
|
||||
@ -29,17 +25,9 @@ case class AbilityId(ability: String, id: Value) extends AbilityResolve
|
||||
|
||||
object FuncOp {
|
||||
|
||||
val notLambdaSymbols = Set(' ', ',', '\n', ')', ':')
|
||||
|
||||
val varLambda: P[VarLambda] = (`name` ~ (`.` *> P.charsWhile(c ⇒ !notLambdaSymbols(c))).?).map{
|
||||
case (n, l) ⇒ VarLambda(n, l)
|
||||
}
|
||||
|
||||
// TODO parse literals
|
||||
val value: P[Value] = varLambda
|
||||
|
||||
val funcCall: P[FuncCall] =
|
||||
(`name` ~ P.repSep0(value, `,`).between(`(`, `)`)).map{
|
||||
(`name` ~ P.repSep0(`value`, `,`).between(`(`, `)`)).map{
|
||||
case (fnName, args) ⇒ FuncCall(fnName, args)
|
||||
}
|
||||
|
||||
@ -54,14 +42,14 @@ object FuncOp {
|
||||
case (v, f) ⇒ Extract(v, f)
|
||||
}
|
||||
|
||||
val abilityResolve: P[AbilityResolve] = ((`Name` <* ` `) ~ value).map{
|
||||
val abilityResolve: P[AbilityResolve] = ((`Name` <* ` `) ~ `value`).map{
|
||||
case (n, v) ⇒ AbilityId(n, v)
|
||||
}
|
||||
|
||||
// TODO can't be in Par, can be in On
|
||||
val execOp: P[ExecOp] = P.oneOf( callOp.backtrack :: abilityResolve.backtrack :: extract :: Nil)
|
||||
|
||||
val startOn: P[Value] = `on` *> ` ` *> value <* ` `.? <* `:` <* ` \n*`
|
||||
val startOn: P[Value] = `on` *> ` ` *> `value` <* ` `.? <* `:` <* ` \n*`
|
||||
|
||||
val execOn: P[On] =
|
||||
(startOn ~ indented(execOp)).map{
|
||||
|
@ -9,14 +9,18 @@ case class ArrayType(data: DataType) extends DataType
|
||||
case class CustomType(name: String) extends DataType
|
||||
case class BasicType(name: String) extends DataType
|
||||
object BasicType {
|
||||
val floatS = "f32" :: "f64" :: Nil
|
||||
val numberS = "s32" :: "s64" :: "i32" :: "i64" :: floatS
|
||||
val boolS = "bool" :: Nil
|
||||
val allS = numberS ++ boolS
|
||||
private val floatS = "f32" :: "f64" :: Nil
|
||||
private val signedS = "s32" :: "s64" :: floatS
|
||||
private val numberS = "i32" :: "i64" :: signedS
|
||||
private val boolS = "bool" :: Nil
|
||||
private val stringS = "string" :: Nil
|
||||
private val allS = numberS ++ boolS ++ stringS
|
||||
|
||||
val float = floatS.map(BasicType(_))
|
||||
val signed = signedS.map(BasicType(_))
|
||||
val number = numberS.map(BasicType(_))
|
||||
val bool = boolS.map(BasicType(_))
|
||||
val string = stringS.map(BasicType(_))
|
||||
|
||||
val `basictypedef`: P[BasicType] =
|
||||
P.oneOf(
|
||||
|
37
src/main/scala/aqua/parse/Value.scala
Normal file
37
src/main/scala/aqua/parse/Value.scala
Normal file
@ -0,0 +1,37 @@
|
||||
package aqua.parse
|
||||
|
||||
import aqua.parse.Token._
|
||||
import cats.parse.{Parser ⇒ P}
|
||||
import cats.parse.Numbers
|
||||
|
||||
sealed trait Value
|
||||
case class VarLambda(name: String, lambda: Option[String]) extends Value
|
||||
case class Literal(value: String, ts: List[BasicType]) extends Value
|
||||
|
||||
object Value {
|
||||
val notLambdaSymbols = Set(' ', ',', '\n', ')', ':')
|
||||
|
||||
val varLambda: P[VarLambda] = (`name` ~ (`.` *> P.charsWhile(c ⇒ !notLambdaSymbols(c))).?).map{
|
||||
case (n, l) ⇒ VarLambda(n, l)
|
||||
}
|
||||
|
||||
val bool: P[Literal] = P.oneOf( ("true" :: "false" :: Nil).map(t ⇒ P.string(t).as(Literal(t, BasicType.bool)) ))
|
||||
|
||||
val num: P[Literal] = (P.char('-').?.with1 ~ Numbers.nonNegativeIntString).map {
|
||||
case (Some(_), n) ⇒ Literal(s"-$n", BasicType.signed)
|
||||
case (None, n) ⇒ Literal(n, BasicType.number)
|
||||
}
|
||||
|
||||
val float: P[Literal] =
|
||||
(P.char('-').?.with1 ~ (Numbers.nonNegativeIntString <* P.char('.')) ~ Numbers.nonNegativeIntString)
|
||||
.string
|
||||
.map(Literal(_, BasicType.float))
|
||||
|
||||
val string: P[Literal] =
|
||||
(P.char('"') *> P.repUntil0(P.anyChar, !P.charWhere(_ != '\\') *> P.char('"'))).string.map(Literal(_, BasicType.string))
|
||||
|
||||
val literal: P[Literal] = P.oneOf(bool :: float.backtrack :: num :: string :: Nil)
|
||||
|
||||
val `value`: P[Value] = P.oneOf(literal.backtrack :: varLambda :: Nil)
|
||||
|
||||
}
|
@ -6,43 +6,6 @@ import org.scalatest.flatspec.AnyFlatSpec
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
|
||||
class FuncOpSpec extends AnyFlatSpec with Matchers with EitherValues{
|
||||
/**
|
||||
* line variants:
|
||||
func(...)
|
||||
x <- func(...)
|
||||
Ability.func(...)
|
||||
x <- Ability.func(...)
|
||||
|
||||
par line
|
||||
xor line
|
||||
|
||||
on peer:
|
||||
indented lines*
|
||||
|
||||
Ability "const"
|
||||
Ability service.id
|
||||
Ability:
|
||||
// we're on a local node
|
||||
call smth
|
||||
res.id
|
||||
|
||||
func {Need, x}(y: i32, z: {x}i64 -> Y, p: -> {x}) -> {x}Bool:
|
||||
|
||||
Ability keyword, parser
|
||||
Literal, true/false
|
||||
AbilityResolve: literal, lens, or arrow that resolves to a string id
|
||||
|
||||
try:
|
||||
...
|
||||
catch( errn)?:
|
||||
...
|
||||
|
||||
|
||||
if a == != b:
|
||||
|
||||
else:
|
||||
|
||||
*/
|
||||
|
||||
"func calls" should "parse func()" in {
|
||||
FuncOp.`funcop`.parseAll("func()") should be(Right(FuncCall("func", Nil)))
|
||||
@ -81,11 +44,11 @@ else:
|
||||
"on" should "parse on x: y" in {
|
||||
val fCall = AbilityFuncCall("Ab", FuncCall("func", Nil))
|
||||
val extr = Extract("x", fCall)
|
||||
val call = FuncCall("call", VarLambda("smth", None) :: Nil)
|
||||
val call = FuncCall("call", Literal("true", BasicType.bool) :: Nil)
|
||||
|
||||
val script = """on peer.id:
|
||||
| x <- Ab.func()
|
||||
| call(smth)""".stripMargin
|
||||
| call(true)""".stripMargin
|
||||
|
||||
FuncOp.`funcop`.parseAll(script).right.value should be(On(VarLambda("peer", Some("id")), NonEmptyList.of(extr, call)))
|
||||
}
|
||||
@ -100,4 +63,27 @@ else:
|
||||
|
||||
FuncOp.`funcop`.parseAll(script) should be('right)
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: xor1
|
||||
try:
|
||||
...
|
||||
catch( errn)?:
|
||||
...
|
||||
(next)
|
||||
*/
|
||||
/*
|
||||
TODO: xor2
|
||||
if a == != b:
|
||||
...
|
||||
else:
|
||||
...
|
||||
(next)
|
||||
*/
|
||||
/*
|
||||
TODO: ability from lens
|
||||
*/
|
||||
/*
|
||||
TODO: fold, fold par, streams, ...
|
||||
*/
|
||||
}
|
||||
|
32
src/test/scala/aqua/parse/ValueSpec.scala
Normal file
32
src/test/scala/aqua/parse/ValueSpec.scala
Normal file
@ -0,0 +1,32 @@
|
||||
package aqua.parse
|
||||
|
||||
import org.scalatest.EitherValues
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
|
||||
class ValueSpec extends AnyFlatSpec with Matchers with EitherValues {
|
||||
|
||||
"var getter" should "parse" in {
|
||||
Value.`value`.parseAll("varname").right.value should be(VarLambda("varname", None))
|
||||
Value.`value`.parseAll("varname.field").right.value should be(VarLambda("varname", Some("field")))
|
||||
Value.`value`.parseAll("varname.field.sub").right.value should be(VarLambda("varname", Some("field.sub")))
|
||||
}
|
||||
|
||||
"literals" should "parse" in {
|
||||
Value.`value`.parseAll("true").right.value should be(Literal("true", BasicType.bool))
|
||||
Value.`value`.parseAll("false").right.value should be(Literal("false", BasicType.bool))
|
||||
|
||||
Value.`value`.parseAll("1").right.value should be(Literal("1", BasicType.number))
|
||||
Value.`value`.parseAll("1111").right.value should be(Literal("1111", BasicType.number))
|
||||
|
||||
Value.`value`.parseAll("-1543").right.value should be(Literal("-1543", BasicType.signed))
|
||||
|
||||
Value.`value`.parseAll("1.0").right.value should be(Literal("1.0", BasicType.float))
|
||||
Value.`value`.parseAll("1.23").right.value should be(Literal("1.23", BasicType.float))
|
||||
Value.`value`.parseAll("-1.23").right.value should be(Literal("-1.23", BasicType.float))
|
||||
|
||||
Value.`value`.parseAll("\"some crazy string\"").right.value should be(Literal("\"some crazy string\"", BasicType.string))
|
||||
Value.`value`.parseAll("\"some crazy string with escaped \\\" quote\"").right.value should be(Literal("\"some crazy string with escaped \\\" quote\"", BasicType.string))
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user