Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BooleanParser #350

Merged
merged 2 commits into from
Jan 14, 2025
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.alephium.ralph.lsp.access.compiler.parser.soft

import fastparse._
import org.alephium.ralph.lsp.access.compiler.parser.soft.ast.{SoftAST, Token}

object BooleanParser {

def parseOrFail[Unknown: P]: P[SoftAST.TokenExpression[Token.PrimitiveBoolean]] =
P(boolean) map (SoftAST.TokenExpression(_))

private def boolean[Unknown: P]: P[SoftAST.TokenDocumented[Token.PrimitiveBoolean]] =
P(TokenParser.parseOrFail(Token.True) | TokenParser.parseOrFail(Token.False))

}
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ private object ExpressionParser {
ReferenceCallParser.parseOrFail |
AnnotationParser.parseOrFail |
TupleParser.parseOrFail |
BooleanParser.parseOrFail |
IdentifierParser.parseOrFail
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,19 @@ object SoftAST {
extends TokenExpectedErrorAST(token)
with TokenDocExpectedAST[T]

/**
* Represents a token that is also an expression, e.g. `true` & `false`.
*
* @param token A token that is also an expression.
* @tparam T Type of token.
*/
case class TokenExpression[+T <: Token.Expression](token: TokenDocumented[T]) extends ExpressionAST {

override def index: SourceIndex =
token.index

}

case class Template(
index: SourceIndex,
templateType: TokenDocumented[Token.TemplateDefinition],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ object Token {
*/
sealed trait Reserved extends Token
sealed trait InfixOperator extends Token
sealed trait Expression extends Token // A token that is also an expression.

sealed abstract class Operator(override val lexeme: String) extends Token
case object Equality extends Operator("==") with Reserved with InfixOperator
Expand Down Expand Up @@ -139,10 +140,14 @@ object Token {
case object Embeds extends Native("embeds")

sealed abstract class Primitive(override val lexeme: String) extends Token
case object True extends Primitive("true") with Reserved
case object False extends Primitive("false") with Reserved
case object Alph_Small extends Primitive("alph") with Reserved
case object Alph_Big extends Primitive("ALPH") with Reserved

sealed abstract class PrimitiveBoolean(override val lexeme: String) extends Primitive(lexeme) with Expression
case object True extends PrimitiveBoolean("true") with Reserved
case object False extends PrimitiveBoolean("false") with Reserved

sealed abstract class PrimitiveUnit(override val lexeme: String) extends Primitive(lexeme)
case object Alph_Small extends PrimitiveUnit("alph") with Reserved
case object Alph_Big extends PrimitiveUnit("ALPH") with Reserved

sealed trait Term extends Token
case class Name(lexeme: String) extends Term
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.alephium.ralph.lsp.access.compiler.parser.soft

import org.alephium.ralph.lsp.access.compiler.parser.soft.TestParser._
import org.alephium.ralph.lsp.access.compiler.parser.soft.ast.TestSoftAST._
import org.alephium.ralph.lsp.access.util.TestCodeUtil._
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
import org.scalatest.OptionValues._

class BooleanParserSpec extends AnyWordSpec with Matchers {

"true" in {
parseBoolean("true").token shouldBe True(indexOf(">>true<<"))
}

"false" in {
parseBoolean("false").token shouldBe False(indexOf(">>false<<"))
}

"boolean with comments" in {
Seq("true", "false") foreach {
bool =>
val result =
parseBoolean {
s"""// comment
|$bool""".stripMargin
}.token

// has comment
result.documentation.value.comments should have size 1
result.documentation.value.comments.head.text.value.text shouldBe "comment"

result.code.text shouldBe bool
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ object TestParser {
def parseIdentifier(code: String): SoftAST.IdentifierAST =
runSoftParser(IdentifierParser.parseOrFail(_))(code)

def parseBoolean(code: String): SoftAST.TokenExpression[Token.PrimitiveBoolean] =
runSoftParser(BooleanParser.parseOrFail(_))(code)

def findAnnotation(identifier: String)(code: String): Option[SoftAST.Annotation] =
findAnnotation(
identifier = identifier,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,18 @@ object TestSoftAST {
token = Token.CloseCurly
)

def True(index: SourceIndex): SoftAST.TokenDocumented[Token.True.type] =
TokenDocumented(
index = index,
token = Token.True
)

def False(index: SourceIndex): SoftAST.TokenDocumented[Token.False.type] =
TokenDocumented(
index = index,
token = Token.False
)

def Identifier(
index: SourceIndex,
text: String): SoftAST.Identifier =
Expand Down
Loading