struct variable *ui_result(struct context *context, void *widget, int32_t w, int32_t h) { struct variable *widget2 = variable_new_void(context, widget); variable_push(context, widget2); variable_push(context, variable_new_int(context, w)); variable_push(context, variable_new_int(context, h)); return variable_new_src(context, 3); }
struct variable *src(struct context *context, enum Opcode op, struct byte_array *program) { int32_t size = serial_decode_int(program); DEBUGPRINT("%s %d\n", NUM_TO_STRING(opcodes, op), size); if (!context->runtime) return NULL; struct variable *v = variable_new_src(context, size); stack_push(context->operand_stack, v); return v; }
void vm_call_src(struct context *context, struct variable *func) { struct map *env = NULL; if (func->map) { struct variable *v = (struct variable*)variable_map_get(context, func, byte_array_from_string(RESERVED_ENV)); if (v) env = v->map; } struct program_state *state = (struct program_state*)stack_peek(context->program_stack, 0); struct variable *s = (struct variable*)stack_peek(context->operand_stack, 0); state->args = array_copy(s->list); INDENT // call the function switch (func->type) { case VAR_FNC: run(context, func->str, env, false); break; case VAR_C: { struct variable *v = func->cfnc(context); if (!v) v = variable_new_src(context, 0); else if (v->type != VAR_SRC) { // convert to VAR_SRC variable stack_push(context->operand_stack, v); v = variable_new_src(context, 1); } stack_push(context->operand_stack, v); // push the result } break; case VAR_NIL: vm_exit_message(context, "can't find function"); break; default: vm_exit_message(context, "not a function"); break; } state->args = NULL; UNDENT }
struct variable *sys_window(struct context *context) { struct variable *value = (struct variable*)stack_pop(context->operand_stack); struct variable *uictx = param_var(value, 1); struct variable *logic = param_var(value, 2); context->singleton->keepalive = true; // so that context_del isn't called when UI is active int32_t w=0, h=0; hal_window(context, uictx, &w, &h, logic); variable_push(context, variable_new_int(context, w)); variable_push(context, variable_new_int(context, h)); return variable_new_src(context, 2); }
struct variable *sys_fileattr(struct context *context) { struct variable *args = (struct variable*)stack_pop(context->operand_stack); struct variable *path = param_var(args, 1); const char *path2 = byte_array_to_string(path->str); long siz = file_size(path2); long mod = file_timestamp(path2); struct variable *siz2 = variable_new_int(context, (int32_t)siz); struct variable *mod2 = variable_new_int(context, (int32_t)mod); variable_push(context, siz2); variable_push(context, mod2 ); struct variable *result = variable_new_src(context, 2); return result; }
void vm_call(struct context *context, struct variable *func, struct variable *arg, ...) { // add variables from vararg if (arg) { va_list argp; va_start(argp, arg); struct variable *s = (struct variable*)stack_peek(context->operand_stack, 0); if (s && s->type == VAR_SRC) s = (struct variable*)stack_pop(context->operand_stack); else s = variable_new_src(context, 0); for (; arg; arg = va_arg(argp, struct variable*)) array_add(s->list, arg); va_end(argp); variable_push(context, s); } vm_call_src(context, func); }
void func_call(struct context *context, enum Opcode op, struct byte_array *program, struct variable *indexable) { struct variable *func = context->runtime ? (struct variable*)variable_pop(context): NULL; struct variable *s = src(context, op, program); if (!context->runtime) return; if (indexable) array_insert(s->list, 0, indexable); // self vm_call_src(context, func); struct variable *result = (struct variable*)stack_peek(context->operand_stack, 0); bool resulted = (result && result->type == VAR_SRC); if (!resulted) { // need a result for an expression, so pretend it returned nil struct variable *v = variable_new_src(context, 0); array_add(v->list, variable_new_nil(context)); stack_push(context->operand_stack, v); } }
// ascii to integer struct variable *sys_atoi(struct context *context) { struct variable *value = (struct variable*)stack_pop(context->operand_stack); char *str = (char*)((struct variable*)array_get(value->list.ordered, 1))->str->data; uint32_t offset = value->list.ordered->length > 2 ? ((struct variable*)array_get(value->list.ordered, 2))->integer : 0; int n=0, i=0; bool negative = false; if (str[offset] == '-') { negative = true; i++; }; while (isdigit(str[offset+i])) n = n*10 + str[offset + i++] - '0'; n *= negative ? -1 : 1; variable_push(context, variable_new_int(context, n)); variable_push(context, variable_new_int(context, i)); return variable_new_src(context, 2); }