Add support for block comments.

This commit is contained in:
Alex Zenla 2023-08-21 02:15:52 -07:00
parent 5f4d74008e
commit 5455846d7a
Signed by: alex
GPG Key ID: C0780728420EBFE5
5 changed files with 43 additions and 6 deletions

View File

@ -1,3 +1,4 @@
/* fibonacci sequence */
fib = { n in fib = { n in
if n == 0 if n == 0
then 0 then 0

View File

@ -1,3 +1,4 @@
/* main function */
main = { in main = { in
three = 3 three = 3
two = 2 two = 2

View File

@ -3,7 +3,7 @@ package gay.pizza.pork.parse
import gay.pizza.pork.ast.nodes.* import gay.pizza.pork.ast.nodes.*
class PorkParser(source: PeekableSource<Token>) { class PorkParser(source: PeekableSource<Token>) {
private val whitespaceIncludedSource = source private val unsanitizedSource = source
private fun readIntLiteral(): IntLiteral { private fun readIntLiteral(): IntLiteral {
val token = expect(TokenType.IntLiteral) val token = expect(TokenType.IntLiteral)
@ -176,8 +176,8 @@ class PorkParser(source: PeekableSource<Token>) {
private fun next(): Token { private fun next(): Token {
while (true) { while (true) {
val token = whitespaceIncludedSource.next() val token = unsanitizedSource.next()
if (token.type == TokenType.Whitespace) { if (ignoredByParser(token.type)) {
continue continue
} }
return token return token
@ -186,12 +186,18 @@ class PorkParser(source: PeekableSource<Token>) {
private fun peek(): Token { private fun peek(): Token {
while (true) { while (true) {
val token = whitespaceIncludedSource.peek() val token = unsanitizedSource.peek()
if (token.type == TokenType.Whitespace) { if (ignoredByParser(token.type)) {
whitespaceIncludedSource.next() unsanitizedSource.next()
continue continue
} }
return token return token
} }
} }
private fun ignoredByParser(type: TokenType): Boolean = when (type) {
TokenType.BlockComment -> true
TokenType.Whitespace -> true
else -> false
}
} }

View File

@ -51,11 +51,39 @@ class PorkTokenizer(val source: CharSource) {
return Token(TokenType.Whitespace, tokenStart, whitespace) return Token(TokenType.Whitespace, tokenStart, whitespace)
} }
private fun readBlockComment(firstChar: Char): Token {
val comment = buildString {
append(firstChar)
var endOfComment = false
while (true) {
val char = source.next()
append(char)
if (endOfComment) {
if (char != '/') {
endOfComment = false
continue
}
break
}
if (char == '*') {
endOfComment = true
}
}
}
return Token(TokenType.BlockComment, tokenStart, comment)
}
fun next(): Token { fun next(): Token {
while (source.peek() != CharSource.NullChar) { while (source.peek() != CharSource.NullChar) {
tokenStart = source.currentIndex tokenStart = source.currentIndex
val char = source.next() val char = source.next()
if (char == '/' && source.peek() == '*') {
return readBlockComment(char)
}
for (item in TokenType.SingleChars) { for (item in TokenType.SingleChars) {
val itemChar = item.singleChar!!.char val itemChar = item.singleChar!!.char
if (itemChar != char) { if (itemChar != char) {

View File

@ -26,6 +26,7 @@ enum class TokenType(vararg properties: TokenTypeProperty) {
Then(Keyword("then")), Then(Keyword("then")),
Else(Keyword("else")), Else(Keyword("else")),
Whitespace, Whitespace,
BlockComment,
EndOfFile; EndOfFile;
val promotions: List<Promotion> = properties.filterIsInstance<Promotion>() val promotions: List<Promotion> = properties.filterIsInstance<Promotion>()