#include "compile-node.h" #include static enum bshell_opcode opcode_for_op(enum bshell_operator_id op) { switch (op) { case BSHELL_OP_ADD: return BSHELL_OPCODE_ADD; case BSHELL_OP_SUBTRACT: return BSHELL_OPCODE_SUB; case BSHELL_OP_MULTIPLY: return BSHELL_OPCODE_MUL; case BSHELL_OP_DIVIDE: return BSHELL_OPCODE_DIV; case BSHELL_OP_MODULO: return BSHELL_OPCODE_MOD; case BSHELL_OP_INCREMENT: return BSHELL_OPCODE_INC; case BSHELL_OP_DECREMENT: return BSHELL_OPCODE_DEC; case BSHELL_OP_LEFT_SHIFT: return BSHELL_OPCODE_SHL; case BSHELL_OP_RIGHT_SHIFT: return BSHELL_OPCODE_SHR; case BSHELL_OP_BINARY_AND: return BSHELL_OPCODE_BAND; case BSHELL_OP_BINARY_OR: return BSHELL_OPCODE_BOR; case BSHELL_OP_BINARY_XOR: return BSHELL_OPCODE_BXOR; case BSHELL_OP_BINARY_NOT: return BSHELL_OPCODE_BNOT; case BSHELL_OP_LESS_THAN: return BSHELL_OPCODE_CMP_LT; case BSHELL_OP_GREATER_THAN: return BSHELL_OPCODE_CMP_GT; case BSHELL_OP_EQUAL: return BSHELL_OPCODE_CMP_EQ; case BSHELL_OP_NOT_EQUAL: return BSHELL_OPCODE_CMP_NE; case BSHELL_OP_LESS_EQUAL: return BSHELL_OPCODE_CMP_LE; case BSHELL_OP_GREATER_EQUAL: return BSHELL_OPCODE_CMP_GE; case BSHELL_OP_LOGICAL_AND: return BSHELL_OPCODE_LAND; case BSHELL_OP_LOGICAL_OR: return BSHELL_OPCODE_LOR; case BSHELL_OP_LOGICAL_XOR: return BSHELL_OPCODE_LXOR; case BSHELL_OP_LOGICAL_NOT: return BSHELL_OPCODE_LNOT; case BSHELL_OP_RANGE: return BSHELL_OPCODE_RANGE; case BSHELL_OP_MATCH: return BSHELL_OPCODE_MATCH; case BSHELL_OP_REPLACE: return BSHELL_OPCODE_REPLACE; case BSHELL_OP_LIKE: return BSHELL_OPCODE_LIKE; case BSHELL_OP_IN: return BSHELL_OPCODE_IN; case BSHELL_OP_FORMAT: return BSHELL_OPCODE_FMT; case BSHELL_OP_CONTAINS: return BSHELL_OPCODE_CONTAINS; case BSHELL_OP_USPLIT: return BSHELL_OPCODE_SPLIT; case BSHELL_OP_BSPLIT: return BSHELL_OPCODE_SPLIT; case BSHELL_OP_UJOIN: return BSHELL_OPCODE_JOIN; case BSHELL_OP_BJOIN: return BSHELL_OPCODE_JOIN; case BSHELL_OP_IS: return BSHELL_OPCODE_IS; case BSHELL_OP_AS: return BSHELL_OPCODE_AS; case BSHELL_OP_ACCESS: return BSHELL_OPCODE_LDPROP; default: return BSHELL_OPCODE_NOP; } } enum bshell_status op_load(struct compile_ctx *ctx, struct compile_value *value) { enum bshell_opcode opcode = opcode_for_op(value->v_op); if (opcode != BSHELL_OPCODE_NOP) { compile_value_load(ctx, value->v_right); compile_value_load(ctx, value->v_left); bshell_scriptblock_push_instruction( ctx->c_block, opcode_for_op(value->v_op), 0); return BSHELL_SUCCESS; } switch (value->v_op) { case BSHELL_OP_ASSIGN: compile_value_load(ctx, value->v_right); compile_value_store(ctx, value->v_left); break; default: return BSHELL_ERR_NOT_SUPPORTED; } return BSHELL_SUCCESS; } static const struct compile_value_type op_type = { .v_load = op_load, }; struct compile_result compile_op( struct compile_ctx *ctx, struct bshell_ast_node *src) { struct bshell_op_ast_node *op = (struct bshell_op_ast_node *)src; struct compile_value *left = NULL, *right = NULL; left = compile_pop_value(ctx); right = compile_pop_value(ctx); compile_push_op(ctx, src, &op_type, op->n_op->op_id, left, right); return COMPILE_OK(0); }