#ifndef CVM_CORE_H
#define CVM_CORE_H

#include <stddef.h>
#include <stdint.h>              /* int64_t 等 */
#include <string.h>              /* memcpy */
#include <math.h>                /* isnan */

/* =========================================================================
 * cvmruntime — 米特-木卫三协议状态机运行时
 * 协议状态机 (ProtoState) 扩展: 为 XL-MD-001 演习 / 六万旅级节点网络
 * 提供事件驱动的状态转换能力
 * ========================================================================= */

typedef struct Runtime Runtime;   /* 前向声明, 供数组 API 等前置使用 */

/* 模块加载深度上限与路径缓冲大小 */
#define CVM_MAX_LOAD_DEPTH 48
#define CVM_MAX_LOAD_PATH  768

/* 调用栈深度上限 (防 C 栈溢出) */
#define CVM_MAX_CALL_DEPTH 2048

/* =========================================================================
 * cvmruntime — 一门 C 风格脚本语言的纯 C 解释器运行时
 * 架构: lexer -> parser -> AST -> 树遍历解释器 + 环境帧 + 宿主API + FFI
 * 零外部依赖 (仅标准库 + 平台动态库 API), 编译: gcc -Wall -Werror -std=c11
 * ========================================================================= */

/* ----------------------------- Arena 内存 ------------------------------ */
typedef struct ArenaBlock {
    unsigned char     *data;
    size_t             size;
    size_t             used;
    struct ArenaBlock *next;
} ArenaBlock;

typedef struct {
    ArenaBlock *head;
    size_t      block_size;
    size_t      gc_bytes;
    size_t      gc_threshold;
} Arena;

void  arena_init(Arena *a);
void  arena_destroy(Arena *a);
void *arena_alloc(Arena *a, size_t n);
char *arena_strndup(Arena *a, const char *s, size_t n);
char *arena_strdup(Arena *a, const char *s);
void  arena_reset(Arena *a); /* 释放所有 block, 保留结构体本身 */
void  gc_collect(Runtime *rt);

/* --------------------------- 值系统 (tagged union) --------------------------- */
/* Value = 带类型标签的联合体, 简单直接, 兼容所有平台 */
#define VAL_NUM 1
#define VAL_STR 2
#define VAL_BOOL 3
#define VAL_NIL 4
#define VAL_INT 5
#define VAL_ARRAY 6
#define VAL_FUNC 7
#define VAL_PTR 8
#define VAL_MODULE 9
#define VAL_CLOSURE 10

typedef struct {
    int type;
    union {
        double   num;
        char    *str;
        int      boolean;
        int64_t  i;
        void    *arr;
        char    *funcname;
        void    *mod;
        void    *closure;
        void    *ptr;
    } as;
} Value;

/* ---- 构造 (内联) ---- */
static inline Value val_num(double n)      { Value v; v.type = VAL_NUM; v.as.num = n; return v; }
static inline Value val_str(char *s)       { Value v; v.type = VAL_STR; v.as.str = s; return v; }
static inline Value val_bool(int b)        { Value v; v.type = VAL_BOOL; v.as.boolean = b ? 1 : 0; return v; }
static inline Value val_nil(void)          { Value v; v.type = VAL_NIL; return v; }
static inline Value val_module(void *m)    { Value v; v.type = VAL_MODULE; v.as.mod = m; return v; }
static inline Value val_func(char *name)   { Value v; v.type = VAL_FUNC; v.as.funcname = name; return v; }
static inline Value val_array(void *arr)   { Value v; v.type = VAL_ARRAY; v.as.arr = arr; return v; }
static inline Value val_closure(void *cl)  { Value v; v.type = VAL_CLOSURE; v.as.closure = cl; return v; }
static inline Value val_ptr(void *p)       { Value v; v.type = VAL_PTR; v.as.ptr = p; return v; }
static inline Value val_int(int64_t n)     { Value v; v.type = VAL_INT; v.as.i = n; return v; }

