while loops working

This commit is contained in:
2026-05-02 09:31:27 +10:00
parent 2320e4901f
commit 072740bf51
4 changed files with 62 additions and 12 deletions

View File

@@ -28,6 +28,8 @@ char* ASTNodeTypeToCStr(CometASTNodeType nodeType) {
return "AST_RETURN_STATEMENT";
case AST_IF_STATEMENT:
return "AST_IF_STATEMENT";
case AST_WHILE_STATEMENT:
return "AST_WHILE_STATEMENT";
case AST_INFIX_EXPRESSION:
return "AST_INFIX_EXPRESSION";

View File

@@ -303,6 +303,35 @@ ResultType(Nothing, charptr) visitIfStatement(CometCompiler* compiler, CometASTN
return Success(Nothing, charptr, {});
}
ResultType(Nothing, charptr) visitWhileStatement(CometCompiler* compiler, CometASTNode* node) {
CometASTNode* condition = node->data.AST_WHILE_STATEMENT.expression;
CometASTNode* body = node->data.AST_WHILE_STATEMENT.program;
ResultType(CometTypeValuePair, charptr) beforeCheck = resolveValue(compiler, condition);
if (beforeCheck.error)
return Error(Nothing, charptr, beforeCheck.as.error);
LLVMBasicBlockRef whileLoopEntry = LLVMAppendBasicBlockInContext(compiler->context, compiler->currentFunction, "whileLoopEntry");
LLVMBasicBlockRef whileLoopOtherwise = LLVMAppendBasicBlockInContext(compiler->context, compiler->currentFunction, "whileLoopOtherwise");
LLVMBuildCondBr(compiler->builder, beforeCheck.as.success.value, whileLoopEntry, whileLoopOtherwise);
// build loop body
LLVMPositionBuilderAtEnd(compiler->builder, whileLoopEntry);
ResultType(Nothing, charptr) bodyResult = compileBlock(compiler, body);
if (bodyResult.error)
return bodyResult;
ResultType(CometTypeValuePair, charptr) afterCheck = resolveValue(compiler, condition);
if (afterCheck.error)
return Error(Nothing, charptr, afterCheck.as.error);
LLVMBuildCondBr(compiler->builder, afterCheck.as.success.value, whileLoopEntry, whileLoopOtherwise);
LLVMPositionBuilderAtEnd(compiler->builder, whileLoopOtherwise);
return Success(Nothing, charptr, {});
}
// -- EXPRESSIONS -- //
ResultType(CometTypeValuePair, charptr) visitInfixExpression(CometCompiler* compiler, CometASTNode* node) {
CometToken op = node->data.AST_INFIX_EXPRESSION.op;
@@ -337,10 +366,32 @@ ResultType(CometTypeValuePair, charptr) visitInfixExpression(CometCompiler* comp
break;
}
// conditionals
case CT_EQ_EQ: {
type = getType(compiler, "bool");
value = LLVMBuildICmp(compiler->builder, LLVMIntEQ, left.as.success.value, right.as.success.value, "tmp");
break;
}
case CT_LT: {
type = getType(compiler, "bool");
value = LLVMBuildICmp(compiler->builder, LLVMIntSLT, left.as.success.value, right.as.success.value, "tmp");
break;
}
case CT_LTE: {
type = getType(compiler, "bool");
value = LLVMBuildICmp(compiler->builder, LLVMIntULE, left.as.success.value, right.as.success.value, "tmp");
break;
}
case CT_GT: {
type = getType(compiler, "bool");
value = LLVMBuildICmp(compiler->builder, LLVMIntSGT, left.as.success.value, right.as.success.value, "tmp");
break;
}
case CT_GTE: {
type = getType(compiler, "bool");
value = LLVMBuildICmp(compiler->builder, LLVMIntUGE, left.as.success.value, right.as.success.value, "tmp");
break;
}
default:
return Error(CometTypeValuePair, charptr, "Unexpected operator for int and int!");
@@ -457,6 +508,8 @@ ResultType(Nothing, charptr) compile(CometCompiler* compiler, CometASTNode* node
return visitReassignStatement(compiler, node);
case AST_IF_STATEMENT:
return visitIfStatement(compiler, node);
case AST_WHILE_STATEMENT:
return visitWhileStatement(compiler, node);
case AST_INFIX_EXPRESSION: {
ResultType(CometTypeValuePair, charptr) result = visitInfixExpression(compiler, node);

View File

@@ -573,9 +573,7 @@ ResultType(astNodePtr, charptr) parseBlockStatement(CometParser* parser) {
appendStatement(program, stmt.as.success);
if (parser->currentToken->type != CT_CLOSE_CURLY) {
parserNextToken(parser);
}
parserNextToken(parser);
}
@@ -616,7 +614,6 @@ ResultType(astNodePtr, charptr) parseOptionalBlockStatement(CometParser* parser)
stmt = block.as.success;
}
printf("current token: %s\n", tokenToCStr(*parser->currentToken));
return Success(astNodePtr, charptr, stmt);
}

View File

@@ -1,10 +1,8 @@
func fib(int n) -> int {
if (n == 0) return 1
if (n == 1) return 1
return fib(n - 1) + fib(n - 2)
}
func main() -> int {
return fib(6)
int number = 0
while number < 10000
number = number + 1
return 0
}