SemVal *p_execute(SemVal *arr) { register size_t count; SemVal tmp, *argp, /* pointer to args */ e; count = arr->type; /* get argument count */ if (count < 6) /* to few arguments */ { util_semantic(gp_illegalArgCount, "execute"); return (arr); /* dummy args return */ } argp = codestruc(arr, 0); /* point to first arg */ e = *(argp + 2); /* cmd head info at e */ p_callRss(&e, f_cmd_head); /* code for cmd_head at e */ p_callRss(argp + 3, f_arg_head); /* code for arg_head */ p_catCode(&e, argp + 3); /* code appended to e*/ p_callRss(&argp[count - 2], f_arg_tail); /* code for arg_tail */ p_catCode(&e, &argp[count - 2]); /* code appended to e*/ p_callRss(&argp[count - 1], f_cmd_tail); /* code for cmd_tail */ p_catCode(&e, &argp[count - 1]); /* code appended to e*/ /* keep variable # of args */ memmove(argp + 2, argp + 4, (count - 2) * sizeof(SemVal)); arr->type -= 4; /* remove 4 arguments */ p_catCode(&e, p_specials(f_exec, arr)); /* catenate call-code */ free(gp_stringbuf); /* make sure empty string */ gp_stringbuf = rss_strdup(""); /* is pushed */ tmp = *p_stackFrame(e_str | e_const); /* empty string argument */ p_expr2stack(&tmp); p_catCode(&e, &tmp); /* empty string on the stack */ p_generateCode(&e, op_call_rss, f_cmd_tail); /* used with cmd_tail..cmd_head */ p_generateCode(&e, op_call_rss, f_arg_tail); p_generateCode(&e, op_call_rss, f_arg_head); p_callRss(&e, f_cmd_head); *arr = e; return arr; }
SemVal *p_optIntSpecial(ExprType type, SemVal *larg, SemVal *rarg) { SemVal tmp; p_expr2stack(larg); /* arg to stack */ if (!test_type(larg, e_int)) /* no first int arg */ { /* prefix the first argument */ rarg = p_insertArg(larg, rarg); /* make 0-argument */ tmp = *p_stackFrame(e_int | e_const); larg = &tmp; /* larg points to inserted arg */ } return p_specials(type, p_insertArg(larg, rarg)); }
void p_makeFrame() { if (symtab_nLocals()) { SemVal e = *p_stackFrame(0); /* initialize empty frame */ p_pushDead(); gp_dead[gp_dead_sp] = 0; p_generateCode(&e, op_frame); /* generate frame instruction */ p_popDead(); util_out(gp_bin, e.code, e.codelen); /* write to gp_bin */ msg("write code frame of %u bytes", e.codelen); free(e.code); } }
SemVal *p_twoArgs(ExprType type, SemVal *larg, SemVal *rarg) { register int ok; msg("start"); p_expr2stack(larg); /* arg to stack */ p_expr2stack(rarg); /* arg to stack */ switch ((FunNr)type) { case f_fgets: ok = test_type(larg, e_str) && test_type(rarg, e_list); break; case f_element: /* f_element */ /* first arg must be int */ if ( (ok = test_type(larg, e_int)) ) { /* second arg == list: ok */ if (!(ok = test_type(rarg, e_list))) { /* second arg == string: ok */ ok = test_type(rarg, e_str); type = f_str_el; /* string element requested */ } } break; case f_resize: ok = test_type(larg, e_str) && test_type(rarg, e_int); break; case f_listfind: ok = test_type(larg, e_list) && test_type(rarg, e_str); break; case f_listunion: ok = test_type(larg, e_list) && test_type(rarg, e_str | e_list); break; default: /* case f_strchr: case f_strtok: case f_c_ext: case f_c_base: case f_c_path: case f_strfind: */ ok = larg->type & rarg->type & e_str; } msg("types test %d, funstring: %x", ok, type); if (ok) { p_catCode(rarg, larg); /* make one code vector */ p_callRss(rarg, type); } else { util_semantic(gp_typeConflict, gp_funstring[type]); p_discard(larg); rarg = p_stackFrame(e_null); } msg("leaving"); return rarg; }