From d083b10f36fa366bd4463a0c9fa393ba8830ef9a Mon Sep 17 00:00:00 2001 From: Lukas Neubert <40118727+serkonda7@users.noreply.github.com> Date: Tue, 21 Jan 2025 21:14:54 +0100 Subject: [PATCH 01/12] less mix_name --- lib/bait/ast/ast.bt | 2 +- lib/bait/gen/js/fun.bt | 6 +++--- lib/bait/parser/stmt.bt | 1 + lib/bait/transformer/transformer.bt | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/bait/ast/ast.bt b/lib/bait/ast/ast.bt index f6ebd3a9..93db7f53 100644 --- a/lib/bait/ast/ast.bt +++ b/lib/bait/ast/ast.bt @@ -112,7 +112,7 @@ pub struct Param { } pub fun (fn FunDecl) is_main() bool { - return not fn.is_method and fn.mix_name == 'main' + return not fn.is_method and fn.name == 'main' } pub struct LoopControlStmt { diff --git a/lib/bait/gen/js/fun.bt b/lib/bait/gen/js/fun.bt index e126d47d..b4c867cd 100644 --- a/lib/bait/gen/js/fun.bt +++ b/lib/bait/gen/js/fun.bt @@ -123,12 +123,12 @@ fun (mut g Gen) call_expr_no_or(node ast.CallExpr) { sym := g.table.get_sym(node.left_type) final_sym := g.table.get_final_sym(sym) - if final_sym.kind == .array and ['push', 'push_many', 'push_many_with_len'].contains(node.mix_name) { - g.gen_array_method(node.mix_name, node, final_sym) + if final_sym.kind == .array and ['push', 'push_many', 'push_many_with_len'].contains(node.name) { + g.gen_array_method(node.name, node, final_sym) return } - name = js_esc(sym.name + '_' + node.mix_name) + name = js_esc(sym.name + '_' + node.name) } else if node.lang == .bait{ name = js_esc(node.mix_name) } diff --git a/lib/bait/parser/stmt.bt b/lib/bait/parser/stmt.bt index 54bdc2c0..a88dfa8b 100644 --- a/lib/bait/parser/stmt.bt +++ b/lib/bait/parser/stmt.bt @@ -56,6 +56,7 @@ fun (mut p Parser) script_mode_main() !ast.FunDecl { } mut node := ast.FunDecl{ + name = "main" mix_name = 'main' return_type = ast.VOID_TYPE } diff --git a/lib/bait/transformer/transformer.bt b/lib/bait/transformer/transformer.bt index 48c6ce97..df257f6e 100644 --- a/lib/bait/transformer/transformer.bt +++ b/lib/bait/transformer/transformer.bt @@ -230,7 +230,7 @@ fun (t Transformer) index_expr(node ast.IndexExpr) ast.Expr { left = node.left left_type = ast.ARRAY_TYPE return_type = ast.ARRAY_TYPE - mix_name = "slice" + name = "slice" args = [ ast.CallArg{ expr = idx.low From 1d4064110aff7eeb35795b2d3b1e2eff72f125d0 Mon Sep 17 00:00:00 2001 From: Lukas Neubert <40118727+serkonda7@users.noreply.github.com> Date: Tue, 21 Jan 2025 21:20:03 +0100 Subject: [PATCH 02/12] gen: remove more obsolete code missed in #294 --- lib/bait/gen/c/cgen.bt | 3 --- lib/bait/gen/c/fun.bt | 6 ------ lib/bait/gen/js/fun.bt | 6 ------ lib/bait/gen/js/jsgen.bt | 2 -- 4 files changed, 17 deletions(-) diff --git a/lib/bait/gen/c/cgen.bt b/lib/bait/gen/c/cgen.bt index 67338b09..7fe659dd 100644 --- a/lib/bait/gen/c/cgen.bt +++ b/lib/bait/gen/c/cgen.bt @@ -37,9 +37,6 @@ struct Gen { mut is_lhs_assign bool mut is_array_map_set bool mut is_for_loop_head bool - // Testing - mut has_test_begin bool - mut has_test_end bool // Cached comptime variables mut baitexe string mut baitdir string diff --git a/lib/bait/gen/c/fun.bt b/lib/bait/gen/c/fun.bt index b6b7dc72..15109cd6 100644 --- a/lib/bait/gen/c/fun.bt +++ b/lib/bait/gen/c/fun.bt @@ -21,12 +21,6 @@ fun (mut g Gen) anon_fun(node ast.AnonFun) { } fun (mut g Gen) fun_decl(node ast.FunDecl) { - if node.mix_name == 'testsuite_begin' { - g.has_test_begin = true - } else if node.mix_name == 'testsuite_end' { - g.has_test_end = true - } - if node.generic_names.length > 0 and g.cur_concrete_types.length == 0 { gtypes := g.table.generic_fun_types[node.key()] for conc_types in gtypes { diff --git a/lib/bait/gen/js/fun.bt b/lib/bait/gen/js/fun.bt index b4c867cd..66a77438 100644 --- a/lib/bait/gen/js/fun.bt +++ b/lib/bait/gen/js/fun.bt @@ -5,12 +5,6 @@ package js import bait.ast fun (mut g Gen) fun_decl(node ast.FunDecl) { - if node.name == 'testsuite_begin' { - g.has_test_begin = true - } else if node.name == 'testsuite_end' { - g.has_test_end = true - } - if node.generic_names.length > 0 and g.cur_concrete_types.length == 0 { gtypes := g.table.generic_fun_types[node.key()] for conc_types in gtypes { diff --git a/lib/bait/gen/js/jsgen.bt b/lib/bait/gen/js/jsgen.bt index 402e7d5a..661a0059 100644 --- a/lib/bait/gen/js/jsgen.bt +++ b/lib/bait/gen/js/jsgen.bt @@ -63,8 +63,6 @@ struct Gen { mut is_for_loop_head bool mut is_lhs_assign bool mut is_array_map_set bool - mut has_test_begin bool - mut has_test_end bool // Cached comptime variables mut baitexe string mut baitdir string From dd929c7785942a53e37eb4a8c120e727571049d9 Mon Sep 17 00:00:00 2001 From: Lukas Neubert <40118727+serkonda7@users.noreply.github.com> Date: Tue, 21 Jan 2025 21:37:52 +0100 Subject: [PATCH 03/12] even less mix_name --- lib/bait/ast/repr.bt | 2 +- lib/bait/checker/fun.bt | 4 ++-- lib/bait/gen/js/fun.bt | 7 ++++++- lib/bait/parser/fun.bt | 1 + lib/bait/parser/stmt.bt | 1 - lib/bait/transformer/gen_test_main.bt | 2 +- 6 files changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/bait/ast/repr.bt b/lib/bait/ast/repr.bt index e912fdd2..b9b1e2ab 100644 --- a/lib/bait/ast/repr.bt +++ b/lib/bait/ast/repr.bt @@ -39,7 +39,7 @@ pub fun (e Expr) repr() string { pub fun (fn FunDecl) key() string { if fn.is_method { - return '${fn.params[0].typ}.${fn.mix_name}' + return '${fn.params[0].typ}.${fn.name}' } return fn.mix_name } diff --git a/lib/bait/checker/fun.bt b/lib/bait/checker/fun.bt index e17302b2..a049fe06 100644 --- a/lib/bait/checker/fun.bt +++ b/lib/bait/checker/fun.bt @@ -173,7 +173,7 @@ fun (mut c Checker) fun_call(mut node ast.CallExpr) ast.Type { } // Handle special builtin functions - if node.mix_name == 'println' or node.mix_name == 'eprintln' or node.mix_name == 'print' or node.mix_name == 'eprint' { + if node.name == 'println' or node.name == 'eprintln' or node.name == 'print' or node.name == 'eprint' { node.args[0].typ = c.non_void_expr(node.args[0].expr) or { ast.ERROR_TYPE } return ast.VOID_TYPE } @@ -185,7 +185,7 @@ fun (mut c Checker) fun_call(mut node ast.CallExpr) ast.Type { c.set_conc_types(mut node, mut def) - if node.mix_name == 'error' { + if node.name == 'error' { node.return_type = c.cur_fun.return_type } diff --git a/lib/bait/gen/js/fun.bt b/lib/bait/gen/js/fun.bt index 66a77438..17350003 100644 --- a/lib/bait/gen/js/fun.bt +++ b/lib/bait/gen/js/fun.bt @@ -26,7 +26,12 @@ fun (mut g Gen) fun_decl(node ast.FunDecl) { sym := g.table.get_sym(node.params[0].typ) name = js_esc(sym.name + '_' + node.name) } else { - name = js_esc(node.mix_name) + // TODO remove exception for main and builtin + if g.pkg == "main" or g.pkg == "builtin" { + name = js_esc(node.name) + } else { + name = js_name(g.pkg + "." + node.name) + } } if g.cur_concrete_types.length > 0 { name = g.get_concrete_name(name, g.cur_concrete_types.values()) diff --git a/lib/bait/parser/fun.bt b/lib/bait/parser/fun.bt index 77dd4c76..ae98fa24 100644 --- a/lib/bait/parser/fun.bt +++ b/lib/bait/parser/fun.bt @@ -143,6 +143,7 @@ fun (mut p Parser) anon_fun() !ast.AnonFun{ return ast.AnonFun{ decl = ast.FunDecl{ mix_name = '_anon_${p.file_hash}_${p.lexer.offset()}' + name = '_anon_${p.file_hash}_${p.lexer.offset()}' params = params return_type = return_type stmts = stmts diff --git a/lib/bait/parser/stmt.bt b/lib/bait/parser/stmt.bt index a88dfa8b..8ef2e762 100644 --- a/lib/bait/parser/stmt.bt +++ b/lib/bait/parser/stmt.bt @@ -57,7 +57,6 @@ fun (mut p Parser) script_mode_main() !ast.FunDecl { mut node := ast.FunDecl{ name = "main" - mix_name = 'main' return_type = ast.VOID_TYPE } p.table.fun_decls['main'] = node diff --git a/lib/bait/transformer/gen_test_main.bt b/lib/bait/transformer/gen_test_main.bt index 94509e44..8773670a 100644 --- a/lib/bait/transformer/gen_test_main.bt +++ b/lib/bait/transformer/gen_test_main.bt @@ -6,7 +6,6 @@ import bait.ast fun (t Transformer) gen_test_main() &ast.File { mut test_main := ast.FunDecl{ - mix_name = "main" name = "main" } @@ -64,6 +63,7 @@ fun (t Transformer) gen_test_main() &ast.File { } }) return ast.File{ + pkg_name = "main" stmts = [test_main as ast.Stmt] } } From b7d997e43e4b6f89e5716a7b35b611f4a48523e0 Mon Sep 17 00:00:00 2001 From: Lukas Neubert <40118727+serkonda7@users.noreply.github.com> Date: Wed, 22 Jan 2025 12:13:53 +0100 Subject: [PATCH 04/12] gen: remove mix_name usage --- lib/bait/ast/ast.bt | 2 +- lib/bait/checker/fun.bt | 5 +++++ lib/bait/gen/c/comptime.bt | 2 +- lib/bait/gen/c/expr.bt | 4 ++-- lib/bait/gen/c/fun.bt | 16 ++++++++-------- lib/bait/gen/c/stmt.bt | 2 +- lib/bait/gen/js/fun.bt | 8 ++++---- 7 files changed, 22 insertions(+), 17 deletions(-) diff --git a/lib/bait/ast/ast.bt b/lib/bait/ast/ast.bt index 93db7f53..12eb4d72 100644 --- a/lib/bait/ast/ast.bt +++ b/lib/bait/ast/ast.bt @@ -199,7 +199,7 @@ pub struct BoolLiteral { pub struct CallExpr { global lang Language - pub pkg string + global pkg string global name string global mix_name string // TMP global return_type Type diff --git a/lib/bait/checker/fun.bt b/lib/bait/checker/fun.bt index a049fe06..b7ce47d6 100644 --- a/lib/bait/checker/fun.bt +++ b/lib/bait/checker/fun.bt @@ -155,6 +155,11 @@ fun (mut c Checker) fun_call(mut node ast.CallExpr) ast.Type { } } + // Set package + if node.pkg.length == 0 and obj.pkg != "main" and obj.pkg != "builtin" { + node.pkg = obj.pkg + } + // Check visibility if not obj.is_pub and obj.pkg != c.pkg { c.error("function `${node.full_name()}` is private", node.pos) diff --git a/lib/bait/gen/c/comptime.bt b/lib/bait/gen/c/comptime.bt index 6d5100b0..0b59241c 100644 --- a/lib/bait/gen/c/comptime.bt +++ b/lib/bait/gen/c/comptime.bt @@ -25,7 +25,7 @@ fun (mut g Gen) get_comptime_val(kind token.ComptimeVar, pos token.Pos) string { line := g.get_comptime_val(.line, pos) '${file}:${line}' } - .fun_ { g.cur_fun.mix_name } + .fun_ { g.cur_fun.name } // Cached .baitexe { g.comptime_baitexe() } diff --git a/lib/bait/gen/c/expr.bt b/lib/bait/gen/c/expr.bt index 4d45dbc1..462dab3e 100644 --- a/lib/bait/gen/c/expr.bt +++ b/lib/bait/gen/c/expr.bt @@ -184,7 +184,7 @@ fun (mut g Gen) infix_expr(node ast.InfixExpr) { if node.op == .ne { g.write('!') } - g.write(c_esc(lsym.name + '_' + overload.mix_name)) + g.write(c_esc(lsym.name + '_' + overload.name)) g.write('(') g.expr(node.left) g.write(', ') @@ -293,7 +293,7 @@ fun (mut g Gen) expr_to_string(expr ast.Expr, typ ast.Type) { } str_def := g.table.get_method(sym, 'str') - if str_def.mix_name.length > 0 { + if str_def.name.length > 0 { final_sym := g.table.get_sym(str_def.params[0].typ) mut name := c_esc(final_sym.name) g.write('${name}_str(') diff --git a/lib/bait/gen/c/fun.bt b/lib/bait/gen/c/fun.bt index 15109cd6..e5b28bcc 100644 --- a/lib/bait/gen/c/fun.bt +++ b/lib/bait/gen/c/fun.bt @@ -17,7 +17,7 @@ fun (mut g Gen) anon_fun(node ast.AnonFun) { g.indent = last_indent g.empty_line = was_line_empty - g.write(node.decl.mix_name) + g.write(node.decl.name) } fun (mut g Gen) fun_decl(node ast.FunDecl) { @@ -37,10 +37,10 @@ fun (mut g Gen) fun_decl(node ast.FunDecl) { g.cur_fun = node type_str := g.typ(node.return_type) - mut name := c_esc(node.mix_name) + mut name := c_esc(node.name) if node.is_method { sym := g.table.get_sym(node.params[0].typ) - name = c_esc(sym.name + '_' + node.mix_name) + name = c_name(sym.name + '_' + node.name) } if g.cur_concrete_types.length > 0 { name = g.get_concrete_name(name, g.cur_concrete_types.values()) @@ -77,14 +77,14 @@ fun (mut g Gen) call_expr(node ast.CallExpr) { } else { g.write('.') } - g.write(node.mix_name) + g.write(node.name) g.write('(') g.call_args(node.args) g.write(')') return } - mut name := c_esc(node.mix_name) + mut name := c_esc(node.full_name()) if node.is_method { sym := g.table.get_sym(node.left_type) final_sym := g.table.get_final_sym(sym) @@ -103,9 +103,9 @@ fun (mut g Gen) call_expr(node ast.CallExpr) { } } - name = c_esc(sym.name + '_' + node.mix_name) + name = c_name(sym.name + '_' + node.name) } else if node.lang != .bait{ - name = node.mix_name.replace('C.', '') + name = node.name.replace('C.', '') } if node.concrete_types.length > 0 { @@ -114,7 +114,7 @@ fun (mut g Gen) call_expr(node ast.CallExpr) { g.write(name) - if not node.is_method and ['println', 'eprintln', 'print', 'eprint'].contains(node.mix_name) { + if not node.is_method and ['println', 'eprintln', 'print', 'eprint'].contains(node.name) { g.write('(') g.expr_to_string(node.args[0].expr, node.args[0].typ) g.write(')') diff --git a/lib/bait/gen/c/stmt.bt b/lib/bait/gen/c/stmt.bt index 551c4bee..647eb664 100644 --- a/lib/bait/gen/c/stmt.bt +++ b/lib/bait/gen/c/stmt.bt @@ -55,7 +55,7 @@ fun (mut g Gen) assign_stmt(node ast.AssignStmt) { if lsym.overloads.contains(node.op.c_repr()) { g.write(' = ') overload := lsym.overloads[node.op.c_repr()] - g.write(c_esc(lsym.name + '_' + overload.mix_name)) + g.write(c_esc(lsym.name + '_' + overload.name)) g.write('(') g.expr(node.left) g.write(', ') diff --git a/lib/bait/gen/js/fun.bt b/lib/bait/gen/js/fun.bt index 17350003..5c76890a 100644 --- a/lib/bait/gen/js/fun.bt +++ b/lib/bait/gen/js/fun.bt @@ -45,7 +45,7 @@ fun (mut g Gen) fun_decl(node ast.FunDecl) { export_attr := node.attrs.find_attr('export') if export_attr.name != '' { - g.writeln('module.exports.${export_attr.value} = ${js_esc(node.mix_name)}') + g.writeln('module.exports.${export_attr.value} = ${name}') } g.writeln('') @@ -113,7 +113,7 @@ fun (mut g Gen) call_expr_no_or(node ast.CallExpr) { return } - mut name := node.mix_name + mut name := node.full_name() if node.is_method { if name == 'str' { g.expr_to_string(node.left, node.left_type) @@ -127,9 +127,9 @@ fun (mut g Gen) call_expr_no_or(node ast.CallExpr) { return } - name = js_esc(sym.name + '_' + node.name) + name = js_name(sym.name + '_' + node.name) } else if node.lang == .bait{ - name = js_esc(node.mix_name) + name = js_esc(name) } if node.concrete_types.length > 0 { From c18218ab5af941441d9c3e952fd4f5792f600d4f Mon Sep 17 00:00:00 2001 From: Lukas Neubert <40118727+serkonda7@users.noreply.github.com> Date: Wed, 22 Jan 2025 12:17:40 +0100 Subject: [PATCH 05/12] fix cgen --- lib/bait/gen/c/fun.bt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/bait/gen/c/fun.bt b/lib/bait/gen/c/fun.bt index e5b28bcc..bba97a43 100644 --- a/lib/bait/gen/c/fun.bt +++ b/lib/bait/gen/c/fun.bt @@ -37,14 +37,24 @@ fun (mut g Gen) fun_decl(node ast.FunDecl) { g.cur_fun = node type_str := g.typ(node.return_type) - mut name := c_esc(node.name) + + mut name := "" if node.is_method { sym := g.table.get_sym(node.params[0].typ) name = c_name(sym.name + '_' + node.name) + } else { + // TODO remove exception for main and builtin + if g.pkg == "main" or g.pkg == "builtin" { + name = c_esc(node.name) + } else { + name = c_name(g.pkg + "." + node.name) + } } + if g.cur_concrete_types.length > 0 { name = g.get_concrete_name(name, g.cur_concrete_types.values()) } + s := '${type_str} ${name}(' g.fun_decls_out += s From 4c29ff6dd93d69e74395f1cad9badb32c839b5c2 Mon Sep 17 00:00:00 2001 From: Lukas Neubert <40118727+serkonda7@users.noreply.github.com> Date: Wed, 22 Jan 2025 14:38:00 +0100 Subject: [PATCH 06/12] less mix_name and dead code --- lib/bait/checker/attribute.bt | 2 +- lib/bait/checker/fun.bt | 25 ++++++++----------------- lib/bait/checker/return.bt | 2 +- lib/bait/checker/stmt.bt | 2 +- lib/bait/transformer/gen_test_main.bt | 4 ---- 5 files changed, 11 insertions(+), 24 deletions(-) diff --git a/lib/bait/checker/attribute.bt b/lib/bait/checker/attribute.bt index 1be92f78..1615efb1 100644 --- a/lib/bait/checker/attribute.bt +++ b/lib/bait/checker/attribute.bt @@ -118,7 +118,7 @@ fun (c Checker) check_fun_attrs_on_call(call ast.CallExpr, def ast.FunDecl) { } if is_deprecated { - mut depr_message := 'function "${call.mix_name}" ' + mut depr_message := 'function "${call.full_name()}" ' if depr_date_attr.name.length > 0 { depr_message += 'will be deprecated after ${depr_date_attr.value}' } else { diff --git a/lib/bait/checker/fun.bt b/lib/bait/checker/fun.bt index b7ce47d6..25f3b138 100644 --- a/lib/bait/checker/fun.bt +++ b/lib/bait/checker/fun.bt @@ -25,16 +25,16 @@ fun (mut c Checker) fun_decl(mut node ast.FunDecl) { if node.is_method { sym := c.table.get_sym(node.params[0].typ) if sym.info is ast.StructInfo { - field := sym.find_field(node.mix_name, c.table) + field := sym.find_field(node.name, c.table) if field.name.length > 0 { if c.table.get_sym(field.typ).kind == .fun_ { - c.error('struct has a field and method named ${node.mix_name}', node.pos) + c.error('struct has a field and method named ${node.name}', node.pos) } } } } else { if node.is_test { - c.gen_ctx.test_fun_names.push(node.mix_name) + c.gen_ctx.test_fun_names.push(node.name) } else if c.prefs.is_test { if node.name == "testsuite_begin" { c.gen_ctx.has_test_begin = true @@ -142,19 +142,10 @@ fun (mut c Checker) call_expr(mut node ast.CallExpr) ast.Type { fun (mut c Checker) fun_call(mut node ast.CallExpr) ast.Type { obj := c.find_in_scope(node.name, node.pkg) if obj.kind != .function { - c.error('unknown function ${node.mix_name}', node.pos) + c.error('unknown function ${node.full_name()}', node.pos) return ast.ERROR_TYPE } - mut found := c.table.fun_decls.contains(node.mix_name) - if not found and not node.mix_name.contains('.') and c.pkg != 'builtin' { - full_name := c.pkg + '.' + node.mix_name - if c.table.fun_decls.contains(full_name) { - node.mix_name = full_name - found = true - } - } - // Set package if node.pkg.length == 0 and obj.pkg != "main" and obj.pkg != "builtin" { node.pkg = obj.pkg @@ -165,7 +156,7 @@ fun (mut c Checker) fun_call(mut node ast.CallExpr) ast.Type { c.error("function `${node.full_name()}` is private", node.pos) } - mut def := c.table.fun_decls[node.mix_name] + mut def := c.table.fun_decls[node.full_name()] node.noreturn = def.noreturn node.return_type = def.return_type @@ -415,14 +406,14 @@ fun (mut c Checker) or_block(mut node ast.CallExpr) { // Function does not return a result if ret_sym.kind != .result { if node.or_block.kind != .none { - c.error('${node.mix_name} does not return a result, it cannot have an `or {}` block or `!` at the end', node.pos) + c.error('${node.name} does not return a result, it cannot have an `or {}` block or `!` at the end', node.pos) } return } // Unhandled result if node.or_block.kind == .none { - c.error('${node.mix_name} returns a result, it must have an `or {}` block or propagation `!` at the end', node.pos) + c.error('${node.name} returns a result, it must have an `or {}` block or propagation `!` at the end', node.pos) return } @@ -434,7 +425,7 @@ fun (mut c Checker) or_block(mut node ast.CallExpr) { // Only possible in `main` or other result function cur_fun_ret_sym := c.table.get_sym(c.cur_fun.return_type) if cur_fun_ret_sym.kind != .result and not c.cur_fun.is_main() { - c.error('`${c.cur_fun.mix_name}` must return a result to use propagation', node.pos) + c.error('`${c.cur_fun.name}` must return a result to use propagation', node.pos) } return diff --git a/lib/bait/checker/return.bt b/lib/bait/checker/return.bt index abb9ba48..bab6bbd8 100644 --- a/lib/bait/checker/return.bt +++ b/lib/bait/checker/return.bt @@ -11,7 +11,7 @@ fun (mut c Checker) return_stmt(mut node ast.ReturnStmt) { if not c.check_types(expr_type, c.cur_fun.return_type) { mut msg := '' if c.cur_fun.return_type == ast.VOID_TYPE { - msg = 'function `${c.cur_fun.mix_name}` should return nothing' + msg = 'function `${c.cur_fun.name}` should return nothing' } else { msg = 'expected return value of type ${c.table.type_name(c.cur_fun.return_type)}' } diff --git a/lib/bait/checker/stmt.bt b/lib/bait/checker/stmt.bt index 83487fbe..78426383 100644 --- a/lib/bait/checker/stmt.bt +++ b/lib/bait/checker/stmt.bt @@ -69,7 +69,7 @@ fun (mut c Checker) expr_stmt(mut node ast.ExprStmt) { // Warn if function call with return value is not used if expr is ast.CallExpr { if expr.return_type > ast.VOID_TYPE { - c.warn("use `_ = ${expr.mix_name}()` to explicitly ignore the return value", expr.pos) + c.warn("use `_ = ${expr.full_name()}()` to explicitly ignore the return value", expr.pos) } return diff --git a/lib/bait/transformer/gen_test_main.bt b/lib/bait/transformer/gen_test_main.bt index 8773670a..d689aa95 100644 --- a/lib/bait/transformer/gen_test_main.bt +++ b/lib/bait/transformer/gen_test_main.bt @@ -12,7 +12,6 @@ fun (t Transformer) gen_test_main() &ast.File { if t.gen_ctx.has_test_begin { test_main.stmts.push(ast.ExprStmt{ expr = ast.CallExpr{ - mix_name = "testsuite_begin" name = "testsuite_begin" } }) @@ -32,7 +31,6 @@ fun (t Transformer) gen_test_main() &ast.File { }) test_main.stmts.push(ast.ExprStmt{ expr = ast.CallExpr{ - mix_name = name name = name } }) @@ -41,7 +39,6 @@ fun (t Transformer) gen_test_main() &ast.File { if t.gen_ctx.has_test_end { test_main.stmts.push(ast.ExprStmt{ expr = ast.CallExpr{ - mix_name = "testsuite_end" name = "testsuite_end" } }) @@ -50,7 +47,6 @@ fun (t Transformer) gen_test_main() &ast.File { // exit(test_runner.exit_code()) test_main.stmts.push(ast.ExprStmt{ expr = ast.CallExpr{ - mix_name = "exit" name = "exit" args = [ ast.CallArg{ From 686335840d4224c3be222597ca5011306f88eb73 Mon Sep 17 00:00:00 2001 From: Lukas Neubert <40118727+serkonda7@users.noreply.github.com> Date: Wed, 22 Jan 2025 14:49:45 +0100 Subject: [PATCH 07/12] less --- lib/bait/ast/repr.bt | 2 +- lib/bait/ast/table.bt | 2 +- lib/bait/ast/types.bt | 2 +- lib/bait/checker/fun.bt | 26 +++++++++++++------------- lib/bait/parser/fun.bt | 12 ++++-------- lib/bait/parser/stmt.bt | 2 +- 6 files changed, 21 insertions(+), 25 deletions(-) diff --git a/lib/bait/ast/repr.bt b/lib/bait/ast/repr.bt index b9b1e2ab..018852c4 100644 --- a/lib/bait/ast/repr.bt +++ b/lib/bait/ast/repr.bt @@ -11,7 +11,7 @@ pub fun (e Expr) repr() string { AsCast { e.expr.repr() + ' as XX' } BlankIdent { '_' } BoolLiteral { e.str() } - CallExpr{ e.mix_name + '()'} + CallExpr{ e.full_name() + '()'} CharLiteral { e.val } ComptimeVar { e.kind.str() } EnumVal{ e.val } diff --git a/lib/bait/ast/table.bt b/lib/bait/ast/table.bt index 02b8f60c..d478a447 100644 --- a/lib/bait/ast/table.bt +++ b/lib/bait/ast/table.bt @@ -176,7 +176,7 @@ pub fun (t Table) get_method(sym TypeSymbol, name string) FunDecl { mut s := sym for true { for m in s.methods { - if m.mix_name == name { + if m.name == name { return m } } diff --git a/lib/bait/ast/types.bt b/lib/bait/ast/types.bt index c8c90e0f..ff5f22f6 100644 --- a/lib/bait/ast/types.bt +++ b/lib/bait/ast/types.bt @@ -104,7 +104,7 @@ pub fun (sym TypeSymbol) find_field(name string, t Table) StructField { pub fun (sym TypeSymbol) has_method(name string) bool { for m in sym.methods { - if m.mix_name == name { + if m.name == name { return true } } diff --git a/lib/bait/checker/fun.bt b/lib/bait/checker/fun.bt index 25f3b138..b572307c 100644 --- a/lib/bait/checker/fun.bt +++ b/lib/bait/checker/fun.bt @@ -199,12 +199,12 @@ fun (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { final_sym := c.table.get_final_sym(left_sym) mut arg_offset := 1 - mut def := c.table.get_method(left_sym, node.mix_name) + mut def := c.table.get_method(left_sym, node.name) - if def.mix_name.length == 0 { + if def.name.length == 0 { // Check for callable struct field if left_sym.kind == .struct_ { - field := left_sym.find_field(node.mix_name, c.table) + field := left_sym.find_field(node.name, c.table) if field.name.length > 0 { field_sym := c.table.get_sym(field.typ) if field_sym.kind != .fun_ { @@ -216,7 +216,7 @@ fun (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { arg_offset = 0 node.is_field = true def = ast.FunDecl{ - mix_name = field.name + name = field.name params = info.to_params() return_type = info.return_type } @@ -224,9 +224,9 @@ fun (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { } } - if def.mix_name.length == 0 { + if def.name.length == 0 { // Autogenerated str method - if node.mix_name == 'str' { + if node.name == 'str' { if node.args.length > 0 { c.error('expected 0 arguments but got ${node.args.length}', node.pos) return ast.STRING_TYPE @@ -238,12 +238,12 @@ fun (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { return node.return_type } - c.error('method ${node.mix_name} not found on type ${left_sym.name}', node.pos) + c.error('method ${node.name} not found on type ${left_sym.name}', node.pos) return ast.ERROR_TYPE } if not def.is_pub and left_sym.pkg != c.pkg { - c.error('method ${def.mix_name} is private', node.pos) + c.error('method ${def.name} is private', node.pos) } node.lang = def.lang @@ -262,7 +262,7 @@ fun (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { // The following is required for some builtin array and map methods node.left_type = def.params[0].typ - if final_sym.kind == .array and ['push', 'push_many_with_len', 'push_many'].contains(node.mix_name) { + if final_sym.kind == .array and ['push', 'push_many_with_len', 'push_many'].contains(node.name) { node.left_type = left_expr_type } @@ -293,7 +293,7 @@ fun (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { } // Array methods with one argument of `any` type, expecting the element - if final_sym.kind == .array and ['push', 'push_many_with_len'].contains(node.mix_name) { + if final_sym.kind == .array and ['push', 'push_many_with_len'].contains(node.name) { mut arg := node.args[0] info := final_sym.info as ast.ArrayInfo c.expected_type = info.elem_type @@ -304,7 +304,7 @@ fun (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { return node.return_type } // Array methods with one argument of `array` type, expecting the specific array type - if final_sym.kind == .array and ['concat', 'push_many'].contains(node.mix_name) { + if final_sym.kind == .array and ['concat', 'push_many'].contains(node.name) { mut arg := node.args[0] c.expected_type = left_expr_type arg.typ = c.expr(arg.expr) @@ -318,12 +318,12 @@ fun (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { c.call_args(def, mut node, arg_offset) // Array methods with return type `array` - if left_sym.kind == .array and ['filter', 'reverse', 'slice', 'copy', 'from_js_arr'].contains(node.mix_name) { + if left_sym.kind == .array and ['filter', 'reverse', 'slice', 'copy', 'from_js_arr'].contains(node.name) { return left_expr_type } // Array methods with return type `any` - if left_sym.kind == .array and ['last'].contains(node.mix_name) { + if left_sym.kind == .array and node.name == "last" { return (left_sym.info as ast.ArrayInfo).elem_type } diff --git a/lib/bait/parser/fun.bt b/lib/bait/parser/fun.bt index ae98fa24..c588f821 100644 --- a/lib/bait/parser/fun.bt +++ b/lib/bait/parser/fun.bt @@ -51,7 +51,7 @@ fun (mut p Parser) fun_decl() !ast.FunDecl{ // normal function name name := p.check_name()! mix_name += name - is_test := mix_name.starts_with('test_') + is_test := name.starts_with('test_') if not is_method and lang == .bait { mix_name = p.prepend_pkg(mix_name) } @@ -88,8 +88,8 @@ fun (mut p Parser) fun_decl() !ast.FunDecl{ if is_method { sym := p.table.get_sym(params[0].typ) // TODO move this error into checker - if lang == .bait and sym.has_method(mix_name) { - p.error('Method "${mix_name}" already exists on type "${sym.name}"')! + if lang == .bait and sym.has_method(name) { + p.error('Method "${name}" already exists on type "${sym.name}"')! } sym.methods.push(node) } else { @@ -142,7 +142,6 @@ fun (mut p Parser) anon_fun() !ast.AnonFun{ stmts := p.parse_block()! return ast.AnonFun{ decl = ast.FunDecl{ - mix_name = '_anon_${p.file_hash}_${p.lexer.offset()}' name = '_anon_${p.file_hash}_${p.lexer.offset()}' params = params return_type = return_type @@ -179,8 +178,7 @@ fun (mut p Parser) fun_params() ![]ast.Param{ fun (mut p Parser) fun_call(lang ast.Language) !ast.CallExpr{ pos := p.pos name := p.check_name()! - pkg := p.expr_pkg - mix_name := p.prepend_expr_pkg(name) + pkg := p.get_expr_pkg() p.check(.lpar)! args := p.call_args()! p.check(.rpar)! @@ -190,7 +188,6 @@ fun (mut p Parser) fun_call(lang ast.Language) !ast.CallExpr{ return ast.CallExpr{ pkg = pkg name = name - mix_name = mix_name args = args or_block = or_block pos = pos @@ -211,7 +208,6 @@ fun (mut p Parser) method_call(left ast.Expr) !ast.CallExpr { is_method = true left = left name = name - mix_name = name args = args or_block = or_block pos = pos diff --git a/lib/bait/parser/stmt.bt b/lib/bait/parser/stmt.bt index 8ef2e762..904721af 100644 --- a/lib/bait/parser/stmt.bt +++ b/lib/bait/parser/stmt.bt @@ -372,7 +372,7 @@ fun (mut p Parser) interface_method(name string, rec_type ast.Type) !ast.FunDecl } return ast.FunDecl{ lang = .js - mix_name = name + name = name params = params return_type = return_type is_pub = true From 345188318ae7965e7a622e53e901dffc7eeffd29 Mon Sep 17 00:00:00 2001 From: Lukas Neubert <40118727+serkonda7@users.noreply.github.com> Date: Wed, 22 Jan 2025 15:18:02 +0100 Subject: [PATCH 08/12] fix pkg tests --- lib/bait/gen/c/fun.bt | 2 +- lib/bait/gen/js/fun.bt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/bait/gen/c/fun.bt b/lib/bait/gen/c/fun.bt index bba97a43..d0f7d763 100644 --- a/lib/bait/gen/c/fun.bt +++ b/lib/bait/gen/c/fun.bt @@ -44,7 +44,7 @@ fun (mut g Gen) fun_decl(node ast.FunDecl) { name = c_name(sym.name + '_' + node.name) } else { // TODO remove exception for main and builtin - if g.pkg == "main" or g.pkg == "builtin" { + if g.pkg == "main" or g.pkg == "builtin" or node.is_test { name = c_esc(node.name) } else { name = c_name(g.pkg + "." + node.name) diff --git a/lib/bait/gen/js/fun.bt b/lib/bait/gen/js/fun.bt index 5c76890a..408288ec 100644 --- a/lib/bait/gen/js/fun.bt +++ b/lib/bait/gen/js/fun.bt @@ -27,7 +27,7 @@ fun (mut g Gen) fun_decl(node ast.FunDecl) { name = js_esc(sym.name + '_' + node.name) } else { // TODO remove exception for main and builtin - if g.pkg == "main" or g.pkg == "builtin" { + if g.pkg == "main" or g.pkg == "builtin" or node.is_test { name = js_esc(node.name) } else { name = js_name(g.pkg + "." + node.name) From 67628d3fb16a531c10d062b2c7ef148684150956 Mon Sep 17 00:00:00 2001 From: Lukas Neubert <40118727+serkonda7@users.noreply.github.com> Date: Wed, 22 Jan 2025 18:37:05 +0100 Subject: [PATCH 09/12] fix: change `unnecessary mut` to be a warning --- CHANGELOG.md | 2 ++ lib/bait/checker/fun.bt | 8 ++++---- tests/out/error/mutability/fun_arg.in.bt | 2 +- tests/out/error/mutability/fun_arg.out | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2dfdfaea..0fe58179 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ All notable changes are documented in this file. - Properly warn if FFI is used in a file intended for a different backend - Improve various error messages and reduce noise - Functions can no longer be shadowed by variables +- fix: change `unnecessary mut` to be a warning ### Other Changes - `static` visibility is now controlled by `pub` keyword @@ -22,6 +23,7 @@ All notable changes are documented in this file. - fix(c): Prevent c error if blank identifier is used ### Compiler internals +- refac: improve handling of FunDecl and CallExpr - refac(gen): move generation of test main function into transformer diff --git a/lib/bait/checker/fun.bt b/lib/bait/checker/fun.bt index b572307c..de7fb782 100644 --- a/lib/bait/checker/fun.bt +++ b/lib/bait/checker/fun.bt @@ -179,7 +179,7 @@ fun (mut c Checker) fun_call(mut node ast.CallExpr) ast.Type { c.or_block(mut node) - c.set_conc_types(mut node, mut def) + c.set_conc_types(mut node, def) if node.name == 'error' { node.return_type = c.cur_fun.return_type @@ -329,12 +329,12 @@ fun (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { c.or_block(mut node) - c.set_conc_types(mut node, mut def) + c.set_conc_types(mut node, def) return node.return_type } -fun (mut c Checker) set_conc_types(mut node ast.CallExpr, mut def ast.FunDecl) { +fun (mut c Checker) set_conc_types(mut node ast.CallExpr, def ast.FunDecl) { if node.concrete_types.length == 0 { return } @@ -388,7 +388,7 @@ fun (mut c Checker) call_args(def ast.FunDecl, mut node ast.CallExpr, poffset i3 if arg.is_mut { if not param.is_mut { - c.error('unnecessary `mut` for argument `${expr.name}`', expr.pos) + c.warn('unnecessary `mut` for argument `${expr.name}`', expr.pos) } if not expr.is_mut { c.error('`${expr.name}` is not declared as mutable', expr.pos) diff --git a/tests/out/error/mutability/fun_arg.in.bt b/tests/out/error/mutability/fun_arg.in.bt index d5333fd6..e9cc9e51 100644 --- a/tests/out/error/mutability/fun_arg.in.bt +++ b/tests/out/error/mutability/fun_arg.in.bt @@ -11,5 +11,5 @@ fun immutable(f Foo) {} fun call_change() { mut f := Foo{} change_me(f) // err - immutable(mut f) // err + immutable(mut f) // warn } diff --git a/tests/out/error/mutability/fun_arg.out b/tests/out/error/mutability/fun_arg.out index 11e1ed27..760fb6ad 100644 --- a/tests/out/error/mutability/fun_arg.out +++ b/tests/out/error/mutability/fun_arg.out @@ -1,2 +1,2 @@ +tests/out/error/mutability/fun_arg.in.bt:14:12 warning: unnecessary `mut` for argument `f` tests/out/error/mutability/fun_arg.in.bt:13:12 error: add `mut` to argument for parameter `f` -tests/out/error/mutability/fun_arg.in.bt:14:12 error: unnecessary `mut` for argument `f` From 9c80d575b9d4653b93af41191c3dd3538b0c3c65 Mon Sep 17 00:00:00 2001 From: Lukas Neubert <40118727+serkonda7@users.noreply.github.com> Date: Wed, 22 Jan 2025 19:52:57 +0100 Subject: [PATCH 10/12] progress removal of Table.fun_decls --- lib/bait/checker/attribute.bt | 4 ++-- lib/bait/checker/fun.bt | 36 ++++++++++++++++++----------------- lib/bait/context/scope.bt | 7 +++++++ lib/bait/parser/fun.bt | 10 +++++++++- 4 files changed, 37 insertions(+), 20 deletions(-) diff --git a/lib/bait/checker/attribute.bt b/lib/bait/checker/attribute.bt index 1615efb1..17ef9872 100644 --- a/lib/bait/checker/attribute.bt +++ b/lib/bait/checker/attribute.bt @@ -101,12 +101,12 @@ fun (c Checker) attr_export(attr ast.Attribute) { c.export_names.push(attr.value) } -fun (c Checker) check_fun_attrs_on_call(call ast.CallExpr, def ast.FunDecl) { +fun (c Checker) check_fun_attrs_on_call(call ast.CallExpr, attrs []ast.Attribute) { mut is_deprecated := false mut depr_attr := ast.Attribute{} mut depr_date_attr := ast.Attribute{} - for attr in def.attrs { + for attr in attrs { if attr.name == 'deprecated_after' { depr_date_attr = attr is_deprecated = true diff --git a/lib/bait/checker/fun.bt b/lib/bait/checker/fun.bt index de7fb782..b76cd87d 100644 --- a/lib/bait/checker/fun.bt +++ b/lib/bait/checker/fun.bt @@ -157,14 +157,14 @@ fun (mut c Checker) fun_call(mut node ast.CallExpr) ast.Type { } mut def := c.table.fun_decls[node.full_name()] - node.noreturn = def.noreturn - node.return_type = def.return_type + node.noreturn = obj.noreturn + node.return_type = obj.return_type - c.check_fun_attrs_on_call(node, def) + c.check_fun_attrs_on_call(node, obj.attrs) // Check argument count - if node.args.length != def.params.length { - c.error('expected ${def.params.length} arguments but got ${node.args.length}', node.pos) + if node.args.length != obj.params.length { + c.error('expected ${obj.params.length} arguments but got ${node.args.length}', node.pos) return node.return_type } @@ -175,11 +175,11 @@ fun (mut c Checker) fun_call(mut node ast.CallExpr) ast.Type { } // Check argument types - c.call_args(def, mut node, 0) + c.call_args(mut node, 0, obj.generic_names, obj.params) c.or_block(mut node) - c.set_conc_types(mut node, def) + c.set_conc_types(mut node, obj.generic_names, def.key()) if node.name == 'error' { node.return_type = c.cur_fun.return_type @@ -284,7 +284,7 @@ fun (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { } } - c.check_fun_attrs_on_call(node, def) + c.check_fun_attrs_on_call(node, def.attrs) // Check argument count if node.args.length + arg_offset != def.params.length { @@ -315,7 +315,7 @@ fun (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { } // Check argument types - c.call_args(def, mut node, arg_offset) + c.call_args(mut node, arg_offset, def.generic_names, def.params) // Array methods with return type `array` if left_sym.kind == .array and ['filter', 'reverse', 'slice', 'copy', 'from_js_arr'].contains(node.name) { @@ -329,36 +329,38 @@ fun (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { c.or_block(mut node) - c.set_conc_types(mut node, def) + c.set_conc_types(mut node, def.generic_names, def.key()) return node.return_type } -fun (mut c Checker) set_conc_types(mut node ast.CallExpr, def ast.FunDecl) { +// TODO clean this up +fun (mut c Checker) set_conc_types(mut node ast.CallExpr, generic_names []string, key string) { if node.concrete_types.length == 0 { return } - c.need_generic_resolve = c.table.register_concrete(def.key(), node.concrete_types) or c.need_generic_resolve + c.need_generic_resolve = c.table.register_concrete(key, node.concrete_types) or c.need_generic_resolve ret_sym := c.table.get_sym(node.return_type) if ret_sym.kind == .generic { - idx := def.generic_names.index(ret_sym.name) + idx := generic_names.index(ret_sym.name) node.return_type = node.concrete_types[idx] } } -fun (mut c Checker) call_args(def ast.FunDecl, mut node ast.CallExpr, poffset i32) { - should_resolve_generics := def.generic_names.length != node.concrete_types.length +// TODO clean this up +fun (mut c Checker) call_args(mut node ast.CallExpr, poffset i32, generic_names []string, params []ast.Param) { + should_resolve_generics := generic_names.length != node.concrete_types.length mut save_as_concrete := false for i, mut arg in node.args { - param := def.params[i + poffset] + param := params[i + poffset] mut param_type := param.typ psym := c.table.get_sym(param_type) if should_resolve_generics and psym.kind == .generic { - gi := def.generic_names.index(psym.name) + gi := generic_names.index(psym.name) if gi < node.concrete_types.length { param_type = node.concrete_types[gi] } else if gi < c.cur_concrete_types.length { diff --git a/lib/bait/context/scope.bt b/lib/bait/context/scope.bt index 2952ee0b..8bbb73a3 100644 --- a/lib/bait/context/scope.bt +++ b/lib/bait/context/scope.bt @@ -17,6 +17,13 @@ pub struct ScopeObject{ pub mut is_mut bool pub mut pkg string // TODO SCOPES move this into Scope (requires multi return) pub mut expr ast.Expr := ast.Void{} // const / static: resolve type on use + + // Only for functions (Note: will be cleaned up in the refactor to use sumtypes) + pub noreturn bool + pub return_type ast.Type + pub params []ast.Param + pub attrs []ast.Attribute + pub generic_names []string } pub enum ObjectKind { diff --git a/lib/bait/parser/fun.bt b/lib/bait/parser/fun.bt index c588f821..6ecc6ba8 100644 --- a/lib/bait/parser/fun.bt +++ b/lib/bait/parser/fun.bt @@ -82,7 +82,6 @@ fun (mut p Parser) fun_decl() !ast.FunDecl{ lang = lang pos = pos } - p.attributes = []ast.Attribute // Register method or function if is_method { @@ -106,16 +105,25 @@ fun (mut p Parser) fun_decl() !ast.FunDecl{ typ = node.typ pkg = p.pkg_name is_pub = is_pub + noreturn = p.attributes.has('noreturn') + return_type = return_type + params = params + attrs = p.attributes + generic_names = generic_names }) } else { ffi_scope := p.sema_ctx.obtain_root_scope(ffi.pkg) ffi_scope.register(name, context.ScopeObject{ kind = .function is_pub = true + return_type = return_type + params = params }) } } + p.attributes = []ast.Attribute + if lang == .bait { node.stmts = p.parse_block()! } From 95be14456bf01bdb375e3ecf10af8f7788d00531 Mon Sep 17 00:00:00 2001 From: Lukas Neubert <40118727+serkonda7@users.noreply.github.com> Date: Wed, 22 Jan 2025 20:01:06 +0100 Subject: [PATCH 11/12] fix callbacks and expand tests --- lib/bait/checker/fun.bt | 2 ++ tests/type/fun_types_test.bt | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/bait/checker/fun.bt b/lib/bait/checker/fun.bt index b76cd87d..ea24c938 100644 --- a/lib/bait/checker/fun.bt +++ b/lib/bait/checker/fun.bt @@ -112,6 +112,8 @@ fun (c Checker) fun_params(params []ast.Param){ typ = p.typ kind = .function pkg = c.pkg + return_type = info.return_type + params = info.to_params() }) } else { c.scope.register(p.name, context.ScopeObject{ diff --git a/tests/type/fun_types_test.bt b/tests/type/fun_types_test.bt index 6f91edd8..15fda410 100644 --- a/tests/type/fun_types_test.bt +++ b/tests/type/fun_types_test.bt @@ -1,11 +1,20 @@ // SPDX-FileCopyrightText: 2023-present Lukas Neubert // SPDX-License-Identifier: MIT +// This struct has to compile struct Foo { fun_field fun (string) i32 } -fun test_placeholder() { - // Above code just has to compile - assert true +fun takes_callback(s string, cb fun (string) i32) i32 { + return cb(s) +} + +fun my_cb(s string) i32 { + return s.length +} + +fun test_callback() { + assert takes_callback("hi", my_cb) == 2 + assert takes_callback("you", my_cb) == 3 } From deb443b30b7a7f7e5224053f67ae9a151fdf4b35 Mon Sep 17 00:00:00 2001 From: Lukas Neubert <40118727+serkonda7@users.noreply.github.com> Date: Thu, 23 Jan 2025 12:43:03 +0100 Subject: [PATCH 12/12] ast: remove Table.fun_decls --- lib/bait/ast/ast.bt | 2 +- lib/bait/ast/repr.bt | 7 ------- lib/bait/ast/table.bt | 1 - lib/bait/checker/fun.bt | 11 +++-------- lib/bait/context/scope.bt | 1 + lib/bait/gen/c/fun.bt | 2 +- lib/bait/gen/js/fun.bt | 2 +- lib/bait/parser/fun.bt | 17 ++++++++++------- lib/bait/parser/stmt.bt | 1 - 9 files changed, 17 insertions(+), 27 deletions(-) diff --git a/lib/bait/ast/ast.bt b/lib/bait/ast/ast.bt index 12eb4d72..5e2691dc 100644 --- a/lib/bait/ast/ast.bt +++ b/lib/bait/ast/ast.bt @@ -91,7 +91,7 @@ pub struct FunDecl { pub is_pub bool pub lang Language pub name string - pub mix_name string // TMP + pub key string // TODO rework generics and possibly remove this field pub params []Param pub return_type Type pub is_test bool diff --git a/lib/bait/ast/repr.bt b/lib/bait/ast/repr.bt index 018852c4..f2051c51 100644 --- a/lib/bait/ast/repr.bt +++ b/lib/bait/ast/repr.bt @@ -36,10 +36,3 @@ pub fun (e Expr) repr() string { InvalidExpr { 'InvalidExpr' } } } - -pub fun (fn FunDecl) key() string { - if fn.is_method { - return '${fn.params[0].typ}.${fn.name}' - } - return fn.mix_name -} diff --git a/lib/bait/ast/table.bt b/lib/bait/ast/table.bt index d478a447..eade2aa1 100644 --- a/lib/bait/ast/table.bt +++ b/lib/bait/ast/table.bt @@ -3,7 +3,6 @@ package ast pub struct Table { - pub mut fun_decls map[string]FunDecl pub mut type_idxs map[string]Type pub mut type_symbols []TypeSymbol pub mut needed_equality_funs []Type diff --git a/lib/bait/checker/fun.bt b/lib/bait/checker/fun.bt index ea24c938..132f3da4 100644 --- a/lib/bait/checker/fun.bt +++ b/lib/bait/checker/fun.bt @@ -104,10 +104,6 @@ fun (c Checker) fun_params(params []ast.Param){ if sym.kind == .fun_ { info := sym.info as ast.FunInfo - c.table.fun_decls[p.name] = ast.FunDecl{ - return_type = info.return_type - params = info.to_params() - } c.scope.register(p.name, context.ScopeObject{ typ = p.typ kind = .function @@ -158,7 +154,6 @@ fun (mut c Checker) fun_call(mut node ast.CallExpr) ast.Type { c.error("function `${node.full_name()}` is private", node.pos) } - mut def := c.table.fun_decls[node.full_name()] node.noreturn = obj.noreturn node.return_type = obj.return_type @@ -181,7 +176,7 @@ fun (mut c Checker) fun_call(mut node ast.CallExpr) ast.Type { c.or_block(mut node) - c.set_conc_types(mut node, obj.generic_names, def.key()) + c.set_conc_types(mut node, obj.generic_names, obj.key) if node.name == 'error' { node.return_type = c.cur_fun.return_type @@ -331,7 +326,7 @@ fun (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { c.or_block(mut node) - c.set_conc_types(mut node, def.generic_names, def.key()) + c.set_conc_types(mut node, def.generic_names, def.key) return node.return_type } @@ -458,7 +453,7 @@ fun (mut c Checker) or_block(mut node ast.CallExpr) { fun (mut c Checker) resolve_generics_funs() { for mut fn in c.file.generic_funs { - gtypes := c.table.generic_fun_types[fn.key()] + gtypes := c.table.generic_fun_types[fn.key] for concrete in gtypes { c.cur_concrete_types = concrete c.fun_instance(mut fn) diff --git a/lib/bait/context/scope.bt b/lib/bait/context/scope.bt index 8bbb73a3..a8d7c91d 100644 --- a/lib/bait/context/scope.bt +++ b/lib/bait/context/scope.bt @@ -24,6 +24,7 @@ pub struct ScopeObject{ pub params []ast.Param pub attrs []ast.Attribute pub generic_names []string + pub key string } pub enum ObjectKind { diff --git a/lib/bait/gen/c/fun.bt b/lib/bait/gen/c/fun.bt index d0f7d763..a7caf17d 100644 --- a/lib/bait/gen/c/fun.bt +++ b/lib/bait/gen/c/fun.bt @@ -22,7 +22,7 @@ fun (mut g Gen) anon_fun(node ast.AnonFun) { fun (mut g Gen) fun_decl(node ast.FunDecl) { if node.generic_names.length > 0 and g.cur_concrete_types.length == 0 { - gtypes := g.table.generic_fun_types[node.key()] + gtypes := g.table.generic_fun_types[node.key] for conc_types in gtypes { for i, gn in node.generic_names { g.cur_concrete_types[gn] = conc_types[i] diff --git a/lib/bait/gen/js/fun.bt b/lib/bait/gen/js/fun.bt index 408288ec..d5c1b0e1 100644 --- a/lib/bait/gen/js/fun.bt +++ b/lib/bait/gen/js/fun.bt @@ -6,7 +6,7 @@ import bait.ast fun (mut g Gen) fun_decl(node ast.FunDecl) { if node.generic_names.length > 0 and g.cur_concrete_types.length == 0 { - gtypes := g.table.generic_fun_types[node.key()] + gtypes := g.table.generic_fun_types[node.key] for conc_types in gtypes { for i, gn in node.generic_names { g.cur_concrete_types[gn] = conc_types[i] diff --git a/lib/bait/parser/fun.bt b/lib/bait/parser/fun.bt index 6ecc6ba8..ef16e56e 100644 --- a/lib/bait/parser/fun.bt +++ b/lib/bait/parser/fun.bt @@ -43,17 +43,19 @@ fun (mut p Parser) fun_decl() !ast.FunDecl{ ffi := p.parse_ffi_pkg()! lang = ffi.lang - mut mix_name := "" + mut key := "" if lang != .bait { - mix_name = ffi.pkg + "." // TMP + key = ffi.pkg + "." // TMP } // normal function name name := p.check_name()! - mix_name += name + key += name is_test := name.starts_with('test_') - if not is_method and lang == .bait { - mix_name = p.prepend_pkg(mix_name) + if is_method { + key = '${params[0].typ}.${name}' + } else if lang == .bait { + key = p.prepend_pkg(key) } // Generics @@ -73,7 +75,7 @@ fun (mut p Parser) fun_decl() !ast.FunDecl{ is_test = is_test is_pub = is_pub name = name - mix_name = mix_name + key = key generic_names = generic_names params = params return_type = return_type @@ -92,7 +94,6 @@ fun (mut p Parser) fun_decl() !ast.FunDecl{ } sym.methods.push(node) } else { - p.table.fun_decls[mix_name] = node mut param_types := []ast.Type for param in params { param_types.push(param.typ) @@ -110,6 +111,7 @@ fun (mut p Parser) fun_decl() !ast.FunDecl{ params = params attrs = p.attributes generic_names = generic_names + key = key }) } else { ffi_scope := p.sema_ctx.obtain_root_scope(ffi.pkg) @@ -118,6 +120,7 @@ fun (mut p Parser) fun_decl() !ast.FunDecl{ is_pub = true return_type = return_type params = params + key = key }) } } diff --git a/lib/bait/parser/stmt.bt b/lib/bait/parser/stmt.bt index 904721af..b06fe0c7 100644 --- a/lib/bait/parser/stmt.bt +++ b/lib/bait/parser/stmt.bt @@ -59,7 +59,6 @@ fun (mut p Parser) script_mode_main() !ast.FunDecl { name = "main" return_type = ast.VOID_TYPE } - p.table.fun_decls['main'] = node node.stmts = stmts return node }