/* ---- 类型检测 ---- */
static inline int v_is_int(Value v)    { return v.type == VAL_INT; }
static inline int v_is_num(Value v)    { return v.type == VAL_NUM; }
static inline int v_is_nil(Value v)    { return v.type == VAL_NIL; }
static inline int v_is_bool(Value v)   { return v.type == VAL_BOOL; }
static inline int v_is_str(Value v)    { return v.type == VAL_STR; }
static inline int v_is_array(Value v)  { return v.type == VAL_ARRAY; }
static inline int v_is_func(Value v)   { return v.type == VAL_FUNC; }
static inline int v_is_ptr(Value v)    { return v.type == VAL_PTR; }
static inline int v_is_closure(Value v){ return v.type == VAL_CLOSURE; }
static inline int v_is_module(Value v) { return v.type == VAL_MODULE; }

/* ---- 取值 ---- */
static inline double  v_as_double(Value v) { return v.as.num; }
static inline int64_t v_as_int(Value v)    { return v.as.i; }
static inline int     v_as_bool(Value v)   { return v.as.boolean; }
static inline char   *v_as_str(Value v)    { return v.as.str; }
static inline void   *v_as_ptr(Value v)    { return v.as.ptr; }

/* ---- 类型枚举 ---- */
static inline int v_type(Value v) { return v.type; }

/* 为 VAL_PTR 增加指针载体, 协议状态机/FFI 使用 */
static inline Value val_ptr_obj(void *p) { Value v; v.type = VAL_PTR; v.as.ptr = p; return v; }

int          val_truthy(Value v);
int          value_equal(Value a, Value b, int depth); /* 结构相等, depth 防无限递归 */
const char  *val_type_name(Value v);
char        *val_to_str(Arena *a, Value v); /* 结果分配在 arena */

/* --------------------------- UTF-8 码点辅助 --------------------------- */
/* 纯函数, 可同时被 cvm_host.c(内置) 与 cvm_interp.c(下标) 复用。
 * 约定: 非法/截断字节一律按单字节处理, 不抛出、不越界读。 */

/* 返回以 c 开头的 UTF-8 序列字节长 (1..4), 非法字节归 1 */
static inline int utf8_seq_len(unsigned char c) {
    if (c < 0x80) return 1;
    if ((c & 0xE0) == 0xC0) return 2;
    if ((c & 0xF0) == 0xE0) return 3;
    if ((c & 0xF8) == 0xF0) return 4;
    return 1;
}

/* 统计字符串的 Unicode 码点数 (区别于 len 的字节数)。
 * 硬化: 多字节首字节承诺 len 字节, 但只计入真正连续且合法的续延字节,
 * 遇到 NUL 或非法续延字节即止。对合法 UTF-8 结果不变; 截断/损坏串不再越过 NUL。 */
static inline long utf8_count_codepoints(const char *s) {
    if (!s) return 0;
    long n = 0;
    const unsigned char *p = (const unsigned char *)s;
    while (*p) {
        int len = utf8_seq_len(*p);
        int actual = 1;   /* 首字节有效; 续延字节需逐个校验 */
        for (int k = 1; k < len; k++) {
            if (p[k] == '\0' || (p[k] & 0xC0) != 0x80) break;
            actual = k + 1;
        }
        p += actual; n++;
    }
    return n;
}

/* 取第 idx 个码点的字节起点指针 (idx 从 0 计)。
 * idx 越界返回 NULL, 并通过 outlen 写出该码点"实际有效"字节长(越界时 0)。
 * 硬化: outlen = 真正连续的合法字节数(截断串为其实际长度, 而非承诺长度),
 * 调用方据此复制不会越过 NUL 读垃圾字节。 */
static inline const char *utf8_char_at_ptr(const char *s, long idx, int *outlen) {
    if (outlen) *outlen = 0;
    if (!s || idx < 0) return NULL;
    const unsigned char *p = (const unsigned char *)s;
    long i = 0;
    while (*p) {
        int len = utf8_seq_len(*p);
        int actual = 1;
        for (int k = 1; k < len; k++) {
            if (p[k] == '\0' || (p[k] & 0xC0) != 0x80) break;
            actual = k + 1;
        }
        if (i == idx) { if (outlen) *outlen = actual; return (const char *)p; }
        p += actual; i++;
    }
    return NULL;
}

