added not eq and fixed some bugs with if statement codegen
This commit is contained in:
13
run_tests.py
13
run_tests.py
@@ -23,8 +23,17 @@ class CometTester(unittest.TestCase):
|
||||
|
||||
for case in cases:
|
||||
with self.subTest():
|
||||
result = subprocess.run(["./cometc", f"{TESTS_FOLDER_NAME}/{case}", "-o", f"{TESTS_OBJ_FOLDER_NAME}/{case}.obj"])
|
||||
self.assertEqual(result.returncode, 0, f"{case} did not compile successfully!")
|
||||
obj_name = f"{TESTS_OBJ_FOLDER_NAME}/{case}.obj"
|
||||
program_name = f"{TESTS_OBJ_FOLDER_NAME}/{case.rstrip(".comet")}"
|
||||
|
||||
result = subprocess.run(["./cometc", f"{TESTS_FOLDER_NAME}/{case}", "-o", obj_name])
|
||||
self.assertEqual(result.returncode, 0, f"{case} did not compile successfully (comet)!")
|
||||
|
||||
gcc_result = subprocess.run(["gcc", obj_name, "-o", program_name, "-no-pie"])
|
||||
self.assertEqual(gcc_result.returncode, 0, f"{case} did not link successfully (gcc)!")
|
||||
|
||||
program_result = subprocess.run([program_name])
|
||||
self.assertEqual(program_result.returncode, 0, f"{case} did not run successfully!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -720,7 +720,8 @@ ResultType(int, charptr) visitIfStatement(CometCompiler* compiler, CometASTNode*
|
||||
ResultType(int, charptr) bodyResult = compileBlock(compiler, consequence);
|
||||
if (bodyResult.error)
|
||||
return Error(int, charptr, bodyResult.as.error);
|
||||
LLVMBuildBr(compiler->builder, mergeBB);
|
||||
if (!bodyResult.as.success)
|
||||
LLVMBuildBr(compiler->builder, mergeBB);
|
||||
|
||||
// build else block
|
||||
bool elseReturns = false;
|
||||
@@ -730,7 +731,8 @@ ResultType(int, charptr) visitIfStatement(CometCompiler* compiler, CometASTNode*
|
||||
ResultType(int, charptr) elseResult = compileBlock(compiler, otherwise);
|
||||
if (elseResult.error)
|
||||
return Error(int, charptr, elseResult.as.error);
|
||||
LLVMBuildBr(compiler->builder, mergeBB);
|
||||
if (!elseResult.as.success)
|
||||
LLVMBuildBr(compiler->builder, mergeBB);
|
||||
elseReturns = elseResult.as.success;
|
||||
}
|
||||
|
||||
@@ -1123,6 +1125,11 @@ ResultType(CometValue, charptr) visitInfixExpression(CometCompiler* compiler, Co
|
||||
value = LLVMBuildICmp(compiler->builder, LLVMIntEQ, left.as.success.value, right.as.success.value, "");
|
||||
break;
|
||||
}
|
||||
case CT_NOT_EQ: {
|
||||
type = getType(compiler, "bool");
|
||||
value = LLVMBuildICmp(compiler->builder, LLVMIntNE, left.as.success.value, right.as.success.value, "");
|
||||
break;
|
||||
}
|
||||
case CT_LT: {
|
||||
type = getType(compiler, "bool");
|
||||
value = LLVMBuildICmp(compiler->builder, LLVMIntSLT, left.as.success.value, right.as.success.value, "");
|
||||
@@ -1327,6 +1334,7 @@ ResultType(Nothing, charptr) compileAST(CometCompiler* compiler, CometASTNode* r
|
||||
|
||||
// verify IR
|
||||
if (LLVMVerifyModule(compiler->module, LLVMReturnStatusAction, &error) != 0) {
|
||||
printf("Module:\n%s\n", LLVMPrintModuleToString(compiler->module));
|
||||
return Error(Nothing, charptr, error);
|
||||
}
|
||||
|
||||
|
||||
23
src/lexer.c
23
src/lexer.c
@@ -278,6 +278,29 @@ ResultType(tokenList, charptr) lex(CometLexer* lexer) {
|
||||
case '\n':
|
||||
case '\r':
|
||||
break;
|
||||
case '!': {
|
||||
ResultType(char, charptr) next = lexerPeek(lexer);
|
||||
|
||||
if (next.error) {
|
||||
append(tokens, TOKEN_LITERAL(CT_NOT, "!"));
|
||||
break;
|
||||
}
|
||||
lexerConsume(lexer);
|
||||
|
||||
if (next.as.success == '=') {
|
||||
|
||||
append(tokens, TOKEN_LITERAL(CT_NOT_EQ, "!="));
|
||||
} else {
|
||||
if (isspace(next.as.success)) {
|
||||
append(tokens, TOKEN_LITERAL(CT_NOT, "!"))
|
||||
break;
|
||||
}
|
||||
|
||||
return Error(tokenList, charptr, "Expected '=' after '!'.");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case '=': {
|
||||
ResultType(char, charptr) next = lexerPeek(lexer);
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ const CometTokenPrecedencePair PRECEDENCES[] = {
|
||||
{CT_LTE, PRECEDENCE_LESSGREATER},
|
||||
{CT_GTE, PRECEDENCE_LESSGREATER},
|
||||
{CT_EQ_EQ, PRECEDENCE_EQUALS},
|
||||
{CT_NOT_EQ, PRECEDENCE_EQUALS},
|
||||
{CT_DOT, PRECEDENCE_INDEX},
|
||||
{CT_EQ, PRECEDENCE_SET}
|
||||
};
|
||||
@@ -61,6 +62,7 @@ const CometInfixParseFn INFIX_PARSE_FUNCTIONS[] = {
|
||||
{CT_LTE, parseInfixExpression},
|
||||
{CT_GTE, parseInfixExpression},
|
||||
{CT_EQ_EQ, parseInfixExpression},
|
||||
{CT_NOT_EQ, parseInfixExpression},
|
||||
{CT_DOT, parseInfixExpression},
|
||||
{CT_EQ, parseInfixExpression}
|
||||
};
|
||||
|
||||
@@ -62,6 +62,10 @@ char* tokenTypeToCStr(CometTokenType tokType) {
|
||||
return "CT_INLINE_FUNC_ARROW";
|
||||
case CT_COMMA:
|
||||
return "CT_COMMA";
|
||||
case CT_NOT:
|
||||
return "CT_NOT";
|
||||
case CT_NOT_EQ:
|
||||
return "CT_NOT_EQ";
|
||||
default:
|
||||
return "FIXME";
|
||||
|
||||
|
||||
@@ -16,10 +16,11 @@ typedef enum {
|
||||
// symbols
|
||||
CT_EQ_EQ, CT_LT, CT_GT, CT_LTE, CT_GTE,
|
||||
CT_COLON,
|
||||
CT_EQ,
|
||||
CT_EQ, CT_NOT_EQ,
|
||||
CT_PLUS, CT_MINUS, CT_DIVIDE, CT_TIMES, CT_MOD, CT_POW,
|
||||
CT_DOT, CT_DOT_DOT, CT_ARROW, CT_INLINE_FUNC_ARROW,
|
||||
CT_OPEN_CURLY, CT_CLOSE_CURLY, CT_OPEN_PAREN, CT_CLOSE_PAREN, CT_COMMA,
|
||||
CT_NOT,
|
||||
|
||||
// other
|
||||
CT_COMMENT, CT_END_LABEL, CT_EOF
|
||||
|
||||
BIN
test_objs/helloWorld
Executable file
BIN
test_objs/helloWorld
Executable file
Binary file not shown.
BIN
test_objs/ifStatements
Executable file
BIN
test_objs/ifStatements
Executable file
Binary file not shown.
BIN
test_objs/inlineFunctions
Executable file
BIN
test_objs/inlineFunctions
Executable file
Binary file not shown.
BIN
test_objs/structs
Executable file
BIN
test_objs/structs
Executable file
Binary file not shown.
BIN
test_objs/variables
Executable file
BIN
test_objs/variables
Executable file
Binary file not shown.
9
tests/ifStatements.comet
Normal file
9
tests/ifStatements.comet
Normal file
@@ -0,0 +1,9 @@
|
||||
func main() -> int {
|
||||
if 1+1 == 2 {
|
||||
return 0
|
||||
} else {
|
||||
return 1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
@@ -13,5 +13,6 @@ struct Vector {
|
||||
func main() -> int {
|
||||
Vector myVector = new Vector(1, 2, 3)
|
||||
print("myVector.x = %d, myVector.y = %d, myVector.z = %d\n", myVector.x, myVector.y, myVector.z)
|
||||
return 0
|
||||
print("%d\n", myVector.y != 2)
|
||||
return myVector.y != 2
|
||||
}
|
||||
Reference in New Issue
Block a user