void ps_remove(pageset_t ps, int page) { if (ps->npages == 0) return; int l = ps_pop(ps); if (l == page) return; for (int i = 0; i < ps->npages; i++) if (ps->data[i] == page) { ps->data[i] = l; return; } ps_push(ps, l); }
static int sub_ps_optiop(t_ps *ps, int op_num, int op_max, int p) { int c; if (p != SB && p != SS && (c = ps_swap(ps, 'b'))) { if (ps_optiop(ps, 1 + op_num, op_max, c)) return (1); ps_swap(ps, 'b'); } if (p != SS && p != SA && p != SB && (c = ps_dswap(ps))) { if (ps_optiop(ps, 1 + op_num, op_max, c)) return (1); ps_dswap(ps); } if (p != PB && (c = ps_push(ps, 'a'))) { if (ps_optiop(ps, 1 + op_num, op_max, c)) return (1); ps_push(ps, 'b'); } return (sub2_ps_optiop(ps, op_num, op_max, c)); }
static int sub2_ps_optiop(t_ps *ps, int op_num, int op_max, int p) { int c; if (p != PA && (c = ps_push(ps, 'b'))) { if (ps_optiop(ps, 1 + op_num, op_max, c)) return (1); ps_push(ps, 'a'); } if (p != RRA && p != RRR && (c = ps_rotate(ps, 'a'))) { if (ps_optiop(ps, 1 + op_num, op_max, c)) return (1); ps_rrotate(ps, 'a'); } if (p != RA && p != RR && (c = ps_rrotate(ps, 'a'))) { if (ps_optiop(ps, 1 + op_num, op_max, c)) return (1); ps_rotate(ps, 'a'); } return (0); }
void Interactive(HPSCRIPTVM v) { #define MAXINPUT 1024 PSChar buffer[MAXINPUT]; PSInteger blocks =0; PSInteger string=0; PSInteger retval=0; PSInteger done=0; PrintVersionInfos(); ps_pushroottable(v); ps_pushstring(v,_SC("quit"),-1); ps_pushuserpointer(v,&done); ps_newclosure(v,quit,1); ps_setparamscheck(v,1,NULL); ps_newslot(v,-3,PSFalse); ps_pop(v,1); while (!done) { PSInteger i = 0; scprintf(_SC("\nps>")); for(;;) { int c; if(done)return; c = getchar(); if (c == _SC('\n')) { if (i>0 && buffer[i-1] == _SC('\\')) { buffer[i-1] = _SC('\n'); } else if(blocks==0)break; buffer[i++] = _SC('\n'); } else if (c==_SC('}')) {blocks--; buffer[i++] = (PSChar)c;} else if(c==_SC('{') && !string){ blocks++; buffer[i++] = (PSChar)c; } else if(c==_SC('"') || c==_SC('\'')){ string=!string; buffer[i++] = (PSChar)c; } else if (i >= MAXINPUT-1) { scfprintf(stderr, _SC("ps : input line too long\n")); break; } else{ buffer[i++] = (PSChar)c; } } buffer[i] = _SC('\0'); if(buffer[0]==_SC('=')){ scsprintf(ps_getscratchpad(v,MAXINPUT),(size_t)MAXINPUT,_SC("return (%s)"),&buffer[1]); memcpy(buffer,ps_getscratchpad(v,-1),(scstrlen(ps_getscratchpad(v,-1))+1)*sizeof(PSChar)); retval=1; } i=scstrlen(buffer); if(i>0){ PSInteger oldtop=ps_gettop(v); if(PS_SUCCEEDED(ps_compilebuffer(v,buffer,i,_SC("interactive console"),PSTrue))){ ps_pushroottable(v); if(PS_SUCCEEDED(ps_call(v,1,retval,PSTrue)) && retval){ scprintf(_SC("\n")); ps_pushroottable(v); ps_pushstring(v,_SC("print"),-1); ps_get(v,-2); ps_pushroottable(v); ps_push(v,-4); ps_call(v,2,PSFalse,PSTrue); retval=0; scprintf(_SC("\n")); } } ps_settop(v,oldtop); } } }
static int F() { // function declaration Tdata_type ftype; switch (token.type) { case TT_INT: case TT_DOUBLE: case TT_STRING: // rule: type idf ( AL ) FD ftype = get_type(); tmp_ftype = ftype; next(); check(TT_ID); try(add_func(ftype, token.p_string)); next(); term(TT_L_BRACKET); call(AL); term(TT_R_BRACKET); return(FD); default: return ERR_PARSER; } } static int AL() { // first function argument switch (token.type) { case TT_INT: case TT_DOUBLE: case TT_STRING: // rule: AL -> AD AL2 call(AD); return(AL2); default: // rule: AL -> eps return OK; } } static int AL2() { // remaining function arguments switch (token.type) { case TT_COMMA: // rule: AL2 -> , AD AL2 next(); call(AD); return(AL2); default: // rule: AL2 -> eps return OK; } } static int AD() { // argument Tdata_type atype; switch (token.type) { case TT_INT: case TT_DOUBLE: case TT_STRING: // rule: AD -> type id atype = get_type(); next(); check(TT_ID); try(add_param(atype, token.p_string)); next(); return OK; default: return ERR_PARSER; } } static int FD() { // function definition unsigned i; switch (token.type) { case TT_SEMICOLON: // rule: FD -> ; try(func_declaration()); next(); return OK; case TT_OPEN_BRACKET: // rule: FD -> { STL } i = get_line(); try(func_definition(i)); // instruction pointer next(); call(STL); term(TT_CLOSE_BRACKET); remove_block(); generate(I_ERR, NULL, NULL, NULL); // no return => runtime error return OK; default: return ERR_PARSER; } } static int STL() { // stat list switch (token.type) { case TT_CLOSE_BRACKET: // rule: STL -> eps return OK; default: // rule: STL -> S STL call(S); return(STL); } } static int S() { // stat unsigned i; Tlocal_sym_tab_node *conv; switch (token.type) { case TT_AUTO: case TT_INT: case TT_DOUBLE: case TT_STRING: // rule: S -> D ; call(D); term(TT_SEMICOLON); return OK; case TT_OPEN_BRACKET: // rule: S -> { STL } next(); try(add_block()); call(STL); term(TT_CLOSE_BRACKET); remove_block(); return OK; case TT_IF: // rule: S -> if ( E ) S else S next(); term(TT_L_BRACKET); call(E); try(type_compare(tmp_psitem.type, TYPE_INT)); if (tmp_psitem.type != TYPE_INT) { try(tmp_var(TYPE_INT, &conv)); generate(I_CONVERT, tmp_psitem.value.ptr, NULL, conv); } else { conv = tmp_psitem.value.ptr; } Tlocal_sym_tab_node *label; try(tmp_var(TYPE_INT, &label)); generate(I_JUMPIFN, conv, label, NULL); term(TT_R_BRACKET); call(S); Tlocal_sym_tab_node *endif; try(tmp_var(TYPE_INT, &endif)); generate(I_JUMP, NULL, endif, NULL); i = get_line(); set_var_value_int(label->name, i); call(ELSE); i = get_line(); set_var_value_int(endif->name, i); return OK; case TT_FOR: // rule: S -> for ( D ; E ; E ) S try(add_block()); next(); term(TT_L_BRACKET); call(D); term(TT_SEMICOLON); Tlocal_sym_tab_node *cond; try(tmp_var(TYPE_INT, &cond)); i = get_line(); set_var_value_int(cond->name, i); call(E); try(type_compare(tmp_psitem.type, TYPE_INT)); if (tmp_psitem.type != TYPE_INT) { try(tmp_var(TYPE_INT, &conv)); generate(I_CONVERT, tmp_psitem.value.ptr, NULL, conv); } else { conv = tmp_psitem.value.ptr; } Tlocal_sym_tab_node *endfor; try(tmp_var(TYPE_INT, &endfor)); generate(I_JUMPIFN, conv, endfor, NULL); Tlocal_sym_tab_node *statlist; try(tmp_var(TYPE_INT, &statlist)); generate(I_JUMP, NULL, statlist, NULL); Tlocal_sym_tab_node *assign; try(tmp_var(TYPE_INT, &assign)); i = get_line(); set_var_value_int(assign->name, i); term(TT_SEMICOLON); call(E); generate(I_JUMP, NULL, cond, NULL); i = get_line(); set_var_value_int(statlist->name, i); term(TT_R_BRACKET); call(S); generate(I_JUMP, NULL, assign, NULL); i = get_line(); set_var_value_int(endfor->name, i); remove_block(); return OK; case TT_WHILE: // rule: S -> while ( E ) S next(); term(TT_L_BRACKET); Tlocal_sym_tab_node *wcond; try(tmp_var(TYPE_INT, &wcond)); i = get_line(); set_var_value_int(wcond->name, i); call(E); try(type_compare(tmp_psitem.type, TYPE_INT)); if (tmp_psitem.type != TYPE_INT) { try(tmp_var(TYPE_INT, &conv)); generate(I_CONVERT, tmp_psitem.value.ptr, NULL, conv); } else { conv = tmp_psitem.value.ptr; } Tlocal_sym_tab_node *endwhile; try(tmp_var(TYPE_INT, &endwhile)); generate(I_JUMPIFN, conv, endwhile, NULL); term (TT_R_BRACKET); call(S); generate(I_JUMP, NULL, wcond, NULL); i = get_line(); set_var_value_int(endwhile->name, i); return OK; case TT_DO: // rule: S -> do S while ( E ) ; next(); Tlocal_sym_tab_node *dwbody; try(tmp_var(TYPE_INT, &dwbody)); i = get_line(); set_var_value_int(dwbody->name, i); call(S); term(TT_WHILE); term(TT_L_BRACKET); call(E); try(type_compare(tmp_psitem.type, TYPE_INT)); if (tmp_psitem.type != TYPE_INT) { try(tmp_var(TYPE_INT, &conv)); generate(I_CONVERT, tmp_psitem.value.ptr, NULL, conv); } else { conv = tmp_psitem.value.ptr; } generate(I_JUMPIF, conv, dwbody, NULL); term(TT_R_BRACKET); term(TT_SEMICOLON); return OK; case TT_RETURN: // rule: S -> return E ; next(); call(E); try(type_compare(tmp_ftype, tmp_psitem.type)); if (tmp_psitem.type != tmp_ftype) { try(tmp_var(tmp_ftype, &conv)); generate(I_CONVERT, tmp_psitem.value.ptr, NULL, conv); } else { conv = tmp_psitem.value.ptr; } generate(I_RETURN, conv, NULL, NULL); term(TT_SEMICOLON); return OK; case TT_CIN: // rule: S -> cin >> id IN ; next(); term(TT_IN); check(TT_ID); if (!var_exists(token.p_string)) return ERR_UNDEF; Tlocal_sym_tab_node *var = get_var(token.p_string); generate(I_CIN, NULL, NULL, var); next(); call(IN); term(TT_SEMICOLON); return OK; case TT_COUT: // rule: S -> cout << E OUT ; next(); term(TT_OUT); call(E); generate(I_COUT, tmp_psitem.value.ptr, NULL, NULL); call(OUT); term(TT_SEMICOLON); return OK; default: // rule: S -> E ; call(E); term(TT_SEMICOLON); return OK; } } static int D() { // variable declaration Tdata_type vtype; switch (token.type) { case TT_AUTO: case TT_INT: case TT_DOUBLE: case TT_STRING: // rule: D -> type id I vtype = get_type(); tmp_type = vtype; next(); check(TT_ID); try(add_var(vtype, token.p_string)); try(tmpstr(token.p_string)); next(); return(I); default: return ERR_PARSER; } } static int I() { // variable definition switch (token.type) { case TT_ASSIGN: // rule: I -> = E next(); call(E); try(assign_type_compare(tmp_buffer.str, tmp_psitem.type)); Tlocal_sym_tab_node *var = get_var(tmp_buffer.str); Tlocal_sym_tab_node *conv; if (tmp_psitem.type != var->data_type) { try(tmp_var(var->data_type, &conv)); generate(I_CONVERT, tmp_psitem.value.ptr, NULL, conv); } else { conv = tmp_psitem.value.ptr; } generate(I_ASSIGN, conv, NULL, var); return OK; default: // rule: I -> eps if (tmp_type == TYPE_AUTO) return ERR_AUTO; return OK; } } static int ELSE() { // else switch (token.type) { case TT_ELSE: // rule: ELSE -> else S next(); return(S); default: // rule: ELSE -> eps return OK; } } static int IN() { // input variables switch (token.type) { case TT_IN: // rule: IN -> >> id IN next(); check(TT_ID); if (!var_exists(token.p_string)) return ERR_UNDEF; Tlocal_sym_tab_node *var = get_var(token.p_string); generate(I_CIN, NULL, NULL, var); next(); return(IN); default: // rule: IN -> eps return OK; } } static int OUT() { // output expressions switch (token.type) { case TT_OUT: // rule: OUT -> << E OUT next(); call(E); generate(I_COUT, tmp_psitem.value.ptr, NULL, NULL); return(OUT); default: // rule: OUT -> eps return OK; } } static int E() { // expression Tpsa_stack *psa_stack = ps_init(); ps_push(psa_stack, OP_END); if (get_prec(OP_END) == ' ') { fprintf(stderr, "Syntax error: 'expression' expected, but '%s' given.\n", token_[token.type]); return ERR_PARSER; } int err; do { Tps_item *ps_item = ps_first_term(psa_stack); switch (get_prec(ps_item->op)) { case '=': err = ps_push_token(psa_stack); if (err != OK) { ps_destroy(psa_stack); return err; } next(); break; case '<': err = ps_ins_after(psa_stack, ps_item, OP_EXPR); if (err != OK) { ps_destroy(psa_stack); return err; } err = ps_push_token(psa_stack); if (err != OK) { ps_destroy(psa_stack); return err; } next(); break; case '>': err = psa(psa_stack); if (err != OK) { ps_destroy(psa_stack); return err; } break; } } while (get_prec(ps_first_term(psa_stack)->op) != ' '); Tps_item *top = ps_top(psa_stack); if (top->op != OP_NTERM || ps_prev(psa_stack)->op != OP_END) { fprintf(stderr, "Syntax error: unexpected '%s'\n", token_[token.type]); return ERR_PARSER; } tmp_psitem.type = top->type; tmp_psitem.value = top->value; ps_destroy(psa_stack); return OK; } int parse() { next(); strInit(&tmp_buffer); int err = P(); strFree(&tmp_buffer); return err; }