This will match all arguments and discard them. This makes the bytecode for simple functions easier and will make it easier to construct simple function programmatically.
112 lines
4.2 KiB
C
112 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,
|
|
};
|
|
|
|
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
|
|
};
|
|
|
|
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 *);
|
|
|
|
void apfl_gc_instructions_traverse(struct instruction_list *, gc_visitor, void *);
|
|
void apfl_gc_matcher_instructions_traverse(struct matcher_instruction_list *, gc_visitor, void *);
|
|
|
|
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);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|