while loop support, and native functions (including ffi!)

This commit is contained in:
2023-09-06 19:07:28 -07:00
parent ddff6cb365
commit 236f812caf
34 changed files with 467 additions and 115 deletions

View File

@ -72,13 +72,26 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
private fun readIf(): If = within {
expect(TokenType.If)
val condition = readExpression()
expect(TokenType.Then)
val thenExpression = readExpression()
var elseExpression: Expression? = null
val thenBlock = readBlock()
var elseBlock: Block? = null
if (next(TokenType.Else)) {
elseExpression = readExpression()
elseBlock = readBlock()
}
If(condition, thenExpression, elseExpression)
If(condition, thenBlock, elseBlock)
}
private fun readWhile(): While = within {
expect(TokenType.While)
val condition = readExpression()
val block = readBlock()
While(condition, block)
}
private fun readNative(): Native = within {
expect(TokenType.Native)
val form = readSymbolRaw()
val definition = readStringLiteral()
Native(form, definition)
}
fun readExpression(): Expression {
@ -120,6 +133,20 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
readIf()
}
TokenType.While -> {
readWhile()
}
TokenType.Break -> {
expect(TokenType.Break)
Break()
}
TokenType.Continue -> {
expect(TokenType.Continue)
Continue()
}
else -> {
throw RuntimeException(
"Failed to parse token: ${token.type} '${token.text}' as" +
@ -178,7 +205,15 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
readSymbolRaw()
}
expect(TokenType.RightParentheses)
FunctionDefinition(modifiers, name, arguments, readBlock())
var native: Native? = null
var block: Block? = null
if (peek(TokenType.Native)) {
native = readNative()
} else {
block = readBlock()
}
FunctionDefinition(modifiers, name, arguments, block, native)
}
private fun maybeReadDefinition(): Definition? {

View File

@ -38,6 +38,8 @@ class Printer(buffer: StringBuilder) : NodeVisitor<Unit> {
}
}
override fun visitBreak(node: Break): Unit = append("break")
override fun visitListLiteral(node: ListLiteral) {
append("[")
if (node.items.isNotEmpty()) {
@ -55,6 +57,13 @@ class Printer(buffer: StringBuilder) : NodeVisitor<Unit> {
append("]")
}
override fun visitNative(node: Native) {
append("native ")
visit(node.form)
append(" ")
visit(node.definition)
}
override fun visitSymbol(node: Symbol) {
append(node.id)
}
@ -82,6 +91,13 @@ class Printer(buffer: StringBuilder) : NodeVisitor<Unit> {
visit(node.symbol)
}
override fun visitWhile(node: While) {
append("while ")
visit(node.condition)
append(" ")
visit(node.block)
}
override fun visitParentheses(node: Parentheses) {
append("(")
visit(node.expression)
@ -96,18 +112,13 @@ class Printer(buffer: StringBuilder) : NodeVisitor<Unit> {
override fun visitIf(node: If) {
append("if ")
visit(node.condition)
append(" then")
out.increaseIndent()
appendLine()
visit(node.thenExpression)
out.decreaseIndent()
if (node.elseExpression != null) {
appendLine()
append(" ")
visit(node.thenBlock)
if (node.elseBlock != null) {
append(" ")
append("else")
out.increaseIndent()
appendLine()
visit(node.elseExpression!!)
out.decreaseIndent()
append(" ")
visit(node.elseBlock!!)
}
}
@ -120,7 +131,7 @@ class Printer(buffer: StringBuilder) : NodeVisitor<Unit> {
}
override fun visitFunctionDefinition(node: FunctionDefinition) {
append("fn ")
append("func ")
visit(node.symbol)
append("(")
for ((index, argument) in node.arguments.withIndex()) {
@ -130,7 +141,13 @@ class Printer(buffer: StringBuilder) : NodeVisitor<Unit> {
}
}
append(") ")
visit(node.block)
if (node.block != null) {
visit(node.block!!)
}
if (node.native != null) {
visit(node.native!!)
}
}
override fun visitBlock(node: Block) {
@ -167,4 +184,6 @@ class Printer(buffer: StringBuilder) : NodeVisitor<Unit> {
appendLine()
}
}
override fun visitContinue(node: Continue): Unit = append("continue")
}

View File

@ -25,11 +25,14 @@ enum class TokenType(vararg properties: TokenTypeProperty) {
False(Keyword("false"), KeywordFamily),
True(Keyword("true"), KeywordFamily),
If(Keyword("if"), KeywordFamily),
Then(Keyword("then"), 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),
Whitespace(CharConsumer { it == ' ' || it == '\r' || it == '\n' || it == '\t' }),
BlockComment(CommentFamily),