Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/main/scala/frontend/generator/domain/Token.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ import frontend.parser.domain.LangToken

type Token = LangToken

sealed trait Instructions
sealed trait Instructions
72 changes: 42 additions & 30 deletions src/main/scala/frontend/parser/domain/Token.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ package frontend.parser.domain

import zio.prelude.data.*

val LANG_DEFAULT_PACKAGE = "foop"
val LANG_DEFAULT_PACKAGE = "chunk"

sealed trait LangToken

Expand All @@ -46,47 +46,59 @@ case class Identifier(value: String) extends LangToken
// Type def used for type descriptions
sealed trait TypeDef extends LangToken
object TypeDef:
case object InferredHole extends TypeDef
case class SimpleTypeDef(name: InvocationName) extends TypeDef
case class HKTTypeDef(name: InvocationName, members: Seq[TypeDef]) extends TypeDef
case object InferredHole extends TypeDef
case class SimpleTypeDef(name: IdentifierName) extends TypeDef
case class HKTTypeDef(name: IdentifierName, members: Seq[TypeDef]) extends TypeDef
end TypeDef

// InvocationName used for identifier/variables usage
case class InvocationName(name: List[Identifier]) extends LangToken
case class IdentifierName(name: List[Identifier]) extends LangToken

//statement
// used for any sentence variable declaration or value/variable usage.
//type Statement = Declaration | Invocation | Evaluable // should add class/trait/object declarations
sealed trait Statement extends LangToken

// invocation used for variables usage
trait Invocation extends LangToken
object Invocation:
case class InvocationLiteral(literal: Literal) extends Invocation
case class InvocationIdentifier(name: InvocationName) extends Invocation
case class InvocationFunction(
name: InvocationName,
genericMembers: List[TypeDef] = Nil,
params: List[ValueToken] = Nil
) extends Invocation
end Invocation
trait ValueToken extends Statement
object ValueToken:
case class ValueTokenLiteral(literal: Literal) extends ValueToken
case class ValueTokenIdentifier(name: IdentifierName) extends ValueToken
case class ValueTokenFunction(
name: IdentifierName,
genericMembers: Seq[TypeDef] = Nil,
params: Seq[ValueToken] = Nil
) extends ValueToken

sealed trait ValueTokenBlock extends ValueToken
object ValueTokenBlock:
case class SimpleBlock(statements: Seq[Statement]) extends ValueTokenBlock
case class FunctionBlock(params: Seq[Assignation], returnType: Optional[TypeDef], statements: Seq[Statement])
extends ValueTokenBlock
end ValueTokenBlock

end ValueToken

// used for literals or variables usage
type ValueToken = Invocation // | Literal
//type ValueToken = Invocation // | Literal

// used for defining variables or class members
trait Member extends LangToken
object Member:
case class ValueDeclaration(name: Identifier, typeDef: TypeDef, defaultValue: Optional[ValueToken]) extends Member
case class VarDeclaration(name: Identifier, typeDef: TypeDef, defaultValue: Optional[ValueToken]) extends Member
case class MethodDeclaration(
sealed trait Assignation extends Statement
object Assignation:
case class ValueAssignation(name: Identifier, typeDef: Optional[TypeDef], defaultValue: ValueToken)
extends Assignation
case class VarAssignation(name: Identifier, typeDef: Optional[TypeDef], defaultValue: Optional[ValueToken])
extends Assignation
case class MethodAssignation(
name: Identifier,
genericParams: List[TypeDef],
params: List[Member],
genericParams: Seq[TypeDef],
params: Seq[Assignation],
returnType: TypeDef,
statements: List[Statements]
) extends Member
end Member

// used for any sentence variable declaration or value/variable usage.
type Statements = Member | Invocation
body: ValueToken
) extends Assignation
end Assignation

//type Assignable = Literal | Identifier
//type Assignabkle = Literal | Identifier
//
//sealed trait AbstractValueDeclaration(
// name: Identifier,
Expand Down
42 changes: 42 additions & 0 deletions src/main/scala/frontend/parser/services/AssignationReader.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package chunk
package frontend.parser.services

import fastparse.*
import NoWhitespace.*
import frontend.parser.domain.*

import BasicReader.{separator, *}
import BasicReader.*
import zio.prelude.data.Optional

trait AssignationReader extends BasicReader[Assignation]:
import BasicReader.*

def valueMemberReader[$: P] = P(
P(
"val" ~ separator
).? ~ IdentifierReader.reader ~ separatorOpt ~ (":" ~ separatorOpt ~ TypeReader.reader).? ~ separatorOpt ~ "=" ~
separatorOpt ~ ValueTokenReader.reader
).map { (identifier, typeValue, token) =>
Assignation.ValueAssignation(identifier, Optional.OptionIsNullable(typeValue), token)
}

