void *hvm_call_function(const char *func_call, hefesto_var_list_ctx **lo_vars, hefesto_var_list_ctx **gl_vars, hefesto_func_list_ctx *functions) { char *f_lbl, *fc, *fl; hefesto_func_list_ctx *function, *curr_exec_fp; void *result = NULL; struct stacked_function_execution_point_ctx *sv_p; if (func_call == NULL) return NULL; f_lbl = (char *) hefesto_mloc(HEFESTO_MAX_BUFFER_SIZE); memset(f_lbl, 0, HEFESTO_MAX_BUFFER_SIZE); for (fc = (char *) func_call; is_hefesto_blank(*fc); fc++); for (fl = f_lbl; *fc != 0 && *fc != '(' && !is_hefesto_blank(*fc); fc++, fl++) *fl = *fc; *fl = 0; for (fc = (char *)func_call; is_hefesto_blank(*fc); fc++); curr_exec_fp = hvm_get_current_executed_function(); if ((function = get_hefesto_func_list_ctx_scoped_name(f_lbl, (curr_exec_fp) ? curr_exec_fp->decl_at : NULL, functions))) { // INFO(Santiago): saves the execution context. sv_p = hvm_save_execution_point(function); hvm_set_current_executed_function(function); hvm_init_function_args(fc+1, lo_vars, gl_vars, functions, &function); result = hvm_exec_function(function, &function->vars, gl_vars, functions); // INFO(Santiago): restores the execution context saved above. hvm_restore_execution_point(&function, sv_p); del_stacked_function_execution_point_ctx(sv_p); } free(f_lbl); return result; }
char *infix2postfix(const char *expr, const size_t esize, const hefesto_int_t main_call) { const char *efinis = expr + esize, *e; char *t, *term, *tt; hefesto_common_stack_ctx *sp = NULL, *dp = NULL; hefesto_common_list_ctx *lp = NULL, *l; hefesto_int_t p, tp; size_t sz; hefesto_int_t bracket = 0; char *indexing; char *iexpr; char *args; size_t offset, count; hefesto_int_t state = 0; term = (char *) hefesto_mloc(HEFESTO_MAX_BUFFER_SIZE); memset(term, 0, HEFESTO_MAX_BUFFER_SIZE); t = term; *t = 0; for (e = expr; e != efinis; e++) { if (*e == 0) break; if (*e == '\n' || *e == '\r' || *e == '\t' || *e == ' ') continue; if (*e != 0 && *e != ' ' && *e != '\n' && *e != '\r' && *e != '\t' && *e != '(' && *e != ')' && !is_op(*e) && *e != '[' && !is_hefesto_string_tok(*e)) { *t = *e; t++; *t = 0; continue; } else if (is_hefesto_string_tok(*e)) { offset = 0; iexpr = get_next_string(e, &offset); e += offset; for (indexing = iexpr; *indexing != 0; indexing++, t++) *t = *indexing; free(iexpr); *t = 0; } else if (*e == '(' && !is_hefesto_numeric_constant(term) && !is_hefesto_string(term) && *term && *term != '(' && !is_op(*term)) { bracket++; offset = 0; args = get_next_call_args(e, &offset); if (*args) { iexpr = infix2postfix_function_args(args, strlen(args)); tt = t; for (indexing = iexpr; *indexing != 0; indexing++, t++) *t = *indexing; *t = 0; free(iexpr); count = 0; for (t = tt; *t != 0; t++) { if (*t == '(') { count++; } else if (*t == ')') { count--; } else if (*t == '"') { t++; while (*t != '"' && *t != 0) { t++; if (*t == '\\') t += 2; } } } // WARN(Santiago): null buffer position skipping avoidance. while (*t == 0 && t != term) { t--; } t++; tt = ((char *)e + offset); while (is_hefesto_blank(*tt)) tt++; // can't add one more ')' because this is a function that is an // argument of another function if (*tt == ',') count--; while (count > 0) { *t = ')'; t++; count--; } *t = 0; } e += offset; free(args); if (*e == ')') e++; } else if ((*e == '-' || *e == '+') && t == term && isdigit(*(e+1)) && state == 0) { *t = *e; t++; continue; } if ((is_op(*e) || *e == '(' || *e == ')') && t == term) { *t = *e; t++; *t = 0; if (is_op(*(e+1)) && *e != '(' && *e != ')') { // composed operands *t = *(e+1); e++; t++; *t = 0; } state = 0; } else if ((e + 1) != efinis) e--; if (strcmp(term,"(") == 0) { sp = hefesto_common_stack_ctx_push(sp, (void *) term, t - term, HEFESTO_VAR_TYPE_UNTYPED); } else if(strcmp(term, ")") == 0) { t = (char *)hefesto_common_stack_ctx_data_on_top(sp); if (t && strcmp(t, "(") != 0) { while (sp && sp->data != NULL && strcmp(sp->data, "(") != 0) { lp = add_data_to_hefesto_common_list_ctx(lp, hefesto_common_stack_ctx_data_on_top(sp), hefesto_common_stack_ctx_dsize_on_top(sp)); dp = hefesto_common_stack_ctx_on_top(sp); sp = hefesto_common_stack_ctx_pop(sp); del_hefesto_common_stack_ctx(dp); } } dp = hefesto_common_stack_ctx_on_top(sp); sp = hefesto_common_stack_ctx_pop(sp); del_hefesto_common_stack_ctx(dp); } else if ((p = get_op_precedence(term)) != -1) { tp = get_op_precedence(hefesto_common_stack_ctx_data_on_top(sp)); while (tp != -1 && tp >= p) { lp = add_data_to_hefesto_common_list_ctx(lp, hefesto_common_stack_ctx_data_on_top(sp), hefesto_common_stack_ctx_dsize_on_top(sp)); dp = hefesto_common_stack_ctx_on_top(sp); sp = hefesto_common_stack_ctx_pop(sp); del_hefesto_common_stack_ctx(dp); tp = get_op_precedence(hefesto_common_stack_ctx_data_on_top(sp)); } sp = hefesto_common_stack_ctx_push(sp, (void *) term, t - term, HEFESTO_VAR_TYPE_UNTYPED); } else { lp = add_data_to_hefesto_common_list_ctx(lp, term, t - term); state = 1; } t = term; *t = 0; } if (*term) { sp = hefesto_common_stack_ctx_push(sp, (void *) term, t - term, HEFESTO_VAR_TYPE_UNTYPED); } while (!hefesto_common_stack_ctx_empty(sp)) { lp = add_data_to_hefesto_common_list_ctx(lp, hefesto_common_stack_ctx_data_on_top(sp), hefesto_common_stack_ctx_dsize_on_top(sp)); dp = hefesto_common_stack_ctx_on_top(sp); sp = hefesto_common_stack_ctx_pop(sp); del_hefesto_common_stack_ctx(dp); } free(term); for (p = 0, sz = 0, l = lp; l; l = l->next, p++) { sz += l->dsize; } sz += (size_t) p; term = (char *) hefesto_mloc(sz); *term = 0; for (l = lp; l; l = l->next) { if (*(char *)l->data == '(') continue; strncat(term, (char *) l->data, sz - 1); if (l->next && *(char *)l->next->data != '[') strncat(term, " ", sz - 1); } del_hefesto_common_list_ctx(lp); return term; }