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

Fix - Unit keyword (and probably others) cannot be used in enum values #315

Merged
merged 2 commits into from
Jan 13, 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
Expand Up @@ -10,21 +10,17 @@ import community.flock.wirespec.compiler.core.Reported.VALIDATED
import community.flock.wirespec.compiler.core.emit.common.Emitted
import community.flock.wirespec.compiler.core.emit.common.Emitter
import community.flock.wirespec.compiler.core.exceptions.WirespecException
import community.flock.wirespec.compiler.core.optimize.optimize
import community.flock.wirespec.compiler.core.parse.AST
import community.flock.wirespec.compiler.core.parse.Parser
import community.flock.wirespec.compiler.core.tokenize.tokenize
import community.flock.wirespec.compiler.core.validate.validate
import community.flock.wirespec.compiler.utils.Logger


fun LanguageSpec.parse(source: String): (Logger) -> Either<NonEmptyList<WirespecException>, AST> =
{ logger ->
tokenize(source)
.also((TOKENIZED::report)(logger))
.optimize()
.also((VALIDATED::report)(logger))
.let { Parser(logger).parse(it) }
.let(Parser(logger)::parse)
.also((PARSED::report)(logger))
.map { it.validate() }
.also((VALIDATED::report)(logger))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,50 +1,53 @@
package community.flock.wirespec.compiler.core

import community.flock.wirespec.compiler.core.tokenize.types.Arrow
import community.flock.wirespec.compiler.core.tokenize.types.Brackets
import community.flock.wirespec.compiler.core.tokenize.types.Character
import community.flock.wirespec.compiler.core.tokenize.types.Colon
import community.flock.wirespec.compiler.core.tokenize.types.Comma
import community.flock.wirespec.compiler.core.tokenize.types.CustomType
import community.flock.wirespec.compiler.core.tokenize.types.CustomValue
import community.flock.wirespec.compiler.core.tokenize.types.Equals
import community.flock.wirespec.compiler.core.tokenize.types.ForwardSlash
import community.flock.wirespec.compiler.core.tokenize.types.Hash
import community.flock.wirespec.compiler.core.tokenize.types.LeftCurly
import community.flock.wirespec.compiler.core.tokenize.types.Method
import community.flock.wirespec.compiler.core.tokenize.types.NewLine
import community.flock.wirespec.compiler.core.tokenize.types.Path
import community.flock.wirespec.compiler.core.tokenize.types.Pipe
import community.flock.wirespec.compiler.core.tokenize.types.QuestionMark
import community.flock.wirespec.compiler.core.tokenize.types.RightCurly
import community.flock.wirespec.compiler.core.tokenize.types.StatusCode
import community.flock.wirespec.compiler.core.tokenize.types.TokenType
import community.flock.wirespec.compiler.core.tokenize.types.WhiteSpaceExceptNewLine
import community.flock.wirespec.compiler.core.tokenize.types.WsBoolean
import community.flock.wirespec.compiler.core.tokenize.types.WsBytes
import community.flock.wirespec.compiler.core.tokenize.types.WsChannelDef
import community.flock.wirespec.compiler.core.tokenize.types.WsComment
import community.flock.wirespec.compiler.core.tokenize.types.WsEndpointDef
import community.flock.wirespec.compiler.core.tokenize.types.WsEnumTypeDef
import community.flock.wirespec.compiler.core.tokenize.types.WsInteger
import community.flock.wirespec.compiler.core.tokenize.types.WsNumber
import community.flock.wirespec.compiler.core.tokenize.types.WsString
import community.flock.wirespec.compiler.core.tokenize.types.WsTypeDef
import community.flock.wirespec.compiler.core.tokenize.types.WsUnit
import community.flock.wirespec.compiler.core.tokenize.Arrow
import community.flock.wirespec.compiler.core.tokenize.Brackets
import community.flock.wirespec.compiler.core.tokenize.ChannelDefinition
import community.flock.wirespec.compiler.core.tokenize.Character
import community.flock.wirespec.compiler.core.tokenize.Colon
import community.flock.wirespec.compiler.core.tokenize.Comma
import community.flock.wirespec.compiler.core.tokenize.Comment
import community.flock.wirespec.compiler.core.tokenize.CustomType
import community.flock.wirespec.compiler.core.tokenize.CustomValue
import community.flock.wirespec.compiler.core.tokenize.EndpointDefinition
import community.flock.wirespec.compiler.core.tokenize.EnumTypeDefinition
import community.flock.wirespec.compiler.core.tokenize.Equals
import community.flock.wirespec.compiler.core.tokenize.ForwardSlash
import community.flock.wirespec.compiler.core.tokenize.Hash
import community.flock.wirespec.compiler.core.tokenize.LeftCurly
import community.flock.wirespec.compiler.core.tokenize.Method
import community.flock.wirespec.compiler.core.tokenize.NewLine
import community.flock.wirespec.compiler.core.tokenize.Path
import community.flock.wirespec.compiler.core.tokenize.Pipe
import community.flock.wirespec.compiler.core.tokenize.Precision.P32
import community.flock.wirespec.compiler.core.tokenize.Precision.P64
import community.flock.wirespec.compiler.core.tokenize.QuestionMark
import community.flock.wirespec.compiler.core.tokenize.RightCurly
import community.flock.wirespec.compiler.core.tokenize.StatusCode
import community.flock.wirespec.compiler.core.tokenize.TokenType
import community.flock.wirespec.compiler.core.tokenize.TypeDefinition
import community.flock.wirespec.compiler.core.tokenize.WhiteSpaceExceptNewLine
import community.flock.wirespec.compiler.core.tokenize.WsBoolean
import community.flock.wirespec.compiler.core.tokenize.WsBytes
import community.flock.wirespec.compiler.core.tokenize.WsInteger
import community.flock.wirespec.compiler.core.tokenize.WsNumber
import community.flock.wirespec.compiler.core.tokenize.WsString
import community.flock.wirespec.compiler.core.tokenize.WsUnit

typealias TokenMatcher = Pair<Regex, TokenType>

interface LanguageSpec {
val customType: CustomType
val orderedMatchers: List<TokenMatcher>
}

object WirespecSpec : LanguageSpec {
@Suppress("RegExpRedundantEscape")
override val customType = WsCustomType
override val orderedMatchers = listOf(
Regex("^type") to WsTypeDef,
Regex("^enum") to WsEnumTypeDef,
Regex("^endpoint") to WsEndpointDef,
Regex("^channel") to WsChannelDef,
Regex("^type") to TypeDefinition,
Regex("^enum") to EnumTypeDefinition,
Regex("^endpoint") to EndpointDefinition,
Regex("^channel") to ChannelDefinition,
Regex("^[^\\S\\r\\n]+") to WhiteSpaceExceptNewLine,
Regex("^[\\r\\n]") to NewLine,
Regex("^\\{") to LeftCurly,
Expand All @@ -57,21 +60,26 @@ object WirespecSpec : LanguageSpec {
Regex("^\\?") to QuestionMark,
Regex("^#") to Hash,
Regex("^\\[\\]") to Brackets,
Regex("^String") to WsString,
Regex("^Bytes") to WsBytes,
Regex("^Integer32") to WsInteger,
Regex("^Integer") to WsInteger,
Regex("^Number32") to WsNumber,
Regex("^Number") to WsNumber,
Regex("^Boolean") to WsBoolean,
Regex("^Unit") to WsUnit,
Regex("^GET|^POST|^PUT|^DELETE|^OPTIONS|^HEAD|^PATCH|^TRACE") to Method,
Regex("^[1-5][0-9][0-9]") to StatusCode,
Regex("^[a-z`][a-zA-Z0-9_`]*") to CustomValue,
Regex("^[A-Z][a-zA-Z0-9_]*") to CustomType,
Regex("^[A-Z][a-zA-Z0-9_]*") to customType,
Regex("^/[a-zA-Z0-9-_]+") to Path,
Regex("^\\/\\*(\\*(?!\\/)|[^*])*\\*\\/") to WsComment,
Regex("^\\/\\*(\\*(?!\\/)|[^*])*\\*\\/") to Comment,
Regex("^/") to ForwardSlash,
Regex("^.") to Character // Catch all regular expression if none of the above matched
)
}

data object WsCustomType : CustomType {
override val types = mapOf(
"Boolean" to WsBoolean,
"Bytes" to WsBytes,
"Integer" to WsInteger(P64),
"Integer32" to WsInteger(P32),
"Number" to WsNumber(P64),
"Number32" to WsNumber(P32),
"String" to WsString,
"Unit" to WsUnit,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ open class WirespecEmitter(logger: Logger = noLogger) : DefinitionModelEmitter,
is FieldIdentifier -> identifier.run { if (value in reservedKeywords || value.first().isUpperCase()) value.addBackticks() else value }
}


override fun emit(channel: Channel): String =
"channel ${emit(channel.identifier)} -> ${channel.reference.emit()}"

Expand All @@ -61,16 +60,16 @@ open class WirespecEmitter(logger: Logger = noLogger) : DefinitionModelEmitter,
is Reference.Custom -> value
is Reference.Primitive -> when (type) {
is Reference.Primitive.Type.String -> "String"
is Reference.Primitive.Type.Boolean -> "Boolean"
is Reference.Primitive.Type.Bytes -> "Bytes"
is Reference.Primitive.Type.Integer -> when(type.precision){
Reference.Primitive.Type.Precision.P32 -> "Integer32"
else ->"Integer"
Reference.Primitive.Type.Precision.P64 -> "Integer"
}
is Reference.Primitive.Type.Number -> when(type.precision){
Reference.Primitive.Type.Precision.P32 -> "Number32"
else ->"Number"
Reference.Primitive.Type.Precision.P64 -> "Number"
}
is Reference.Primitive.Type.Boolean -> "Boolean"
is Reference.Primitive.Type.Bytes -> "Bytes"
}
}
.let { if (isIterable) "$it[]" else it }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package community.flock.wirespec.compiler.core.exceptions

import community.flock.wirespec.compiler.core.tokenize.Token
import community.flock.wirespec.compiler.core.tokenize.types.TokenType
import community.flock.wirespec.compiler.core.tokenize.types.name
import community.flock.wirespec.compiler.core.tokenize.TokenType
import community.flock.wirespec.compiler.core.tokenize.name
import kotlin.reflect.KClass

sealed class WirespecException(message: String, val coordinates: Token.Coordinates) : RuntimeException(message) {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ import arrow.core.Either
import arrow.core.raise.either
import community.flock.wirespec.compiler.core.exceptions.WirespecException
import community.flock.wirespec.compiler.core.exceptions.WirespecException.CompilerException.ParserException.WrongTokenException
import community.flock.wirespec.compiler.core.tokenize.types.Arrow
import community.flock.wirespec.compiler.core.tokenize.types.Colon
import community.flock.wirespec.compiler.core.tokenize.types.CustomType
import community.flock.wirespec.compiler.core.tokenize.types.LeftCurly
import community.flock.wirespec.compiler.core.tokenize.types.QuestionMark
import community.flock.wirespec.compiler.core.tokenize.types.RightCurly
import community.flock.wirespec.compiler.core.tokenize.types.WirespecType
import community.flock.wirespec.compiler.core.tokenize.Arrow
import community.flock.wirespec.compiler.core.tokenize.Colon
import community.flock.wirespec.compiler.core.tokenize.LeftCurly
import community.flock.wirespec.compiler.core.tokenize.QuestionMark
import community.flock.wirespec.compiler.core.tokenize.RightCurly
import community.flock.wirespec.compiler.core.tokenize.WirespecType
import community.flock.wirespec.compiler.utils.Logger

class ChannelParser(logger: Logger) : AbstractParser(logger) {
Expand All @@ -21,8 +20,8 @@ class ChannelParser(logger: Logger) : AbstractParser(logger) {
eatToken().bind()
token.log()
when (token.type) {
is CustomType -> parseChannelDefinition(comment, DefinitionIdentifier(token.value)).bind()
else -> raise(WrongTokenException<CustomType>(token).also { eatToken().bind() })
is WirespecType -> parseChannelDefinition(comment, DefinitionIdentifier(token.value)).bind()
else -> raise(WrongTokenException<WirespecType>(token).also { eatToken().bind() })
}
}

Expand Down Expand Up @@ -52,7 +51,7 @@ class ChannelParser(logger: Logger) : AbstractParser(logger) {
}
}

else -> raise(WrongTokenException<CustomType>(token).also { eatToken().bind() })
else -> raise(WrongTokenException<WirespecType>(token).also { eatToken().bind() })
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,26 @@ import arrow.core.Either
import arrow.core.raise.either
import community.flock.wirespec.compiler.core.exceptions.WirespecException
import community.flock.wirespec.compiler.core.exceptions.WirespecException.CompilerException.ParserException.WrongTokenException
import community.flock.wirespec.compiler.core.tokenize.types.Arrow
import community.flock.wirespec.compiler.core.tokenize.types.Brackets
import community.flock.wirespec.compiler.core.tokenize.types.Colon
import community.flock.wirespec.compiler.core.tokenize.types.CustomType
import community.flock.wirespec.compiler.core.tokenize.types.CustomValue
import community.flock.wirespec.compiler.core.tokenize.types.ForwardSlash
import community.flock.wirespec.compiler.core.tokenize.types.Hash
import community.flock.wirespec.compiler.core.tokenize.types.LeftCurly
import community.flock.wirespec.compiler.core.tokenize.types.Method
import community.flock.wirespec.compiler.core.tokenize.types.Path
import community.flock.wirespec.compiler.core.tokenize.types.QuestionMark
import community.flock.wirespec.compiler.core.tokenize.types.RightCurly
import community.flock.wirespec.compiler.core.tokenize.types.StatusCode
import community.flock.wirespec.compiler.core.tokenize.types.WirespecType
import community.flock.wirespec.compiler.core.tokenize.types.WsBoolean
import community.flock.wirespec.compiler.core.tokenize.types.WsBytes
import community.flock.wirespec.compiler.core.tokenize.types.WsInteger
import community.flock.wirespec.compiler.core.tokenize.types.WsNumber
import community.flock.wirespec.compiler.core.tokenize.types.WsString
import community.flock.wirespec.compiler.core.tokenize.types.WsUnit
import community.flock.wirespec.compiler.core.tokenize.Arrow
import community.flock.wirespec.compiler.core.tokenize.Brackets
import community.flock.wirespec.compiler.core.tokenize.Colon
import community.flock.wirespec.compiler.core.tokenize.CustomType
import community.flock.wirespec.compiler.core.tokenize.CustomValue
import community.flock.wirespec.compiler.core.tokenize.ForwardSlash
import community.flock.wirespec.compiler.core.tokenize.Hash
import community.flock.wirespec.compiler.core.tokenize.LeftCurly
import community.flock.wirespec.compiler.core.tokenize.Method
import community.flock.wirespec.compiler.core.tokenize.Path
import community.flock.wirespec.compiler.core.tokenize.QuestionMark
import community.flock.wirespec.compiler.core.tokenize.RightCurly
import community.flock.wirespec.compiler.core.tokenize.StatusCode
import community.flock.wirespec.compiler.core.tokenize.WirespecType
import community.flock.wirespec.compiler.core.tokenize.WsBoolean
import community.flock.wirespec.compiler.core.tokenize.WsBytes
import community.flock.wirespec.compiler.core.tokenize.WsInteger
import community.flock.wirespec.compiler.core.tokenize.WsNumber
import community.flock.wirespec.compiler.core.tokenize.WsString
import community.flock.wirespec.compiler.core.tokenize.WsUnit
import community.flock.wirespec.compiler.utils.Logger

class EndpointParser(logger: Logger) : AbstractParser(logger) {
Expand All @@ -34,8 +34,8 @@ class EndpointParser(logger: Logger) : AbstractParser(logger) {
eatToken().bind()
token.log()
when (token.type) {
is CustomType -> parseEndpointDefinition(comment, DefinitionIdentifier(token.value)).bind()
else -> raise(WrongTokenException<CustomType>(token).also { eatToken().bind() })
is WirespecType -> parseEndpointDefinition(comment, DefinitionIdentifier(token.value)).bind()
else -> raise(WrongTokenException<WirespecType>(token).also { eatToken().bind() })
}
}

Expand Down Expand Up @@ -254,19 +254,13 @@ class EndpointParser(logger: Logger) : AbstractParser(logger) {
)

is WsInteger -> Reference.Primitive(
type = Reference.Primitive.Type.Integer(when(value) {
"Integer32" -> Reference.Primitive.Type.Precision.P32
else -> Reference.Primitive.Type.Precision.P64
}),
type = Reference.Primitive.Type.Integer(wsType.precision.toPrimitivePrecision()),
isIterable = isIterable,
isDictionary = isDict,
)

is WsNumber -> Reference.Primitive(
type = Reference.Primitive.Type.Number(when(value) {
"Number32" -> Reference.Primitive.Type.Precision.P32
else -> Reference.Primitive.Type.Precision.P64
}),
type = Reference.Primitive.Type.Number(wsType.precision.toPrimitivePrecision()),
isIterable = isIterable,
isDictionary = isDict,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import arrow.core.Either
import arrow.core.raise.either
import community.flock.wirespec.compiler.core.exceptions.WirespecException
import community.flock.wirespec.compiler.core.exceptions.WirespecException.CompilerException.ParserException.WrongTokenException
import community.flock.wirespec.compiler.core.tokenize.types.Comma
import community.flock.wirespec.compiler.core.tokenize.types.CustomType
import community.flock.wirespec.compiler.core.tokenize.types.LeftCurly
import community.flock.wirespec.compiler.core.tokenize.types.RightCurly
import community.flock.wirespec.compiler.core.tokenize.Comma
import community.flock.wirespec.compiler.core.tokenize.LeftCurly
import community.flock.wirespec.compiler.core.tokenize.RightCurly
import community.flock.wirespec.compiler.core.tokenize.WirespecType
import community.flock.wirespec.compiler.utils.Logger

class EnumParser(logger: Logger) : AbstractParser(logger) {
Expand All @@ -16,8 +16,8 @@ class EnumParser(logger: Logger) : AbstractParser(logger) {
eatToken().bind()
token.log()
when (token.type) {
is CustomType -> parseEnumTypeDefinition(comment, DefinitionIdentifier(token.value)).bind()
else -> raise(WrongTokenException<CustomType>(token).also { eatToken().bind() })
is WirespecType -> parseEnumTypeDefinition(comment, DefinitionIdentifier(token.value)).bind()
else -> raise(WrongTokenException<WirespecType>(token).also { eatToken().bind() })
}
}

Expand All @@ -44,19 +44,19 @@ class EnumParser(logger: Logger) : AbstractParser(logger) {
eatToken().bind()
token.log()
when (token.type) {
is CustomType -> mutableListOf<String>().apply {
is WirespecType -> mutableListOf<String>().apply {
add(token.value)
eatToken().bind()
while (token.type == Comma) {
eatToken().bind()
when (token.type) {
is CustomType -> add(token.value).also { eatToken().bind() }
else -> raise(WrongTokenException<CustomType>(token).also { eatToken().bind() })
is WirespecType -> add(token.value).also { eatToken().bind() }
else -> raise(WrongTokenException<WirespecType>(token).also { eatToken().bind() })
}
}
}

else -> raise(WrongTokenException<CustomType>(token).also { eatToken().bind() })
else -> raise(WrongTokenException<WirespecType>(token).also { eatToken().bind() })
}.toSet()
}
}
Loading
Loading