// codegen.h -- DVX BASIC p-code emitter // // Builds a p-code byte stream and string constant pool from // calls made by the parser. Provides helpers for backpatching // forward jumps. // // Embeddable: no DVX dependencies, pure C. #ifndef DVXBASIC_CODEGEN_H #define DVXBASIC_CODEGEN_H #include "../runtime/vm.h" #include "../runtime/values.h" #include #include // ============================================================ // Code generator state // ============================================================ typedef struct { uint8_t *code; // stb_ds dynamic array int32_t codeLen; BasStringT **constants; // stb_ds dynamic array int32_t constCount; int32_t globalCount; BasValueT *dataPool; // stb_ds dynamic array int32_t dataCount; BasFormVarInfoT *formVarInfo; // stb_ds dynamic array int32_t formVarInfoCount; } BasCodeGenT; // ============================================================ // API // ============================================================ void basCodeGenInit(BasCodeGenT *cg); void basCodeGenFree(BasCodeGenT *cg); // Emit single byte void basEmit8(BasCodeGenT *cg, uint8_t b); // Emit 16-bit signed value void basEmit16(BasCodeGenT *cg, int16_t v); // Emit 16-bit unsigned value void basEmitU16(BasCodeGenT *cg, uint16_t v); // Emit 32-bit float void basEmitFloat(BasCodeGenT *cg, float v); // Emit 64-bit double void basEmitDouble(BasCodeGenT *cg, double v); // Get current code position (for jump targets) int32_t basCodePos(const BasCodeGenT *cg); // Patch a 16-bit value at a previous position (for backpatching jumps) void basPatch16(BasCodeGenT *cg, int32_t pos, int16_t val); // Add a string to the constant pool. Returns the pool index. uint16_t basAddConstant(BasCodeGenT *cg, const char *text, int32_t len); // Add a value to the data pool (for DATA statements). Returns true on success. bool basAddData(BasCodeGenT *cg, BasValueT val); // Build a BasModuleT from the generated code. The caller takes // ownership of the module and must free it with basModuleFree(). BasModuleT *basCodeGenBuildModule(BasCodeGenT *cg); // Build a module with procedure table from parser symbol table. // symtab is a BasSymTabT* (cast to void* to avoid circular include). BasModuleT *basCodeGenBuildModuleWithProcs(BasCodeGenT *cg, void *symtab); // Free a module built by basCodeGenBuildModule. void basModuleFree(BasModuleT *mod); // Find a procedure by name in a module's procedure table. // Case-insensitive. Returns NULL if not found. const BasProcEntryT *basModuleFindProc(const BasModuleT *mod, const char *name); #endif // DVXBASIC_CODEGEN_H