Files
bshell/bshell.runtime/compile/op.c
T
wash edfb3e24a3 bshell: re-organise build into three separate components
bshell: the front-end binary
bshell.runtime: contains the parser, compiler, and classes needed to run bshell scripts
bshell.core: contains the builtin commandlets and aliases
2026-05-25 10:33:29 +01:00

127 lines
3.2 KiB
C

#include "compile-node.h"
#include <bshell/runtime/operator.h>
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);
}