/* 取第 idx 个码点的 Unicode 标量值; 越界返回 -1。
 * 硬化: 若序列被截断/损坏(实际字节 < 承诺长度), 降级返回首字节原值,
 * 而非越界拼出乱码; 完整序列仍按 UTF-8 精确解码。 */
static inline int64_t utf8_codepoint_at(const char *s, long idx) {
    int len;
    const char *p = utf8_char_at_ptr(s, idx, &len);
    if (!p) return -1;
    const unsigned char *u = (const unsigned char *)p;
    if (len < utf8_seq_len(u[0])) return (int64_t)u[0]; /* 截断/损坏: 首字节降级 */
    switch (len) {
        case 1: return (int64_t)u[0];
        case 2: return (int64_t)(((u[0] & 0x1F) << 6)  | (u[1] & 0x3F));
        case 3: return (int64_t)(((u[0] & 0x0F) << 12) | ((u[1] & 0x3F) << 6) | (u[2] & 0x3F));
        case 4: return (int64_t)(((u[0] & 0x07) << 18) | ((u[1] & 0x3F) << 12) | ((u[2] & 0x3F) << 6) | (u[3] & 0x3F));
        default: return -1;
    }
}

/* ---- 将 Unicode 码点编码为 UTF-8 (输出 1~4 字节) ---- */
static inline int utf8_encode(int64_t cp, char out[4]) {
    if (cp < 0x80)      { out[0] = (char)cp; return 1; }
    if (cp < 0x800)     { out[0] = (char)(0xC0 | (cp >> 6));
                          out[1] = (char)(0x80 | (cp & 0x3F)); return 2; }
    if (cp < 0x10000)   { out[0] = (char)(0xE0 | (cp >> 12));
                          out[1] = (char)(0x80 | ((cp >> 6) & 0x3F));
                          out[2] = (char)(0x80 | (cp & 0x3F)); return 3; }
    out[0] = (char)(0xF0 | (cp >> 18));
    out[1] = (char)(0x80 | ((cp >> 12) & 0x3F));
    out[2] = (char)(0x80 | ((cp >> 6) & 0x3F));
    out[3] = (char)(0x80 | (cp & 0x3F));
    return 4;
}

/* ---- Unicode 大小写折叠 (Latin-1 / 希腊 / 西里尔, 零依赖) ----
 * to_upper=1 则返回大写, =0 则返回小写; 未知字符返回原值 */
