#ifndef APFL_BYTECODE_H #define APFL_BYTECODE_H #ifdef __cplusplus extern "C" { #endif #include "apfl.h" #include "gc.h" enum instruction { INSN_NIL, // ( -- nil) INSN_TRUE, // ( -- true) INSN_FALSE, // ( -- false) INSN_NUMBER, // ( -- number), arg: number INSN_STRING, // ( -- string), arg: string INSN_LIST, // ( -- list), arg: count (preallocation hint) INSN_LIST_APPEND, // ( list val -- list' ) INSN_LIST_EXPAND_INTO, // ( list list -- list' ) INSN_DICT, // ( -- dict ) INSN_DICT_APPEND_KVPAIR, // ( dict key value -- dict' ) INSN_GET_MEMBER, // ( list/dict key -- value ) INSN_GET_BY_INDEX_KEEP, // ( list/dict -- list/dict value ), arg: index INSN_VAR_GET, // ( -- value ), arg: string INSN_VAR_SET, // ( value -- value ), arg: string INSN_VAR_SET_LOCAL, // ( value -- value ), arg: string INSN_VAR_NEW, // ( -- ), arg: string INSN_VAR_NEW_LOCAL, // ( -- ), arg: string INSN_MOVE_TO_LOCAL_VAR, // ( value -- ), arg: string INSN_NEXT_LINE, // ( -- ) INSN_SET_LINE, // ( -- ), arg: count (new line number) INSN_DROP, // ( value -- ) INSN_CALL, // ( func list -- value ) INSN_FUNC, // ( -- func ), arg: body }; union instruction_or_arg { enum instruction instruction; struct apfl_string *string; apfl_number number; size_t count; size_t index; struct instruction_list *body; }; struct instruction_list { union instruction_or_arg *instructions; size_t len; size_t cap; int line; }; const char *apfl_instruction_to_string(enum instruction); struct instruction_list *apfl_instructions_new(struct gc *, int line); void apfl_instructions_deinit(struct apfl_allocator, struct instruction_list *); void apfl_gc_instructions_traverse(struct instruction_list *, gc_visitor, void *); #ifdef __cplusplus } #endif #endif