#ifndef SPVM_OP_H
#define SPVM_OP_H
#include "spvm_base.h"
/* Operation code */
enum {
SPVM_OP_C_CODE_IF,
SPVM_OP_C_CODE_ELSIF,
SPVM_OP_C_CODE_ELSE,
SPVM_OP_C_CODE_FOR,
SPVM_OP_C_CODE_WHILE,
SPVM_OP_C_CODE_NULL,
SPVM_OP_C_CODE_LIST,
SPVM_OP_C_CODE_PUSHMARK,
SPVM_OP_C_CODE_GRAMMAR,
SPVM_OP_C_CODE_NAME,
SPVM_OP_C_CODE_PACKAGE,
SPVM_OP_C_CODE_MY,
SPVM_OP_C_CODE_FIELD,
SPVM_OP_C_CODE_SUB,
SPVM_OP_C_CODE_ENUM,
SPVM_OP_C_CODE_DESCRIPTOR,
SPVM_OP_C_CODE_ENUMERATION_VALUE,
SPVM_OP_C_CODE_BLOCK,
SPVM_OP_C_CODE_ENUM_BLOCK,
SPVM_OP_C_CODE_CLASS_BLOCK,
SPVM_OP_C_CODE_TYPE,
SPVM_OP_C_CODE_CONSTANT,
SPVM_OP_C_CODE_PRE_INC,
SPVM_OP_C_CODE_POST_INC,
SPVM_OP_C_CODE_PRE_DEC,
SPVM_OP_C_CODE_POST_DEC,
SPVM_OP_C_CODE_COMPLEMENT,
SPVM_OP_C_CODE_NEGATE,
SPVM_OP_C_CODE_PLUS,
SPVM_OP_C_CODE_EQ,
SPVM_OP_C_CODE_NE,
SPVM_OP_C_CODE_LT,
SPVM_OP_C_CODE_LE,
SPVM_OP_C_CODE_GT,
SPVM_OP_C_CODE_GE,
SPVM_OP_C_CODE_ADD,
SPVM_OP_C_CODE_SUBTRACT,
SPVM_OP_C_CODE_MULTIPLY,
SPVM_OP_C_CODE_DIVIDE,
SPVM_OP_C_CODE_BIT_AND,
SPVM_OP_C_CODE_BIT_OR,
SPVM_OP_C_CODE_BIT_XOR,
SPVM_OP_C_CODE_BIT_NOT,
SPVM_OP_C_CODE_REMAINDER,
SPVM_OP_C_CODE_LEFT_SHIFT,
SPVM_OP_C_CODE_RIGHT_SHIFT,
SPVM_OP_C_CODE_RIGHT_SHIFT_UNSIGNED,
SPVM_OP_C_CODE_AND,
SPVM_OP_C_CODE_OR,
SPVM_OP_C_CODE_NOT,
SPVM_OP_C_CODE_ARRAY_ELEM,
SPVM_OP_C_CODE_ASSIGN,
SPVM_OP_C_CODE_CALL_SUB,
SPVM_OP_C_CODE_CALL_FIELD,
SPVM_OP_C_CODE_USE,
SPVM_OP_C_CODE_RETURN,
SPVM_OP_C_CODE_LAST,
SPVM_OP_C_CODE_NEXT,
SPVM_OP_C_CODE_LOOP,
SPVM_OP_C_CODE_VAR,
SPVM_OP_C_CODE_CONVERT,
SPVM_OP_C_CODE_POP,
SPVM_OP_C_CODE_UNDEF,
SPVM_OP_C_CODE_MALLOC,
SPVM_OP_C_CODE_ARRAY_LENGTH,
SPVM_OP_C_CODE_CONDITION,
SPVM_OP_C_CODE_DIE,
SPVM_OP_C_CODE_SWITCH,
SPVM_OP_C_CODE_CASE,
SPVM_OP_C_CODE_DEFAULT,
SPVM_OP_C_CODE_SWITCH_CONDITION,
SPVM_OP_C_CODE_VOID,
SPVM_OP_C_CODE_EVAL,
SPVM_OP_C_CODE_BLOCK_END,
SPVM_OP_C_CODE_EXCEPTION_VAR,
};
extern const char* const SPVM_OP_C_CODE_NAMES[];
enum {
// Block flag
SPVM_OP_C_FLAG_BLOCK_IF_TRUE = 1,
SPVM_OP_C_FLAG_BLOCK_IF_FALSE = 2,
SPVM_OP_C_FLAG_BLOCK_LOOP = 4,
SPVM_OP_C_FLAG_BLOCK_SWITCH = 8,
SPVM_OP_C_FLAG_BLOCK_SUB = 32,
SPVM_OP_C_FLAG_BLOCK_EVAL = 64,
};
enum {
// Condition flag
SPVM_OP_C_FLAG_CONDITION_IF = 1,
SPVM_OP_C_FLAG_CONDITION_LOOP = 2,
};
enum {
// Case flag
SPVM_OP_C_FLAG_CONSTANT_CASE = 1,
};
enum {
// Assign flag
SPVM_OP_C_FLAG_ASSIGN_TMP_VAR = 1
};
/* Binary operation */
struct SPVM_op {
SPVM_OP* first;
SPVM_OP* last;
SPVM_OP* sibparent;
const char* file;
union {
const char* name;
SPVM_MY_VAR* my_var;
SPVM_SUB* sub;
SPVM_CONSTANT* constant;
SPVM_NAME_INFO* name_info;
SPVM_TYPE* type;
SPVM_VAR* var;
SPVM_FIELD* field;
SPVM_PACKAGE* package;
SPVM_ENUMERATION* enumeration;
SPVM_SWITCH_INFO* switch_info;
} uv;
int32_t code;
int32_t flag;
int32_t line;
_Bool moresib;
_Bool lvalue;
_Bool rvalue;
};
SPVM_OP* SPVM_OP_new_op_use_from_package_name(SPVM_COMPILER* compiler, const char* package_name, const char* file, int32_t line);
SPVM_OP* SPVM_OP_get_op_block_from_op_sub(SPVM_COMPILER* compiler, SPVM_OP* op_sub);
SPVM_TYPE* SPVM_OP_get_type(SPVM_COMPILER* compiler, SPVM_OP* op);
void SPVM_OP_convert_to_op_constant_true(SPVM_COMPILER* compiler, SPVM_OP* op);
void SPVM_OP_convert_to_op_constant_false(SPVM_COMPILER* compiler, SPVM_OP* op);
void SPVM_OP_convert_not_to_if(SPVM_COMPILER* compiler, SPVM_OP* op);
void SPVM_OP_convert_and_to_if(SPVM_COMPILER* compiler, SPVM_OP* op);
void SPVM_OP_convert_or_to_if(SPVM_COMPILER* compiler, SPVM_OP* op);
void SPVM_OP_resolve_type(SPVM_COMPILER* compiler, SPVM_TYPE* type, int32_t name_length);
void SPVM_OP_resolve_sub_name(SPVM_COMPILER* compiler, SPVM_OP* op_package, SPVM_OP* op_name);
void SPVM_OP_resolve_field_name(SPVM_COMPILER* compiler, SPVM_OP* op_name);
SPVM_OP* SPVM_OP_build_return(SPVM_COMPILER* compiler, SPVM_OP* op_return, SPVM_OP* op_term);
SPVM_OP* SPVM_OP_build_die(SPVM_COMPILER* compiler, SPVM_OP* op_die, SPVM_OP* op_term);
SPVM_OP* SPVM_OP_build_eval(SPVM_COMPILER* compiler, SPVM_OP* op_eval, SPVM_OP* op_block);
SPVM_OP* SPVM_OP_build_switch_statement(SPVM_COMPILER* compiler, SPVM_OP* op_switch, SPVM_OP* op_term, SPVM_OP* op_block);
SPVM_OP* SPVM_OP_build_case_statement(SPVM_COMPILER* compiler, SPVM_OP* op_case, SPVM_OP* op_term);
SPVM_OP* SPVM_OP_build_logical_op(SPVM_COMPILER* compiler, SPVM_OP* op_logical_op, SPVM_OP* op_first, SPVM_OP* op_last);
SPVM_OP* SPVM_OP_build_for_statement(SPVM_COMPILER* compiler, SPVM_OP* op_for, SPVM_OP* op_term_loop_var, SPVM_OP* op_term_condition, SPVM_OP* op_term_next_value, SPVM_OP* op_block);
SPVM_OP* SPVM_OP_build_while_statement(SPVM_COMPILER* compiler, SPVM_OP* op_while, SPVM_OP* op_term_condition, SPVM_OP* op_block);
SPVM_OP* SPVM_OP_build_if_statement(SPVM_COMPILER* compiler, SPVM_OP* op_if, SPVM_OP* op_term, SPVM_OP* op_block, SPVM_OP* op_else_statement);
SPVM_OP* SPVM_OP_build_array_length(SPVM_COMPILER* compiler, SPVM_OP* op_array_length, SPVM_OP* op_term);
SPVM_OP* SPVM_OP_build_malloc_object(SPVM_COMPILER* compiler, SPVM_OP* op_malloc, SPVM_OP* op_type);
SPVM_OP* SPVM_OP_build_array_init(SPVM_COMPILER* compiler, SPVM_OP* op_opt_terms);
SPVM_OP* SPVM_OP_build_binop(SPVM_COMPILER* compiler, SPVM_OP* op_call_op, SPVM_OP* op_first, SPVM_OP* op_last);
SPVM_OP* SPVM_OP_build_type_name(SPVM_COMPILER* compiler, SPVM_OP* op_type_name);
SPVM_OP* SPVM_OP_build_type_array(SPVM_COMPILER* compiler, SPVM_OP* op_type, SPVM_OP* op_term);
SPVM_OP* SPVM_OP_build_call_field(SPVM_COMPILER* compiler, SPVM_OP* op_name_package, SPVM_OP* op_name_field);
SPVM_OP* SPVM_OP_build_package(SPVM_COMPILER* compiler, SPVM_OP* op_package, SPVM_OP* op_name_package, SPVM_OP* op_block);
SPVM_OP* SPVM_OP_build_sub(SPVM_COMPILER* compiler, SPVM_OP* op_sub, SPVM_OP* op_subname, SPVM_OP* op_subargs, SPVM_OP* op_descriptors, SPVM_OP* type, SPVM_OP* op_block);
SPVM_OP* SPVM_OP_build_CONSTVALUE(SPVM_COMPILER* compiler, SPVM_OP* op_const);
SPVM_OP* SPVM_OP_build_field(SPVM_COMPILER* compiler, SPVM_OP* op_field, SPVM_OP* op_field_base_name, SPVM_OP* type);
SPVM_OP* SPVM_OP_build_my_var(SPVM_COMPILER* compiler, SPVM_OP* op_my, SPVM_OP* op_var, SPVM_OP* op_type);
SPVM_OP* SPVM_OP_build_grammar(SPVM_COMPILER* compiler, SPVM_OP* op_packages);
SPVM_OP* SPVM_OP_build_use(SPVM_COMPILER* compiler, SPVM_OP* op_use, SPVM_OP* op_name_package);
SPVM_OP* SPVM_OP_build_call_sub(SPVM_COMPILER* compiler, SPVM_OP* op_invocant, SPVM_OP* op_subname, SPVM_OP* op_terms);
SPVM_OP* SPVM_OP_build_convert_type(SPVM_COMPILER* compiler, SPVM_OP* op_type, SPVM_OP* op_term);
SPVM_OP* SPVM_OP_build_enumeration(SPVM_COMPILER* compiler, SPVM_OP* op_enumeration, SPVM_OP* op_enumeration_block);
SPVM_OP* SPVM_OP_build_unop(SPVM_COMPILER* compiler, SPVM_OP* op_unary, SPVM_OP* op_first);
SPVM_OP* SPVM_OP_build_array_elem(SPVM_COMPILER* compiler, SPVM_OP* op_var, SPVM_OP* op_term);
SPVM_OP* SPVM_OP_build_assignop(SPVM_COMPILER* compiler, SPVM_OP* op_assign, SPVM_OP* op_first, SPVM_OP* op_last);
SPVM_OP* SPVM_OP_build_constant(SPVM_COMPILER* compiler, SPVM_OP* op_constant);
void SPVM_OP_resolve_op_convert_type(SPVM_COMPILER* compiler, SPVM_OP* op_convert_type);
const char* SPVM_OP_create_abs_name(SPVM_COMPILER* compiler, const char* package_name, const char* base_name);
SPVM_OP* SPVM_OP_new_op_constant_int(SPVM_COMPILER* compiler, int32_t value, const char* file, int32_t line);
SPVM_OP* SPVM_OP_new_op_constant_long(SPVM_COMPILER* compiler, int64_t value, const char* file, int32_t line);
SPVM_OP* SPVM_OP_new_op_constant_float(SPVM_COMPILER* compiler, float value, const char* file, int32_t line);
SPVM_OP* SPVM_OP_new_op_constant_double(SPVM_COMPILER* compiler, double value, const char* file, int32_t line);
SPVM_OP* SPVM_OP_new_op_var_from_op_my_var(SPVM_COMPILER* compiler, SPVM_OP* op_my_var);
SPVM_OP* SPVM_OP_new_op_list(SPVM_COMPILER* compiler, const char* file, int32_t line);
SPVM_OP* SPVM_OP_new_op(SPVM_COMPILER* compiler, int32_t code, const char* file, int32_t line);
void SPVM_OP_insert_child(SPVM_COMPILER* compiler, SPVM_OP* parent, SPVM_OP* start, SPVM_OP* insert);
SPVM_OP* SPVM_OP_sibling(SPVM_COMPILER* compiler, SPVM_OP* o);
#endif