static inline int64_t unicode_casefold(int64_t cp, int to_upper) {
    /* ASCII: 标准规则 */
    if (cp <= 0x7F) {
        if (to_upper) { if (cp >= 'a' && cp <= 'z') return cp - 32; }
        else          { if (cp >= 'A' && cp <= 'Z') return cp + 32; }
        return cp;
    }
    if (to_upper) {
        /* Latin-1 Supplement 小写→大写 */
        if (cp >= 0xE0 && cp <= 0xF6) return cp - 0x20;  /* à-ö → À-Ö */
        if (cp >= 0xF8 && cp <= 0xFE) return cp - 0x20;  /* ø-þ → Ø-Þ */
        if (cp == 0xFF)               return 0x178;       /* ÿ → Ÿ */
        /* Greek 小写→大写 (基础字母) */
        if (cp >= 0x3B1 && cp <= 0x3C1) return cp - 0x20; /* α-ρ → Α-Ρ */
        if (cp >= 0x3C3 && cp <= 0x3CB) return cp - 0x20; /* σ-ϋ → Σ-Ϋ */
        if (cp == 0x3C2)                 return 0x3A3;    /* ς(词尾) → Σ */
        /* Greek 重音小写→大写 (不规则偏移) */
        switch (cp) {
            case 0x3AC: return 0x386; /* ά → Ά */
            case 0x3AD: return 0x388; /* έ → Έ */
            case 0x3AE: return 0x389; /* ή → Ή */
            case 0x3AF: return 0x38A; /* ί → Ί */
            case 0x3CC: return 0x38C; /* ό → Ό */
            case 0x3CD: return 0x38E; /* ύ → Ύ */
            case 0x3CE: return 0x38F; /* ώ → Ώ */
        }
        /* Cyrillic 小写→大写 */
        if (cp >= 0x430 && cp <= 0x44F) return cp - 0x20; /* а-я → А-Я */
        if (cp >= 0x450 && cp <= 0x45F) return cp - 0x50; /* ѐ-џ → Ѐ-Џ */
    } else {
        /* Latin-1 Supplement 大写→小写 */
        if (cp >= 0xC0 && cp <= 0xD6) return cp + 0x20;  /* À-Ö → à-ö */
        if (cp >= 0xD8 && cp <= 0xDE) return cp + 0x20;  /* Ø-Þ → ø-þ */
        if (cp == 0x178)              return 0xFF;        /* Ÿ → ÿ */
        /* Greek 大写→小写 (基础字母) */
        if (cp >= 0x391 && cp <= 0x3A1) return cp + 0x20; /* Α-Ρ → α-ρ */
        if (cp >= 0x3A3 && cp <= 0x3AB) return cp + 0x20; /* Σ-Ϋ → σ-ϋ */
        /* Greek 重音大写→小写 */
        switch (cp) {
            case 0x386: return 0x3AC; /* Ά → ά */
            case 0x388: return 0x3AD; /* Έ → έ */
            case 0x389: return 0x3AE; /* Ή → ή */
            case 0x38A: return 0x3AF; /* Ί → ί */
            case 0x38C: return 0x3CC; /* Ό → ό */
            case 0x38E: return 0x3CD; /* Ύ → ύ */
            case 0x38F: return 0x3CE; /* Ώ → ώ */
        }
        /* Cyrillic 大写→小写 */
        if (cp >= 0x410 && cp <= 0x42F) return cp + 0x20; /* А-Я → а-я */
        if (cp >= 0x400 && cp <= 0x40F) return cp + 0x50; /* Ѐ-Џ → ѐ-џ */
    }
    return cp; /* 未知块保持不变 */
}

/* --------------------------- 通用字符串映射 --------------------------- */
typedef struct MapNode {
    char            *key;
    void            *value;
    struct MapNode  *next;
} MapNode;

typedef struct {
    MapNode **buckets;
    int       cap;
    int       count;
} Map;

void  map_init(Map *m);
void  map_destroy(Map *m);                    /* 释放节点与 key, 不释放 value */
void  map_set(Map *m, const char *key, void *value);
void *map_get(Map *m, const char *key);       /* 不存在返回 NULL */

/* --------------------- 有序关联数组 (PHP 风格) ----------------------- */
/* 一个类型同时充当 list(整数键 0..n-1) 与 map(字符串键), 保留插入顺序。
 * 数组按引用语义共享(类似 Lua table / Python list)。数据分配在 arena,
 * 随运行时销毁, 运行期不单独释放。 */
typedef struct ArrEntry {
    int            is_str;   /* 1: 字符串键(skey); 0: 整数键(ikey) */
    char          *skey;     /* 仅 is_str 时有效, 指向 arena 内稳定字符串 */
    int64_t        ikey;     /* 仅 !is_str 时有效 (int64, 支持大整数键) */
    Value          value;
    struct ArrEntry *hnext;   /* 同一 hash 桶的链 */
} ArrEntry;

typedef struct {
    ArrEntry     **buckets;
    int            cap;       /* 桶数量 */
    int            count;     /* 元素个数 */
    ArrEntry     **order;     /* 插入顺序, order[0..count-1] */
    int            order_cap;
    int64_t        next_ikey; /* 下一次自动整数键(用于 append) */
} Arr;

