From cf7e2492fd07b598c59ef2e4e6c229c21223e410 Mon Sep 17 00:00:00 2001 From: luboslenco Date: Mon, 29 Jun 2026 13:54:17 +0200 Subject: [PATCH] minic: add minic_register_global --- base/sources/libs/minic.c | 70 ++++++++++++++++++++++++++++++++------- base/sources/libs/minic.h | 17 ++++++---- 2 files changed, 68 insertions(+), 19 deletions(-) diff --git a/base/sources/libs/minic.c b/base/sources/libs/minic.c index 097adb16..ecee14d1 100644 --- a/base/sources/libs/minic.c +++ b/base/sources/libs/minic.c @@ -16,18 +16,19 @@ // ██║ ╚██████╔╝██║ ██╗███████╗██║ ╚████║ // ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═══╝ -#define MINIC_TOK_LIST \ - X(TOK_INT, "'int'") \ - X(TOK_FLOAT, "'float'") \ - X(TOK_CHAR, "'char'") X(TOK_DOUBLE, "'double'") X(TOK_BOOL, "'bool'") X(TOK_RETURN, "'return'") X(TOK_IF, "'if'") X(TOK_ELSE, "'else'") \ - X(TOK_WHILE, "'while'") X(TOK_FOR, "'for'") X(TOK_BREAK, "'break'") X(TOK_CONTINUE, "'continue'") X(TOK_STRUCT, "'struct'") \ - X(TOK_TYPEDEF, "'typedef'") X(TOK_ENUM, "'enum'") X(TOK_VOID, "'void'") X(TOK_IDENT, "identifier") X(TOK_NUMBER, "number") \ - X(TOK_CHAR_LIT, "char literal") X(TOK_STR_LIT, "string literal") X(TOK_LPAREN, "'('") X(TOK_RPAREN, "')'") X(TOK_LBRACE, "'{'") \ - X(TOK_RBRACE, "'}'") X(TOK_LBRACKET, "'['") X(TOK_RBRACKET, "']'") X(TOK_SEMICOLON, "';'") X(TOK_COMMA, "','") X(TOK_ASSIGN, "'='") \ - X(TOK_PLUS_ASSIGN, "'+='") X(TOK_MINUS_ASSIGN, "'-='") X(TOK_MUL_ASSIGN, "'*='") X(TOK_DIV_ASSIGN, "'/='") X(TOK_EQ, "'=='") \ - X(TOK_NEQ, "'!='") X(TOK_LT, "'<'") X(TOK_GT, "'>'") X(TOK_LE, "'<='") X(TOK_GE, "'>='") X(TOK_AND, "'&&'") X(TOK_OR, "'||'") \ - X(TOK_NOT, "'!'") X(TOK_AMP, "'&'") X(TOK_PLUS, "'+'") X(TOK_MINUS, "'-'") X(TOK_INC, "'++'") X(TOK_DEC, "'--'") \ - X(TOK_STAR, "'*'") X(TOK_SLASH, "'/'") X(TOK_DOT, "'.'") X(TOK_ARROW, "'->'") X(TOK_EOF, "end of file") +#define MINIC_TOK_LIST \ + X(TOK_INT, "'int'") \ + X(TOK_FLOAT, "'float'") \ + X(TOK_CHAR, "'char'") \ + X(TOK_DOUBLE, "'double'") X(TOK_BOOL, "'bool'") X(TOK_RETURN, "'return'") X(TOK_IF, "'if'") X(TOK_ELSE, "'else'") X(TOK_WHILE, "'while'") \ + X(TOK_FOR, "'for'") X(TOK_BREAK, "'break'") X(TOK_CONTINUE, "'continue'") X(TOK_STRUCT, "'struct'") X(TOK_TYPEDEF, "'typedef'") X(TOK_ENUM, "'enum'") \ + X(TOK_VOID, "'void'") X(TOK_IDENT, "identifier") X(TOK_NUMBER, "number") X(TOK_CHAR_LIT, "char literal") X(TOK_STR_LIT, "string literal") \ + X(TOK_LPAREN, "'('") X(TOK_RPAREN, "')'") X(TOK_LBRACE, "'{'") X(TOK_RBRACE, "'}'") X(TOK_LBRACKET, "'['") X(TOK_RBRACKET, "']'") \ + X(TOK_SEMICOLON, "';'") X(TOK_COMMA, "','") X(TOK_ASSIGN, "'='") X(TOK_PLUS_ASSIGN, "'+='") X(TOK_MINUS_ASSIGN, "'-='") \ + X(TOK_MUL_ASSIGN, "'*='") X(TOK_DIV_ASSIGN, "'/='") X(TOK_EQ, "'=='") X(TOK_NEQ, "'!='") X(TOK_LT, "'<'") X(TOK_GT, "'>'") \ + X(TOK_LE, "'<='") X(TOK_GE, "'>='") X(TOK_AND, "'&&'") X(TOK_OR, "'||'") X(TOK_NOT, "'!'") X(TOK_AMP, "'&'") X(TOK_PLUS, "'+'") \ + X(TOK_MINUS, "'-'") X(TOK_INC, "'++'") X(TOK_DEC, "'--'") X(TOK_STAR, "'*'") X(TOK_SLASH, "'/'") X(TOK_DOT, "'.'") \ + X(TOK_ARROW, "'->'") X(TOK_EOF, "end of file") typedef enum { #define X(t, s) t, @@ -970,6 +971,11 @@ static minic_val_t minic_parse_primary(minic_env_t *e) { if (ec >= 0) { return minic_val_int(ec); } + // Check for a registered host global + minic_val_t gv; + if (minic_var_find(e, name) == NULL && minic_global_get(name, &gv)) { + return gv; + } return minic_var_get(e, name); } if (e->lex.cur.type == TOK_LPAREN) { @@ -1917,12 +1923,20 @@ typedef struct { int value; } minic_enum_const_t; +typedef struct { + char name[MINIC_MAX_NAME]; + const void *ptr; // points at the live host variable + minic_type_t type; // MINIC_T_INT or MINIC_T_FLOAT +} minic_global_t; + static minic_ext_func_t minic_ext_funcs[MINIC_MAX_EXTFUNS]; static int minic_ext_func_count = 0; static minic_enum_const_t minic_enum_consts[MINIC_MAX_ENUM_CONSTS]; static int minic_enum_const_count = 0; static char minic_int_typedefs[MINIC_MAX_INT_TYPEDEFS][MINIC_MAX_NAME]; static int minic_int_typedef_count = 0; +static minic_global_t minic_globals[MINIC_MAX_GLOBALS]; +static int minic_global_count = 0; minic_struct_t minic_structs[MINIC_MAX_STRUCTS]; int minic_struct_count = 0; @@ -1995,6 +2009,38 @@ int minic_enum_const_get(const char *name) { return -1; } +void minic_register_global(const char *name, const void *ptr, minic_type_t type) { + for (int i = 0; i < minic_global_count; ++i) { + if (strcmp(minic_globals[i].name, name) == 0) { + minic_globals[i].ptr = ptr; + minic_globals[i].type = type; + return; + } + } + if (minic_global_count >= MINIC_MAX_GLOBALS) { + return; + } + strncpy(minic_globals[minic_global_count].name, name, MINIC_MAX_NAME - 1); + minic_globals[minic_global_count].ptr = ptr; + minic_globals[minic_global_count].type = type; + minic_global_count++; +} + +bool minic_global_get(const char *name, minic_val_t *out) { + for (int i = 0; i < minic_global_count; ++i) { + if (strcmp(minic_globals[i].name, name) == 0) { + if (minic_globals[i].type == MINIC_T_FLOAT) { + *out = minic_val_float(*(const float *)minic_globals[i].ptr); + } + else { + *out = minic_val_int(*(const int *)minic_globals[i].ptr); + } + return true; + } + } + return false; +} + void minic_int_typedef_add(const char *name) { if (minic_is_int_typedef(name) || minic_int_typedef_count >= MINIC_MAX_INT_TYPEDEFS) { return; diff --git a/base/sources/libs/minic.h b/base/sources/libs/minic.h index 46b93423..7285a39b 100644 --- a/base/sources/libs/minic.h +++ b/base/sources/libs/minic.h @@ -12,6 +12,7 @@ #define MINIC_MAX_INT_TYPEDEFS 128 #define MINIC_MAX_STRUCT_FIELDS 32 #define MINIC_MAX_STRUCTS 64 +#define MINIC_MAX_GLOBALS 64 #define MINIC_MAX_NAME 64 typedef unsigned char minic_u8; @@ -83,10 +84,11 @@ void minic_register(const char *name, const char *sig, minic_ext_fn_raw_t fn); / void minic_register_native(const char *name, minic_native_fn_t fn); void minic_struct_begin(const char *name, int size); void minic_struct_field(const char *field, int offset, minic_type_t type, minic_type_t deref_type, const char *struct_type); -void minic_register_struct(const char *name, const char **fields, int field_count); // script-layout struct (boxed fields) +void minic_register_struct(const char *name, const char **fields, int field_count); // script-layout struct (boxed fields) void minic_register_enum(const char *typedef_name, const char **names, const int *values, int count); // values NULL = 0,1,2... void minic_enum_const_add(const char *name, int value); void minic_int_typedef_add(const char *name); +void minic_register_global(const char *name, const void *ptr, minic_type_t type); void minic_register_builtins(void); // Registry lookups (used by the interpreter) @@ -94,11 +96,12 @@ minic_ext_func_t *minic_ext_func_get(const char *name); minic_val_t minic_dispatch(minic_ext_func_t *ef, minic_val_t *args, int argc); int minic_enum_const_get(const char *name); // -1 if unknown bool minic_is_int_typedef(const char *name); +bool minic_global_get(const char *name, minic_val_t *out); // false if unknown // Native struct registration helpers: // MINIC_STRUCT(my_t); MINIC_I(count); MINIC_S(name); MINIC_O(child, other_t); MINIC_END(); -#define MINIC_STRUCT(T) \ - { \ +#define MINIC_STRUCT(T) \ + { \ typedef T minic_st_t; \ minic_struct_begin(#T, (int)sizeof(minic_st_t)) #define MINIC_FIELD(f, t, dt, s) minic_struct_field(#f, (int)offsetof(minic_st_t, f), t, dt, s) @@ -109,13 +112,13 @@ bool minic_is_int_typedef(const char *name); #define MINIC_P(f) MINIC_FIELD(f, MINIC_T_PTR, MINIC_T_PTR, NULL) // untyped pointer #define MINIC_O(f, T2) MINIC_FIELD(f, MINIC_T_PTR, MINIC_T_PTR, #T2) // pointer to struct T2 #define MINIC_E(f, T2) MINIC_FIELD(f, MINIC_T_EMBED, MINIC_T_PTR, #T2) // embedded struct T2 -#define MINIC_END() } +#define MINIC_END() } // Enum registration helper (sequential values starting at 0): // MINIC_ENUM("my_enum_t", "MY_A", "MY_B", "MY_C"); -#define MINIC_ENUM(T, ...) \ - do { \ - static const char *_minic_names[] = {__VA_ARGS__}; \ +#define MINIC_ENUM(T, ...) \ + do { \ + static const char *_minic_names[] = {__VA_ARGS__}; \ minic_register_enum(T, _minic_names, NULL, (int)(sizeof(_minic_names) / sizeof(_minic_names[0]))); \ } while (0)