def variableMemberReader[$: P] = P(
P("var" ~ separator)
~ IdentifierReader.reader ~ separatorOpt ~ (":" ~ separatorOpt ~ TypeReader.reader).? ~ separatorOpt ~ "=" ~
separatorOpt ~ ValueTokenReader.reader.?
).map { (identifier, typeValue, token) =>
println(identifier)
Assignation.VarAssignation(identifier, Optional.OptionIsNullable(typeValue), Optional.OptionIsNullable(token))
}

// .map{
// (identifier: Identifier, typeValue: TypeDef, token: ValueToken) => ???
// }

override def reader[$: P]: P[Assignation] = variableMemberReader | valueMemberReader

end AssignationReader

object AssignationReader extends AssignationReader:
end AssignationReader
3 changes: 2 additions & 1 deletion src/main/scala/frontend/parser/services/BasicReader.scala
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ end BasicReader
object BasicReader:

private def stringChars(c: Char) = c != '\"' && c != '\\'
private inline def separator[$: P] = P(CharsWhileIn(" \r\n", 0))
inline def separator[$: P]: P[Unit] = P(CharsWhileIn(" \r\n", 1))
inline def separatorOpt[$: P]: P[Unit] = separator.?
inline def digit[$: P] = P(CharIn("0-9"))
inline def digits[$: P] = P(digit.rep(min=1))
inline def double[$: P] = P(digits ~ "." ~ digits)
Expand Down
16 changes: 16 additions & 0 deletions src/main/scala/frontend/parser/services/IdentifierNameReader.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package chunk
package frontend.parser.services

import fastparse.*
import ScalaWhitespace.*

import frontend.parser.domain.*

trait IdentifierNameReader extends BasicReader[IdentifierName]:
override def reader[$: P]: P[IdentifierName] = P(
IdentifierReader.reader.rep(min = 1, sep = ".").map(identifiers => IdentifierName(identifiers.toList))
)
end IdentifierNameReader

object IdentifierNameReader extends IdentifierNameReader:
end IdentifierNameReader
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ package chunk
package frontend.parser.services

import fastparse.*
import ScalaWhitespace.*
import NoWhitespace.*

import frontend.parser.domain.Identifier

Expand All @@ -38,8 +38,10 @@ trait IdentifierReader extends BasicReader[Identifier]:
private inline def specialCharacterIdentifier[$: P] = P(CharIn("_$"))
private inline def basicCharIdentifier[$: P] = P(lowerCases | upperCases | specialCharacterIdentifier)
private inline def basicMixedIdentifier[$: P] = P(basicCharIdentifier | digit)
private def identifierText[$: P] = P(basicCharIdentifier ~ basicMixedIdentifier.rep).!
override def reader[$: P]: P[Identifier] = identifierText.filter(a => a != "True" && a != "False").map(Identifier.apply)
private def identifierText[$: P] = P(basicCharIdentifier ~ basicMixedIdentifier.rep).!

override def reader[$: P]: P[Identifier] =
identifierText.filter(a => a != "True" && a != "False").map(Identifier.apply)
end IdentifierReader

object IdentifierReader extends IdentifierReader:
Expand Down
17 changes: 0 additions & 17 deletions src/main/scala/frontend/parser/services/InvocationNameReader.scala

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ package chunk
package frontend.parser.services

import fastparse.*
import ScalaWhitespace.*
import NoWhitespace.*
import frontend.parser.domain.*

trait LiteralReader extends BasicReader[Literal]:
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/frontend/parser/services/TypeReader.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import NoWhitespace.*
import frontend.parser.domain.*

trait TypeReader extends BasicReader[TypeDef]:
def basicType[$: P]: P[TypeDef.SimpleTypeDef] = InvocationNameReader.reader
def basicType[$: P]: P[TypeDef.SimpleTypeDef] = IdentifierNameReader.reader
.map(TypeDef.SimpleTypeDef.apply)

private def inferredByContext[$: P]: P[TypeDef] = "_".!.map(_ => TypeDef.InferredHole)

private def hktType[$: P]: P[TypeDef.HKTTypeDef] =
P(
InvocationNameReader.reader ~ "[" ~ (reader | inferredByContext)
IdentifierNameReader.reader ~ "[" ~ (reader | inferredByContext)
.rep(1, sep = ",") ~ "]"
)
.map((name, attrs) => TypeDef.HKTTypeDef(name, attrs))
Expand Down
14 changes: 7 additions & 7 deletions src/main/scala/frontend/parser/services/ValueTokenReader.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ import frontend.parser.domain
trait ValueTokenReader extends BasicReader[ValueToken]:

