minic: add minic_register_global

This commit is contained in:
luboslenco
2026-06-29 13:54:17 +02:00
parent 198f717cce
commit cf7e2492fd
2 changed files with 68 additions and 19 deletions
+58 -12
View File
@@ -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;
+10 -7
View File
@@ -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)