@@ -1938,84 +1938,30 @@ let gen_decl (ctx : context) (decl : top_level) : context result =
19381938 (* These declarations don't generate code *)
19391939 Ok ctx
19401940
1941- (* * Cross-module imports: walk [prog.prog_imports], load each referenced module
1942- via [loader], and for every imported function name register
1943- a WASM [(import "<mod>" "<fn>" (func ...))] entry plus a
1944- [(local_alias_name → func_idx)] mapping in [func_indices].
1945-
1946- [ImportSimple] (e.g. [use Core]) brings the namespace itself but no specific
1947- symbol; nothing to emit. [ImportList] emits one import per listed item.
1948- [ImportGlob] enumerates every public [TopFn] in the loaded module.
1949-
1950- The verifier matches imports by [i_name] only, so the [i_module] string is
1951- informational; we use the dotted module path to keep it human-readable.
1952-
1953- Silent on missing modules / non-function items / loader errors: the
1954- resolver runs before codegen and would have already errored. *)
1955- let gen_imports (loader : Module_loader.t ) (imports : import_decl list ) (ctx : context )
1956- : context result =
1957- let process_one ctx (mod_path , orig_name , alias_opt ) =
1958- match Module_loader. load_module loader mod_path with
1959- | Error _ -> Ok ctx
1960- | Ok loaded ->
1961- let fn_decl_opt = List. find_map (function
1962- | TopFn fd when fd.fd_name.name = orig_name -> Some fd
1963- | _ -> None
1964- ) loaded.mod_program.prog_decls in
1965- match fn_decl_opt with
1966- | None -> Ok ctx
1967- | Some fd ->
1968- let local_name = Option. value alias_opt ~default: orig_name in
1969- let ft = func_type_of_fn_decl fd in
1970- let (type_idx, types_after) = intern_func_type ctx.types ft in
1971- let import_func_idx = import_func_count ctx in
1972- let import = {
1973- i_module = String. concat " ." mod_path;
1974- i_name = orig_name;
1975- i_desc = ImportFunc type_idx;
1976- } in
1977- Ok { ctx with
1978- types = types_after;
1979- imports = ctx.imports @ [import];
1980- func_indices = (local_name, import_func_idx) :: ctx.func_indices;
1981- }
1982- in
1983- let expand_import imp : (string list * string * string option) list =
1984- let path_strs path = List. map (fun (id : ident ) -> id.name) path in
1985- match imp with
1986- | ImportSimple _ -> []
1987- | ImportList (path , items ) ->
1988- let p = path_strs path in
1989- List. map (fun item ->
1990- (p, item.ii_name.name, Option. map (fun (id : ident ) -> id.name) item.ii_alias)
1991- ) items
1992- | ImportGlob path ->
1993- let p = path_strs path in
1994- (match Module_loader. load_module loader p with
1995- | Error _ -> []
1996- | Ok lm ->
1997- List. filter_map (function
1998- | TopFn fd when fd.fd_vis = Public || fd.fd_vis = PubCrate ->
1999- Some (p, fd.fd_name.name, None )
2000- | _ -> None
2001- ) lm.mod_program.prog_decls)
2002- in
2003- let entries = List. concat_map expand_import imports in
2004- List. fold_left (fun acc e ->
2005- let * ctx = acc in
2006- process_one ctx e
2007- ) (Ok ctx) entries
2008-
2009- (* * Generate WASM module from AffineScript program.
2010-
2011- [?loader] supplies the module loader used to resolve cross-module imports.
2012- Defaults to a fresh loader with [Module_loader.default_config ()] so that
2013- existing call sites keep working without modification. *)
2014- let generate_module ?loader (prog : program ) : wasm_module result =
2015- let loader = match loader with
2016- | Some l -> l
2017- | None -> Module_loader. create (Module_loader. default_config () )
2018- in
1941+ | TopExternType _ ->
1942+ (* Opaque host type — no code generated; type is available to the type-checker *)
1943+ Ok ctx
1944+
1945+ | TopExternFn ef ->
1946+ (* Add a WebAssembly import for the extern fn declaration.
1947+ Module name defaults to "env" (conventional host environment namespace). *)
1948+ let param_types = List. map (fun _ -> I32 ) ef.ef_params in
1949+ let result_types = match ef.ef_ret_ty with
1950+ | None -> []
1951+ | Some _ -> [I32 ]
1952+ in
1953+ let func_type = { ft_params = param_types; ft_results = result_types } in
1954+ let type_idx = List. length ctx.types in
1955+ let ctx_with_type = { ctx with types = ctx.types @ [func_type] } in
1956+ let func_idx = import_func_count ctx_with_type in
1957+ let import_entry = { i_module = " env" ; i_name = ef.ef_name.name;
1958+ i_desc = ImportFunc type_idx } in
1959+ Ok { ctx_with_type with
1960+ imports = ctx_with_type.imports @ [import_entry];
1961+ func_indices = (ef.ef_name.name, func_idx) :: ctx_with_type.func_indices }
1962+
1963+ (* * Generate WASM module from AffineScript program *)
1964+ let generate_module (prog : program ) : wasm_module result =
20191965 let ctx = create_context () in
20201966
20211967 (* Add WASI fd_write import at index 0 *)
0 commit comments