void  arr_init(Arena *a, Arr *arr);
void  arr_set(Arena *a, Arr *arr, int is_str, const char *skey, int64_t ikey, Value v);
void  arr_append(Arena *a, Arr *arr, Value v);          /* 追加到末尾(整数键) */
void  arr_set_from_key(Runtime *rt, Arr *arr, Value key, Value v); /* 按值推断键 */
ArrEntry *arr_lookup(Runtime *rt, Arr *arr, Value key);  /* 不存在返回 NULL */
ArrEntry *arr_find(int is_str, const char *skey, int64_t ikey, const Arr *arr); /* 无错误版查找 */
int   arr_del(Arr *arr, Value key);                      /* 成功 1 / 不存在 0 */
int   arr_len(const Arr *arr);
ArrEntry *arr_at(const Arr *arr, int idx);              /* 按插入顺序取第 idx 项 */
Arr  *arr_copy(Arena *a, const Arr *src);               /* 浅拷贝(嵌套共享) */
Arr  *arr_keys(Arena *a, const Arr *src);               /* 新数组: 键的列表 */
Arr  *arr_values(Arena *a, const Arr *src);             /* 新数组: 值的列表 */
int   arr_equal(const Arr *x, const Arr *y);            /* 结构相等(递归) */

/* ------------------------------- 环境 --------------------------------- */
typedef struct Env Env;
struct Env { Env *parent; Map vars; };
typedef struct Runtime Runtime;   /* 前向声明, 供模块系统等前置声明使用 */

Env *env_new(Env *parent, Arena *a);
void  env_free(Env *e);                       /* 释放本帧 map (不递归父帧) */
Value *env_get(Env *e, const char *name);     /* 沿 parent 链查找, 无则 NULL */
void   env_define(Env *e, const char *name, Value v, Arena *a); /* 当前作用域 */
void   env_assign(Env *e, const char *name, Value v, Arena *a); /* 向上找, 无则定义 */
Env   *env_get_owner(Env *e, const char *name, Value **out);   /* 返回拥有该名的 Env*, out 出参值指针 */
Env   *env_root(Env *e);                                       /* 返回环境链的根 (最外层) */
void   env_link(Env *e, const char *name, Value *slot);        /* 将已有 Value* 槽直接塞入环境 (不复制) */

/* ------------------------------- 词法 --------------------------------- */
enum {
    TK_EOF = 0,
    TK_NUM, TK_STR, TK_IDENT,
    TK_LET, TK_IF, TK_ELSE, TK_WHILE, TK_FOR, TK_FUNC, TK_RETURN,
    TK_BREAK, TK_CONTINUE,
    TK_TRUE, TK_FALSE, TK_NIL,
    TK_AND, TK_OR, TK_NOT,
    TK_EQEQ, TK_NOTEQ, TK_LE, TK_GE, TK_LT, TK_GT,
    TK_ASSIGN,
    TK_PLUS, TK_MINUS, TK_STAR, TK_SLASH, TK_PERCENT,
    TK_LPAREN, TK_RPAREN, TK_LBRACE, TK_RBRACE, TK_SEMI, TK_COMMA,
    TK_LBRACKET, TK_RBRACKET, TK_COLON,
    TK_DOT,
    TK_IN,
    TK_TRY, TK_CATCH, TK_FINALLY, TK_THROW
};

typedef struct {
    int    type;
    char  *text;   /* 词素, arena 拥有 */
    double num;
    int    is_int; /* 1: 整数词素 (inum 有效); 0: 浮点词素 (num 有效) */
    int64_t inum;  /* 整数词素的 int64 值 */
    int    line;
} Token;

typedef struct {
    Token *tokens;
    int    count;
    int    cap;
} TokenList;

TokenList lex(Arena *a, const char *src, char *err, size_t errsz);

/* ------------------------------- AST ---------------------------------- */
typedef struct Expr Expr;
typedef struct Stmt Stmt;

enum {
    EXPR_NUM, EXPR_STR, EXPR_BOOL, EXPR_NIL,
    EXPR_VAR, EXPR_UNARY, EXPR_BINARY, EXPR_CALL, EXPR_ASSIGN, EXPR_MEMBER,
    EXPR_INDEX, EXPR_INDEX_ASSIGN, EXPR_ARRAY, EXPR_LAMBDA
};
enum {
    STMT_LET, STMT_ASSIGN, STMT_IF, STMT_WHILE, STMT_FOR, STMT_FOR_IN,
    STMT_RETURN, STMT_BREAK, STMT_CONTINUE,
    STMT_BLOCK, STMT_FUNC, STMT_EXPR,
    STMT_TRY, STMT_THROW
};

