1
0
Fork 0
forked from fun/fun
fun/src/bytecode.h
2025-09-15 03:59:03 +02:00

115 lines
3.6 KiB
C

#ifndef FUN_BYTECODE_H
#define FUN_BYTECODE_H
#include <stdint.h>
#include "value.h"
// VM opcodes
typedef enum {
OP_NOP,
OP_LOAD_CONST, // operand = constant index
OP_LOAD_LOCAL, // operand = local slot index
OP_STORE_LOCAL, // operand = local slot index
OP_LOAD_GLOBAL, //
OP_STORE_GLOBAL, //
OP_ADD, //
OP_SUB, //
OP_MUL, //
OP_DIV, //
OP_LT, // a < b -> push 1/0
OP_LTE, // a <= b -> push 1/0
OP_GT, // a > b -> push 1/0
OP_GTE, // a >= b -> push 1/0
OP_EQ, // a == b -> push 1/0
OP_NEQ, // a != b -> push 1/0
OP_POP, // discard top of stack
OP_JUMP, // unconditional jump
OP_JUMP_IF_FALSE, // jump if top of stack is false (0)
OP_CALL, // operand = arg count; pops fn + args and enters fn
OP_RETURN, // pop optional return value and return to caller
OP_PRINT,
OP_HALT,
// add after existing opcodes
OP_MOD, // a % b
OP_AND, // logical AND
OP_OR, // logical OR
OP_NOT, // logical NOT
OP_DUP, // duplicate top of stack
OP_SWAP, // swap top two stack values
// arrays
OP_MAKE_ARRAY, // operand = element count; pops N values, pushes array
OP_INDEX_GET, // pops index, array; pushes element copy
OP_INDEX_SET, // pops value, index, array; sets in place
// array and builtin helpers
OP_LEN, // pops array or string; pushes length
OP_ARR_PUSH, // pops value, array; pushes new length
OP_ARR_POP, // pops array; pushes removed element
OP_ARR_SET, // pops value, index, array; pushes value
OP_ARR_INSERT, // pops value, index, array; pushes new length
OP_ARR_REMOVE, // pops index, array; pushes removed element
OP_SLICE, // pops end, start, array; pushes new array
// conversions
OP_TO_NUMBER, // pops any; pushes int (parse strings)
OP_TO_STRING, // pops any; pushes string
// string ops
OP_SPLIT, // pops sep, string; pushes array of strings
OP_JOIN, // pops sep, array; pushes string
OP_SUBSTR, // pops len, start, string; pushes string
OP_FIND, // pops needle, haystack; pushes int index or -1
// array utils
OP_CONTAINS, // pops value, array; pushes 1/0
OP_INDEX_OF, // pops value, array; pushes index or -1
OP_CLEAR, // pops array; clears it; pushes nothing (we'll push 0)
// iteration helpers
OP_ENUMERATE, // pops array; pushes array of [index, value]
OP_ZIP, // pops b, a; pushes array of [a[i], b[i]]
// math
OP_MIN, // pops b, a; pushes min(a,b)
OP_MAX, // pops b, a; pushes max(a,b)
OP_CLAMP, // pops hi, lo, x; pushes clamped
OP_ABS, // pops x; pushes |x|
OP_POW, // pops b, a; pushes a^b
OP_RANDOM_SEED, // pops seed; sets RNG seed; pushes nothing (we'll push 0)
OP_RANDOM_INT // pops hi, lo; pushes random int in [lo, hi)
} OpCode;
typedef struct {
OpCode op;
int32_t operand;
} Instruction;
typedef struct Bytecode {
Instruction *instructions;
int instr_count;
Value *constants;
int const_count;
} Bytecode;
// constructors / manipulation
Bytecode *bytecode_new(void);
int bytecode_add_constant(Bytecode *bc, Value v); /* stores copy */
int bytecode_add_instruction(Bytecode *bc, OpCode op, int32_t operand);
void bytecode_set_operand(Bytecode *bc, int idx, int32_t operand); /* patching */
void bytecode_free(Bytecode *bc);
// utilities
void bytecode_dump(const Bytecode *bc);
#endif