81 lines
2.5 KiB
C
81 lines
2.5 KiB
C
// 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 <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
// ============================================================
|
|
// 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;
|
|
} 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
|