struct Expr {
    int kind;
    int line;
    union {
        struct { int is_int; int64_t ival; double fval; } numlit; /* EXPR_NUM: 真 int64 字面量 */
        char   *str;
        int     boolean;
        char   *name;
        struct { int op; Expr *inner; }              unary;
        struct { int op; Expr *left; Expr *right; }   binary;
        struct { Expr *callee; Expr **args; int argc; } call;
        struct { char *name; Expr *value; }          assign;
        struct { Expr *obj; char *name; }            member;
        struct { Expr *obj; Expr *index; }           idx;       /* a[i] 读取 */
        struct { Expr *target; Expr *value; }        index_assign; /* a[i] = v */
        struct { Expr **keys; Expr **vals; int *haskey; int count; } array; /* [..] */
        Stmt *lambda;       /* EXPR_LAMBDA: 匿名函数体 */
    } u;
};

struct Stmt {
    int kind;
    int line;
    union {
        struct { char *name; Expr *init; }                let;
        struct { char *name; Expr *value; }                assign;
        struct { Expr *cond; Stmt *then_b; Stmt *else_b; } ifs;
        struct { Expr *cond; Stmt *body; }                whiles;
        struct { Stmt *init; Expr *cond; Expr *step; Stmt *body; } fors;
        struct { char *iter_var; Expr *iterable; Stmt *body; } for_in;
        struct { Expr *value; }                           returns;
        struct { Stmt **stmts; int count; }               block;
        struct { char *name; char **params; int pcount; char **freevars; int freecount; Stmt *body; } func;
        struct { Stmt *body; char *catchvar; Stmt *catchbody; Stmt *finallybody; } trys;
        struct { Expr *value; } throws;
        Expr *expr;
    } u;
};

/* AST 构造器 (分配在 arena) */
Expr *expr_num(Arena *a, int is_int, int64_t ival, double fval, int line);
Expr *expr_str(Arena *a, char *s, int line);
Expr *expr_bool(Arena *a, int b, int line);
Expr *expr_nil(Arena *a, int line);
Expr *expr_var(Arena *a, char *name, int line);
Expr *expr_unary(Arena *a, int op, Expr *inner, int line);
Expr *expr_binary(Arena *a, int op, Expr *l, Expr *r, int line);
Expr *expr_call(Arena *a, Expr *callee, Expr **args, int argc, int line);
Expr *expr_member(Arena *a, Expr *obj, char *name, int line);
Expr *expr_assign(Arena *a, char *name, Expr *value, int line);
Expr *expr_index(Arena *a, Expr *obj, Expr *index, int line);
Expr *expr_index_assign(Arena *a, Expr *target, Expr *value, int line);
Expr *expr_array(Arena *a, Expr **keys, Expr **vals, int *haskey, int count, int line);
Expr *expr_lambda(Arena *a, Stmt *funcDef, int line);
Stmt *stmt_let(Arena *a, char *name, Expr *init, int line);
Stmt *stmt_assign(Arena *a, char *name, Expr *value, int line);
Stmt *stmt_if(Arena *a, Expr *cond, Stmt *thenb, Stmt *elseb, int line);
Stmt *stmt_while(Arena *a, Expr *cond, Stmt *body, int line);
Stmt *stmt_for(Arena *a, Stmt *init, Expr *cond, Expr *step, Stmt *body, int line);
Stmt *stmt_for_in(Arena *a, char *var, Expr *iterable, Stmt *body, int line);
Stmt *stmt_break(Arena *a, int line);
Stmt *stmt_continue(Arena *a, int line);
Stmt *stmt_return(Arena *a, Expr *value, int line);
Stmt *stmt_block(Arena *a, Stmt **stmts, int count, int line);
Stmt *stmt_func(Arena *a, char *name, char **params, int pcount, Stmt *body, int line);
Stmt *stmt_expr(Arena *a, Expr *e, int line);
Stmt *stmt_try(Arena *a, Stmt *body, char *catchvar, Stmt *catchbody, Stmt *finallybody, int line);
Stmt *stmt_throw(Arena *a, Expr *value, int line);