private def invocationIdentifier[$: P] =
InvocationNameReader.reader.map(name => Invocation.InvocationIdentifier(name))
IdentifierNameReader.reader.map(name => ValueToken.ValueTokenIdentifier(name))

private def invocationLiteral[$: P] = LiteralReader.reader.map(value => Invocation.InvocationLiteral(value))
private def invocationLiteral[$: P] = LiteralReader.reader.map(value => ValueToken.ValueTokenLiteral(value))

private def hktGenericParam[$: P]: P[TypeDef] =
P(
InvocationNameReader.reader ~ "[" ~ hktGenericParam
IdentifierNameReader.reader ~ "[" ~ hktGenericParam
.rep(1, sep = ",") ~ "]"
)
.map((name, attrs) => TypeDef.HKTTypeDef(name, attrs))
Expand All @@ -27,14 +27,14 @@ trait ValueTokenReader extends BasicReader[ValueToken]:
"[" ~ hktGenericParam.rep(min = 1, sep = ",") ~ "]"
).?

private def literal[$: P] = P(LiteralReader.reader.map(Invocation.InvocationLiteral.apply))
private def invocation[$: P] = P(InvocationNameReader.reader.map(name => Invocation.InvocationIdentifier(name)))
private def literal[$: P] = P(LiteralReader.reader.map(ValueToken.ValueTokenLiteral.apply))
private def invocation[$: P] = P(IdentifierNameReader.reader.map(name => ValueToken.ValueTokenIdentifier(name)))

override def reader[$: P]: P[ValueToken] =
P(
(InvocationNameReader.reader ~ genericParams ~ "(" ~ reader.rep(sep = ",") ~ ")").map {
(IdentifierNameReader.reader ~ genericParams ~ "(" ~ reader.rep(sep = ",") ~ ")").map {
case (name, hktParams, params) =>
Invocation.InvocationFunction(name, hktParams.getOrElse(Nil).toList, params.toList)
ValueToken.ValueTokenFunction(name, hktParams.getOrElse(Nil).toList, params.toList)
}
) | literal | invocation

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package chunk
package frontend.parser.services

import frontend.parser.domain.*

import fastparse.*
import fastparse.NoWhitespace.*
import zio.*
import zio.prelude.data.Optional
import zio.test.*
import zio.test.Assertion.*

object AssignationReaderSpec extends ZIOSpecDefault {
import TestAspect.*
private val subject = new AssignationReader {}
private val givenAndExpected = List(
(
"a = 22",
Assignation.ValueAssignation(
Identifier("a"),
typeDef = Optional.Absent,
defaultValue = ValueToken.ValueTokenLiteral(Literal.IntLiteral(value = 22))
)
),
(
"val a = 22",
Assignation.ValueAssignation(
Identifier("a"),
typeDef = Optional.Absent,
defaultValue = ValueToken.ValueTokenLiteral(Literal.IntLiteral(value = 22))
)
),
(
"a: Boolean = True",
Assignation.ValueAssignation(
Identifier("a"),
typeDef = TypeDef.SimpleTypeDef(IdentifierName(List(Identifier("Boolean")))),
defaultValue = ValueToken.ValueTokenLiteral(Literal.BooleanLiteral(true))
)
),
(
"val a: Boolean = True",
Assignation.ValueAssignation(
Identifier("a"),
typeDef = TypeDef.SimpleTypeDef(IdentifierName(List(Identifier("Boolean")))),
defaultValue = ValueToken.ValueTokenLiteral(Literal.BooleanLiteral(true))
)
),
(
"var a: Boolean = True",
Assignation.VarAssignation(
Identifier("a"),
typeDef = TypeDef.SimpleTypeDef(IdentifierName(List(Identifier("Boolean")))),
defaultValue = ValueToken.ValueTokenLiteral(Literal.BooleanLiteral(true))
)
)
)

private val invalidIdentifiers = List(
"0s",
"person[]()",
"person[_]()",
"000asdfa",
"%%",
"--",
"@@",
"!43#",
"a.b..c",
"_a.bc.01"
)

override def spec: Spec[Any, Nothing] = suite("MemberReader.reader")(
suite("should succeed with valid member:")(for {
(identifier, expected) <- givenAndExpected
} yield test(identifier) {
// given
for {
// when
responses <- zioFromParsed(parse(identifier, subject.test)).either
// then
} yield assertTrue(responses.map(_.value) == Right(expected))
}),

// given
suite("should fail on invalid identifier:")(for {
identifier <- invalidIdentifiers
} yield test(identifier) {
for {
// when
response <- zioFromParsed(parse(identifier, subject.test)).either
// then
} yield assertTrue(response.isLeft)
})
)

}
Loading