Add support for while loops
This commit is contained in:
parent
907a5d12ca
commit
3f2ee15302
@ -320,6 +320,24 @@ generate_llvm :: proc(ctx: LLVMContextRef, mod: LLVMModuleRef, builder: LLVMBuil
|
||||
return LLVMBuildICmp(builder, .LLVMIntUGE, lhs, rhs, "getmp")
|
||||
}
|
||||
}
|
||||
case .Assign:
|
||||
if node.children[0].kind != .Identifier {
|
||||
fmt.panicf("LLVM-C: Left hand side of assignment is not an identifier")
|
||||
}
|
||||
name := &node.children[0].value.([dynamic]u8)
|
||||
def := llvm_scope_find_definition(name)
|
||||
if def == nil {
|
||||
append(
|
||||
&g_message_list,
|
||||
message_create(
|
||||
.Error,
|
||||
fmt.aprintf("Variable '%s' not found", name),
|
||||
node.range,
|
||||
),
|
||||
)
|
||||
return nil
|
||||
}
|
||||
return LLVMBuildStore(builder, rhs, def)
|
||||
case:
|
||||
fmt.panicf("LLVM-C: Unexpected binary expression kind: {}", op)
|
||||
}
|
||||
@ -402,10 +420,30 @@ generate_llvm :: proc(ctx: LLVMContextRef, mod: LLVMModuleRef, builder: LLVMBuil
|
||||
LLVMBuildBr(builder, basic_block)
|
||||
LLVMPositionBuilderAtEnd(builder, basic_block)
|
||||
scope_number^ += 1
|
||||
llvm_scope_enter("for_body", basic_block)
|
||||
generate_llvm_scope(ctx, mod, builder, function, node.children[3], scope_number, basic_block)
|
||||
llvm_scope_leave()
|
||||
LLVMBuildBr(builder, basic_block)
|
||||
} else if loop_type == LoopType.While {
|
||||
panic("FIXME: Implement while loops")
|
||||
fmt.println("In while")
|
||||
condition_block := LLVMAppendBasicBlockInContext(ctx, function, "while_condition")
|
||||
body_block := LLVMAppendBasicBlockInContext(ctx, function, "while_body")
|
||||
end_block := LLVMAppendBasicBlockInContext(ctx, function, "while_end")
|
||||
|
||||
LLVMBuildBr(builder, condition_block)
|
||||
|
||||
LLVMPositionBuilderAtEnd(builder, condition_block)
|
||||
cond := generate_llvm_expression(ctx, mod, builder, node.children[1])
|
||||
LLVMBuildCondBr(builder, cond, body_block, end_block)
|
||||
|
||||
LLVMPositionBuilderAtEnd(builder, body_block)
|
||||
llvm_scope_enter("for_body", body_block)
|
||||
scope_number^ += 1
|
||||
generate_llvm_scope(ctx, mod, builder, function, node.children[3], scope_number, body_block)
|
||||
llvm_scope_leave()
|
||||
LLVMBuildBr(builder, condition_block)
|
||||
|
||||
LLVMPositionBuilderAtEnd(builder, end_block)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,8 +38,12 @@ main :: proc() {
|
||||
}
|
||||
return
|
||||
}
|
||||
fmt.println("After parse:")
|
||||
node_print(ast)
|
||||
clear(&g_message_list)
|
||||
type_check(ast, nil)
|
||||
fmt.println("After type check:")
|
||||
node_print(ast)
|
||||
if len(g_message_list) > 0 {
|
||||
for msg in g_message_list {
|
||||
fmt.printf("%s\n", msg)
|
||||
|
@ -356,14 +356,29 @@ parser_parse_binary_expression :: proc(
|
||||
kinds: []TokenKind,
|
||||
next: proc(parser: ^Parser) -> ^Node,
|
||||
) -> ^Node {
|
||||
poo := false
|
||||
if (parser.next.kind == .BitwiseLeftShift) {
|
||||
fmt.println("parser_parse_bitwise {} {}", parser.tok.kind, parser.next.kind)
|
||||
poo = true
|
||||
}
|
||||
|
||||
lhs := next(parser)
|
||||
for kind in kinds {
|
||||
for accept(parser, kind) {
|
||||
prev_can_be_function := parser.can_be_function
|
||||
parser.can_be_function = false
|
||||
rhs := next(parser)
|
||||
lhs = node_create_binary(kind, lhs.range, lhs, rhs)
|
||||
lhs^.range.end = rhs.range.end
|
||||
parser.can_be_function = prev_can_be_function
|
||||
}
|
||||
}
|
||||
|
||||
if poo {
|
||||
fmt.println("parser_parse_bitwise2 {} {}", parser.tok.kind, parser.next.kind)
|
||||
|
||||
}
|
||||
|
||||
return lhs
|
||||
}
|
||||
|
||||
@ -431,7 +446,7 @@ parser_parse_multiplication :: proc(parser: ^Parser) -> ^Node {
|
||||
|
||||
@(private = "file")
|
||||
parser_parse_exponent :: proc(parser: ^Parser) -> ^Node {
|
||||
return parser_parse_binary_expression(parser, {.Exponent}, parser_parse_prefix_2)
|
||||
return parser_parse_binary_expression(parser, {.Exponent}, parser_parse_bitwise)
|
||||
}
|
||||
|
||||
@(private = "file")
|
||||
|
@ -98,6 +98,17 @@ scope_variable_lookup :: proc(name: [dynamic]u8) -> ^Type {
|
||||
return nil
|
||||
}
|
||||
|
||||
scope_variable_lookup_mutable :: proc(name: [dynamic]u8) -> bool {
|
||||
name_ := name
|
||||
#reverse for &scope in scope_stack {
|
||||
type, ok := scope.variable_mutability_definitions[get_character_sum_of_dyn_arr(&name_)]
|
||||
if ok {
|
||||
return type
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
scope_function_lookup :: proc(name: [dynamic]u8) -> ^FunctionType {
|
||||
name_ := name
|
||||
#reverse for &scope in scope_stack {
|
||||
@ -241,11 +252,12 @@ type_check :: proc(ast: ^Node, parent_ast: ^Node) {
|
||||
|
||||
if ast.value_token_kind == .Assign {
|
||||
ast.return_type = nil
|
||||
if !scope_stack[len(scope_stack) - 1].variable_mutability_definitions[get_character_sum_of_dyn_arr(&ast.children[0].value.([dynamic]u8))] {
|
||||
|
||||
if !scope_variable_lookup_mutable(ast.children[0].value.([dynamic]u8)) {
|
||||
append(&g_message_list,
|
||||
message_create(
|
||||
.Error,
|
||||
fmt.aprintf("Variable is not mutable: {}", ast.children[0].value.([dynamic]u8)),
|
||||
fmt.aprintf("Variable is not mutable: %s", ast.children[0].value.([dynamic]u8)),
|
||||
ast.range,
|
||||
),
|
||||
)
|
||||
@ -310,6 +322,7 @@ type_check :: proc(ast: ^Node, parent_ast: ^Node) {
|
||||
ast.return_type = ast_to_type(ast.children[1])
|
||||
}
|
||||
scope_stack[len(scope_stack) - 1].variable_definitions[get_character_sum_of_dyn_arr(&ast.children[0].value.([dynamic]u8))] = ast.return_type
|
||||
scope_stack[len(scope_stack) - 1].variable_mutability_definitions[get_character_sum_of_dyn_arr(&ast.children[0].value.([dynamic]u8))] = !ast.value.(bool)
|
||||
case .If:
|
||||
type_check(ast.children[0], ast)
|
||||
if ast.children[0].return_type == nil || ast.children[0].return_type.kind != .Integer {
|
||||
|
@ -11,11 +11,11 @@
|
||||
|
||||
fn put_i32(val: i32) i32
|
||||
|
||||
\let amogus := 500 + (put_i32 8008135)
|
||||
\
|
||||
\put_i32 69 * amogus + 420
|
||||
let amogus := 500 + (put_i32 8008135)
|
||||
|
||||
let a b := 2 1
|
||||
put_i32 69 * amogus + 420
|
||||
|
||||
let a b := 5 1
|
||||
|
||||
if a == 5 {
|
||||
if b {
|
||||
@ -29,6 +29,7 @@ if a == 5 {
|
||||
put_i32 420
|
||||
}
|
||||
|
||||
for {
|
||||
put_i32 123456789
|
||||
for a != 0 {
|
||||
put_i32 (1 << a)
|
||||
a = a - 1
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user