/* ------------------------------ 解析 ---------------------------------- */
typedef struct {
    Stmt **stmts;
    int    count;
    int    cap;
    char   err[256];
    int    has_error;
} Program;

Program parse(Arena *a, TokenList *tl);

/* 编译/执行辅助 (模块系统用) */
Program cvm_compile(Runtime *rt, const char *source, const char *name);
void    cvm_collect_freevars(Arena *a, Program *p);  /* 自由变量收集 (执行前调用) */
void    cvm_exec_program(Runtime *rt, Program *p, Env *env);
Map    *load_module(Runtime *rt, const char *spec); /* 返回导出 Map* 或 NULL */

/* ----------------------------- 运行时 --------------------------------- */
typedef Value (*BuiltinFunc)(Runtime *rt, int argc, Value *args);

typedef struct {
    void *lib;          /* HMODULE / void* */
    char  path[256];
} FFILib;

struct Runtime {
    Arena       arena;
    Env        *global;
    Map         funcs;     /* name -> Stmt* (func 节点) */
    Map         builtins;  /* name -> BuiltinFunc */
    Map         modules;   /* 模块缓存: 路径 -> 导出 Map* */
    FFILib      ffi_libs[16];
    int         ffi_count;
    Map         ffi_syms;  /* name -> void* (函数指针缓存) */
    int         ffi_enabled;       /* FFI 总开关: 0=默认全拒绝, v1.1 由 cvmruntime.ffi 配置开启 */
    Map         ffi_sigs;          /* 符号名 -> 签名串(char*) (ffi_decl 写入, v1.1 须先命中白名单) */
    Map         ffi_allow;         /* v1.1: lib_path -> Map(symbol->(void*)1) operator 白名单 */
    Map         ffi_allow_sym;     /* v1.1: 扁平 symbol_name -> (void*)1 快速查询 */
    int         return_flag;
    Value       return_value;
    int         break_flag;       /* break 语句标志 (跳出最近循环) */
    int         continue_flag;    /* continue 语句标志 (跳到下次迭代) */
    int         call_depth;                                     /* 调用栈深度 (递归守卫) */
    char        errbuf[512];
    int         has_error;
    int         has_throw;      /* v1: 仅显式 throw 置位 (interp_err 只设 has_error) */
    Value       thrown;         /* throw 携带的值 */
    char        current_file[512];                          /* 当前执行脚本路径(供相对 require 解析) */
    char        loading_paths[CVM_MAX_LOAD_DEPTH][CVM_MAX_LOAD_PATH]; /* 加载链: 循环依赖检测 */
    int         loading_n;

    /* ---- v1.1+ 事件循环 / 定时器 ---- */
    int         timer_count;                       /* 活跃定时器数 */
    int64_t     timer_epoch;                       /* 运行时启动时刻 (ms) */
    struct {
        char    name[256];                         /* 回调函数名 */
        int64_t deadline_ms;                       /* 绝对触发时刻 (ms, 自 timer_epoch) */
        int     repeat_ms;                         /* 0=单次, >0=重复间隔 */
        int     active;
    } timers[64];
};

/* ===================== 字节码 VM (v1.1+) ===================== */
typedef enum {
    OP_PUSH_CONST, OP_PUSH_NIL, OP_PUSH_TRUE, OP_PUSH_FALSE,
    OP_PUSH_INT,
    OP_LOAD, OP_STORE, OP_DEFINE, OP_DUP,
    OP_POP,
    OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_MOD,
    OP_NEG, OP_NOT,
    OP_EQ, OP_NE, OP_LT, OP_GT, OP_LE, OP_GE,
    OP_JMP, OP_JMP_FALSE, OP_JMP_TRUE,
    OP_CALL, OP_RET,
    OP_INDEX, OP_ARRAY_NEW, OP_ARRAY_PUSH, OP_ARRAY_KV,
    OP_HALT
} OpCode;

