@@ -165,6 +165,7 @@ pub fn (mut g FlatGen) gen_with_used_options(a &flat.FlatAst, used_fns map[strin
165165 g.collect_gen_info ()
166166 g.collect_interface_impls ()
167167 g.preseed_struct_fn_ptr_types ()
168+ g.preseed_global_fn_ptr_types ()
168169 const_code := g.precompute_consts ()
169170 orig_sb := g.sb
170171 orig_line_start := g.line_start
@@ -317,14 +318,8 @@ fn (mut g FlatGen) collect_gen_info() {
317318 continue
318319 }
319320 if kind_id == 70 {
320- mut methods := []string {}
321- for i in 0 .. node.children_count {
322- f := g.a.child_node (& node, i)
323- if node_kind_id (f) == 71 && f.op == .dot {
324- methods << f.value
325- }
326- }
327- g.interfaces[qualify_name_in_module (cur_module, node.value)] = methods
321+ iface_name := qualify_name_in_module (cur_module, node.value)
322+ g.interfaces[iface_name] = g.tc.interface_abstract_method_names (iface_name)
328323 continue
329324 }
330325 if kind_id == 65 {
@@ -452,6 +447,12 @@ fn (mut g FlatGen) register_fn_decl_param_types(name string, full_name string, p
452447 if name ! in g.fn_decl_param_types {
453448 g.fn_decl_param_types[name] = ptypes.clone ()
454449 }
450+ if g.tc.cur_module.len > 0 && g.tc.cur_module != 'main' && g.tc.cur_module != 'builtin' {
451+ dotted_name := '${g .tc .cur_module }.${name }'
452+ if dotted_name ! in g.fn_decl_param_types {
453+ g.fn_decl_param_types[dotted_name] = ptypes.clone ()
454+ }
455+ }
455456 if full_name ! in g.fn_decl_param_types {
456457 g.fn_decl_param_types[full_name] = ptypes.clone ()
457458 }
@@ -542,6 +543,17 @@ fn (mut g FlatGen) gen_expr_with_expected_type(id flat.NodeId, expected types.Ty
542543 actual = param_type
543544 }
544545 }
546+ if node.kind == .ident {
547+ if _ := fn_type_from (expected) {
548+ call_name := g.call_key (id, node.value)
549+ if call_name in g.tc.fn_param_types || call_name in g.tc.fn_ret_types {
550+ g.write (c_name (call_name))
551+ g.expected_expr_type = old_expected
552+ g.expected_enum = old_expected_enum
553+ return
554+ }
555+ }
556+ }
545557 if expected is types.Array && node.kind == .array_literal {
546558 elem_type := if node.children_count > 0 {
547559 g.tc.resolve_type (g.a.child (& node, 0 ))
@@ -568,6 +580,11 @@ fn (mut g FlatGen) gen_expr_with_expected_type(id flat.NodeId, expected types.Ty
568580 g.expected_enum = old_expected_enum
569581 return
570582 }
583+ if g.gen_interface_value_expr (id, expected) {
584+ g.expected_expr_type = old_expected
585+ g.expected_enum = old_expected_enum
586+ return
587+ }
571588 if g.gen_sum_value_expr (id, expected) {
572589 g.expected_expr_type = old_expected
573590 g.expected_enum = old_expected_enum
@@ -734,6 +751,13 @@ fn (mut g FlatGen) gen_expr_with_possible_enum_type(id flat.NodeId, expected typ
734751 g.gen_expr (id)
735752}
736753
754+ fn (g &FlatGen) expected_expr_is_optional_struct () bool {
755+ if g.expected_expr_type is types.Struct {
756+ return g.expected_expr_type.name.starts_with ('Optional' )
757+ }
758+ return false
759+ }
760+
737761fn (mut g FlatGen) optional_none_type (id flat.NodeId) types.Type {
738762 if g.expected_expr_type is types.OptionType || g.expected_expr_type is types.ResultType {
739763 return g.expected_expr_type
@@ -1275,7 +1299,7 @@ fn (mut g FlatGen) gen_expr(id flat.NodeId) {
12751299 g.gen_heap_assoc_expr (child)
12761300 } else if node.op == .amp && child.kind == .cast_expr {
12771301 target_type := g.tc.parse_type (child.value)
1278- ct := g.tc. c_type (target_type)
1302+ ct := g.cast_c_type (target_type)
12791303 cast_arg := g.a.child_node (& child, 0 )
12801304 if cast_arg.kind == .nil_literal {
12811305 g.write ('(${ct }*)NULL' )
@@ -1522,8 +1546,8 @@ fn (mut g FlatGen) gen_expr(id flat.NodeId) {
15221546 if node.value == 'range' {
15231547 g.gen_slice_expr (node, base_id, base_type)
15241548 } else if base_type is types.Map {
1525- c_key := g.tc. c_type (base_type.key_type)
1526- c_val := g.tc. c_type (base_type.value_type)
1549+ c_key := g.value_c_type (base_type.key_type)
1550+ c_val := g.value_c_type (base_type.value_type)
15271551 g.write ('(*(${c_val }*)map__get(&' )
15281552 g.gen_expr (base_id)
15291553 g.write (', &(${c_key }[]){' )
@@ -1532,7 +1556,16 @@ fn (mut g FlatGen) gen_expr(id flat.NodeId) {
15321556 } else {
15331557 is_array_index , is_ptr , arr_type := array_index_info (base_type)
15341558 if is_array_index {
1535- c_elem := g.tc.c_type (arr_type.elem_type)
1559+ index_type := if g.expected_expr_type is types.OptionType
1560+ || g.expected_expr_type is types.ResultType
1561+ || g.expected_expr_is_optional_struct () {
1562+ g.expected_expr_type
1563+ } else if node.typ.starts_with ('?' ) || node.typ.starts_with ('!' ) {
1564+ g.tc.parse_type (node.typ)
1565+ } else {
1566+ arr_type.elem_type
1567+ }
1568+ c_elem := g.value_c_type (index_type)
15361569 g.write ('(*(${c_elem }*)array_get(' )
15371570 if is_ptr {
15381571 g.write ('*' )
@@ -1587,7 +1620,7 @@ fn (mut g FlatGen) gen_expr(id flat.NodeId) {
15871620 }
15881621 .cast_expr {
15891622 target_type := g.tc.parse_type (node.value)
1590- mut ct := g.tc. c_type (target_type)
1623+ mut ct := g.cast_c_type (target_type)
15911624 if ct.starts_with ('fn_ptr:' ) {
15921625 ct = g.resolve_fn_ptr_type (ct)
15931626 }
@@ -2179,8 +2212,42 @@ fn (mut g FlatGen) late_compat_decls() {
21792212 g.writeln ('static inline Array binary__little_endian_get_u32(u32 v) { (void)v; return (Array){.data = NULL, .offset = 0, .len = 0, .cap = 0, .flags = 0, .element_size = sizeof(u8)}; }' )
21802213 g.writeln ('static inline Array binary__big_endian_get_u32(u32 v) { (void)v; return (Array){.data = NULL, .offset = 0, .len = 0, .cap = 0, .flags = 0, .element_size = sizeof(u8)}; }' )
21812214 g.writeln ('static inline Optional rand__int_u64(u64 max) { (void)max; return (Optional){.ok = true, .value = 0}; }' )
2215+ g.writeln ('typedef struct PGconn { int _dummy; } PGconn;' )
2216+ g.writeln ('typedef struct PGresult { int _dummy; } PGresult;' )
2217+ g.writeln ('typedef struct PGnotify { char* relname; int be_pid; char* extra; } PGnotify;' )
2218+ g.writeln ('static inline PGconn* PQconnectdb(char* conninfo) { (void)conninfo; static PGconn conn; return &conn; }' )
2219+ g.writeln ('static inline int PQstatus(PGconn* conn) { (void)conn; return 0; }' )
2220+ g.writeln ('static inline int PQtransactionStatus(PGconn* conn) { (void)conn; return 0; }' )
2221+ g.writeln ('static inline char* PQerrorMessage(PGconn* conn) { (void)conn; return ""; }' )
2222+ g.writeln ('static inline PGresult* PQexec(PGconn* conn, char* query) { (void)conn; (void)query; static PGresult res; return &res; }' )
2223+ g.writeln ('static inline int PQgetisnull(PGresult* res, int row, int col) { (void)res; (void)row; (void)col; return 1; }' )
2224+ g.writeln ('static inline char* PQgetvalue(PGresult* res, int row, int col) { (void)res; (void)row; (void)col; return ""; }' )
2225+ g.writeln ('static inline int PQresultStatus(PGresult* res) { (void)res; return 1; }' )
2226+ g.writeln ('static inline int PQntuples(PGresult* res) { (void)res; return 0; }' )
2227+ g.writeln ('static inline int PQnfields(PGresult* res) { (void)res; return 0; }' )
2228+ g.writeln ('static inline char* PQfname(PGresult* res, int col) { (void)res; (void)col; return ""; }' )
2229+ g.writeln ('static inline PGresult* PQexecParams(PGconn* conn, char* query, int nparams, void* types, void* vals, void* lens, void* formats, int result_format) { (void)conn; (void)query; (void)nparams; (void)types; (void)vals; (void)lens; (void)formats; (void)result_format; static PGresult res; return &res; }' )
2230+ g.writeln ('static inline int PQputCopyData(PGconn* conn, void* buffer, int nbytes) { (void)conn; (void)buffer; (void)nbytes; return 1; }' )
2231+ g.writeln ('static inline int PQputCopyEnd(PGconn* conn, char* errmsg) { (void)conn; (void)errmsg; return 1; }' )
2232+ g.writeln ('static inline int PQgetCopyData(PGconn* conn, char** buffer, int async) { (void)conn; (void)buffer; (void)async; return -1; }' )
2233+ g.writeln ('static inline PGresult* PQprepare(PGconn* conn, char* name, char* query, int nparams, void* param_types) { (void)conn; (void)name; (void)query; (void)nparams; (void)param_types; static PGresult res; return &res; }' )
2234+ g.writeln ('static inline PGresult* PQexecPrepared(PGconn* conn, char* name, int nparams, void* vals, void* lens, void* formats, int result_format) { (void)conn; (void)name; (void)nparams; (void)vals; (void)lens; (void)formats; (void)result_format; static PGresult res; return &res; }' )
2235+ g.writeln ('static inline void PQclear(PGresult* res) { (void)res; }' )
2236+ g.writeln ('static inline void PQfreemem(void* ptr) { (void)ptr; }' )
2237+ g.writeln ('static inline void PQfinish(PGconn* conn) { (void)conn; }' )
2238+ g.writeln ('static inline PGnotify* PQnotifies(PGconn* conn) { (void)conn; return NULL; }' )
2239+ g.writeln ('static inline int PQconsumeInput(PGconn* conn) { (void)conn; return 1; }' )
2240+ g.writeln ('static inline int PQsocket(PGconn* conn) { (void)conn; return -1; }' )
2241+ g.writeln ('static inline char* PQescapeLiteral(PGconn* conn, char* str, size_t len) { (void)conn; (void)len; return str; }' )
2242+ g.writeln ('static inline void pg__pg_stmt_match_array(Array* types, Array* vals, Array* lens, Array* formats, Array data) { (void)types; (void)vals; (void)lens; (void)formats; (void)data; }' )
21822243 g.writeln ('typedef void* _fn_ptr_64;' )
21832244 g.writeln ('static inline Optional_string orm__orm_table_gen(int sql_dialect, orm__Table table, string q, bool defaults, int def_unique_len, Array fields, void* sql_from_v, bool unique) { (void)sql_dialect; (void)table; (void)q; (void)defaults; (void)def_unique_len; (void)fields; (void)sql_from_v; (void)unique; return (Optional_string){.ok = true, .value = v3_empty_string_lit()}; }' )
2245+ if 'sqlite.Stmt' ! in g.struct_decl_infos {
2246+ g.writeln ('typedef struct sqlite__Stmt { void* stmt; void* db; } sqlite__Stmt;' )
2247+ }
2248+ if 'sqlite.ConnectionPool' ! in g.struct_decl_infos {
2249+ g.writeln ('typedef struct sqlite__ConnectionPool { int _dummy; } sqlite__ConnectionPool;' )
2250+ }
21842251 g.writeln ('static inline int sqlite__bind_array(sqlite__Stmt stmt, int** c, Array data) { (void)stmt; (void)c; (void)data; return 0; }' )
21852252 g.writeln ('#ifndef orm__type_string' )
21862253 g.writeln ('#define orm__type_string 9' )
@@ -2430,7 +2497,7 @@ fn (mut g FlatGen) late_compat_decls() {
24302497 g.writeln ('static inline void blowfish__Blowfish__encrypt(blowfish__Blowfish* bf, Array* dst, Array src) { (void)bf; (void)dst; (void)src; }' )
24312498 g.writeln ('static inline Optional_blowfish__Blowfish blowfish__new_cipher(Array key) { (void)key; return (Optional_blowfish__Blowfish){.ok = true, .value = (blowfish__Blowfish){}}; }' )
24322499 g.writeln ('static inline Optional_blowfish__Blowfish blowfish__new_salted_cipher(Array key, Array salt) { (void)key; (void)salt; return (Optional_blowfish__Blowfish){.ok = true, .value = (blowfish__Blowfish){}}; }' )
2433- g.writeln ('static inline void mbedtls__SSLListener__init_sni(mbedtls__SSLListener* l, _fn_ptr_3 get_cert_callback) { (void)l; (void)get_cert_callback; }' )
2500+ g.writeln ('static inline void mbedtls__SSLListener__init_sni(mbedtls__SSLListener* l, void* get_cert_callback) { (void)l; (void)get_cert_callback; }' )
24342501 g.writeln ('static inline orm__Primitive v3_orm_empty_primitive(void) { return (orm__Primitive){}; }' )
24352502 g.writeln ('static inline orm__Primitive orm__bool_to_primitive(bool b) { (void)b; return v3_orm_empty_primitive(); }' )
24362503 g.writeln ('static inline orm__Primitive orm__f32_to_primitive(float b) { (void)b; return v3_orm_empty_primitive(); }' )
0 commit comments