OnyxTypeInfo *type;
OnyxAstNodeLocal *prev_local;
OnyxAstNode *shadowed;
- OnyxAstNode *unused;
+ ptr unused;
};
// NOTE: Needs to have shadowed in the same position as OnyxAstNodeLocal
OnyxTypeInfo *type;
OnyxAstNodeParam *next;
OnyxAstNode *shadowed;
- u64 param_count;
+ ptr unused;
};
struct OnyxAstNodeScope {
#include "onyxparser.h"
-typedef char WasmType;
+typedef u8 WasmType;
extern const WasmType WASM_TYPE_INT32;
extern const WasmType WASM_TYPE_INT64;
WasmType param_types[];
} WasmFuncType;
+
typedef struct WasmFunc {
- i32 idx;
i32 type_idx;
} WasmFunc;
+typedef enum WasmExportKind {
+ WASM_EXPORT_FUNCTION,
+ WASM_EXPORT_TABLE,
+ WASM_EXPORT_MEMORY,
+ WASM_EXPORT_GLOBAL,
+} WasmExportKind;
+
+typedef struct WasmExport {
+ WasmExportKind kind;
+ i32 idx;
+} WasmExport;
+
typedef struct OnyxWasmModule {
bh_allocator allocator;
// to the function type index if it has been created.
bh_hash(i32) type_map;
i32 next_type_idx;
-
// NOTE: This have to be pointers because the type is variadic in size
bh_arr(WasmFuncType*) functypes;
+
bh_arr(WasmFunc) funcs;
+ i32 next_func_idx;
+
+ bh_hash(WasmExport) exports;
} OnyxWasmModule;
OnyxWasmModule onyx_wasm_generate_module(bh_allocator alloc, OnyxAstNode* program);
return a + b;
}
+export foo :: proc () -> i32 {
+ return 10 as i32;
+}
+
export mul :: proc (a i32, b i32) -> i64 {
// Typechecked
- c: const i64 = ((a as i64) - (b as i64));
+ c: const = a - b;
// Don't love this syntax, but it's easy to parse so whatever
// Inferred type, but constant
e: i32 = 10 as i32;
- return ((c as i32) * d) as i64;
+ return (c * d) as i64;
}
#include "onyxmsgs.h"
#include "onyxparser.h"
#include "onyxutils.h"
+#include "onyxwasm.h"
int main(int argc, char *argv[]) {
bh_file source_file;
bh_printf("\nNo errors.\n");
}
+ OnyxWasmModule wasm_mod = onyx_wasm_generate_module(alloc, program);
+#if 1
+ // NOTE: Ensure type table made correctly
+
+ bh_printf("Type map:\n");
+ bh_hash_iterator type_map_it = bh_hash_iter_setup(i32, wasm_mod.type_map);
+ while (bh_hash_iter_next(&type_map_it)) {
+ const char* key = bh_hash_iter_key(type_map_it);
+ i32 value = bh_hash_iter_value(i32, type_map_it);
+
+ bh_printf("%s -> %d\n", key, value);
+ }
+
+ bh_printf("Type list:\n");
+ WasmFuncType** func_type = wasm_mod.functypes;
+ while (!bh_arr_end(wasm_mod.functypes, func_type)) {
+ for (int p = 0; p < (*func_type)->param_count; p++) {
+ bh_printf("%c ", (*func_type)->param_types[p]);
+ }
+ bh_printf("-> ");
+ bh_printf("%c\n", (*func_type)->return_type);
+
+ func_type++;
+ }
+#endif
+
+#if 1
+ // NOTE: Ensure the export table was built correctly
+
+ bh_printf("Function types:\n");
+ for (WasmFunc* func_it = wasm_mod.funcs; !bh_arr_end(wasm_mod.funcs, func_it); func_it++) {
+ bh_printf("%d\n", func_it->type_idx);
+ }
+
+ bh_printf("Exports:\n");
+ bh_hash_iterator export_it = bh_hash_iter_setup(WasmExport, wasm_mod.exports);
+ while (bh_hash_iter_next(&export_it)) {
+ const char* key = bh_hash_iter_key(export_it);
+ WasmExport value = bh_hash_iter_value(WasmExport, export_it);
+
+ bh_printf("%s: %d %d\n", key, value.kind, value.idx);
+ }
+#endif
+
+
+ onyx_wasm_module_free(&wasm_mod);
main_exit: // NOTE: Cleanup, since C doesn't have defer
bh_arena_free(&msg_arena);
bh_arena_free(&ast_arena);
}
OnyxAstNodeParam* first_param = NULL;
- u64 param_count = 0;
-
OnyxAstNodeParam* curr_param = NULL;
OnyxAstNodeParam* trailer = NULL;
OnyxToken* symbol;
while (parser->curr_token->type != TOKEN_TYPE_CLOSE_PAREN) {
if (parser->curr_token->type == TOKEN_TYPE_SYM_COMMA) parser_next_token(parser);
- param_count++;
symbol = expect(parser, TOKEN_TYPE_SYMBOL);
trailer = curr_param;
}
- first_param->param_count = param_count;
-
parser_next_token(parser); // Skip the )
return first_param;
}
#include "onyxwasm.h"
+// NOTE: Allows easier testing of types since most of the characters
+// corresponding to these values are not printable
+#if 0
const WasmType WASM_TYPE_INT32 = 0x7F;
const WasmType WASM_TYPE_INT64 = 0x7E;
const WasmType WASM_TYPE_FLOAT32 = 0x7D;
const WasmType WASM_TYPE_FLOAT64 = 0x7C;
+#else
+const WasmType WASM_TYPE_INT32 = 'A';
+const WasmType WASM_TYPE_INT64 = 'B';
+const WasmType WASM_TYPE_FLOAT32 = 'C';
+const WasmType WASM_TYPE_FLOAT64 = 'D';
+#endif
static WasmType onyx_type_to_wasm_type(OnyxTypeInfo* type) {
if (type->is_bool) return WASM_TYPE_INT32;
- if (type->is_int) {
+ else if (type->is_int) {
if (type->size == 4) return WASM_TYPE_INT32;
if (type->size == 8) return WASM_TYPE_INT64;
}
- if (type->is_float) {
+ else if (type->is_float) {
if (type->size == 4) return WASM_TYPE_FLOAT32;
if (type->size == 8) return WASM_TYPE_FLOAT64;
}
// TODO: Should produce an error message if this isn't successful
- // TODO: Also, this should be able to handle a "void" type
return WASM_TYPE_INT32;
}
type_idx = mod->next_type_idx;
mod->next_type_idx++;
}
+
+ WasmFunc wasm_func = {
+ .type_idx = type_idx
+ };
+ bh_arr_push(mod->funcs, wasm_func);
+ i32 func_idx = mod->next_func_idx++;
+
+ if (fd->flags & ONYX_AST_FLAG_EXPORTED) {
+ onyx_token_null_toggle(*fd->token);
+
+ WasmExport wasm_export = {
+ .kind = WASM_EXPORT_FUNCTION,
+ .idx = func_idx,
+ };
+ bh_hash_put(WasmExport, mod->exports, fd->token->token, wasm_export);
+
+ onyx_token_null_toggle(*fd->token);
+ }
}
OnyxWasmModule onyx_wasm_generate_module(bh_allocator alloc, OnyxAstNode* program) {
.type_map = NULL,
.next_type_idx = 0,
-
.functypes = NULL,
+
.funcs = NULL,
+ .next_func_idx = 0,
+
+ .exports = NULL,
};
bh_arr_new(alloc, module.functypes, 4);
bh_arr_new(alloc, module.funcs, 4);
bh_hash_init(bh_heap_allocator(), module.type_map);
+ bh_hash_init(bh_heap_allocator(), module.exports);
OnyxAstNode* walker = program;
while (walker) {