Add support for assign stacking

Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
Slendi 2024-04-10 19:26:20 +03:00
parent 3b70d9786c
commit f65507c5e1
5 changed files with 34 additions and 21 deletions

View File

@ -2,6 +2,8 @@ struct Color {
r g b a: u8, r g b a: u8,
} }
let KEY_R :: 82
fn InitWindow(w h: i32, title: []u8) fn InitWindow(w h: i32, title: []u8)
fn CloseWindow fn CloseWindow
fn BeginDrawing fn BeginDrawing
@ -99,16 +101,14 @@ for WindowShouldClose == 0 {
} }
if lc >= 10 { if lc >= 10 {
alpha = alpha - 0.02 alpha = alpha - 0.01
if alpha <= 0.0 { if alpha <= 0.0 {
alpha = 0.0 alpha = 0.0
state = 4 state = 4
} }
} }
} else { } elif IsKeyPressed(KEY_R) { \
if IsKeyPressed(82) { \ KEY_R fc = lc = 0
fc = 0
lc = 0
top_side_rec_width = 16 top_side_rec_width = 16
left_side_rec_height = 16 left_side_rec_height = 16
@ -118,7 +118,6 @@ for WindowShouldClose == 0 {
state = 0 state = 0
alpha = 1.0 alpha = 1.0
} }
}
BeginDrawing BeginDrawing
ClearBackgroundWrap WHITE ClearBackgroundWrap WHITE

View File

@ -697,7 +697,8 @@ generate_llvm :: proc(ctx: LLVMContextRef, mod: LLVMModuleRef, builder: LLVMBuil
) )
return nil return nil
} }
return LLVMBuildStore(builder, rhs, def) LLVMBuildStore(builder, rhs, def)
return rhs
case: case:
fmt.panicf("LLVM-C: Unexpected binary expression kind: {}", op) fmt.panicf("LLVM-C: Unexpected binary expression kind: {}", op)
} }

View File

@ -65,8 +65,6 @@ main :: proc() {
} }
} }
// node_print(ast)
name: string name: string
if handle == os.stdin { if handle == os.stdin {
name = "stdin" name = "stdin"

View File

@ -85,6 +85,7 @@ parser_parse_statement :: proc(parser: ^Parser) -> (ret: ^Node) {
range_beg := parser.tok.range range_beg := parser.tok.range
if accept(parser, .Semicolon) { if accept(parser, .Semicolon) {
ret = nil ret = nil
return
} else if parser.tok.kind == .If { } else if parser.tok.kind == .If {
expect(parser, .If) expect(parser, .If)
ret = parser_parse_if_statement(parser) ret = parser_parse_if_statement(parser)
@ -109,11 +110,11 @@ parser_parse_statement :: proc(parser: ^Parser) -> (ret: ^Node) {
ret = parser_parse_ret(parser) ret = parser_parse_ret(parser)
} else { } else {
ret = parser_parse_expression(parser) ret = parser_parse_expression(parser)
expect(parser, .Semicolon)
} }
if ret != nil { if ret != nil {
ret.range.range.start = range_beg.range.start ret.range.range.start = range_beg.range.start
} }
expect(parser, .Semicolon)
return return
} }
@ -384,6 +385,7 @@ parser_parse_binary_expression :: proc(
parser: ^Parser, parser: ^Parser,
kinds: []TokenKind, kinds: []TokenKind,
next: proc(parser: ^Parser) -> ^Node, next: proc(parser: ^Parser) -> ^Node,
right_assoc := false,
) -> ^Node { ) -> ^Node {
lhs := next(parser) lhs := next(parser)
i := 0 i := 0
@ -393,7 +395,13 @@ parser_parse_binary_expression :: proc(
i = 0 i = 0
prev_can_be_function := parser.can_be_function prev_can_be_function := parser.can_be_function
parser.can_be_function = false 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 = node_create_binary(kind, lhs.range, lhs, rhs)
lhs^.range.range.end = rhs.range.range.end lhs^.range.range.end = rhs.range.range.end
parser.can_be_function = prev_can_be_function parser.can_be_function = prev_can_be_function
@ -406,7 +414,7 @@ parser_parse_binary_expression :: proc(
@(private = "file") @(private = "file")
parser_parse_assignment :: proc(parser: ^Parser) -> ^Node { 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") @(private = "file")

View File

@ -327,6 +327,11 @@ type_check :: proc(ast: ^Node, parent_ast: ^Node) {
type := scope_variable_lookup(ast.children[0].value.([dynamic]u8)) type := scope_variable_lookup(ast.children[0].value.([dynamic]u8))
if type != nil { 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) name := ast.children[0].value.([dynamic]u8)
free(ast.children[0]) free(ast.children[0])
clear(&ast.children) 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 { 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)) { if !scope_variable_lookup_mutable(ast.children[0].value.([dynamic]u8)) {
append( append(