diff --git a/examples/fib.pork b/examples/fib.pork index 03a6edb..d3e943c 100644 --- a/examples/fib.pork +++ b/examples/fib.pork @@ -1,3 +1,4 @@ +/* fibonacci sequence */ fib = { n in if n == 0 then 0 diff --git a/examples/syntax.pork b/examples/syntax.pork index 5461f6a..7441cb5 100644 --- a/examples/syntax.pork +++ b/examples/syntax.pork @@ -1,3 +1,4 @@ +/* main function */ main = { in three = 3 two = 2 diff --git a/src/main/kotlin/gay/pizza/pork/parse/PorkParser.kt b/src/main/kotlin/gay/pizza/pork/parse/PorkParser.kt index 0425c07..f9c2ac0 100644 --- a/src/main/kotlin/gay/pizza/pork/parse/PorkParser.kt +++ b/src/main/kotlin/gay/pizza/pork/parse/PorkParser.kt @@ -3,7 +3,7 @@ package gay.pizza.pork.parse import gay.pizza.pork.ast.nodes.* class PorkParser(source: PeekableSource) { - private val whitespaceIncludedSource = source + private val unsanitizedSource = source private fun readIntLiteral(): IntLiteral { val token = expect(TokenType.IntLiteral) @@ -176,8 +176,8 @@ class PorkParser(source: PeekableSource) { private fun next(): Token { while (true) { - val token = whitespaceIncludedSource.next() - if (token.type == TokenType.Whitespace) { + val token = unsanitizedSource.next() + if (ignoredByParser(token.type)) { continue } return token @@ -186,12 +186,18 @@ class PorkParser(source: PeekableSource) { private fun peek(): Token { while (true) { - val token = whitespaceIncludedSource.peek() - if (token.type == TokenType.Whitespace) { - whitespaceIncludedSource.next() + val token = unsanitizedSource.peek() + if (ignoredByParser(token.type)) { + unsanitizedSource.next() continue } return token } } + + private fun ignoredByParser(type: TokenType): Boolean = when (type) { + TokenType.BlockComment -> true + TokenType.Whitespace -> true + else -> false + } } diff --git a/src/main/kotlin/gay/pizza/pork/parse/PorkTokenizer.kt b/src/main/kotlin/gay/pizza/pork/parse/PorkTokenizer.kt index 2badaad..d300f89 100644 --- a/src/main/kotlin/gay/pizza/pork/parse/PorkTokenizer.kt +++ b/src/main/kotlin/gay/pizza/pork/parse/PorkTokenizer.kt @@ -51,11 +51,39 @@ class PorkTokenizer(val source: CharSource) { 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 { while (source.peek() != CharSource.NullChar) { tokenStart = source.currentIndex val char = source.next() + if (char == '/' && source.peek() == '*') { + return readBlockComment(char) + } + for (item in TokenType.SingleChars) { val itemChar = item.singleChar!!.char if (itemChar != char) { diff --git a/src/main/kotlin/gay/pizza/pork/parse/TokenType.kt b/src/main/kotlin/gay/pizza/pork/parse/TokenType.kt index d41ecab..2b102f5 100644 --- a/src/main/kotlin/gay/pizza/pork/parse/TokenType.kt +++ b/src/main/kotlin/gay/pizza/pork/parse/TokenType.kt @@ -26,6 +26,7 @@ enum class TokenType(vararg properties: TokenTypeProperty) { Then(Keyword("then")), Else(Keyword("else")), Whitespace, + BlockComment, EndOfFile; val promotions: List = properties.filterIsInstance()