From 4679f0da485fee9c601cd9c199ab8b51e570b105 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Tue, 21 Jan 2025 10:07:18 +0100 Subject: [PATCH] refactor meta tables --- src/app/app.meta.c | 200 +++++++++++++++++------------------ src/meta/meta_format.c | 36 +++---- src/meta/meta_table_format.c | 161 +++++++++++++++++----------- src/ui/ui.meta.c | 137 ++++++++++++++++++++---- src/wasm_app/wasm_app.meta.c | 18 ++-- todo.txt | 12 ++- 6 files changed, 352 insertions(+), 212 deletions(-) diff --git a/src/app/app.meta.c b/src/app/app.meta.c index 7dce4f8..8dd9a34 100644 --- a/src/app/app.meta.c +++ b/src/app/app.meta.c @@ -3,128 +3,120 @@ void mt_app(ma_arena_t *arena) { sb8_t *c = sb8_serial_begin(arena); - ast_t *keys = mt_table_parse(arena, __FILE__, S8_CODE( + ast_t *keys = mtt_parse(arena, __FILE__, S8_CODE( // javascript filter out - | name | js1 | js2 | jf | windows1 | windows2 | - | null | XXX | XXX | 1 | XXX | XXX | - | 1 | 1 | XXX | 0 | `'1'` | XXX | - | 2 | 2 | XXX | 0 | `'2'` | XXX | - | 3 | 3 | XXX | 0 | `'3'` | XXX | - | 4 | 4 | XXX | 0 | `'4'` | XXX | - | 5 | 5 | XXX | 0 | `'5'` | XXX | - | 6 | 6 | XXX | 0 | `'6'` | XXX | - | 7 | 7 | XXX | 0 | `'7'` | XXX | - | 8 | 8 | XXX | 0 | `'8'` | XXX | - | 9 | 9 | XXX | 0 | `'9'` | XXX | - | 0 | 0 | XXX | 0 | `'0'` | XXX | - | f1 | F1 | XXX | 1 | VK_F1 | XXX | - | f2 | F2 | XXX | 1 | VK_F2 | XXX | - | f3 | F3 | XXX | 1 | VK_F3 | XXX | - | f4 | F4 | XXX | 1 | VK_F4 | XXX | - | f5 | F5 | XXX | 1 | VK_F5 | XXX | - | f6 | F6 | XXX | 1 | VK_F6 | XXX | - | f7 | F7 | XXX | 1 | VK_F7 | XXX | - | f8 | F8 | XXX | 1 | VK_F8 | XXX | - | f9 | F9 | XXX | 1 | VK_F9 | XXX | - | f10 | F10 | XXX | 1 | VK_F10 | XXX | - | f11 | F11 | XXX | 1 | VK_F11 | XXX | - | f12 | F12 | XXX | 1 | VK_F12 | XXX | - | a | a | XXX | 0 | `'A'` | XXX | - | b | b | XXX | 0 | `'B'` | XXX | - | c | c | XXX | 0 | `'C'` | XXX | - | d | d | XXX | 0 | `'D'` | XXX | - | e | e | XXX | 0 | `'E'` | XXX | - | f | f | XXX | 0 | `'F'` | XXX | - | g | g | XXX | 0 | `'G'` | XXX | - | h | h | XXX | 0 | `'H'` | XXX | - | i | i | XXX | 0 | `'I'` | XXX | - | j | j | XXX | 0 | `'J'` | XXX | - | k | k | XXX | 0 | `'K'` | XXX | - | l | l | XXX | 0 | `'L'` | XXX | - | m | m | XXX | 0 | `'M'` | XXX | - | n | n | XXX | 0 | `'N'` | XXX | - | o | o | XXX | 0 | `'O'` | XXX | - | p | p | XXX | 0 | `'P'` | XXX | - | q | q | XXX | 0 | `'Q'` | XXX | - | r | r | XXX | 0 | `'R'` | XXX | - | s | s | XXX | 0 | `'S'` | XXX | - | _t | t | XXX | 0 | `'T'` | XXX | - | u | u | XXX | 0 | `'U'` | XXX | - | v | v | XXX | 0 | `'V'` | XXX | - | w | w | XXX | 0 | `'W'` | XXX | - | x | x | XXX | 0 | `'X'` | XXX | - | y | y | XXX | 0 | `'Y'` | XXX | - | z | z | XXX | 0 | `'Z'` | XXX | - | space | ` ` | XXX | 0 | VK_SPACE | XXX | - | enter | Enter | XXX | 1 | VK_RETURN | XXX | - | escape | Escape | XXX | 1 | VK_ESCAPE | XXX | - | left | ArrowLeft | XXX | 1 | VK_LEFT | XXX | - | up | ArrowUp | XXX | 1 | VK_UP | XXX | - | right | ArrowRight | XXX | 1 | VK_RIGHT | XXX | - | down | ArrowDown | XXX | 1 | VK_DOWN | XXX | - | tab | Tab | XXX | 1 | VK_TAB | XXX | - | backspace | Backspace | XXX | 1 | VK_BACK | XXX | - | control | Control | XXX | 1 | VK_CONTROL | XXX | - | shift | Shift | XXX | 1 | VK_SHIFT | XXX | - | alt | Alt | AltGraph | 1 | VK_LMENU | VK_RMENU | - | meta | Meta | XXX | 1 | VK_LWIN | VK_RWIN | - | caps_lock | CapsLock | XXX | 1 | VK_CAPITAL | XXX | - | delete | Delete | XXX | 1 | VK_DELETE | XXX | - | home | Home | XXX | 1 | VK_HOME | XXX | - | end | End | XXX | 1 | VK_END | XXX | - | insert | Insert | XXX | 1 | VK_NEXT | XXX | - | page_up | PageUp | XXX | 1 | VK_INSERT | XXX | - | page_down | PageDown | XXX | 1 | VK_PRIOR | XXX | + { name js1 js2 jf windows1 windows2 } + { null XXX XXX 1 XXX XXX } + { 1 1 XXX 0 `'1'` XXX } + { 2 2 XXX 0 `'2'` XXX } + { 3 3 XXX 0 `'3'` XXX } + { 4 4 XXX 0 `'4'` XXX } + { 5 5 XXX 0 `'5'` XXX } + { 6 6 XXX 0 `'6'` XXX } + { 7 7 XXX 0 `'7'` XXX } + { 8 8 XXX 0 `'8'` XXX } + { 9 9 XXX 0 `'9'` XXX } + { 0 0 XXX 0 `'0'` XXX } + { f1 F1 XXX 1 VK_F1 XXX } + { f2 F2 XXX 1 VK_F2 XXX } + { f3 F3 XXX 1 VK_F3 XXX } + { f4 F4 XXX 1 VK_F4 XXX } + { f5 F5 XXX 1 VK_F5 XXX } + { f6 F6 XXX 1 VK_F6 XXX } + { f7 F7 XXX 1 VK_F7 XXX } + { f8 F8 XXX 1 VK_F8 XXX } + { f9 F9 XXX 1 VK_F9 XXX } + { f10 F10 XXX 1 VK_F10 XXX } + { f11 F11 XXX 1 VK_F11 XXX } + { f12 F12 XXX 1 VK_F12 XXX } + { a a XXX 0 `'A'` XXX } + { b b XXX 0 `'B'` XXX } + { c c XXX 0 `'C'` XXX } + { d d XXX 0 `'D'` XXX } + { e e XXX 0 `'E'` XXX } + { f f XXX 0 `'F'` XXX } + { g g XXX 0 `'G'` XXX } + { h h XXX 0 `'H'` XXX } + { i i XXX 0 `'I'` XXX } + { j j XXX 0 `'J'` XXX } + { k k XXX 0 `'K'` XXX } + { l l XXX 0 `'L'` XXX } + { m m XXX 0 `'M'` XXX } + { n n XXX 0 `'N'` XXX } + { o o XXX 0 `'O'` XXX } + { p p XXX 0 `'P'` XXX } + { q q XXX 0 `'Q'` XXX } + { r r XXX 0 `'R'` XXX } + { s s XXX 0 `'S'` XXX } + { _t t XXX 0 `'T'` XXX } + { u u XXX 0 `'U'` XXX } + { v v XXX 0 `'V'` XXX } + { w w XXX 0 `'W'` XXX } + { x x XXX 0 `'X'` XXX } + { y y XXX 0 `'Y'` XXX } + { z z XXX 0 `'Z'` XXX } + { space ` ` XXX 0 VK_SPACE XXX } + { enter Enter XXX 1 VK_RETURN XXX } + { escape Escape XXX 1 VK_ESCAPE XXX } + { left ArrowLeft XXX 1 VK_LEFT XXX } + { up ArrowUp XXX 1 VK_UP XXX } + { right ArrowRight XXX 1 VK_RIGHT XXX } + { down ArrowDown XXX 1 VK_DOWN XXX } + { tab Tab XXX 1 VK_TAB XXX } + { backspace Backspace XXX 1 VK_BACK XXX } + { control Control XXX 1 VK_CONTROL XXX } + { shift Shift XXX 1 VK_SHIFT XXX } + { alt Alt AltGraph 1 VK_LMENU VK_RMENU } + { meta Meta XXX 1 VK_LWIN VK_RWIN } + { caps_lock CapsLock XXX 1 VK_CAPITAL XXX } + { delete Delete XXX 1 VK_DELETE XXX } + { home Home XXX 1 VK_HOME XXX } + { end End XXX 1 VK_END XXX } + { insert Insert XXX 1 VK_NEXT XXX } + { page_up PageUp XXX 1 VK_INSERT XXX } + { page_down PageDown XXX 1 VK_PRIOR XXX } )); - mt_table_serial(c, h, keys, s8_lit("app_key")); + mtt_serialb(c, h, keys, s8_lit("app_key")); - // Javascript + /////////////////////////////// + // generate mappings { - i32 name_idx = mt_table_find_rowi(keys->first, "name"); - i32 js1_idx = mt_table_find_rowi(keys->first, "js1"); - i32 js2_idx = mt_table_find_rowi(keys->first, "js2"); - i32 filter_out_idx = mt_table_find_rowi(keys->first, "jf"); - - + /////////////////////////////// + // javascript sb8_stmtf(c, "\n#if PLATFORM_WASM"); sb8_stmtf(c, "typedef struct { app_key_t key; b32 filter_out; } wasm_key_map_t;"); sb8_stmtf(c, "wasm_key_map_t wasm_map_key_string_to_app_key(s8_t key) {"); c->indent += 1; - sb8_stmtf(c, "if (0) {}"); - for (ast_t *row = keys->first->next; row; row = row->next) { - s8_t name = mt_table_get_rowi(row, name_idx)->string; - i64 filter_out = mt_table_get_rowi(row, filter_out_idx)->integer; - assert(filter_out == 0 || filter_out == 1); - - s8_t js[] = {mt_table_get_rowi(row, js1_idx)->string, mt_table_get_rowi(row, js2_idx)->string}; - for (i32 i = 0; i < lengthof(js); i += 1) { - if (s8_are_equal(js[i], s8_lit("XXX"))) continue; - sb8_stmtf(c, "else if (s8_are_equal_ex(key, s8_lit(\"%S\"), s8_ignore_case)) return (wasm_key_map_t){app_key_%S, %d};", js[i], name, (i32)filter_out); + { + sb8_stmtf(c, "if (0) {}"); + for (mtt_iter_t it = mtt_iterate(c->arena, keys); mtt_is_valid(it); mtt_advance(&it)) { + assert(mtt(it, "jf")->integer == 0 || mtt(it, "jf")->integer == 1); + s8_t js[] = {mtts(it, "js1"), mtts(it, "js2")}; + for (i32 i = 0; i < lengthof(js); i += 1) { + if (s8_are_equal(js[i], s8_lit("XXX"))) continue; + sb8_stmtf(c, "else if (s8_are_equal_ex(key, s8_lit(\"%S\"), s8_ignore_case)) return (wasm_key_map_t){app_key_%S, %d};", js[i], mtts(it, "name"), (int)mtt(it, "jf")->integer); + } } + sb8_stmtf(c, "return (wasm_key_map_t){0};"); } - sb8_stmtf(c, "return (wasm_key_map_t){0};"); c->indent -= 1; sb8_stmtf(c, "}"); sb8_stmtf(c, "#endif"); - } - - // Windows - { - i32 name_idx = mt_table_find_rowi(keys->first, "name"); - i32 w1i = mt_table_find_rowi(keys->first, "windows1"); - i32 w2i = mt_table_find_rowi(keys->first, "windows2"); + /////////////////////////////// + // windows sb8_stmtf(c, "\n#if PLATFORM_WINDOWS"); sb8_stmtf(c, "app_key_t w32_map_wparam_to_app_key(WPARAM wparam) {"); c->indent += 1; sb8_stmtf(c, "switch(wparam) {"); c->indent += 1; - for (ast_t *row = keys->first->next; row; row = row->next) { - s8_t name = mt_table_get_rowi(row, name_idx)->string; - s8_t w[] = {mt_table_get_rowi(row, w1i)->string, mt_table_get_rowi(row, w2i)->string}; - for (i32 i = 0; i < lengthof(w); i += 1) { - if (s8_are_equal(w[i], s8_lit("XXX"))) continue; - sb8_stmtf(c, "case %S: return app_key_%S; break;", w[i], name); + { + for (mtt_iter_t it = mtt_iterate(c->arena, keys); mtt_is_valid(it); mtt_advance(&it)) { + s8_t w[] = {mtts(it, "windows1"), mtts(it, "windows2")}; + for (i32 i = 0; i < lengthof(w); i += 1) { + if (s8_are_equal(w[i], s8_lit("XXX"))) continue; + sb8_stmtf(c, "case %S: return app_key_%S; break;", w[i], mtts(it, "name")); + } } } sb8_stmtf(c, "default: {return app_key_null;} break;"); @@ -135,6 +127,8 @@ void mt_app(ma_arena_t *arena) { sb8_stmtf(c, "#endif"); } + /////////////////////////////// + // declaring app structures and generating type info { ast_t *decls = mt_parse_decls(arena, __FILE__, S8_CODE( typedef enum { diff --git a/src/meta/meta_format.c b/src/meta/meta_format.c index f25f2a1..1bdf889 100644 --- a/src/meta/meta_format.c +++ b/src/meta/meta_format.c @@ -49,8 +49,8 @@ fn s8_t s8_serial_ast_flag_t(ma_arena_t *arena, ast_flag_t flag) { return result; } -fn ast_t *mt_create_ast(parser_t *par, lex_t *pos, ast_flag_t flags) { - ast_t *result = ma_push_type(par->arena, ast_t); +fn ast_t *mt_create_ast(ma_arena_t *arena, lex_t *pos, ast_flag_t flags) { + ast_t *result = ma_push_type(arena, ast_t); memset(result, 0, sizeof(ast_t)); result->flags = flags; result->pos = pos; @@ -62,8 +62,8 @@ fn void mt_ast_append(ast_t *parent, ast_t *node) { parent->len += 1; } -fn ast_t *mt_create_ast_binary(parser_t *par, lex_t *pos, ast_t *left, lex_kind_t op, ast_t *right) { - ast_t *result = mt_create_ast(par, pos, set_bit(ast_flag_string) | set_bit(ast_flag_binary) | set_bit(ast_flag_integer)); +fn ast_t *mt_create_ast_binary(ma_arena_t *arena, lex_t *pos, ast_t *left, lex_kind_t op, ast_t *right) { + ast_t *result = mt_create_ast(arena, pos, set_bit(ast_flag_string) | set_bit(ast_flag_binary) | set_bit(ast_flag_integer)); mt_ast_append(result, left); mt_ast_append(result, right); result->integer = op; @@ -75,12 +75,12 @@ fn ast_t *mt_parse_expr(parser_t *par); fn ast_t *mt_parse_lit_expr(parser_t *par) { lex_t *token = parser_next(par); if (token->kind == lex_kind_integer) { - ast_t *result = mt_create_ast(par, token, set_bit(ast_flag_integer) | set_bit(ast_flag_string)); + ast_t *result = mt_create_ast(par->arena, token, set_bit(ast_flag_integer) | set_bit(ast_flag_string)); result->integer = token->integer; result->string = token->string; return result; } else if (token->kind == lex_kind_real) { - ast_t *result = mt_create_ast(par, token, set_bit(ast_flag_real) | set_bit(ast_flag_string)); + ast_t *result = mt_create_ast(par->arena, token, set_bit(ast_flag_real) | set_bit(ast_flag_string)); result->real = (double)token->real; result->string = token->string; return result; @@ -98,7 +98,7 @@ fn ast_t *mt_parse_mul_expr(parser_t *par) { ast_t *left = mt_parse_lit_expr(par); while (par->at->kind == lex_kind_multiply || par->at->kind == lex_kind_divide || par->at->kind == lex_kind_modulo) { lex_t *op = parser_next(par); - left = mt_create_ast_binary(par, op, left, op->kind, mt_parse_lit_expr(par)); + left = mt_create_ast_binary(par->arena, op, left, op->kind, mt_parse_lit_expr(par)); } return left; } @@ -107,7 +107,7 @@ fn ast_t *mt_parse_add_expr(parser_t *par) { ast_t *left = mt_parse_mul_expr(par); while (par->at->kind == lex_kind_plus || par->at->kind == lex_kind_minus) { lex_t *op = parser_next(par); - left = mt_create_ast_binary(par, op, left, op->kind, mt_parse_lit_expr(par)); + left = mt_create_ast_binary(par->arena, op, left, op->kind, mt_parse_lit_expr(par)); } return left; } @@ -116,7 +116,7 @@ fn ast_t *mt_parse_logical_and_expr(parser_t *par) { ast_t *left = mt_parse_add_expr(par); while (par->at->kind == lex_kind_or) { lex_t *op = parser_next(par); - left = mt_create_ast_binary(par, op, left, op->kind, mt_parse_lit_expr(par)); + left = mt_create_ast_binary(par->arena, op, left, op->kind, mt_parse_lit_expr(par)); } return left; } @@ -125,7 +125,7 @@ fn ast_t *parse_logical_or_expr(parser_t *par) { ast_t *left = mt_parse_logical_and_expr(par); while (par->at->kind == lex_kind_or) { lex_t *op = parser_next(par); - left = mt_create_ast_binary(par, op, left, op->kind, mt_parse_lit_expr(par)); + left = mt_create_ast_binary(par->arena, op, left, op->kind, mt_parse_lit_expr(par)); } return left; } @@ -193,11 +193,11 @@ fn void run_parser_test() { fn ast_t *mt_parse_struct_mem(parser_t *par, s8_t *name) { lex_t *type_name = parser_expect(par, lex_kind_ident); - ast_t *type = mt_create_ast(par, type_name, set_bit(ast_flag_type_name) | set_bit(ast_flag_string)); + ast_t *type = mt_create_ast(par->arena, type_name, set_bit(ast_flag_type_name) | set_bit(ast_flag_string)); type->string = type_name->string; while (parser_match(par, lex_kind_multiply)) { - ast_t *pointer = mt_create_ast(par, par->at, set_bit(ast_flag_type_pointer) | set_bit(ast_flag_string)); + ast_t *pointer = mt_create_ast(par->arena, par->at, set_bit(ast_flag_type_pointer) | set_bit(ast_flag_string)); mt_ast_append(pointer, type); pointer->string = s8_printf(par->arena, "%S*", type->string); type = pointer; @@ -206,7 +206,7 @@ fn ast_t *mt_parse_struct_mem(parser_t *par, s8_t *name) { *name = parser_expect(par, lex_kind_ident)->string; while (parser_match(par, lex_kind_open_bracket)) { - ast_t *array = mt_create_ast(par, par->at, set_bit(ast_flag_type_array) | set_bit(ast_flag_string)); + ast_t *array = mt_create_ast(par->arena, par->at, set_bit(ast_flag_type_array) | set_bit(ast_flag_string)); mt_ast_append(array, type); lex_t *num = parser_match(par, lex_kind_integer); if (num) { @@ -226,7 +226,7 @@ fn ast_t *mt_parse_struct_mem(parser_t *par, s8_t *name) { fn ast_t *mt_parse_decls(ma_arena_t *arena, char *file, s8_t code) { lex_array_t tokens = lex_tokens(arena, file, code); parser_t *par = parser_make(arena, tokens.data); - ast_t *result = mt_create_ast(par, par->at, set_bit(ast_flag_string)); + ast_t *result = mt_create_ast(arena, par->at, set_bit(ast_flag_string)); result->string = s8_copy_char(arena, file); for (;par->at->kind != lex_kind_eof;) { lex_t *pos = par->at; @@ -235,13 +235,13 @@ fn ast_t *mt_parse_decls(ma_arena_t *arena, char *file, s8_t code) { b32 is_typedef = !!parser_matchi(par, s8_lit("typedef")); if (is_typedef && parser_matchi(par, s8_lit("enum"))) { - ast_t *n = mt_create_ast(par, pos, set_bit(ast_flag_string) | set_bit(ast_flag_enum)); + ast_t *n = mt_create_ast(arena, pos, set_bit(ast_flag_string) | set_bit(ast_flag_enum)); mt_ast_append(result, n); parser_expect(par, lex_kind_open_brace); while (par->at->kind == lex_kind_ident) { lex_t *val = parser_expect(par, lex_kind_ident); - ast_t *mem = mt_create_ast(par, val, set_bit(ast_flag_enum_member) | set_bit(ast_flag_string)); + ast_t *mem = mt_create_ast(arena, val, set_bit(ast_flag_enum_member) | set_bit(ast_flag_string)); mem->string = val->string; mt_ast_append(n, mem); @@ -273,13 +273,13 @@ fn ast_t *mt_parse_decls(ma_arena_t *arena, char *file, s8_t code) { } if (parser_matchi(par, s8_lit("struct"))) { - ast_t *n = mt_create_ast(par, pos, set_bit(ast_flag_string) | set_bit(ast_flag_struct)); + ast_t *n = mt_create_ast(arena, pos, set_bit(ast_flag_string) | set_bit(ast_flag_struct)); mt_ast_append(result, n); n->string = parser_expect(par, lex_kind_ident)->string; parser_expect(par, lex_kind_open_brace); while (par->at->kind != lex_kind_close_brace) { - ast_t *mem = mt_create_ast(par, par->at, set_bit(ast_flag_struct_member) | set_bit(ast_flag_var) | set_bit(ast_flag_string)); + ast_t *mem = mt_create_ast(arena, par->at, set_bit(ast_flag_struct_member) | set_bit(ast_flag_var) | set_bit(ast_flag_string)); mt_ast_append(n, mem); ast_t *type = mt_parse_struct_mem(par, &mem->string); diff --git a/src/meta/meta_table_format.c b/src/meta/meta_table_format.c index 82ae4a3..7cc2840 100644 --- a/src/meta/meta_table_format.c +++ b/src/meta/meta_table_format.c @@ -1,93 +1,130 @@ -fn ast_t *mt_table_parse(ma_arena_t *arena, char *file, s8_t code) { +fn void mtt__parse_row(parser_t *par, ast_t *parent) { + parser_match(par, lex_kind_open_brace); + while (par->at->kind != lex_kind_eof) { + lex_t *token = par->at; + if (parser_match(par, lex_kind_ident) || parser_match(par, lex_kind_string)) { + ast_t *col = mt_create_ast(par->arena, par->at, set_bit(ast_flag_string)); + mt_ast_append(parent, col); + col->string = token->string; + } else if (parser_match(par, lex_kind_integer)) { + ast_t *col = mt_create_ast(par->arena, par->at, set_bit(ast_flag_string) | set_bit(ast_flag_integer)); + mt_ast_append(parent, col); + col->string = token->string; + col->integer = token->integer; + } else if (parser_match(par, lex_kind_real)) { + ast_t *col = mt_create_ast(par->arena, par->at, set_bit(ast_flag_string) | set_bit(ast_flag_real)); + mt_ast_append(parent, col); + col->string = token->string; + col->real = token->real; + } else if (parser_match(par, lex_kind_close_brace) || parser_match(par, lex_kind_eof)) { + break; + } else { + parser_panicf(par->at, "invalid token: %S", lex_kind_to_s8(par->at->kind)); + } + + if (parent->next) parent = parent->next; + } +} + +fn ast_t *mtt_parse(ma_arena_t *arena, char *file, s8_t code) { lex_array_t tokens = lex_tokens(arena, file, code); parser_t *par = parser_make(arena, tokens.data); - ast_t *table = mt_create_ast(par, par->at, 0); + ast_t *table = mt_create_ast(arena, par->at, 0); + mtt__parse_row(par, table); while (par->at->kind != lex_kind_eof) { - ast_t *row = mt_create_ast(par, par->at, 0); - mt_ast_append(table, row); - while (par->at->kind != lex_kind_eof) { - parser_match(par, lex_kind_bit_or); - - lex_t *token = par->at; - if (parser_match(par, lex_kind_ident) || parser_match(par, lex_kind_string)) { - ast_t *col = mt_create_ast(par, par->at, set_bit(ast_flag_string)); - mt_ast_append(row, col); - col->string = token->string; - } else if (parser_match(par, lex_kind_integer)) { - ast_t *col = mt_create_ast(par, par->at, set_bit(ast_flag_string) | set_bit(ast_flag_integer)); - mt_ast_append(row, col); - col->string = token->string; - col->integer = token->integer; - } else if (parser_match(par, lex_kind_real)) { - ast_t *col = mt_create_ast(par, par->at, set_bit(ast_flag_string) | set_bit(ast_flag_real)); - mt_ast_append(row, col); - col->string = token->string; - col->real = token->real; - } else if (parser_match(par, lex_kind_bit_or) || parser_match(par, lex_kind_eof)) { - break; - } else { - parser_panicf(par->at, "invalid token: %S", lex_kind_to_s8(par->at->kind)); - } - } + mtt__parse_row(par, table->first); } return table; } -fn int mt_table_find_rowi(ast_t *row, char *name) { - s8_t s = s8_from_char(name); - int i = 0; - for (ast_t *col = row->first; col; col = col->next) { - if (s8_are_equal(col->string, s)) { - return i; - } +fn ast_t *mtt_find_row(ast_t *table, char *name) { + s8_t name_string = s8_from_char(name); + for (ast_t *it = table->first; it; it = it->next) { + if (s8_are_equal(it->string, name_string)) return it; + } + return NULL; +} + +typedef struct mtt_iter_t mtt_iter_t; +struct mtt_iter_t { + ma_arena_t *arena; + ast_t **first_row; + ast_t **it; + i32 len; +}; + +fn mtt_iter_t mtt_iterate(ma_arena_t *arena, ast_t *table) { + mtt_iter_t iter = {arena}; + iter.len = table->len; + iter.first_row = ma_push_array(arena, ast_t *, iter.len); + iter.it = ma_push_array(arena, ast_t *, iter.len); + i32 i = 0; + for (ast_t *it = table->first; it; it = it->next) { + iter.it[i] = it->first; + iter.first_row[i] = it; i += 1; } - return -1; + return iter; } -fn ast_t *mt_table_get_rowi(ast_t *row, int idx) { - if (idx == -1) return NULL; +fn s8_t mttsi(mtt_iter_t iter, i32 idx) { + assert(idx >= 0 && idx < iter.len); + return iter.it[idx]->string; +} - int i = 0; - for (ast_t *col = row->first; col; col = col->next, i+=1) { - if (i == idx) return col; +fn ast_t *mtt(mtt_iter_t iter, char *name) { + s8_t name_string = s8_from_char(name); + for (i32 i = 0; i < iter.len; i += 1) { + if (s8_are_equal(iter.first_row[i]->string, name_string)) return iter.it[i]; } - return false; + return NULL; } -fn void mt_table_serial(sb8_t *c, sb8_t *h, ast_t *table, s8_t decl) { - int name_idx = mt_table_find_rowi(table->first, "name"); - int value_idx = mt_table_find_rowi(table->first, "value"); +fn s8_t mtts(mtt_iter_t iter, char *name) { + return mtt(iter, name)->string; +} +fn void mtt_advance(mtt_iter_t *iter) { + for (i32 i = 0; i < iter->len; i += 1) { + iter->it[i] = iter->it[i]->next; + } +} + +fn b32 mtt_is_valid(mtt_iter_t iter) { + b32 result = iter.it[0] != NULL; + return result; +} + +fn void mtt_serialb(sb8_t *c, sb8_t *h, ast_t *table, s8_t decl) { s8_t name_t = s8_printf(c->arena, "%S_t", decl); + /////////////////////////////// + // enum typedef sb8_printf(h, "typedef enum {\n"); - for (ast_t *row = table->first->next; row; row = row->next) { - s8_t name = mt_table_get_rowi(row, name_idx)->string; - ast_t *value = mt_table_get_rowi(row, value_idx); - sb8_printf(h, "%S_%S", decl, name); - if (value) sb8_printf(h, " = %S", value->string); + for (mtt_iter_t it = mtt_iterate(c->arena, table); mtt_is_valid(it); mtt_advance(&it)) { + sb8_printf(h, "%S_%S", decl, mtts(it, "name")); sb8_printf(h, ",\n"); } sb8_printf(h, "%S_count,\n", decl); sb8_printf(h, "} %S;\n", name_t); + /////////////////////////////// + // type info sb8_stmtf(c, "type_t type__%S = { type_kind_enum, s8_const_lit(\"%S\"), sizeof(%S),", name_t, name_t, name_t); c->indent += 1; + { + sb8_stmtf(c, ".members = (type_member_t[]){"); + c->indent += 1; + { + for (mtt_iter_t it = mtt_iterate(c->arena, table); mtt_is_valid(it); mtt_advance(&it)) { + sb8_stmtf(c, "{.name = s8_const_lit(\"%S_%S\"), .value = %S_%S},", decl, mtts(it, "name"), decl, mtts(it, "name")); + } + } + c->indent -= 1; + sb8_stmtf(c, "},"); - sb8_stmtf(c, ".members = (type_member_t[]){"); - c->indent += 1; - int item_count = 0; - for (ast_t *row = table->first->next; row; row = row->next) { - s8_t name = mt_table_get_rowi(row, name_idx)->string; - ast_t *value = mt_table_get_rowi(row, value_idx); - sb8_stmtf(c, "{.name = s8_const_lit(\"%S_%S\"), .value = %S_%S},", decl, name, decl, name); - item_count += 1; + sb8_stmtf(c, ".count = %d,", mtt_find_row(table, "name")->len); } c->indent -= 1; - sb8_stmtf(c, "},"); - - sb8_stmtf(c, ".count = %d,", item_count); - c->indent -= 1; sb8_stmtf(c, "};"); } diff --git a/src/ui/ui.meta.c b/src/ui/ui.meta.c index d20d86a..76ec47e 100644 --- a/src/ui/ui.meta.c +++ b/src/ui/ui.meta.c @@ -1,4 +1,82 @@ +void mt_test_replace(ma_arena_t *arena) { + ast_t *keys = mtt_parse(arena, __FILE__, S8_CODE( + // javascript filter out + { name js1 js2 jf windows1 windows2 } + { null XXX XXX 1 XXX XXX } + { 1 1 XXX 0 `'1'` XXX } + { 2 2 XXX 0 `'2'` XXX } + { 3 3 XXX 0 `'3'` XXX } + { 4 4 XXX 0 `'4'` XXX } + { 5 5 XXX 0 `'5'` XXX } + { 6 6 XXX 0 `'6'` XXX } + { 7 7 XXX 0 `'7'` XXX } + { 8 8 XXX 0 `'8'` XXX } + { 9 9 XXX 0 `'9'` XXX } + { 0 0 XXX 0 `'0'` XXX } + { f1 F1 XXX 1 VK_F1 XXX } + { f2 F2 XXX 1 VK_F2 XXX } + { f3 F3 XXX 1 VK_F3 XXX } + { f4 F4 XXX 1 VK_F4 XXX } + { f5 F5 XXX 1 VK_F5 XXX } + { f6 F6 XXX 1 VK_F6 XXX } + { f7 F7 XXX 1 VK_F7 XXX } + { f8 F8 XXX 1 VK_F8 XXX } + { f9 F9 XXX 1 VK_F9 XXX } + { f10 F10 XXX 1 VK_F10 XXX } + { f11 F11 XXX 1 VK_F11 XXX } + { f12 F12 XXX 1 VK_F12 XXX } + { a a XXX 0 `'A'` XXX } + { b b XXX 0 `'B'` XXX } + { c c XXX 0 `'C'` XXX } + { d d XXX 0 `'D'` XXX } + { e e XXX 0 `'E'` XXX } + { f f XXX 0 `'F'` XXX } + { g g XXX 0 `'G'` XXX } + { h h XXX 0 `'H'` XXX } + { i i XXX 0 `'I'` XXX } + { j j XXX 0 `'J'` XXX } + { k k XXX 0 `'K'` XXX } + { l l XXX 0 `'L'` XXX } + { m m XXX 0 `'M'` XXX } + { n n XXX 0 `'N'` XXX } + { o o XXX 0 `'O'` XXX } + { p p XXX 0 `'P'` XXX } + { q q XXX 0 `'Q'` XXX } + { r r XXX 0 `'R'` XXX } + { s s XXX 0 `'S'` XXX } + { _t t XXX 0 `'T'` XXX } + { u u XXX 0 `'U'` XXX } + { v v XXX 0 `'V'` XXX } + { w w XXX 0 `'W'` XXX } + { x x XXX 0 `'X'` XXX } + { y y XXX 0 `'Y'` XXX } + { z z XXX 0 `'Z'` XXX } + { space ` ` XXX 0 VK_SPACE XXX } + { enter Enter XXX 1 VK_RETURN XXX } + { escape Escape XXX 1 VK_ESCAPE XXX } + { left ArrowLeft XXX 1 VK_LEFT XXX } + { up ArrowUp XXX 1 VK_UP XXX } + { right ArrowRight XXX 1 VK_RIGHT XXX } + { down ArrowDown XXX 1 VK_DOWN XXX } + { tab Tab XXX 1 VK_TAB XXX } + { backspace Backspace XXX 1 VK_BACK XXX } + { control Control XXX 1 VK_CONTROL XXX } + { shift Shift XXX 1 VK_SHIFT XXX } + { alt Alt AltGraph 1 VK_LMENU VK_RMENU } + { meta Meta XXX 1 VK_LWIN VK_RWIN } + { caps_lock CapsLock XXX 1 VK_CAPITAL XXX } + { delete Delete XXX 1 VK_DELETE XXX } + { home Home XXX 1 VK_HOME XXX } + { end End XXX 1 VK_END XXX } + { insert Insert XXX 1 VK_NEXT XXX } + { page_up PageUp XXX 1 VK_INSERT XXX } + { page_down PageDown XXX 1 VK_PRIOR XXX } + )); + +} + void mt_ui(ma_arena_t *arena) { + mt_test_replace(arena); typedef struct mt_ui_stacks_t mt_ui_stacks_t; struct mt_ui_stacks_t { s8_t type; @@ -30,49 +108,72 @@ void mt_ui(ma_arena_t *arena) { if (!s8_starts_with(it->node, s8_lit("ui_"), false)) it->node = s8_printf(arena, "ui_%S", it->node); } - sb8_t *h_sb = sb8_serial_begin(arena); - sb8_t *c_sb = sb8_serial_begin(arena); + sb8_t *h = sb8_serial_begin(arena); + sb8_t *c = sb8_serial_begin(arena); /////////////////////////////// // generate types for (mt_ui_stacks_t *it = stacks; it < stacks + lengthof(stacks); it += 1) { for (mt_ui_stacks_t *jt = it - 1; jt >= stacks; jt -= 1) if (s8_are_equal(it->type, jt->type)) goto type_already_gened; - sb8_stmtf(h_sb, "typedef struct %S %S; struct %S { %S value; %S *next; };", it->node, it->node, it->node, it->type, it->node); + sb8_stmtf(h, "typedef struct %S %S; struct %S { %S value; %S *next; };", it->node, it->node, it->node, it->type, it->node); type_already_gened:; } - sb8_printf(h_sb, "\n"); + sb8_printf(h, "\n"); /////////////////////////////// // generate field embeds - sb8_stmtf(h_sb, "#define UI_DECL_BOX_MEMBERS \\"); + sb8_stmtf(h, "#define UI_DECL_BOX_MEMBERS \\"); for (mt_ui_stacks_t *it = stacks; it < stacks + lengthof(stacks); it += 1) { if (it->skip_box_member) continue; - sb8_stmtf(h_sb, "%S %S;\\", it->type, it->name); + sb8_stmtf(h, "%S %S;\\", it->type, it->name); } - sb8_printf(h_sb, "\n"); + sb8_printf(h, "\n"); - sb8_stmtf(h_sb, "#define UI_DECL_STACKS \\"); + sb8_stmtf(h, "#define UI_DECL_STACKS \\"); for (mt_ui_stacks_t *it = stacks; it < stacks + lengthof(stacks); it += 1) { - sb8_stmtf(h_sb, "%S *%S;\\", it->node, it->stack); + sb8_stmtf(h, "%S *%S;\\", it->node, it->stack); } - sb8_printf(h_sb, "\n"); + sb8_printf(h, "\n"); /////////////////////////////// // generate stack functions for (mt_ui_stacks_t *it = stacks; it < stacks + lengthof(stacks); it += 1) { - sb8_stmtf(c_sb, "fn void ui_push_%S(%S v) { %S *n = ma_push_type(tcx.temp, %S); n->value = v; SLLS_PUSH(ui->%S, n); }", it->name, it->type, it->node, it->node, it->stack); - sb8_stmtf(c_sb, "fn void ui_pop_%S(void) { SLLS_POP(ui->%S); }", it->name, it->stack); - sb8_stmtf(c_sb, "#define ui_set_%S(x) defer_block(ui_push_%S(x), ui_pop_%S())", it->name, it->name, it->name); + sb8_stmtf(c, "fn void ui_push_%S(%S v) { %S *n = ma_push_type(tcx.temp, %S); n->value = v; SLLS_PUSH(ui->%S, n); }", it->name, it->type, it->node, it->node, it->stack); + sb8_stmtf(c, "fn void ui_pop_%S(void) { SLLS_POP(ui->%S); }", it->name, it->stack); + sb8_stmtf(c, "#define ui_set_%S(x) defer_block(ui_push_%S(x), ui_pop_%S())", it->name, it->name, it->name); } - sb8_stmtf(c_sb, "fn void ui_assert_stacks_are_null(void) {"); + sb8_stmtf(c, "fn void ui_assert_stacks_are_null(void) {"); for (mt_ui_stacks_t *it = stacks; it < stacks + lengthof(stacks); it += 1) { - sb8_stmtf(c_sb, "assert(ui->%S == NULL);", it->stack); + sb8_stmtf(c, "assert(ui->%S == NULL);", it->stack); } - sb8_stmtf(c_sb, "}"); + sb8_stmtf(c, "}"); /////////////////////////////// // write to disk - os_write_file(mt_cpath(arena), sb8_serial_end(arena, c_sb)); - os_write_file(mt_hpath(arena), sb8_serial_end(arena, h_sb)); + os_write_file(mt_cpath(arena), sb8_serial_end(arena, c)); + os_write_file(mt_hpath(arena), sb8_serial_end(arena, h)); + + /////////////////////////////// + // idea + #if 0 + sb8_t *h = sb8_serial_begin(arena); + sb8_stmtf(h, "typedef struct node_type node_type; struct node_type { value_type value; node_type *next; };"); + + sb8_serial_end_use_template(arena, h, (variables_t){ + {"node_type", node_type_name}, + {"value_type", value_type_name}, + {0}. + }); + + /// + + variables_t vars = serial_vars_from_struct(it, type(mt_ui_stacks_t)); + sb8_tmplf(h, "typedef struct node_type node_type; struct node_type { value_type value; node_type *next; };", vars); + + //// + + sb8_stmtf(h, "typedef struct node_type node_type; struct node_type { value_type value; node_type *next; };", vars); + + #endif } \ No newline at end of file diff --git a/src/wasm_app/wasm_app.meta.c b/src/wasm_app/wasm_app.meta.c index c922bb1..de297c8 100644 --- a/src/wasm_app/wasm_app.meta.c +++ b/src/wasm_app/wasm_app.meta.c @@ -1,17 +1,17 @@ -typedef struct cg_tweak_t cg_tweak_t; -struct cg_tweak_t { - cg_tweak_t *next; - type_t *type; - s8_t name; - s8_t value; - s8_t min, max; -}; - void mt_wasm_app(ma_arena_t *arena) { sb8_t *include_paths = sb8(arena); sb8_append(include_paths, OS_GetAbsolutePath(&Perm, s8_lit("../src"))); mt_files_t files = mt_lex_files(arena, s8_lit("../src/wasm_app/main.c"), include_paths); + typedef struct cg_tweak_t cg_tweak_t; + struct cg_tweak_t { + cg_tweak_t *next; + type_t *type; + s8_t name; + s8_t value; + s8_t min, max; + }; + cg_tweak_t *first_tweak = NULL; cg_tweak_t *last_tweak = NULL; diff --git a/todo.txt b/todo.txt index 93c019e..5418303 100644 --- a/todo.txt +++ b/todo.txt @@ -1,8 +1,7 @@ [ ] app - [ ] ui [ ] event playback [ ] win32 - [ ] sleep + [x] sleep [ ] hot reload / plugins [ ] tests using yield [ ] touchpad gestures: https://learn.microsoft.com/en-us/windows/win32/wintouch/windows-touch-gestures-overview @@ -19,9 +18,18 @@ [ ] revisit api [x] change name, hard to type +[ ] ui + [ ] text input + [ ] color picker + [ ] slider + [ ] custom image as part of design + [ ] demo with different buttons and controls, headings + + [ ] core [x] remove dates and time from core [ ] meta + [ ] prototype something like templates, readable string generation [x] search for python snippets and execute meta.py script on that file [x] simplify logging!!!! [x] somehow index properly the meta files and ignore generated files