static void unary_op(struct context *context, enum Opcode op) { if (!context->runtime) VM_DEBUGPRINT("%s\n", NUM_TO_STRING(opcodes, op)); struct variable *v = (struct variable*)variable_pop(context); struct variable *result = NULL; switch (v->type) { case VAR_NIL: { switch (op) { case VM_NEG: result = variable_new_nil(context); break; case VM_NOT: result = variable_new_bool(context, true); break; default: vm_exit_message(context, "bad math operator"); break; } } break; case VAR_INT: { int32_t n = v->integer; switch (op) { case VM_NEG: result = variable_new_int(context, -n); break; case VM_NOT: result = variable_new_bool(context, !n); break; case VM_INV: result = variable_new_int(context, ~n); break; default: vm_exit_message(context, "bad math operator"); break; } } break; case VAR_FLT: { float n = v->floater; switch (op) { case VM_NEG: result = variable_new_float(context, -n); break; case VM_NOT: result = variable_new_bool(context, !n); break; default: vm_exit_message(context, "bad math operator"); break; } } break; default: if (op == VM_NOT) result = variable_new_bool(context, false); else vm_exit_message(context, "bad math type"); break; } variable_push(context, result); DEBUGPRINT("%s(%s) = %s\n", NUM_TO_STRING(opcodes, op), variable_value_str(context, v), variable_value_str(context, result)); }
// this is the fn parameter passed into file_list() int file_list_callback(const char *path, bool dir, long mod, void *fl_context) { // -> / path = remove_substring(path, "//"); //printf("file_list_callback %s\n", path); size_t size = file_size(path); path = remove_substring(path, hal_doc_path(NULL)); struct file_list_context *flc = (struct file_list_context*)fl_context; struct variable *path3 = variable_new_str_chars(flc->context, path); struct variable *key2 = variable_new_str_chars(flc->context, RESERVED_DIR); struct variable *value = variable_new_bool(flc->context, dir); struct variable *metadata = variable_new_list(flc->context, NULL); variable_map_insert(flc->context, metadata, key2, value); key2 = variable_new_str_chars(flc->context, RESERVED_MODIFIED); value = variable_new_int(flc->context, (int32_t)mod); variable_map_insert(flc->context, metadata, key2, value); variable_map_insert(flc->context, flc->result, path3, metadata); key2 = variable_new_str_chars(flc->context, RESERVED_SIZE); value = variable_new_int(flc->context, (int32_t)size); variable_map_insert(flc->context, metadata, key2, value); variable_map_insert(flc->context, flc->result, path3, metadata); return 0; }
static void push_bool(struct context *context, struct byte_array *program) { null_check(program); int32_t num = serial_decode_int(program); VM_DEBUGPRINT("BOOL %d\n", num); struct variable* var = variable_new_bool(context, num); variable_push(context, var); }
static struct variable *binary_op_nil(struct context *context, enum Opcode op, const struct variable *u, const struct variable *v) { vm_assert(context, u->type==VAR_NIL || v->type==VAR_NIL, "nil op with non-nils"); if (v->type == VAR_NIL && u->type != VAR_NIL) return binary_op_nil(context, op, v, u); // 1st var should be nil switch (op) { case VM_EQU: return variable_new_bool(context, v->type == u->type); case VM_NEQ: return variable_new_bool(context, v->type != u->type); case VM_ADD: case VM_SUB: return variable_copy(context, v); case VM_LTN: case VM_GTN: case VM_LEQ: case VM_GRQ: return variable_new_bool(context, false); default: return vm_exit_message(context, "unknown binary nil op"); } }
struct variable *sys_open(struct context *context) { struct variable *args = (struct variable*)stack_pop(context->operand_stack); struct variable *path = param_var(args, 1); char *path2 = byte_array_to_string(path->str); bool result = hal_open(path2); struct variable *result2 = variable_new_bool(context, result); variable_push(context, result2); free(path2); return NULL; }
static inline struct variable *cfnc_find2(struct context *context, bool has) { struct variable *args = (struct variable*)stack_pop(context->operand_stack); struct variable *self = (struct variable*)array_get(args->list.ordered, 0); struct variable *sought = (struct variable*)array_get(args->list.ordered, 1); struct variable *start = args->list.ordered->length > 2 ? (struct variable*)array_get(args->list.ordered, 2) : NULL; null_check(self); null_check(sought); struct variable *result = variable_find(context, self, sought, start); if (has) return variable_new_bool(context, result->integer != -1); return result; }
static void binary_op(struct context *context, enum Opcode op) { if (!context->runtime) VM_DEBUGPRINT("%s\n", NUM_TO_STRING(opcodes, op)); struct variable *u = variable_pop(context); struct variable *v = variable_pop(context); enum VarType ut = (enum VarType)u->type; enum VarType vt = (enum VarType)v->type; struct variable *w; if (ut == VAR_NIL || vt == VAR_NIL) { w = binary_op_nil(context, op, u, v); } else if ((op == VM_EQU) || (op == VM_NEQ)) { bool same = variable_compare(context, u, v) ^ (op == VM_NEQ); w = variable_new_bool(context, same); } else { bool floater = (ut == VAR_FLT && is_num(vt)) || (vt == VAR_FLT && is_num(ut)); bool inter = (ut==VAR_INT || ut==VAR_BOOL) && (vt==VAR_INT || vt==VAR_BOOL); if (floater) w = binary_op_float(context, op, u, v); else if (inter) w = binary_op_int(context, op, v, u); else if (vt == VAR_STR || ut == VAR_STR) w = binary_op_str(context, op, u, v); else if (vt == VAR_LST) w = binary_op_lst(context, op, u, v); else vm_exit_message(context, "unknown binary op"); } variable_push(context, w); DEBUGPRINT("%s(%s,%s) = %s\n", NUM_TO_STRING(opcodes, op), variable_value_str(context, v), variable_value_str(context, u), variable_value_str(context, w)); }