From f65507c5e1aa2041fea920db7578cbc063ee9177 Mon Sep 17 00:00:00 2001 From: Slendi Date: Wed, 10 Apr 2024 19:26:20 +0300 Subject: [PATCH] Add support for assign stacking Signed-off-by: Slendi --- pong.cat | 25 ++++++++++++------------- src/llvm_emitter.odin | 3 ++- src/main.odin | 2 -- src/parser.odin | 14 +++++++++++--- src/type_checker.odin | 11 +++++++++-- 5 files changed, 34 insertions(+), 21 deletions(-) diff --git a/pong.cat b/pong.cat index ee3f187..003cfbd 100644 --- a/pong.cat +++ b/pong.cat @@ -2,6 +2,8 @@ struct Color { r g b a: u8, } +let KEY_R :: 82 + fn InitWindow(w h: i32, title: []u8) fn CloseWindow fn BeginDrawing @@ -99,25 +101,22 @@ for WindowShouldClose == 0 { } if lc >= 10 { - alpha = alpha - 0.02 + alpha = alpha - 0.01 if alpha <= 0.0 { alpha = 0.0 state = 4 } } - } else { - if IsKeyPressed(82) { \ KEY_R - fc = 0 - lc = 0 - - top_side_rec_width = 16 - left_side_rec_height = 16 - bottom_side_rec_width = 16 - right_side_rec_height = 16 + } elif IsKeyPressed(KEY_R) { \ + fc = lc = 0 + + top_side_rec_width = 16 + left_side_rec_height = 16 + bottom_side_rec_width = 16 + right_side_rec_height = 16 - state = 0 - alpha = 1.0 - } + state = 0 + alpha = 1.0 } BeginDrawing diff --git a/src/llvm_emitter.odin b/src/llvm_emitter.odin index 19088be..d1a4057 100644 --- a/src/llvm_emitter.odin +++ b/src/llvm_emitter.odin @@ -697,7 +697,8 @@ generate_llvm :: proc(ctx: LLVMContextRef, mod: LLVMModuleRef, builder: LLVMBuil ) return nil } - return LLVMBuildStore(builder, rhs, def) + LLVMBuildStore(builder, rhs, def) + return rhs case: fmt.panicf("LLVM-C: Unexpected binary expression kind: {}", op) } diff --git a/src/main.odin b/src/main.odin index 74fa8a5..34c53eb 100644 --- a/src/main.odin +++ b/src/main.odin @@ -65,8 +65,6 @@ main :: proc() { } } - // node_print(ast) - name: string if handle == os.stdin { name = "stdin" diff --git a/src/parser.odin b/src/parser.odin index 3b41f49..2424e4c 100644 --- a/src/parser.odin +++ b/src/parser.odin @@ -85,6 +85,7 @@ parser_parse_statement :: proc(parser: ^Parser) -> (ret: ^Node) { range_beg := parser.tok.range if accept(parser, .Semicolon) { ret = nil + return } else if parser.tok.kind == .If { expect(parser, .If) ret = parser_parse_if_statement(parser) @@ -109,11 +110,11 @@ parser_parse_statement :: proc(parser: ^Parser) -> (ret: ^Node) { ret = parser_parse_ret(parser) } else { ret = parser_parse_expression(parser) - expect(parser, .Semicolon) } if ret != nil { ret.range.range.start = range_beg.range.start } + expect(parser, .Semicolon) return } @@ -384,6 +385,7 @@ parser_parse_binary_expression :: proc( parser: ^Parser, kinds: []TokenKind, next: proc(parser: ^Parser) -> ^Node, + right_assoc := false, ) -> ^Node { lhs := next(parser) i := 0 @@ -393,7 +395,13 @@ parser_parse_binary_expression :: proc( i = 0 prev_can_be_function := parser.can_be_function parser.can_be_function = false - rhs := next(parser) + rhs: ^Node + if !right_assoc { + rhs = next(parser) + } else { + rhs = parser_parse_binary_expression(parser, kinds, next, right_assoc) + } + lhs = node_create_binary(kind, lhs.range, lhs, rhs) lhs^.range.range.end = rhs.range.range.end parser.can_be_function = prev_can_be_function @@ -406,7 +414,7 @@ parser_parse_binary_expression :: proc( @(private = "file") parser_parse_assignment :: proc(parser: ^Parser) -> ^Node { - return parser_parse_binary_expression(parser, {.Assign}, parser_parse_arrow) + return parser_parse_binary_expression(parser, {.Assign}, parser_parse_arrow, true) } @(private = "file") diff --git a/src/type_checker.odin b/src/type_checker.odin index 389bfb2..89fb796 100644 --- a/src/type_checker.odin +++ b/src/type_checker.odin @@ -327,6 +327,11 @@ type_check :: proc(ast: ^Node, parent_ast: ^Node) { type := scope_variable_lookup(ast.children[0].value.([dynamic]u8)) if type != nil { + if len(ast.children) != 1 { + append(&g_message_list, message_create(.Error, "Variable is not a function", ast.range)) + break + } + name := ast.children[0].value.([dynamic]u8) free(ast.children[0]) clear(&ast.children) @@ -424,10 +429,12 @@ type_check :: proc(ast: ^Node, parent_ast: ^Node) { ) } - ast.return_type = ast.children[0].return_type + ast.return_type = ast.children[1].return_type if ast.value_token_kind == .Assign { - ast.return_type = nil + if ast.children[0].kind != .Identifier && ast.children[0].kind != .FieldAccess { + append(&g_message_list, message_create(.Error, fmt.aprintf("LHS of assignment is invalid"), ast.range)) + } if !scope_variable_lookup_mutable(ast.children[0].value.([dynamic]u8)) { append(