typedef struct ByteFunc {
    int32_t *code;
    int      clen;
    Value   *consts;
    int      nconsts;
    char   **names;      /* 全局变量名池 */
    int      nnames;
    int      nlocals;    /* 局部寄存器总数 (含参数) */
    int      nargs;      /* 参数数量 */
    int      max_args;   /* 调用其他函数时的最大参数数量 */
    int      unsupported;
    char    *name;       /* 函数名 (顶层为 "<main>") */
} ByteFunc;

Runtime *rt_new(void);
void     rt_free(Runtime *rt);
void     rt_register_builtin(Runtime *rt, const char *name, BuiltinFunc f);
void     host_register_all(Runtime *rt); /* 注册全部宿主内置函数 */

/* 执行一段源码, name 仅用于错误提示。返回 0 成功 / -1 失败(填充 errbuf) */
int rt_run(Runtime *rt, const char *source, const char *name);
int rt_run_file(Runtime *rt, const char *path);

/* v1.1+ 字节码 VM */
ByteFunc *cvm_bc_compile_all(Runtime *rt, Program *program, int *out_count);
int      cvm_bc_run(Runtime *rt, ByteFunc *main_bf, ByteFunc *bfs, int nbfs);
void     cvm_bc_free(ByteFunc *bfs, int count);
int      cvm_bc_supported(Program *program);

/* v1.1+ 事件循环与定时器 */
int64_t rt_now_ms(Runtime *rt);
int     rt_timer_add(Runtime *rt, const char *func_name, int delay_ms, int repeat_ms);
int     rt_process_timers(Runtime *rt);

/* ------------------------------- FFI --------------------------------- */
int   ffi_load(Runtime *rt, const char *path);  /* 0 ok / -1 */
void *ffi_resolve(Runtime *rt, const char *name); /* fn ptr 或 NULL */
void *ffi_resolve_allowed(Runtime *rt, const char *name); /* v1.1: 先查白名单再解析 */
int   rt_load_ffi_allowfile(Runtime *rt, const char *filename); /* v1.1: 加载操作员白名单 */
void  ffi_close(void *lib);                       /* 关闭已加载库 */

/* 闭包: 函数 AST 节点 + 捕获环境 */
typedef struct Closure {
    Stmt *fn;          /* func 节点 (params + body), arena 常驻 */
    Env  *capenv;      /* 捕获环境: 外侧局部变量的 Value* 槽, 父链指向定义根 */
} Closure;

/* ===================== 协议状态机 (ProtoState) ===================== */
/* 为米特-木卫三协议 / 零刻演习 / 六万旅级节点网络提供事件驱动状态机 */
#define PROTO_MAX_STATES    64
#define PROTO_MAX_EVENTS    256
#define PROTO_MAX_ACTIONS   256
#define PROTO_NAME_LEN      64
#define PROTO_LABEL_LEN     64
#define PROTO_EVENT_LEN     64
#define PROTO_ACTION_LEN    128

typedef struct {
    int   id;
    char  label[PROTO_LABEL_LEN];
    int   level;       /* 响应层级: 0=个人 1=组织 2=系统 3=国家 */
} PState;

typedef struct {
    int   from;
    char  event[PROTO_EVENT_LEN];
    int   to;
    char  action[PROTO_ACTION_LEN];  /* 动作标签, 可为空 */
} PTransition;

typedef struct ProtoState {
    char         name[PROTO_NAME_LEN];
    PState       states[PROTO_MAX_STATES];
    int          nstates;
    PTransition  trans[PROTO_MAX_EVENTS];
    int          ntrans;
    int          current;
    int64_t      enter_time_ms;
    int          running;
} ProtoState;

ProtoState *proto_new(const char *name);
int         proto_state_add(ProtoState *ps, int id, const char *label, int level);
int         proto_transition_add(ProtoState *ps, int from, const char *event, int to, const char *action);
int         proto_event(ProtoState *ps, const char *event);
const char *proto_current_label(ProtoState *ps);
int         proto_current_id(ProtoState *ps);
int         proto_current_level(ProtoState *ps);
const char *proto_level_name(int level);

#endif /* CVM_CORE_H */