apfl/src/bytecode.h
Laria Carolin Chabowski 396c5ad866 gc: Tighter coupling to full context
We'll soon need the whole apfl_ctx in the garbage collector.
2023-11-23 21:30:51 +01:00

116 lines
4.2 KiB
C

#ifndef APFL_BYTECODE_H
#define APFL_BYTECODE_H
#ifdef __cplusplus
extern "C" {
#endif
#include "apfl.h"
#include "gc.h"
enum matcher_instruction {
MATCHER_IGNORE,
MATCHER_CAPTURE_TO_VAR, // with name
MATCHER_CAPTURE_TO_VAR_LOCAL, // with name
MATCHER_CAPTURE_TO_VAR_WITH_PATH, // with name, index and len
MATCHER_CAPTURE_TO_VAR_LOCAL_WITH_PATH, // with name, index and len
MATCHER_CHECK_CONST, // with index as values index
MATCHER_CHECK_PRED, // with index as values index
MATCHER_ENTER_LIST,
MATCHER_LEAVE_LIST,
MATCHER_CONTINUE_FROM_END,
MATCHER_REMAINDING,
MATCHER_UNPACK_PAIR,
};
union matcher_instruction_or_arg {
enum matcher_instruction instruction;
size_t index;
size_t len;
struct apfl_string *string;
};
struct matcher_instruction_list {
union matcher_instruction_or_arg *instructions;
size_t len;
size_t cap;
size_t value_count;
size_t capture_count;
};
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_DUP, // ( value -- value value)
INSN_CALL, // ( func list -- value )
INSN_FUNC, // ( -- func ), arg: count
INSN_FUNC_ADD_SUBFUNC, // ( func -- func' ), arg: body; pops a matcher from the matcher stack
INSN_FUNC_ADD_SUBFUNC_ANYARGS, // ( func -- func' ), arg: body
INSN_FUNC_SET_NAME, // ( func -- func' ), arg: string
INSN_MATCHER_PUSH, // ( -- ), arg: matcher; pushes a matcher onto the matcher stack
INSN_MATCHER_SET_VAL, // ( val -- ), arg: index
INSN_MATCHER_MUST_MATCH, // ( val -- ); pops a matcher from the matcher stack
INSN_BUILD_PAIR, // ( val val -- pair )
};
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 matcher_instruction_list *matcher;
};
struct instruction_list {
union instruction_or_arg *instructions;
size_t len;
size_t cap;
size_t line;
struct apfl_string *filename;
};
const char *apfl_instruction_to_string(enum instruction);
const char *apfl_matcher_instruction_to_string(enum matcher_instruction);
struct instruction_list *apfl_instructions_new(struct gc *, size_t line, struct apfl_string *filename);
void apfl_instructions_deinit(struct apfl_allocator, struct instruction_list *);
struct matcher_instruction_list *apfl_matcher_instructions_new(struct gc *);
void apfl_matcher_instructions_deinit(struct apfl_allocator, struct matcher_instruction_list *);
bool apfl_bytecode_dump_matcher(unsigned indent, struct apfl_io_writer w, struct matcher_instruction_list *milist);
bool apfl_bytecode_dump(unsigned indent, struct apfl_io_writer w, struct instruction_list *ilist);
struct instruction_list *apfl_bytecode_unserialize(
struct gc *gc,
struct apfl_io_reader r
);
#ifdef __cplusplus
}
#endif
#endif