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")
|
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:
|
case:
|
||||||
fmt.panicf("LLVM-C: Unexpected binary expression kind: {}", op)
|
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)
|
LLVMBuildBr(builder, basic_block)
|
||||||
LLVMPositionBuilderAtEnd(builder, basic_block)
|
LLVMPositionBuilderAtEnd(builder, basic_block)
|
||||||
scope_number^ += 1
|
scope_number^ += 1
|
||||||
|
llvm_scope_enter("for_body", basic_block)
|
||||||
generate_llvm_scope(ctx, mod, builder, function, node.children[3], scope_number, basic_block)
|
generate_llvm_scope(ctx, mod, builder, function, node.children[3], scope_number, basic_block)
|
||||||
|
llvm_scope_leave()
|
||||||
LLVMBuildBr(builder, basic_block)
|
LLVMBuildBr(builder, basic_block)
|
||||||
} else if loop_type == LoopType.While {
|
} 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
|
return
|
||||||
}
|
}
|
||||||
|
fmt.println("After parse:")
|
||||||
|
node_print(ast)
|
||||||
clear(&g_message_list)
|
clear(&g_message_list)
|
||||||
type_check(ast, nil)
|
type_check(ast, nil)
|
||||||
|
fmt.println("After type check:")
|
||||||
|
node_print(ast)
|
||||||
if len(g_message_list) > 0 {
|
if len(g_message_list) > 0 {
|
||||||
for msg in g_message_list {
|
for msg in g_message_list {
|
||||||
fmt.printf("%s\n", msg)
|
fmt.printf("%s\n", msg)
|
||||||
|
@ -356,14 +356,29 @@ parser_parse_binary_expression :: proc(
|
|||||||
kinds: []TokenKind,
|
kinds: []TokenKind,
|
||||||
next: proc(parser: ^Parser) -> ^Node,
|
next: proc(parser: ^Parser) -> ^Node,
|
||||||
) -> ^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)
|
lhs := next(parser)
|
||||||
for kind in kinds {
|
for kind in kinds {
|
||||||
for accept(parser, kind) {
|
for accept(parser, kind) {
|
||||||
|
prev_can_be_function := parser.can_be_function
|
||||||
|
parser.can_be_function = false
|
||||||
rhs := next(parser)
|
rhs := next(parser)
|
||||||
lhs = node_create_binary(kind, lhs.range, lhs, rhs)
|
lhs = node_create_binary(kind, lhs.range, lhs, rhs)
|
||||||
lhs^.range.end = rhs.range.end
|
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
|
return lhs
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,7 +446,7 @@ parser_parse_multiplication :: proc(parser: ^Parser) -> ^Node {
|
|||||||
|
|
||||||
@(private = "file")
|
@(private = "file")
|
||||||
parser_parse_exponent :: proc(parser: ^Parser) -> ^Node {
|
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")
|
@(private = "file")
|
||||||
|
@ -98,6 +98,17 @@ scope_variable_lookup :: proc(name: [dynamic]u8) -> ^Type {
|
|||||||
return nil
|
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 {
|
scope_function_lookup :: proc(name: [dynamic]u8) -> ^FunctionType {
|
||||||
name_ := name
|
name_ := name
|
||||||
#reverse for &scope in scope_stack {
|
#reverse for &scope in scope_stack {
|
||||||
@ -241,11 +252,12 @@ type_check :: proc(ast: ^Node, parent_ast: ^Node) {
|
|||||||
|
|
||||||
if ast.value_token_kind == .Assign {
|
if ast.value_token_kind == .Assign {
|
||||||
ast.return_type = nil
|
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,
|
append(&g_message_list,
|
||||||
message_create(
|
message_create(
|
||||||
.Error,
|
.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,
|
ast.range,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -310,6 +322,7 @@ type_check :: proc(ast: ^Node, parent_ast: ^Node) {
|
|||||||
ast.return_type = ast_to_type(ast.children[1])
|
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_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:
|
case .If:
|
||||||
type_check(ast.children[0], ast)
|
type_check(ast.children[0], ast)
|
||||||
if ast.children[0].return_type == nil || ast.children[0].return_type.kind != .Integer {
|
if ast.children[0].return_type == nil || ast.children[0].return_type.kind != .Integer {
|
||||||
|
@ -11,11 +11,11 @@
|
|||||||
|
|
||||||
fn put_i32(val: i32) i32
|
fn put_i32(val: i32) i32
|
||||||
|
|
||||||
\let amogus := 500 + (put_i32 8008135)
|
let amogus := 500 + (put_i32 8008135)
|
||||||
\
|
|
||||||
\put_i32 69 * amogus + 420
|
|
||||||
|
|
||||||
let a b := 2 1
|
put_i32 69 * amogus + 420
|
||||||
|
|
||||||
|
let a b := 5 1
|
||||||
|
|
||||||
if a == 5 {
|
if a == 5 {
|
||||||
if b {
|
if b {
|
||||||
@ -29,6 +29,7 @@ if a == 5 {
|
|||||||
put_i32 420
|
put_i32 420
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for a != 0 {
|
||||||
put_i32 123456789
|
put_i32 (1 << a)
|
||||||
|
a = a - 1
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user