mirror of
https://github.com/GayPizzaSpecifications/pork.git
synced 2025-08-03 21:21:33 +00:00
language: prelude and internal functions, and varargs support
This commit is contained in:
@ -217,7 +217,7 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
|
||||
private fun readImportDeclaration(): ImportDeclaration = within {
|
||||
expect(TokenType.Import)
|
||||
val form = readSymbolRaw()
|
||||
val components = oneAndContinuedBy(TokenType.Period) { readSymbolRaw() }
|
||||
val components = oneAndContinuedBy(TokenType.Dot) { readSymbolRaw() }
|
||||
ImportDeclaration(form, components)
|
||||
}
|
||||
|
||||
@ -237,7 +237,12 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
|
||||
val name = readSymbolRaw()
|
||||
expect(TokenType.LeftParentheses)
|
||||
val arguments = collect(TokenType.RightParentheses, TokenType.Comma) {
|
||||
readSymbolRaw()
|
||||
val symbol = readSymbolRaw()
|
||||
var multiple: Boolean = false
|
||||
if (next(TokenType.DotDotDot)) {
|
||||
multiple = true
|
||||
}
|
||||
ArgumentSpec(symbol, multiple)
|
||||
}
|
||||
expect(TokenType.RightParentheses)
|
||||
|
||||
|
@ -155,7 +155,10 @@ class Printer(buffer: StringBuilder) : NodeVisitor<Unit> {
|
||||
visit(node.symbol)
|
||||
append("(")
|
||||
for ((index, argument) in node.arguments.withIndex()) {
|
||||
visit(argument)
|
||||
visit(argument.symbol)
|
||||
if (argument.multiple) {
|
||||
append("...")
|
||||
}
|
||||
if (index + 1 != node.arguments.size) {
|
||||
append(", ")
|
||||
}
|
||||
|
@ -30,23 +30,25 @@ enum class TokenType(vararg properties: TokenTypeProperty) {
|
||||
LeftParentheses(SingleChar('(')),
|
||||
RightParentheses(SingleChar(')')),
|
||||
Negation(SingleChar('!'), Promotion('=', Inequality), OperatorFamily),
|
||||
Mod(Keyword("mod"), OperatorFamily),
|
||||
Rem(Keyword("rem"), OperatorFamily),
|
||||
Mod(ManyChars("mod"), OperatorFamily),
|
||||
Rem(ManyChars("rem"), OperatorFamily),
|
||||
Comma(SingleChar(',')),
|
||||
Period(SingleChar('.')),
|
||||
False(Keyword("false"), KeywordFamily),
|
||||
True(Keyword("true"), KeywordFamily),
|
||||
If(Keyword("if"), KeywordFamily),
|
||||
Else(Keyword("else"), KeywordFamily),
|
||||
While(Keyword("while"), KeywordFamily),
|
||||
Continue(Keyword("continue"), KeywordFamily),
|
||||
Break(Keyword("break"), KeywordFamily),
|
||||
Import(Keyword("import"), KeywordFamily),
|
||||
Export(Keyword("export"), KeywordFamily),
|
||||
Func(Keyword("func"), KeywordFamily),
|
||||
Native(Keyword("native"), KeywordFamily),
|
||||
Let(Keyword("let"), KeywordFamily),
|
||||
Var(Keyword("var"), KeywordFamily),
|
||||
DotDotDot(ManyChars("...")),
|
||||
DotDot(ManyChars(".."), Promotion('.', DotDotDot)),
|
||||
Dot(SingleChar('.'), Promotion('.', DotDot)),
|
||||
False(ManyChars("false"), KeywordFamily),
|
||||
True(ManyChars("true"), KeywordFamily),
|
||||
If(ManyChars("if"), KeywordFamily),
|
||||
Else(ManyChars("else"), KeywordFamily),
|
||||
While(ManyChars("while"), KeywordFamily),
|
||||
Continue(ManyChars("continue"), KeywordFamily),
|
||||
Break(ManyChars("break"), KeywordFamily),
|
||||
Import(ManyChars("import"), KeywordFamily),
|
||||
Export(ManyChars("export"), KeywordFamily),
|
||||
Func(ManyChars("func"), KeywordFamily),
|
||||
Native(ManyChars("native"), KeywordFamily),
|
||||
Let(ManyChars("let"), KeywordFamily),
|
||||
Var(ManyChars("var"), KeywordFamily),
|
||||
Whitespace(CharConsumer { it == ' ' || it == '\r' || it == '\n' || it == '\t' }),
|
||||
BlockComment(CommentFamily),
|
||||
LineComment(CommentFamily),
|
||||
@ -54,8 +56,8 @@ enum class TokenType(vararg properties: TokenTypeProperty) {
|
||||
|
||||
val promotions: List<Promotion> =
|
||||
properties.filterIsInstance<Promotion>()
|
||||
val keyword: Keyword? =
|
||||
properties.filterIsInstance<Keyword>().singleOrNull()
|
||||
val manyChars: ManyChars? =
|
||||
properties.filterIsInstance<ManyChars>().singleOrNull()
|
||||
val singleChar: SingleChar? =
|
||||
properties.filterIsInstance<SingleChar>().singleOrNull()
|
||||
val family: TokenFamily =
|
||||
@ -67,7 +69,7 @@ enum class TokenType(vararg properties: TokenTypeProperty) {
|
||||
properties.filterIsInstance<TokenUpgrader>().singleOrNull()
|
||||
|
||||
companion object {
|
||||
val Keywords = entries.filter { item -> item.keyword != null }
|
||||
val ManyChars = entries.filter { item -> item.manyChars != null }
|
||||
val SingleChars = entries.filter { item -> item.singleChar != null }
|
||||
val CharConsumers = entries.filter { item ->
|
||||
item.charConsumer != null || item.charIndexConsumer != null }
|
||||
|
@ -3,15 +3,15 @@ package gay.pizza.pork.parser
|
||||
interface TokenTypeProperty {
|
||||
class SingleChar(val char: Char) : TokenTypeProperty
|
||||
class Promotion(val nextChar: Char, val type: TokenType) : TokenTypeProperty
|
||||
class Keyword(val text: String) : TokenTypeProperty
|
||||
class ManyChars(val text: String) : TokenTypeProperty
|
||||
class CharConsumer(val isValid: (Char) -> Boolean) : TokenTypeProperty
|
||||
class CharIndexConsumer(val isValid: (Char, Int) -> Boolean) : TokenTypeProperty
|
||||
open class TokenUpgrader(val maybeUpgrade: (Token) -> Token?) : TokenTypeProperty
|
||||
|
||||
object KeywordUpgrader : TokenUpgrader({ token ->
|
||||
var upgraded: Token? = null
|
||||
for (item in TokenType.Keywords) {
|
||||
if (item.keyword != null && token.text == item.keyword.text) {
|
||||
for (item in TokenType.ManyChars) {
|
||||
if (item.manyChars != null && token.text == item.manyChars.text) {
|
||||
upgraded = Token(item, token.start, token.text)
|
||||
break
|
||||
}
|
||||
|
@ -79,13 +79,18 @@ class Tokenizer(val source: CharSource) {
|
||||
|
||||
var type = item
|
||||
var text = itemChar.toString()
|
||||
for (promotion in item.promotions) {
|
||||
if (source.peek() != promotion.nextChar) {
|
||||
continue
|
||||
var promoted = true
|
||||
while (promoted) {
|
||||
promoted = false
|
||||
for (promotion in type.promotions) {
|
||||
if (source.peek() != promotion.nextChar) {
|
||||
continue
|
||||
}
|
||||
val nextChar = source.next()
|
||||
type = promotion.type
|
||||
text += nextChar
|
||||
promoted = true
|
||||
}
|
||||
val nextChar = source.next()
|
||||
type = promotion.type
|
||||
text += nextChar
|
||||
}
|
||||
return Token(type, tokenStart, text)
|
||||
}
|
||||
|
Reference in New Issue
Block a user