1#ifndef REDUCT_EVAL_IMPL_H
2#define REDUCT_EVAL_IMPL_H 1
65 state->
regs = newRegs;
156 op = REDUCT_INST_GET_OP(inst); \
157 goto* dispatchTable[op]; \
160#define OP_COMPARE(_label, _op) \
161LABEL_C_OP(_label, { \
164 base[a] = REDUCT_HANDLE_COMPARE_FAST(reduct, &base[b], &valC, _op) ? REDUCT_HANDLE_TRUE() : REDUCT_HANDLE_FALSE(); \
168#define OP_ARITH(_label, _op) \
169LABEL_C_OP(_label, { \
172 REDUCT_HANDLE_ARITHMETIC_FAST(reduct, &base[a], &base[b], &valC, _op); \
176#define DECODE_A() reduct_uint32_t a = REDUCT_INST_GET_A(inst)
177#define DECODE_B() reduct_uint32_t b = REDUCT_INST_GET_B(inst)
178#define DECODE_C_REG() \
179 reduct_uint32_t c = REDUCT_INST_GET_C(inst); \
180 reduct_handle_t valC = base[c]
181#define DECODE_C_CONST() \
182 reduct_uint32_t c = REDUCT_INST_GET_C(inst); \
183 reduct_handle_t valC = constants[c]
184#define DECODE_SBX() reduct_int32_t sbx = REDUCT_INST_GET_SBX(inst)
186#define ERROR_CHECK(_expr, ...) \
189 if (REDUCT_UNLIKELY(!(_expr))) \
192 REDUCT_ERROR_RUNTIME(__VA_ARGS__); \
196#define OP_ENTRY(_op, _label) [_op] = &&_label, [_op | REDUCT_MODE_CONST] = &&_label
198#define OP_ENTRY_C(_op, _label) [_op] = &&_label, [_op | REDUCT_MODE_CONST] = &&_label##_k
200#define OP_BITWISE(_label, _op) \
201LABEL_C_OP(_label, { \
204 base[a] = REDUCT_HANDLE_FROM_INT(reduct_get_int(reduct, &base[b]) _op reduct_get_int(reduct, &valC)); \
208#define OP_EQUALITY(_label, _func, _truth) \
209LABEL_C_OP(_label, { \
212 base[a] = (_func(reduct, &base[b], &valC) == _truth) ? REDUCT_HANDLE_TRUE() : REDUCT_HANDLE_FALSE(); \
216 void* dispatchTable[] = {
250#define LABEL_C_OP(_label, ...) \
320 constants = frame->
closure->constants;
333 constants = frame->
closure->constants;
357 base[i] = base[a + i];
366 constants = frame->
closure->constants;
389 constants = frame->
closure->constants;
413 constants = frame->
closure->constants;
459 ERROR_CHECK(left >= 0 && left < 64, reduct,
REDUCT_NULL,
"expected left shift amount 0-63, got %ld", left);
467 ERROR_CHECK(right >= 0 && right < 64, reduct,
REDUCT_NULL,
"expected right shift amount 0-63, got %ld", right);
584 argv = state->
regs + argvOffset;
590 state->
regs[target + i] = argv[i];
#define REDUCT_MALLOC(_size)
#define REDUCT_LIKELY(_x)
#define REDUCT_UNLIKELY(_x)
reduct_bool_t
Boolean type.
#define REDUCT_REALLOC(_ptr, _size)
reduct_uint64_t reduct_handle_t
Handle type.
#define REDUCT_ALWAYS_INLINE
#define REDUCT_ASSERT(_cond)
#define REDUCT_FREE(_ptr)
Virtual machine evaluation.
static REDUCT_ALWAYS_INLINE void reduct_eval_push_frame(reduct_t *reduct, reduct_eval_state_t *state, reduct_closure_t *closure, reduct_uint32_t target)
static REDUCT_ALWAYS_INLINE void reduct_eval_ensure_regs(reduct_t *reduct, reduct_eval_state_t *state, reduct_uint32_t neededRegs)
static REDUCT_ALWAYS_INLINE void reduct_eval_tail_frame(reduct_t *reduct, reduct_eval_state_t *state, reduct_closure_t *closure)
static reduct_handle_t reduct_eval_run(reduct_t *reduct, reduct_eval_state_t *state, reduct_uint32_t initialFrameCount)
#define OP_ARITH(_label, _op)
#define OP_ENTRY_C(_op, _label)
static REDUCT_ALWAYS_INLINE void reduct_eval_pop_frame(reduct_eval_state_t *state)
#define LABEL_C_OP(_label,...)
#define ERROR_CHECK(_expr,...)
REDUCT_API reduct_handle_t reduct_eval(struct reduct *reduct, reduct_function_t *function)
#define OP_BITWISE(_label, _op)
#define OP_ENTRY(_op, _label)
#define OP_COMPARE(_label, _op)
#define OP_EQUALITY(_label, _func, _truth)
static void reduct_eval_state_init(reduct_t *reduct, reduct_eval_state_t *state)
REDUCT_API reduct_closure_t * reduct_closure_new(struct reduct *reduct, reduct_function_t *function)
Allocate a new closure.
REDUCT_API reduct_function_t * reduct_compile(reduct_t *reduct, reduct_handle_t *ast)
Compiles a Reduct AST into a callable bytecode function.
#define REDUCT_ERROR_RUNTIME(_reduct,...)
Throw a runtime error using the jump buffer in the error structure.
#define REDUCT_ERROR_INTERNAL(_reduct,...)
Throw an internal error using the jump buffer in the error structure.
REDUCT_API reduct_handle_t reduct_eval_string(reduct_t *reduct, const char *str, reduct_size_t len)
Parses, compiles and evaluates a string.
REDUCT_API void reduct_eval_state_deinit(reduct_eval_state_t *state)
Deinitialize an evaluation state structure.
#define REDUCT_EVAL_REGS_INITIAL
The initial amount of registers.
#define REDUCT_EVAL_FRAMES_INITIAL
The initial size of the frames array.
REDUCT_API reduct_handle_t reduct_eval_file(reduct_t *reduct, const char *path)
Parses, compiles and evaluates a file.
#define REDUCT_EVAL_REGS_GROWTH_FACTOR
The growth factor of the registers array.
REDUCT_API reduct_handle_t reduct_eval_call(reduct_t *reduct, reduct_handle_t callable, reduct_size_t argc, reduct_handle_t *argv)
Calls a Reduct callable (closure or native) with arguments.
#define REDUCT_EVAL_FRAMES_GROWTH_FACTOR
The growth factor of the frames array.
#define REDUCT_HANDLE_FALSE()
Constant false handle.
#define REDUCT_HANDLE_IS_ITEM(_handle)
Check if a handle is an item.
#define REDUCT_HANDLE_FROM_LIST(_list)
Create a handle from a list pointer.
#define REDUCT_HANDLE_TO_ITEM(_handle)
Get the item pointer of a handle.
#define REDUCT_HANDLE_FROM_CLOSURE(_closure)
Create a handle from a closure pointer.
REDUCT_API void reduct_handle_promote(struct reduct *reduct, reduct_handle_t *a, reduct_handle_t *b, reduct_promotion_t *out)
Promote two handles to a common numeric type.
REDUCT_API reduct_handle_t reduct_handle_nil(struct reduct *reduct)
Get the constant nil handle.
#define REDUCT_HANDLE_GET_TYPE(_handle)
Get the type of the item referenced by the handle, or REDUCT_ITEM_TYPE_ATOM if not an item.
REDUCT_API reduct_bool_t reduct_handle_is_equal(struct reduct *reduct, reduct_handle_t *a, reduct_handle_t *b)
Check if two items are exactly equal string-wise or structurally.
#define REDUCT_HANDLE_FROM_INT(_val)
Create a handle from an integer.
#define REDUCT_HANDLE_NONE
Invalid handle constant.
#define REDUCT_HANDLE_IS_TRUTHY(_handle)
Check if a handle is truthy.
#define REDUCT_HANDLE_TRUE()
Constant true handle.
@ REDUCT_PROMOTION_TYPE_INT
#define REDUCT_INST_GET_C(_inst)
Get the C operand from an instruction.
reduct_opcode_t
Opcode enumeration.
reduct_uint32_t reduct_inst_t
Instruction type.
@ REDUCT_OPCODE_DIV
(A, B, C) R(A) = R(B) / R/K(C)
@ REDUCT_OPCODE_JMPF
(A, sBx) Jump by sBx if R(A) is falsy.
@ REDUCT_OPCODE_JMPT
(A, sBx) Jump by sBx if R(A) is truthy.
@ REDUCT_OPCODE_APPEND
(A, C) Append value in R/K(C) to the back of the list in R(A).
@ REDUCT_OPCODE_SHR
(A, B, C) R(A) = R(B) >> R/K(C)
@ REDUCT_OPCODE_SEQ
(A, B, C) If R(B) === R/K(C) store true in R(A), else false.
@ REDUCT_OPCODE_SHL
(A, B, C) R(A) = R(B) << R/K(C)
@ REDUCT_OPCODE_SUB
(A, B, C) R(A) = R(B) - R/K(C)
@ REDUCT_OPCODE_NEQ
(A, B, C) If R(B) != R/K(C) store true in R(A), else false.
@ REDUCT_OPCODE_MOV
(A, C) Move value in R/K(C) to R(A).
@ REDUCT_OPCODE_MUL
(A, B, C) R(A) = R(B) * R/K(C)
@ REDUCT_OPCODE_ADD
(A, B, C) R(A) = R(B) + R/K(C)
@ REDUCT_OPCODE_BAND
(A, B, C) R(A) = R(B) & R/K(C)
@ REDUCT_OPCODE_RET
(C) Return value in R/K(C).
@ REDUCT_OPCODE_BNOT
(A, C) R(A) = ~R/K(C)
@ REDUCT_OPCODE_EQ
(A, B, C) If R(B) == R/K(C) store true in R(A), else false.
@ REDUCT_OPCODE_CALL
(A, B, C) Call callable in R/K(C) with B args starting from R(A). Result in R(A).
@ REDUCT_OPCODE_GT
(A, B, C) If R(B) > R/K(C) store true in R(A), else false.
@ REDUCT_OPCODE_JMP
(sBx) Unconditional jump by relative offset sBx.
@ REDUCT_OPCODE_SNEQ
(A, B, C) If R(B) !== R/K(C) store true in R(A), else false.
@ REDUCT_OPCODE_GE
(A, B, C) If R(B) >= R/K(C) store true in R(A), else false.
@ REDUCT_OPCODE_BOR
(A, B, C) R(A) = R(B) | R/K(C)
@ REDUCT_OPCODE_CLOSURE
(A, C) Wrap the function prototype in K(C) in a closure and store in R(A).
@ REDUCT_OPCODE_LE
(A, B, C) If R(B) <= R/K(C) store true in R(A), else false.
@ REDUCT_OPCODE_LIST
(A) Create a new list and store it in R(A).
@ REDUCT_OPCODE_TAILCALL
(A, B, C) Tail call callable in R/K(C) with B args starting from R(A).
@ REDUCT_OPCODE_BXOR
(A, B, C) R(A) = R(B) ^ R/K(C)
@ REDUCT_OPCODE_CAPTURE
(A, B, C) Capture R/K(C) into constant slot B in closure R(A).
@ REDUCT_OPCODE_MOD
(A, B, C) R(A) = R(B) % R/K(C)
@ REDUCT_OPCODE_LT
(A, B, C) If R(B) < R/K(C) store true in R(A), else false.
#define REDUCT_ITEM_TYPE_LIST
A list.
REDUCT_API const char * reduct_item_type_str(reduct_item_type_t type)
Get the string representation of an Reduct item type.
#define REDUCT_ITEM_TYPE_FUNCTION
A function.
#define REDUCT_ITEM_TYPE_CLOSURE
A closure.
#define REDUCT_ITEM_FLAG_NATIVE
Item is an atom and a native function.
REDUCT_API reduct_handle_t reduct_parse_file(reduct_t *reduct, const char *path)
Parse a Reduct file.
REDUCT_API reduct_handle_t reduct_parse(reduct_t *reduct, const char *str, reduct_size_t len, const char *path)
Parse a Reduct string.
REDUCT_API reduct_handle_t reduct_get_int(struct reduct *reduct, reduct_handle_t *handle)
REDUCT_API void reduct_list_append(struct reduct *reduct, reduct_list_t *list, reduct_handle_t val)
Append an element to the list.
REDUCT_API reduct_list_t * reduct_list_new(struct reduct *reduct)
Create a new editable list.
Built-in library registration and operations.
reduct_eval_frame_t * frame
reduct_handle_t * constants
reduct_native_fn native
Native function, item must have REDUCT_ITEM_FLAG_NATIVE.
reduct_handle_t * constants
The array of constant slots forming the constant template.
reduct_function_t * function
Pointer to the prototype function item.
Evaluation frame structure.
struct reduct_closure * closure
The closure being evaluated.
reduct_inst_t * ip
The current instruction pointer.
reduct_uint32_t prevRegCount
The previous register count to restore upon return.
reduct_uint32_t base
The base register, where the functions registers start.
Evaluation state structure.
reduct_uint32_t frameCapacity
reduct_eval_frame_t * frames
reduct_uint32_t frameCount
reduct_uint32_t regCapacity
Compiled function structure.
reduct_inst_t * insts
An array of instructions.
reduct_uint16_t registerCount
The number of registers the function uses.
reduct_uint8_t arity
The number of arguments the function expects.
reduct_list_t list
A list.
reduct_closure_t closure
A closure.
reduct_function_t function
A function.
reduct_item_flags_t flags
Flags for the item.
reduct_atom_t atom
An atom.
reduct_item_type_t type
The type of the item.
struct reduct_eval_state * evalState