void outcode(tree *t, int eflag) { int p, q; tree *tt; if(t==0) return; if(t->type!=NOT && t->type!=';') runq->iflast = 0; switch(t->type){ default: pfmt(err, "bad type %d in outcode\n", t->type); break; case '$': emitf(Xmark); outcode(c0, eflag); emitf(Xdol); break; case '"': emitf(Xmark); outcode(c0, eflag); emitf(Xqdol); break; case SUB: emitf(Xmark); outcode(c0, eflag); emitf(Xmark); outcode(c1, eflag); emitf(Xsub); break; case '&': emitf(Xasync); if(havefork){ p = emiti(0); outcode(c0, eflag); emitf(Xexit); stuffdot(p); } else emits(fnstr(c0)); break; case ';': outcode(c0, eflag); outcode(c1, eflag); break; case '^': emitf(Xmark); outcode(c1, eflag); emitf(Xmark); outcode(c0, eflag); emitf(Xconc); break; case '`': emitf(Xbackq); if(havefork){ p = emiti(0); outcode(c0, 0); emitf(Xexit); stuffdot(p); } else emits(fnstr(c0)); break; case ANDAND: outcode(c0, 0); emitf(Xtrue); p = emiti(0); outcode(c1, eflag); stuffdot(p); break; case ARGLIST: outcode(c1, eflag); outcode(c0, eflag); break; case BANG: outcode(c0, eflag); emitf(Xbang); break; case PCMD: case BRACE: outcode(c0, eflag); break; case COUNT: emitf(Xmark); outcode(c0, eflag); emitf(Xcount); break; case FN: emitf(Xmark); outcode(c0, eflag); if(c1){ emitf(Xfn); p = emiti(0); emits(fnstr(c1)); outcode(c1, eflag); emitf(Xunlocal); /* get rid of $* */ emitf(Xreturn); stuffdot(p); } else emitf(Xdelfn); break; case IF: outcode(c0, 0); emitf(Xif); p = emiti(0); outcode(c1, eflag); emitf(Xwastrue); stuffdot(p); break; case NOT: if(!runq->iflast) yyerror("`if not' does not follow `if(...)'"); emitf(Xifnot); p = emiti(0); outcode(c0, eflag); stuffdot(p); break; case OROR: outcode(c0, 0); emitf(Xfalse); p = emiti(0); outcode(c1, eflag); stuffdot(p); break; case PAREN: outcode(c0, eflag); break; case SIMPLE: emitf(Xmark); outcode(c0, eflag); emitf(Xsimple); if(eflag) emitf(Xeflag); break; case SUBSHELL: emitf(Xsubshell); if(havefork){ p = emiti(0); outcode(c0, eflag); emitf(Xexit); stuffdot(p); } else emits(fnstr(c0)); if(eflag) emitf(Xeflag); break; case SWITCH: codeswitch(t, eflag); break; case TWIDDLE: emitf(Xmark); outcode(c1, eflag); emitf(Xmark); outcode(c0, eflag); emitf(Xmatch); if(eflag) emitf(Xeflag); break; case WHILE: q = codep; outcode(c0, 0); if(q==codep) emitf(Xsettrue); /* empty condition == while(true) */ emitf(Xtrue); p = emiti(0); outcode(c1, eflag); emitf(Xjump); emiti(q); stuffdot(p); break; case WORDS: outcode(c1, eflag); outcode(c0, eflag); break; case FOR: emitf(Xmark); if(c1){ outcode(c1, eflag); emitf(Xglob); } else{ emitf(Xmark); emitf(Xword); emits(strdup("*")); emitf(Xdol); } emitf(Xmark); /* dummy value for Xlocal */ emitf(Xmark); outcode(c0, eflag); emitf(Xlocal); p = emitf(Xfor); q = emiti(0); outcode(c2, eflag); emitf(Xjump); emiti(p); stuffdot(q); emitf(Xunlocal); break; case WORD: emitf(Xword); emits(strdup(t->str)); break; case DUP: if(t->rtype==DUPFD){ emitf(Xdup); emiti(t->fd0); emiti(t->fd1); } else{ emitf(Xclose); emiti(t->fd0); } outcode(c1, eflag); emitf(Xpopredir); break; case PIPEFD: emitf(Xpipefd); emiti(t->rtype); if(havefork){ p = emiti(0); outcode(c0, eflag); emitf(Xexit); stuffdot(p); } else { emits(fnstr(c0)); } break; case REDIR: emitf(Xmark); outcode(c0, eflag); emitf(Xglob); switch(t->rtype){ case APPEND: emitf(Xappend); break; case WRITE: emitf(Xwrite); break; case READ: case HERE: emitf(Xread); break; case RDWR: emitf(Xrdwr); break; } emiti(t->fd0); outcode(c1, eflag); emitf(Xpopredir); break; case '=': tt = t; for(;t && t->type=='=';t = c2); if(t){ for(t = tt;t->type=='=';t = c2){ emitf(Xmark); outcode(c1, eflag); emitf(Xmark); outcode(c0, eflag); emitf(Xlocal); } outcode(t, eflag); for(t = tt; t->type=='='; t = c2) emitf(Xunlocal); } else{ for(t = tt;t;t = c2){ emitf(Xmark); outcode(c1, eflag); emitf(Xmark); outcode(c0, eflag); emitf(Xassign); } } t = tt; /* so tests below will work */ break; case PIPE: emitf(Xpipe); emiti(t->fd0); emiti(t->fd1); if(havefork){ p = emiti(0); q = emiti(0); outcode(c0, eflag); emitf(Xexit); stuffdot(p); } else { emits(fnstr(c0)); q = emiti(0); } outcode(c1, eflag); emitf(Xreturn); stuffdot(q); emitf(Xpipewait); break; } if(t->type!=NOT && t->type!=';') runq->iflast = t->type==IF; else if(c0) runq->iflast = c0->type==IF; }
data eval_routine(routineNode rout, symrec ** symTable, list * routineList){ data res; //recupera la routine e controlla se esiste routine * r = getRoutine(rout.name, routineList); if(r==NULL){ yyerror("accessing unexisting procedure or function.."); exit(NO_SUCH_PROCEDURE); } //dalla routine prendi gli i parametri form * forms; forms = r->parameters; //dal nodo passato prendi gli argomenti actual * aes; aes = rout.args; //HERE HAPPENS typechecking //we do minimal typechecking on length - the rest is left as exercise int flen = formLength(forms); int alen = actLength(aes); if(flen!=alen){ yyerror("args len is different from formal length"); } //qui fai il bind tra parametri e argomenti, mettendoli nella symbol TABLE // da ripassare a tutta la funzione di eval, usando il nodo expr come funzione di partenza symrec * rSymrec; rSymrec = NULL; for(int i = 0; i< flen; i++){ form * f = getFormAtIndex(i,forms); if(f == NULL){ //TODO place here the number of forms already used yyerror("execeed form list"); exit(FORM_LIST_EXCEEDED); } actual * a = getActualAtIndex(i,aes); if (a == NULL){ //TODO place here the number of args already used yyerror("execeed args list"); exit(ARGS_LIST_EXCEEDED); } //eseguo dichiarazione e assegnazione nella symbol table che userà la routine type * t = basicDec(f->bt); //TODO: considered only basic type treeNode * dec = varDec(f->name,false,t); eval_identifier_declaration(dec->value.dec,&rSymrec,routineList); //cerca la var appena inserita e fai l'assignement identifier id; id.name = malloc(strlen(f->name)+1); strcpy(id.name,f->name); if (f->byref){ if (a->expr->type != identifier_type){ yyerror("incompatible arg for pass by ref"); exit(ARGS_LIST_EXCEEDED); } symrec * tmp = getSymbolFromIdentifier(id,&rSymrec); symrec * tmp2 = getSymbolFromIdentifier(a->expr->value.id, symTable); tmp->value = tmp2->value; } else { //eval expr in current env, then assign it symrec * tmp = getSymbolFromIdentifier(id,&rSymrec); data e = eval(a->expr, symTable,routineList); spec_assignment(tmp,e, &rSymrec, routineList); } // printf("%s", ); } //eventually with return res = eval... eval(r->statementList, &rSymrec,routineList); if(r->type == procedure){ res.type = no_op; }else{ //qui cerca nella routine, nel suo return value il valore, puliscilo e resituicilo res = *r->returnValue; r->returnValue = NULL; } return res; }
// // fixed point input // required syntax is [+-][0[x]]d* // void mpatofix(Mpint *a, char *as) { int c, f; char *s; s = as; f = 0; mpmovecfix(a, 0); c = *s++; switch(c) { case '-': f = 1; case '+': c = *s++; if(c != '0') break; case '0': goto oct; } while(c) { if(c >= '0' && c <= '9') { mpmulcfix(a, 10); mpaddcfix(a, c-'0'); c = *s++; continue; } goto bad; } goto out; oct: c = *s++; if(c == 'x' || c == 'X') goto hex; while(c) { if(c >= '0' && c <= '7') { mpmulcfix(a, 8); mpaddcfix(a, c-'0'); c = *s++; continue; } goto bad; } goto out; hex: c = *s++; while(c) { if(c >= '0' && c <= '9') { mpmulcfix(a, 16); mpaddcfix(a, c-'0'); c = *s++; continue; } if(c >= 'a' && c <= 'f') { mpmulcfix(a, 16); mpaddcfix(a, c+10-'a'); c = *s++; continue; } if(c >= 'A' && c <= 'F') { mpmulcfix(a, 16); mpaddcfix(a, c+10-'A'); c = *s++; continue; } goto bad; } out: if(f) mpnegfix(a); return; bad: yyerror("set ovf in mpatov: %s", as); mpmovecfix(a, 0); }
void typecheckrange(Node *n) { char *why; Type *t, *t1, *t2; Node *v1, *v2; NodeList *ll; // delicate little dance. see typecheckas2 for(ll=n->list; ll; ll=ll->next) if(ll->n->defn != n) typecheck(&ll->n, Erv | Easgn); typecheck(&n->right, Erv); if((t = n->right->type) == T) goto out; if(isptr[t->etype] && isfixedarray(t->type)) t = t->type; n->type = t; switch(t->etype) { default: yyerror("cannot range over %lN", n->right); goto out; case TARRAY: t1 = types[TINT]; t2 = t->type; break; case TMAP: t1 = t->down; t2 = t->type; break; case TCHAN: if(!(t->chan & Crecv)) { yyerror("invalid operation: range %N (receive from send-only type %T)", n->right, n->right->type); goto out; } t1 = t->type; t2 = nil; if(count(n->list) == 2) goto toomany; break; case TSTRING: t1 = types[TINT]; t2 = runetype; break; } if(count(n->list) > 2) { toomany: yyerror("too many variables in range"); } v1 = n->list->n; v2 = N; if(n->list->next) v2 = n->list->next->n; if(v1->defn == n) v1->type = t1; else if(v1->type != T && assignop(t1, v1->type, &why) == 0) yyerror("cannot assign type %T to %lN in range%s", t1, v1, why); if(v2) { if(v2->defn == n) v2->type = t2; else if(v2->type != T && assignop(t2, v2->type, &why) == 0) yyerror("cannot assign type %T to %lN in range%s", t2, v2, why); } out: typechecklist(n->nbody, Etop); // second half of dance n->typecheck = 1; for(ll=n->list; ll; ll=ll->next) if(ll->n->typecheck == 0) typecheck(&ll->n, Erv | Easgn); }
//We assume here typechecking has already happened data operation(int oper, data e1, data e2){ data res; basic b; //pointer to a funcion that takes two int input and return an int int (*funIntPtr)(int,int); float (*funFloatPtr)(float,float); bool (*funBoolFloatPrt)(float,float); bool (*funBoolIntPrt)(int,int); bool (*funBoolPtr)(bool,bool); funIntPtr = NULL; funFloatPtr= NULL; funBoolFloatPrt = NULL; funBoolIntPrt = NULL; //I look for the function to be called switch (oper) { case MINUS: //*functionPtr = &subInt; switch (e1.b.type) { case basic_int_value:funIntPtr = subInt;break; case basic_float_value:funFloatPtr = subFloat;break; case basic_boolean_value: yyerror("boolean arithmetic operation are NOT_ALLOWED"); exit(NOT_ALLOWED); break; case undef: default: yyerror("operation unmanaged type..."); exit(BUGGY_THE_CLOWN); break; } break; case PLUS : switch (e1.b.type) { case basic_int_value:funIntPtr = addInt;break; case basic_float_value:funFloatPtr = addFloat;break; case basic_boolean_value: yyerror("boolean arithmetic operation are NOT_ALLOWED"); exit(NOT_ALLOWED); break; case undef: default: yyerror("operation unmanaged type..."); exit(BUGGY_THE_CLOWN); break; } break; case MULTIPLY: switch (e1.b.type) { case basic_int_value:funIntPtr = mulInt;break; case basic_float_value:funFloatPtr = mulFloat;break; case basic_boolean_value: yyerror("boolean arithmetic operation are NOT_ALLOWED"); exit(NOT_ALLOWED); break; case undef: default: yyerror("operation unmanaged type..."); exit(BUGGY_THE_CLOWN); break; } break; case DIVIDE : switch (e1.b.type) { case basic_int_value:funIntPtr = divInt;break; case basic_float_value:funFloatPtr = divFloat;break; case basic_boolean_value: yyerror("boolean arithmetic operation are NOT_ALLOWED"); exit(NOT_ALLOWED); break; case undef: default: yyerror("operation unmanaged type..."); exit(BUGGY_THE_CLOWN); break; } break; case LT : { switch (e1.b.type) { case basic_int_value:funBoolIntPrt = ltInt;break; case basic_float_value:funBoolFloatPrt = ltFloat;break; case basic_boolean_value: yyerror("boolean arithmetic operation are NOT_ALLOWED"); exit(NOT_ALLOWED); break; case undef: default: yyerror("operation unmanaged type..."); exit(BUGGY_THE_CLOWN); break; } } break; case GT : {switch (e1.b.type) { case basic_int_value:funBoolIntPrt = gtInt;break; case basic_float_value:funBoolFloatPrt = gtFloat;break; case basic_boolean_value: yyerror("boolean arithmetic operation are NOT_ALLOWED"); exit(NOT_ALLOWED); break; case undef: default: yyerror("operation unmanaged type..."); exit(BUGGY_THE_CLOWN); break; } } break; case GE : {switch (e1.b.type) { case basic_int_value:funBoolIntPrt = geInt;break; case basic_float_value:funBoolFloatPrt = geFloat;break; case basic_boolean_value: yyerror("boolean arithmetic operation are NOT_ALLOWED"); exit(NOT_ALLOWED); break; case undef: default: yyerror("operation unmanaged type..."); exit(BUGGY_THE_CLOWN); break; } } break; case LE : {switch (e1.b.type) { case basic_int_value:funBoolIntPrt = leInt;break; case basic_float_value:funBoolFloatPrt = leFloat;break; case basic_boolean_value: yyerror("boolean arithmetic operation are NOT_ALLOWED"); exit(NOT_ALLOWED); break; case undef: default: yyerror("operation unmanaged type..."); exit(BUGGY_THE_CLOWN); break; } } break; case NE : { switch (e1.b.type) { case basic_int_value:funBoolIntPrt = neInt;break; case basic_float_value:funBoolFloatPrt = neFloat;break; case basic_boolean_value: yyerror("boolean arithmetic operation are NOT_ALLOWED"); exit(NOT_ALLOWED); break; case undef: default: yyerror("operation unmanaged type..."); exit(BUGGY_THE_CLOWN); break; } } break; case EQ : { switch (e1.b.type) { case basic_int_value:funBoolIntPrt = eqInt;break; case basic_float_value:funBoolFloatPrt = eqFloat;break; case basic_boolean_value: funBoolPtr = eqBool;break; case undef: default: yyerror("operation unmanaged type..."); exit(BUGGY_THE_CLOWN); break; } } break; default: yyerror("what now?"); exit(BUGGY_THE_CLOWN); break; } //look for values to be used if( funIntPtr == NULL && funFloatPtr == NULL && funBoolIntPrt == NULL && funBoolFloatPrt == NULL && funBoolPtr == NULL ){ yyerror("no function found for the specified operation.."); exit(BUGGY_THE_CLOWN); } res.type = basic_dataType; switch (e1.b.type) { case basic_int_value: { if(funIntPtr!=NULL){ if(oper == EQUALS){ //il risultato è booleano res.b.type = basic_boolean_value; res.b.b = funIntPtr(e1.b.i, e2.b.i); }else{ res.b.type = e1.b.type;//inherithed res.b.i = funIntPtr(e1.b.i, e2.b.i); } }else if(funBoolIntPrt!=NULL){ //evaluating something like int < int or int == int res.b.type = basic_boolean_value; res.b.b = funBoolIntPrt(e1.b.i, e2.b.i); }else{ yyerror("reached unexpected state.."); exit(BUGGY_THE_CLOWN); } } break; case basic_float_value: { if(funFloatPtr!=NULL){ if(oper == EQUALS){ //il risultato è booleano res.b.type = basic_boolean_value; res.b.b = funFloatPtr(e1.b.f, e2.b.f); }else{ res.b.type = e1.b.type;//inherithed res.b.f = funFloatPtr(e1.b.f, e2.b.f); } }else if(funBoolFloatPrt!=NULL){ res.b.type = basic_boolean_value; res.b.b = funBoolFloatPrt(e1.b.f, e2.b.f); }else{ yyerror("reached unexpected state.."); exit(BUGGY_THE_CLOWN); } } break; case basic_boolean_value: { if(funFloatPtr!=NULL || funBoolFloatPrt!=NULL || funBoolIntPrt!=NULL || funIntPtr!=NULL){ yyerror("reached unexpected state.."); exit(BUGGY_THE_CLOWN); }else{ res.b.type = e1.b.type;//inherithed res.b.b = funBoolPtr(e1.b.b, e2.b.b); } } break; default: yyerror("no data found for the specified operation.."); exit(BUGGY_THE_CLOWN); } return res; }
int add_object_sections(NAME_LIST *section_name_list) { OBJECT_FILE **current; Elf_Scn *elf_section; Elf32_Shdr *shdr; NAME_LIST *section_name; Elf_Scn **array; int scns_available; int scns_added; array_index_t link_index; int page_links; const char *input_name; scns_added = scns_available = 0; array = NULL; array_index_init( &link_index, &link_array ); current = (OBJECT_FILE **)array_index_next_page( &link_index, &page_links ); while (current) { elf_section = NULL; while ((elf_section = elf_nextscn((*current)->elf, elf_section)) != 0) { shdr = elf32_getshdr(elf_section); elfcheck( shdr != NULL ); if ( shdr->sh_type == SHT_PROGBITS || shdr->sh_type == SHT_NOBITS ) { input_name = (*current)->strings+shdr->sh_name; for ( section_name = section_name_list ; section_name ; section_name = section_name->next ) { if (strcmp( input_name, section_name->name) == 0) { if ((shdr->sh_flags & SHF_REFERENCED) == 0) { if ( scns_added >= scns_available ) { array_update( &scn_array, scns_added ); scns_added = 0; array = array_alloc( &scn_array, &scns_available ); } *array++ = elf_section; ++scns_added; // elf_flagshdr( elf_section, ELF_C_SET, SHF_REFERENCED ); shdr->sh_flags |= SHF_REFERENCED; } else { yyerror( "Input section is referenced twice" ); } break; } } } } ++current; if ( --page_links == 0 ) { current = (OBJECT_FILE **)array_index_next_page( &link_index, &page_links ); } } array_update( &scn_array, scns_added ); return 1; }
/* ** yyparse - return 0 if worked, 1 if syntax error not recovered from */ int yyparse() { register YYSTYPE *yypvt; /* top of value stack for $vars */ unsigned yymaxdepth = YYMAXDEPTH; /* ** Initialize externals - yyparse may be called more than once */ yyv = (YYSTYPE*)malloc(yymaxdepth*sizeof(YYSTYPE)); yys = (int*)malloc(yymaxdepth*sizeof(int)); if (!yyv || !yys) { yyerror( "out of memory" ); return(1); } yypv = &yyv[-1]; yyps = &yys[-1]; yystate = 0; yytmp = 0; yynerrs = 0; yyerrflag = 0; yychar = -1; goto yystack; { register YYSTYPE *yy_pv; /* top of value stack */ register int *yy_ps; /* top of state stack */ register int yy_state; /* current state */ register int yy_n; /* internal state number info */ /* ** get globals into registers. ** branch to here only if YYBACKUP was called. */ yynewstate: yy_pv = yypv; yy_ps = yyps; yy_state = yystate; goto yy_newstate; /* ** get globals into registers. ** either we just started, or we just finished a reduction */ yystack: yy_pv = yypv; yy_ps = yyps; yy_state = yystate; /* ** top of for (;;) loop while no reductions done */ yy_stack: /* ** put a state and value onto the stacks */ #if YYDEBUG /* ** if debugging, look up token value in list of value vs. ** name pairs. 0 and negative (-1) are special values. ** Note: linear search is used since time is not a real ** consideration while debugging. */ if ( yydebug ) { register int yy_i; (void)printf( "State %d, token ", yy_state ); if ( yychar == 0 ) (void)printf( "end-of-file\n" ); else if ( yychar < 0 ) (void)printf( "-none-\n" ); else { for ( yy_i = 0; yytoks[yy_i].t_val >= 0; yy_i++ ) { if ( yytoks[yy_i].t_val == yychar ) break; } (void)printf( "%s\n", yytoks[yy_i].t_name ); } } #endif /* YYDEBUG */ if ( ++yy_ps >= &yys[ yymaxdepth ] ) /* room on stack? */ { /* ** reallocate and recover. Note that pointers ** have to be reset, or bad things will happen */ int yyps_index = (yy_ps - yys); int yypv_index = (yy_pv - yyv); int yypvt_index = (yypvt - yyv); yymaxdepth += YYMAXDEPTH; yyv = (YYSTYPE*)realloc((char*)yyv, yymaxdepth * sizeof(YYSTYPE)); yys = (int*)realloc((char*)yys, yymaxdepth * sizeof(int)); if (!yyv || !yys) { yyerror( "yacc stack overflow" ); return(1); } yy_ps = yys + yyps_index; yy_pv = yyv + yypv_index; yypvt = yyv + yypvt_index; } *yy_ps = yy_state; *++yy_pv = yyval; /* ** we have a new state - find out what to do */ yy_newstate: if ( ( yy_n = yypact[ yy_state ] ) <= YYFLAG ) goto yydefault; /* simple state */ #if YYDEBUG /* ** if debugging, need to mark whether new token grabbed */ yytmp = yychar < 0; #endif if ( ( yychar < 0 ) && ( ( yychar = yylex() ) < 0 ) ) yychar = 0; /* reached EOF */ #if YYDEBUG if ( yydebug && yytmp ) { register int yy_i; (void)printf( "Received token " ); if ( yychar == 0 ) (void)printf( "end-of-file\n" ); else if ( yychar < 0 ) (void)printf( "-none-\n" ); else { for ( yy_i = 0; yytoks[yy_i].t_val >= 0; yy_i++ ) { if ( yytoks[yy_i].t_val == yychar ) break; } (void)printf( "%s\n", yytoks[yy_i].t_name ); } } #endif /* YYDEBUG */ if ( ( ( yy_n += yychar ) < 0 ) || ( yy_n >= YYLAST ) ) goto yydefault; if ( yychk[ yy_n = yyact[ yy_n ] ] == yychar ) /*valid shift*/ { yychar = -1; yyval = yylval; yy_state = yy_n; if ( yyerrflag > 0 ) yyerrflag--; goto yy_stack; } yydefault: if ( ( yy_n = yydef[ yy_state ] ) == -2 ) { #if YYDEBUG yytmp = yychar < 0; #endif if ( ( yychar < 0 ) && ( ( yychar = yylex() ) < 0 ) ) yychar = 0; /* reached EOF */ #if YYDEBUG if ( yydebug && yytmp ) { register int yy_i; (void)printf( "Received token " ); if ( yychar == 0 ) (void)printf( "end-of-file\n" ); else if ( yychar < 0 ) (void)printf( "-none-\n" ); else { for ( yy_i = 0; yytoks[yy_i].t_val >= 0; yy_i++ ) { if ( yytoks[yy_i].t_val == yychar ) { break; } } (void)printf( "%s\n", yytoks[yy_i].t_name ); } } #endif /* YYDEBUG */ /* ** look through exception table */ { register int *yyxi = yyexca; while ( ( *yyxi != -1 ) || ( yyxi[1] != yy_state ) ) { yyxi += 2; } while ( ( *(yyxi += 2) >= 0 ) && ( *yyxi != yychar ) ) ; if ( ( yy_n = yyxi[1] ) < 0 ) YYACCEPT; } } /* ** check for syntax error */ if ( yy_n == 0 ) /* have an error */ { /* no worry about speed here! */ switch ( yyerrflag ) { case 0: /* new error */ yyerror( "syntax error" ); goto skip_init; yyerrlab: /* ** get globals into registers. ** we have a user generated syntax type error */ yy_pv = yypv; yy_ps = yyps; yy_state = yystate; yynerrs++; skip_init: case 1: case 2: /* incompletely recovered error */ /* try again... */ yyerrflag = 3; /* ** find state where "error" is a legal ** shift action */ while ( yy_ps >= yys ) { yy_n = yypact[ *yy_ps ] + YYERRCODE; if ( yy_n >= 0 && yy_n < YYLAST && yychk[yyact[yy_n]] == YYERRCODE) { /* ** simulate shift of "error" */ yy_state = yyact[ yy_n ]; goto yy_stack; } /* ** current state has no shift on ** "error", pop stack */ #if YYDEBUG # define _POP_ "Error recovery pops state %d, uncovers state %d\n" if ( yydebug ) (void)printf( _POP_, *yy_ps, yy_ps[-1] ); # undef _POP_ #endif yy_ps--; yy_pv--; } /* ** there is no state on stack with "error" as ** a valid shift. give up. */ YYABORT; case 3: /* no shift yet; eat a token */ #if YYDEBUG /* ** if debugging, look up token in list of ** pairs. 0 and negative shouldn't occur, ** but since timing doesn't matter when ** debugging, it doesn't hurt to leave the ** tests here. */ if ( yydebug ) { register int yy_i; (void)printf( "Error recovery discards " ); if ( yychar == 0 ) (void)printf( "token end-of-file\n" ); else if ( yychar < 0 ) (void)printf( "token -none-\n" ); else { for ( yy_i = 0; yytoks[yy_i].t_val >= 0; yy_i++ ) { if ( yytoks[yy_i].t_val == yychar ) { break; } } (void)printf( "token %s\n", yytoks[yy_i].t_name ); } } #endif /* YYDEBUG */ if ( yychar == 0 ) /* reached EOF. quit */ YYABORT; yychar = -1; goto yy_newstate; } }/* end if ( yy_n == 0 ) */ /* ** reduction by production yy_n ** put stack tops, etc. so things right after switch */ #if YYDEBUG /* ** if debugging, print the string that is the user's ** specification of the reduction which is just about ** to be done. */ if ( yydebug ) (void)printf( "Reduce by (%d) \"%s\"\n", yy_n, yyreds[ yy_n ] ); #endif yytmp = yy_n; /* value to switch over */ yypvt = yy_pv; /* $vars top of value stack */ /* ** Look in goto table for next state ** Sorry about using yy_state here as temporary ** register variable, but why not, if it works... ** If yyr2[ yy_n ] doesn't have the low order bit ** set, then there is no action to be done for ** this reduction. So, no saving & unsaving of ** registers done. The only difference between the ** code just after the if and the body of the if is ** the goto yy_stack in the body. This way the test ** can be made before the choice of what to do is needed. */ { /* length of production doubled with extra bit */ register int yy_len = yyr2[ yy_n ]; if ( !( yy_len & 01 ) ) { yy_len >>= 1; yyval = ( yy_pv -= yy_len )[1]; /* $$ = $1 */ yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] + *( yy_ps -= yy_len ) + 1; if ( yy_state >= YYLAST || yychk[ yy_state = yyact[ yy_state ] ] != -yy_n ) { yy_state = yyact[ yypgo[ yy_n ] ]; } goto yy_stack; } yy_len >>= 1; yyval = ( yy_pv -= yy_len )[1]; /* $$ = $1 */ yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] + *( yy_ps -= yy_len ) + 1; if ( yy_state >= YYLAST || yychk[ yy_state = yyact[ yy_state ] ] != -yy_n ) { yy_state = yyact[ yypgo[ yy_n ] ]; } } /* save until reenter driver code */ yystate = yy_state; yyps = yy_ps; yypv = yy_pv; }
static int IsCf3Scalar(char *str) { char *sp; char left = 'x', right = 'x'; int dollar = false; int bracks = 0, vars = 0; CfDebug("IsCf3Scalar(%s) - syntax verify\n", str); if (str == NULL) { return false; } for (sp = str; *sp != '\0'; sp++) /* check for varitems */ { switch (*sp) { case '$': if (*(sp + 1) == '{' || *(sp + 1) == '(') { dollar = true; } break; case '(': case '{': if (dollar) { left = *sp; bracks++; } break; case ')': case '}': if (dollar) { bracks--; right = *sp; } break; } /* Some chars cannot be in variable ids, e.g. $(/bin/cat file) is legal in bash */ if (bracks > 0) { switch (*sp) { case '/': return false; } } if (left == '(' && right == ')' && dollar && (bracks == 0)) { vars++; dollar = false; } if (left == '{' && right == '}' && dollar && (bracks == 0)) { vars++; dollar = false; } } if (dollar && (bracks != 0)) { char output[CF_BUFSIZE]; snprintf(output, CF_BUFSIZE, "Broken scalar variable syntax or bracket mismatch in \"%s\"", str); yyerror(output); return false; } CfDebug("Found %d variables in (%s)\n", vars, str); return vars; }
const char *ExtractInnerCf3VarString(const char *str, char *substr) { const char *sp; int bracks = 1; CfDebug("ExtractInnerVarString( %s ) - syntax verify\n", str); if (str == NULL || strlen(str) == 0) { return NULL; } memset(substr, 0, CF_BUFSIZE); if (*(str + 1) != '(' && *(str + 1) != '{') { return NULL; } /* Start this from after the opening $( */ for (sp = str + 2; *sp != '\0'; sp++) /* check for varitems */ { switch (*sp) { case '(': case '{': bracks++; break; case ')': case '}': bracks--; break; default: if (isalnum((int) *sp) || strchr("_[]$.:-", *sp)) { } else { CfDebug("Illegal character found: '%c'\n", *sp); CfDebug("Illegal character somewhere in variable \"%s\" or nested expansion", str); } } if (bracks == 0) { strncpy(substr, str + 2, sp - str - 2); CfDebug("Returning substring value %s\n", substr); return substr; } } if (bracks != 0) { char output[CF_BUFSIZE]; if (strlen(substr) > 0) { snprintf(output, CF_BUFSIZE, "Broken variable syntax or bracket mismatch - inner (%s/%s)", str, substr); yyerror(output); } return NULL; } return sp - 1; }
int yyparse( void ) { short yypnum; short yyi, yylhs; YYACTTYPE yyaction; YYTOKENTYPE yytoken; YYACTTYPE yys[MAXDEPTH], *yysp; YYSTYPE yyv[MAXDEPTH], *yyvp; short yyerrflag; yyerrflag = 0; yysp = yys; yyvp = yyv; *yysp = YYSTART; yytoken = yylex(); for( ;; ) { yynewact: yyaction = find_action( *yysp, yytoken ); if( yyaction == YYNOACTION ) { yyaction = find_action( *yysp, YYDEFTOKEN ); if( yyaction == YYNOACTION ) { switch( yyerrflag ) { case 0: yyerror( "syntax error" ); YYERROR; yyerrlab: case 1: case 2: yyerrflag = 3; while( yysp >= yys ) { yyaction = find_action( *yysp, YYERRTOKEN ); if( yyaction != YYNOACTION && yyaction < YYUSED ) { *++yysp = yyaction; ++yyvp; goto yynewact; } --yysp; --yyvp; } YYABORT; case 3: if( yytoken == YYEOFTOKEN ) YYABORT; yytoken = yylex(); goto yynewact; } } } if( yyaction < YYUSED ) { if( yyaction == YYSTOP ) { YYACCEPT; } *++yysp = yyaction; *++yyvp = yylval; if( yyerrflag ) --yyerrflag; yytoken = yylex(); } else { yypnum = yyaction - YYUSED; yyi = yyplentab[yypnum]; yysp -= yyi; yyvp -= yyi; yylhs = yyplhstab[yypnum]; if( yysp < yys ) { printf( "stack underflow\n" ); YYABORT; } yyaction = find_action( *yysp, yylhs ); if( yyaction == YYNOACTION ) { printf( "missing nonterminal\n" ); YYABORT; } *++yysp = yyaction; ++yyvp; switch( yypnum ) { default: yyval = yyvp[0]; } *yyvp = yyval; } } }
void pragvararg(void) { Sym *s; int n, c; char *t; Rune r; Type *ty; if(!debug['F']) goto out; s = getsym(); if(s && strcmp(s->name, "argpos") == 0) goto ckpos; if(s && strcmp(s->name, "type") == 0) goto cktype; if(s && strcmp(s->name, "flag") == 0) goto ckflag; yyerror("syntax in #pragma varargck"); goto out; ckpos: /*#pragma varargck argpos warn 2*/ s = getsym(); if(s == S) goto bad; n = getnsn(); if(n < 0) goto bad; newname(s->name, n); goto out; ckflag: /*#pragma varargck flag 'c'*/ c = getnsc(); if(c != '\'') goto bad; c = getr(); if(c == '\\') c = getr(); else if(c == '\'') goto bad; if(c == '\n') goto bad; if(getc() != '\'') goto bad; argflag(c, Fignor); goto out; cktype: /*#pragma varargck type O int*/ c = getnsc(); if(c != '"') goto bad; t = fmtbuf; for(;;) { r = getr(); if(r == ' ' || r == '\n') goto bad; if(r == '"') break; t += runetochar(t, &r); } *t = 0; t = strdup(fmtbuf); s = getsym(); if(s == S) goto bad; ty = s->type; while((c = getnsc()) == '*') ty = typ(TIND, ty); unget(c); newprot(s, ty, t); goto out; bad: yyerror("syntax in #pragma varargck"); out: while(getnsc() != '\n') ; }
int yyparse(void) { struct { YYSTYPE yyv; int yys; } yys[YYMAXDEPTH], *yyp, *yypt; short *yyxi; int yyj, yym, yystate, yyn, yyg; long yychar; YYSTYPE save1, save2; int save3, save4; save1 = yylval; save2 = yyval; save3 = yynerrs; save4 = yyerrflag; yystate = 0; yychar = -1; yynerrs = 0; yyerrflag = 0; yyp = &yys[-1]; goto yystack; ret0: yyn = 0; goto ret; ret1: yyn = 1; goto ret; ret: yylval = save1; yyval = save2; yynerrs = save3; yyerrflag = save4; return yyn; yystack: /* put a state and value onto the stack */ if(yydebug >= 4) fprint(2, "char %s in %s", yytokname(yychar), yystatname(yystate)); yyp++; if(yyp >= &yys[YYMAXDEPTH]) { yyerror("yacc stack overflow"); goto ret1; } yyp->yys = yystate; yyp->yyv = yyval; yynewstate: yyn = yypact[yystate]; if(yyn <= YYFLAG) goto yydefault; /* simple state */ if(yychar < 0) yychar = yylex1(); yyn += yychar; if(yyn < 0 || yyn >= YYLAST) goto yydefault; yyn = yyact[yyn]; if(yychk[yyn] == yychar) { /* valid shift */ yychar = -1; yyval = yylval; yystate = yyn; if(yyerrflag > 0) yyerrflag--; goto yystack; } yydefault: /* default state action */ yyn = yydef[yystate]; if(yyn == -2) { if(yychar < 0) yychar = yylex1(); /* look through exception table */ for(yyxi=yyexca;; yyxi+=2) if(yyxi[0] == -1 && yyxi[1] == yystate) break; for(yyxi += 2;; yyxi += 2) { yyn = yyxi[0]; if(yyn < 0 || yyn == yychar) break; } yyn = yyxi[1]; if(yyn < 0) goto ret0; } if(yyn == 0) { /* error ... attempt to resume parsing */ switch(yyerrflag) { case 0: /* brand new error */ yyerror("syntax error"); yynerrs++; if(yydebug >= 1) { fprint(2, "%s", yystatname(yystate)); fprint(2, "saw %s\n", yytokname(yychar)); } case 1: case 2: /* incompletely recovered error ... try again */ yyerrflag = 3; /* find a state where "error" is a legal shift action */ while(yyp >= yys) { yyn = yypact[yyp->yys] + YYERRCODE; if(yyn >= 0 && yyn < YYLAST) { yystate = yyact[yyn]; /* simulate a shift of "error" */ if(yychk[yystate] == YYERRCODE) goto yystack; } /* the current yyp has no shift onn "error", pop stack */ if(yydebug >= 2) fprint(2, "error recovery pops state %d, uncovers %d\n", yyp->yys, (yyp-1)->yys ); yyp--; } /* there is no state on the stack with an error shift ... abort */ goto ret1; case 3: /* no shift yet; clobber input char */ if(yydebug >= 2) fprint(2, "error recovery discards %s\n", yytokname(yychar)); if(yychar == YYEOFCODE) goto ret1; yychar = -1; goto yynewstate; /* try again in the same state */ } } /* reduction by production yyn */ if(yydebug >= 2) fprint(2, "reduce %d in:\n\t%s", yyn, yystatname(yystate)); yypt = yyp; yyp -= yyr2[yyn]; yyval = (yyp+1)->yyv; yym = yyn; /* consult goto table to find next state */ yyn = yyr1[yyn]; yyg = yypgo[yyn]; yyj = yyg + yyp->yys + 1; if(yyj >= YYLAST || yychk[yystate=yyact[yyj]] != -yyn) yystate = yyact[yyg]; switch(yym) { case 1: #line 41 "asm.y" { assem(yypt[-0].yyv.inst); } break; case 2: #line 47 "asm.y" { yyval.inst = nil; } break; case 3: #line 49 "asm.y" { if(yypt[-0].yyv.inst != nil) { yypt[-0].yyv.inst->link = yypt[-1].yyv.inst; yyval.inst = yypt[-0].yyv.inst; } else yyval.inst = yypt[-1].yyv.inst; } break; case 4: #line 60 "asm.y" { yypt[-0].yyv.inst->sym = yypt[-2].yyv.sym; yyval.inst = yypt[-0].yyv.inst; } break; case 5: #line 65 "asm.y" { heap(yypt[-3].yyv.ival, yypt[-1].yyv.ival, yypt[-0].yyv.string); yyval.inst = nil; } break; case 6: #line 70 "asm.y" { yyval.inst = nil; } break; case 8: #line 77 "asm.y" { yyval.ival = yypt[-0].yyv.ival; } break; case 9: #line 81 "asm.y" { yypt[-0].yyv.sym->value = heapid++; yyval.ival = yypt[-0].yyv.sym->value; } break; case 10: #line 88 "asm.y" { yyval.string = nil; } break; case 11: #line 90 "asm.y" { yyval.string = yypt[-0].yyv.string; } break; case 12: #line 96 "asm.y" { yyval.list = newi(yypt[-0].yyv.ival, nil); } break; case 13: #line 100 "asm.y" { yyval.list = newi(yypt[-0].yyv.ival, yypt[-2].yyv.list); } break; case 14: #line 106 "asm.y" { yyval.inst = ai(yypt[-3].yyv.ival); yyval.inst->src = yypt[-2].yyv.addr; yyval.inst->dst = yypt[-0].yyv.addr; } break; case 15: #line 112 "asm.y" { yyval.inst = ai(yypt[-5].yyv.ival); yyval.inst->src = yypt[-4].yyv.addr; yyval.inst->reg = yypt[-2].yyv.addr; yyval.inst->dst = yypt[-0].yyv.addr; } break; case 16: #line 119 "asm.y" { yyval.inst = ai(yypt[-3].yyv.ival); yyval.inst->src = yypt[-2].yyv.addr; yyval.inst->dst = yypt[-0].yyv.addr; } break; case 17: #line 125 "asm.y" { yyval.inst = ai(yypt[-1].yyv.ival); yyval.inst->dst = yypt[-0].yyv.addr; } break; case 18: #line 130 "asm.y" { yyval.inst = ai(yypt[-0].yyv.ival); } break; case 19: #line 136 "asm.y" { data(DEFB, yypt[-2].yyv.ival, yypt[-0].yyv.list); } break; case 20: #line 140 "asm.y" { data(DEFW, yypt[-2].yyv.ival, yypt[-0].yyv.list); } break; case 21: #line 144 "asm.y" { data(DEFL, yypt[-2].yyv.ival, yypt[-0].yyv.list); } break; case 22: #line 148 "asm.y" { data(DEFF, yypt[-2].yyv.ival, newi(dtocanon((double)yypt[-0].yyv.ival), nil)); } break; case 23: #line 152 "asm.y" { data(DEFF, yypt[-2].yyv.ival, newi(dtocanon(yypt[-0].yyv.fval), nil)); } break; case 24: #line 156 "asm.y" { if(strcmp(yypt[-0].yyv.sym->name, "Inf") == 0 || strcmp(yypt[-0].yyv.sym->name, "Infinity") == 0) { u.l = (uvlong)0x7ff00000<<32; data(DEFF, yypt[-2].yyv.ival, newi(dtocanon(u.d), nil)); } else if(strcmp(yypt[-0].yyv.sym->name, "NaN") == 0) { u.l = ((uvlong)0x7fffffff<<32) | (uvlong)0xffffffffUL; data(DEFF, yypt[-2].yyv.ival, newi(dtocanon(u.d), nil)); } else diag("bad value for real: %s", yypt[-0].yyv.sym->name); } break; case 25: #line 167 "asm.y" { data(DEFF, yypt[-3].yyv.ival, newi(dtocanon(-(double)yypt[-0].yyv.ival), nil)); } break; case 26: #line 171 "asm.y" { data(DEFF, yypt[-3].yyv.ival, newi(dtocanon(-yypt[-0].yyv.fval), nil)); } break; case 27: #line 175 "asm.y" { if(strcmp(yypt[-0].yyv.sym->name, "Inf") == 0 || strcmp(yypt[-0].yyv.sym->name, "Infinity") == 0) { u.l = (uvlong)0xfff00000<<32; data(DEFF, yypt[-3].yyv.ival, newi(dtocanon(u.d), nil)); } else diag("bad value for real: %s", yypt[-0].yyv.sym->name); } break; case 28: #line 183 "asm.y" { data(DEFS, yypt[-2].yyv.ival, news(yypt[-0].yyv.string, nil)); } break; case 29: #line 187 "asm.y" { if(yypt[-2].yyv.sym->ds != 0) diag("%s declared twice", yypt[-2].yyv.sym->name); yypt[-2].yyv.sym->ds = yypt[-0].yyv.ival; yypt[-2].yyv.sym->value = dseg; dseg += yypt[-0].yyv.ival; } break; case 30: #line 195 "asm.y" { ext(yypt[-4].yyv.ival, yypt[-2].yyv.ival, yypt[-0].yyv.string); } break; case 31: #line 199 "asm.y" { mklink(yypt[-6].yyv.ival, yypt[-4].yyv.ival, yypt[-2].yyv.ival, yypt[-0].yyv.string); } break; case 32: #line 203 "asm.y" { if(module != nil) diag("this module already defined as %s", yypt[-0].yyv.sym->name); else module = yypt[-0].yyv.sym; } break; case 33: #line 210 "asm.y" { if(pcentry >= 0) diag("this module already has entry point %d, %d" , pcentry, dentry); pcentry = yypt[-2].yyv.ival; dentry = yypt[-0].yyv.ival; } break; case 34: #line 217 "asm.y" { data(DEFA, yypt[-4].yyv.ival, newa(yypt[-2].yyv.ival, yypt[-0].yyv.ival)); } break; case 35: #line 221 "asm.y" { data(DIND, yypt[-2].yyv.ival, newa(yypt[-0].yyv.ival, 0)); } break; case 36: #line 225 "asm.y" { data(DAPOP, 0, newa(0, 0)); } break; case 37: #line 229 "asm.y" { ldts(yypt[-0].yyv.ival); } break; case 38: #line 233 "asm.y" { excs(yypt[-0].yyv.ival); } break; case 39: #line 237 "asm.y" { exc(yypt[-10].yyv.ival, yypt[-8].yyv.ival, yypt[-6].yyv.ival, yypt[-4].yyv.ival, yypt[-2].yyv.ival, yypt[-0].yyv.ival); } break; case 40: #line 241 "asm.y" { etab(yypt[-2].yyv.string, yypt[-0].yyv.ival); } break; case 41: #line 245 "asm.y" { etab(nil, yypt[-0].yyv.ival); } break; case 42: #line 249 "asm.y" { source(yypt[-0].yyv.string); } break; case 43: #line 255 "asm.y" { yyval.addr = aa(yypt[-0].yyv.ival); yyval.addr->mode = AXIMM; if(yyval.addr->val > 0x7FFF || yyval.addr->val < -0x8000) diag("immediate %d too large for middle operand", yyval.addr->val); } break; case 44: #line 262 "asm.y" { if(yypt[-0].yyv.addr->mode == AMP) yypt[-0].yyv.addr->mode = AXINM; else yypt[-0].yyv.addr->mode = AXINF; if(yypt[-0].yyv.addr->mode == AXINM && (ulong)yypt[-0].yyv.addr->val > 0xFFFF) diag("register offset %d(mp) too large", yypt[-0].yyv.addr->val); if(yypt[-0].yyv.addr->mode == AXINF && (ulong)yypt[-0].yyv.addr->val > 0xFFFF) diag("register offset %d(fp) too large", yypt[-0].yyv.addr->val); yyval.addr = yypt[-0].yyv.addr; } break; case 45: #line 276 "asm.y" { yyval.addr = aa(yypt[-0].yyv.ival); yyval.addr->mode = AIMM; } break; case 46: #line 281 "asm.y" { yyval.addr = aa(0); yyval.addr->sym = yypt[-0].yyv.sym; } break; case 48: #line 289 "asm.y" { yypt[-0].yyv.addr->mode |= AIND; yyval.addr = yypt[-0].yyv.addr; } break; case 49: #line 294 "asm.y" { yypt[-1].yyv.addr->mode |= AIND; if(yypt[-1].yyv.addr->val & 3) diag("indirect offset must be word size"); if(yypt[-1].yyv.addr->mode == (AMP|AIND) && ((ulong)yypt[-1].yyv.addr->val > 0xFFFF || (ulong)yypt[-3].yyv.ival > 0xFFFF)) diag("indirect offset %d(%d(mp)) too large", yypt[-3].yyv.ival, yypt[-1].yyv.addr->val); if(yypt[-1].yyv.addr->mode == (AFP|AIND) && ((ulong)yypt[-1].yyv.addr->val > 0xFFFF || (ulong)yypt[-3].yyv.ival > 0xFFFF)) diag("indirect offset %d(%d(fp)) too large", yypt[-3].yyv.ival, yypt[-1].yyv.addr->val); yypt[-1].yyv.addr->off = yypt[-1].yyv.addr->val; yypt[-1].yyv.addr->val = yypt[-3].yyv.ival; yyval.addr = yypt[-1].yyv.addr; } break; case 51: #line 310 "asm.y" { yyval.addr = aa(yypt[-3].yyv.ival); yyval.addr->mode = AMP; } break; case 52: #line 315 "asm.y" { yyval.addr = aa(yypt[-3].yyv.ival); yyval.addr->mode = AFP; } break; case 54: #line 323 "asm.y" { yyval.ival = yypt[-0].yyv.sym->value; } break; case 55: #line 327 "asm.y" { yyval.ival = -yypt[-0].yyv.ival; } break; case 56: #line 331 "asm.y" { yyval.ival = yypt[-0].yyv.ival; } break; case 57: #line 335 "asm.y" { yyval.ival = ~yypt[-0].yyv.ival; } break; case 58: #line 339 "asm.y" { yyval.ival = yypt[-1].yyv.ival; } break; case 60: #line 346 "asm.y" { yyval.ival = yypt[-2].yyv.ival + yypt[-0].yyv.ival; } break; case 61: #line 350 "asm.y" { yyval.ival = yypt[-2].yyv.ival - yypt[-0].yyv.ival; } break; case 62: #line 354 "asm.y" { yyval.ival = yypt[-2].yyv.ival * yypt[-0].yyv.ival; } break; case 63: #line 358 "asm.y" { yyval.ival = yypt[-2].yyv.ival / yypt[-0].yyv.ival; } break; case 64: #line 362 "asm.y" { yyval.ival = yypt[-2].yyv.ival % yypt[-0].yyv.ival; } break; case 65: #line 366 "asm.y" { yyval.ival = yypt[-3].yyv.ival << yypt[-0].yyv.ival; } break; case 66: #line 370 "asm.y" { yyval.ival = yypt[-3].yyv.ival >> yypt[-0].yyv.ival; } break; case 67: #line 374 "asm.y" { yyval.ival = yypt[-2].yyv.ival & yypt[-0].yyv.ival; } break; case 68: #line 378 "asm.y" { yyval.ival = yypt[-2].yyv.ival ^ yypt[-0].yyv.ival; } break; case 69: #line 382 "asm.y" { yyval.ival = yypt[-2].yyv.ival | yypt[-0].yyv.ival; } break; } goto yystack; /* stack new state and value */ }
void regopt(Prog *firstp) { Reg *r, *r1; Prog *p; int i, z, nr; uint32 vreg; Bits bit; if(first == 0) { fmtinstall('Q', Qconv); } fixjmp(firstp); first++; if(debug['K']) { if(first != 13) return; // debug['R'] = 2; // debug['P'] = 2; print("optimizing %S\n", curfn->nname->sym); } // count instructions nr = 0; for(p=firstp; p!=P; p=p->link) nr++; // if too big dont bother if(nr >= 10000) { // print("********** %S is too big (%d)\n", curfn->nname->sym, nr); return; } firstr = R; lastr = R; /* * control flow is more complicated in generated go code * than in generated c code. define pseudo-variables for * registers, so we have complete register usage information. */ nvar = NREGVAR; memset(var, 0, NREGVAR*sizeof var[0]); for(i=0; i<NREGVAR; i++) { if(regnodes[i] == N) regnodes[i] = newname(lookup(regname[i])); var[i].node = regnodes[i]; } regbits = RtoB(REGSP)|RtoB(REGLINK)|RtoB(REGPC); for(z=0; z<BITS; z++) { externs.b[z] = 0; params.b[z] = 0; consts.b[z] = 0; addrs.b[z] = 0; ovar.b[z] = 0; } // build list of return variables setoutvar(); /* * pass 1 * build aux data structure * allocate pcs * find use and set of variables */ nr = 0; for(p=firstp; p != P; p = p->link) { switch(p->as) { case ADATA: case AGLOBL: case ANAME: case ASIGNAME: continue; } r = rega(); nr++; if(firstr == R) { firstr = r; lastr = r; } else { lastr->link = r; r->p1 = lastr; lastr->s1 = r; lastr = r; } r->prog = p; p->regp = r; r1 = r->p1; if(r1 != R) { switch(r1->prog->as) { case ARET: case AB: case ARFE: r->p1 = R; r1->s1 = R; } } // Avoid making variables for direct-called functions. if(p->as == ABL && p->to.type == D_EXTERN) continue; /* * left side always read */ bit = mkvar(r, &p->from); for(z=0; z<BITS; z++) r->use1.b[z] |= bit.b[z]; /* * middle always read when present */ if(p->reg != NREG) { if(p->from.type != D_FREG) r->use1.b[0] |= RtoB(p->reg); else r->use1.b[0] |= FtoB(p->reg); } /* * right side depends on opcode */ bit = mkvar(r, &p->to); if(bany(&bit)) switch(p->as) { default: yyerror("reg: unknown op: %A", p->as); break; /* * right side read */ case ATST: case ATEQ: case ACMP: case ACMN: case ACMPD: case ACMPF: rightread: for(z=0; z<BITS; z++) r->use2.b[z] |= bit.b[z]; break; /* * right side read or read+write, depending on middle * ADD x, z => z += x * ADD x, y, z => z = x + y */ case AADD: case AAND: case AEOR: case ASUB: case ARSB: case AADC: case ASBC: case ARSC: case AORR: case ABIC: case ASLL: case ASRL: case ASRA: case AMUL: case AMULU: case ADIV: case AMOD: case AMODU: case ADIVU: if(p->reg != NREG) goto rightread; // fall through /* * right side read+write */ case AADDF: case AADDD: case ASUBF: case ASUBD: case AMULF: case AMULD: case ADIVF: case ADIVD: case AMULA: case AMULAL: case AMULALU: for(z=0; z<BITS; z++) { r->use2.b[z] |= bit.b[z]; r->set.b[z] |= bit.b[z]; } break; /* * right side write */ case ANOP: case AMOVB: case AMOVBU: case AMOVD: case AMOVDF: case AMOVDW: case AMOVF: case AMOVFW: case AMOVH: case AMOVHU: case AMOVW: case AMOVWD: case AMOVWF: case AMVN: case AMULL: case AMULLU: if((p->scond & C_SCOND) != C_SCOND_NONE) for(z=0; z<BITS; z++) r->use2.b[z] |= bit.b[z]; for(z=0; z<BITS; z++) r->set.b[z] |= bit.b[z]; break; /* * funny */ case ABL: setaddrs(bit); break; } if(p->as == AMOVM) { z = p->to.offset; if(p->from.type == D_CONST) z = p->from.offset; for(i=0; z; i++) { if(z&1) regbits |= RtoB(i); z >>= 1; } } }
void genfuncname(struct table *tp, char *cname, char *fname, int type) { char tmp[512], *xp; struct column *cp = NULL; if (tp == NULL) return; if (cname != NULL && (cp = findcolumn(tp, cname)) == NULL) { yyerror("cannot find column within table"); return; } switch (type) { case DBOW_INSERT: if (tp->ifname != NULL) { yyerror("multiple insert definitions for table"); return; } xp = "insert"; break; case DBOW_DELETE: if (cp == NULL) return; if (cp->dfname != NULL) { yyerror("multiple insert definitions for column"); return; } xp = "delete"; break; case DBOW_SEARCH: if (cp == NULL) return; if (cp->sfname != NULL) { yyerror("multiple insert definitions for column"); return; } xp = "find"; break; case DBOW_UPDATE: if (cp == NULL) return; if (cp->ufname != NULL) { yyerror("multiple insert definitions for column"); return; } xp = "update"; break; } if (fname == NULL) { if (type != DBOW_INSERT) sprintf(tmp, "db_%s%sby%s", xp, tp->name, cp->name); else sprintf(tmp, "db_%s%s", xp, tp->name); xp = tmp; } else xp = fname; switch (type) { case DBOW_INSERT: tp->ifname = strdup(xp); break; case DBOW_DELETE: cp->dfname = strdup(xp); break; case DBOW_SEARCH: cp->sfname = strdup(xp); break; case DBOW_UPDATE: cp->ufname = strdup(xp); break; } }
int yyparse(void) { struct { YYSTYPE yyv; int yys; } yys[YYMAXDEPTH], *yyp, *yypt; short *yyxi; int yyj, yym, yystate, yyn, yyg; long yychar; YYSTYPE save1, save2; int save3, save4; save1 = yylval; save2 = yyval; save3 = yynerrs; save4 = yyerrflag; yystate = 0; yychar = -1; yynerrs = 0; yyerrflag = 0; yyp = &yys[-1]; goto yystack; ret0: yyn = 0; goto ret; ret1: yyn = 1; goto ret; ret: yylval = save1; yyval = save2; yynerrs = save3; yyerrflag = save4; return yyn; yystack: /* put a state and value onto the stack */ if(yydebug >= 4) fprint(2, "char %s in %s", yytokname(yychar), yystatname(yystate)); yyp++; if(yyp >= &yys[YYMAXDEPTH]) { yyerror("yacc stack overflow"); goto ret1; } yyp->yys = yystate; yyp->yyv = yyval; yynewstate: yyn = yypact[yystate]; if(yyn <= YYFLAG) goto yydefault; /* simple state */ if(yychar < 0) yychar = yylex1(); yyn += yychar; if(yyn < 0 || yyn >= YYLAST) goto yydefault; yyn = yyact[yyn]; if(yychk[yyn] == yychar) { /* valid shift */ yychar = -1; yyval = yylval; yystate = yyn; if(yyerrflag > 0) yyerrflag--; goto yystack; } yydefault: /* default state action */ yyn = yydef[yystate]; if(yyn == -2) { if(yychar < 0) yychar = yylex1(); /* look through exception table */ for(yyxi=yyexca;; yyxi+=2) if(yyxi[0] == -1 && yyxi[1] == yystate) break; for(yyxi += 2;; yyxi += 2) { yyn = yyxi[0]; if(yyn < 0 || yyn == yychar) break; } yyn = yyxi[1]; if(yyn < 0) goto ret0; } if(yyn == 0) { /* error ... attempt to resume parsing */ switch(yyerrflag) { case 0: /* brand new error */ yyerror("syntax error"); yynerrs++; if(yydebug >= 1) { fprint(2, "%s", yystatname(yystate)); fprint(2, "saw %s\n", yytokname(yychar)); } case 1: case 2: /* incompletely recovered error ... try again */ yyerrflag = 3; /* find a state where "error" is a legal shift action */ while(yyp >= yys) { yyn = yypact[yyp->yys] + YYERRCODE; if(yyn >= 0 && yyn < YYLAST) { yystate = yyact[yyn]; /* simulate a shift of "error" */ if(yychk[yystate] == YYERRCODE) goto yystack; } /* the current yyp has no shift onn "error", pop stack */ if(yydebug >= 2) fprint(2, "error recovery pops state %d, uncovers %d\n", yyp->yys, (yyp-1)->yys ); yyp--; } /* there is no state on the stack with an error shift ... abort */ goto ret1; case 3: /* no shift yet; clobber input char */ if(yydebug >= 2) fprint(2, "error recovery discards %s\n", yytokname(yychar)); if(yychar == YYEOFCODE) goto ret1; yychar = -1; goto yynewstate; /* try again in the same state */ } } /* reduction by production yyn */ if(yydebug >= 2) fprint(2, "reduce %d in:\n\t%s", yyn, yystatname(yystate)); yypt = yyp; yyp -= yyr2[yyn]; yyval = (yyp+1)->yyv; yym = yyn; /* consult goto table to find next state */ yyn = yyr1[yyn]; yyg = yypgo[yyn]; yyj = yyg + yyp->yys + 1; if(yyj >= YYLAST || yychk[yystate=yyact[yyj]] != -yyn) yystate = yyact[yyg]; switch(yym) { case 3: #line 77 "cc.y" { dodecl(xdecl, lastclass, lasttype, Z); } break; case 5: #line 82 "cc.y" { lastdcl = T; firstarg = S; dodecl(xdecl, lastclass, lasttype, yypt[-0].yyv.node); if(lastdcl == T || lastdcl->etype != TFUNC) { diag(yypt[-0].yyv.node, "not a function"); lastdcl = types[TFUNC]; } thisfn = lastdcl; markdcl(); firstdcl = dclstack; argmark(yypt[-0].yyv.node, 0); } break; case 6: #line 96 "cc.y" { argmark(yypt[-2].yyv.node, 1); } break; case 7: #line 100 "cc.y" { Node *n; n = revertdcl(); if(n) yypt[-0].yyv.node = new(OLIST, n, yypt[-0].yyv.node); if(!debug['a'] && !debug['Z']) codgen(yypt[-0].yyv.node, yypt[-4].yyv.node); } break; case 8: #line 112 "cc.y" { dodecl(xdecl, lastclass, lasttype, yypt[-0].yyv.node); } break; case 9: #line 116 "cc.y" { yypt[-0].yyv.node = dodecl(xdecl, lastclass, lasttype, yypt[-0].yyv.node); } break; case 10: #line 120 "cc.y" { doinit(yypt[-3].yyv.node->sym, yypt[-3].yyv.node->type, 0L, yypt[-0].yyv.node); } break; case 13: #line 128 "cc.y" { yyval.node = new(OIND, yypt[-0].yyv.node, Z); yyval.node->garb = simpleg(yypt[-1].yyv.lval); } break; case 15: #line 136 "cc.y" { yyval.node = yypt[-1].yyv.node; } break; case 16: #line 140 "cc.y" { yyval.node = new(OFUNC, yypt[-3].yyv.node, yypt[-1].yyv.node); } break; case 17: #line 144 "cc.y" { yyval.node = new(OARRAY, yypt[-3].yyv.node, yypt[-1].yyv.node); } break; case 18: #line 153 "cc.y" { yyval.node = dodecl(adecl, lastclass, lasttype, Z); } break; case 19: #line 157 "cc.y" { yyval.node = yypt[-1].yyv.node; } break; case 20: #line 163 "cc.y" { dodecl(adecl, lastclass, lasttype, yypt[-0].yyv.node); yyval.node = Z; } break; case 21: #line 168 "cc.y" { yypt[-0].yyv.node = dodecl(adecl, lastclass, lasttype, yypt[-0].yyv.node); } break; case 22: #line 172 "cc.y" { long w; w = yypt[-3].yyv.node->sym->type->width; yyval.node = doinit(yypt[-3].yyv.node->sym, yypt[-3].yyv.node->type, 0L, yypt[-0].yyv.node); yyval.node = contig(yypt[-3].yyv.node->sym, yyval.node, w); } break; case 23: #line 180 "cc.y" { yyval.node = yypt[-2].yyv.node; if(yypt[-0].yyv.node != Z) { yyval.node = yypt[-0].yyv.node; if(yypt[-2].yyv.node != Z) yyval.node = new(OLIST, yypt[-2].yyv.node, yypt[-0].yyv.node); } } break; case 26: #line 197 "cc.y" { dodecl(pdecl, lastclass, lasttype, yypt[-0].yyv.node); } break; case 28: #line 207 "cc.y" { lasttype = yypt[-0].yyv.type; } break; case 30: #line 212 "cc.y" { lasttype = yypt[-0].yyv.type; } break; case 32: #line 218 "cc.y" { lastfield = 0; edecl(CXXX, lasttype, S); } break; case 34: #line 226 "cc.y" { dodecl(edecl, CXXX, lasttype, yypt[-0].yyv.node); } break; case 36: #line 233 "cc.y" { lastbit = 0; firstbit = 1; } break; case 37: #line 238 "cc.y" { yyval.node = new(OBIT, yypt[-2].yyv.node, yypt[-0].yyv.node); } break; case 38: #line 242 "cc.y" { yyval.node = new(OBIT, Z, yypt[-0].yyv.node); } break; case 39: #line 250 "cc.y" { yyval.node = (Z); } break; case 41: #line 257 "cc.y" { yyval.node = new(OIND, (Z), Z); yyval.node->garb = simpleg(yypt[-0].yyv.lval); } break; case 42: #line 262 "cc.y" { yyval.node = new(OIND, yypt[-0].yyv.node, Z); yyval.node->garb = simpleg(yypt[-1].yyv.lval); } break; case 45: #line 271 "cc.y" { yyval.node = new(OFUNC, yypt[-3].yyv.node, yypt[-1].yyv.node); } break; case 46: #line 275 "cc.y" { yyval.node = new(OARRAY, yypt[-3].yyv.node, yypt[-1].yyv.node); } break; case 47: #line 281 "cc.y" { yyval.node = new(OFUNC, (Z), Z); } break; case 48: #line 285 "cc.y" { yyval.node = new(OARRAY, (Z), yypt[-1].yyv.node); } break; case 49: #line 289 "cc.y" { yyval.node = yypt[-1].yyv.node; } break; case 51: #line 296 "cc.y" { yyval.node = new(OINIT, invert(yypt[-1].yyv.node), Z); } break; case 52: #line 302 "cc.y" { yyval.node = new(OARRAY, yypt[-1].yyv.node, Z); } break; case 53: #line 306 "cc.y" { yyval.node = new(OELEM, Z, Z); yyval.node->sym = yypt[-0].yyv.sym; } break; case 56: #line 315 "cc.y" { yyval.node = new(OLIST, yypt[-2].yyv.node, yypt[-1].yyv.node); } break; case 58: #line 320 "cc.y" { yyval.node = new(OLIST, yypt[-1].yyv.node, yypt[-0].yyv.node); } break; case 61: #line 328 "cc.y" { yyval.node = new(OLIST, yypt[-1].yyv.node, yypt[-0].yyv.node); } break; case 62: #line 333 "cc.y" { yyval.node = Z; } break; case 63: #line 337 "cc.y" { yyval.node = invert(yypt[-0].yyv.node); } break; case 65: #line 345 "cc.y" { yyval.node = new(OPROTO, yypt[-0].yyv.node, Z); yyval.node->type = yypt[-1].yyv.type; } break; case 66: #line 350 "cc.y" { yyval.node = new(OPROTO, yypt[-0].yyv.node, Z); yyval.node->type = yypt[-1].yyv.type; } break; case 67: #line 355 "cc.y" { yyval.node = new(ODOTDOT, Z, Z); } break; case 68: #line 359 "cc.y" { yyval.node = new(OLIST, yypt[-2].yyv.node, yypt[-0].yyv.node); } break; case 69: #line 365 "cc.y" { yyval.node = invert(yypt[-1].yyv.node); // if(yypt[-1].yyv.node != Z) // yyval.node = new(OLIST, yypt[-1].yyv.node, yyval.node); if(yyval.node == Z) yyval.node = new(OLIST, Z, Z); } break; case 70: #line 374 "cc.y" { yyval.node = Z; } break; case 71: #line 378 "cc.y" { yyval.node = new(OLIST, yypt[-1].yyv.node, yypt[-0].yyv.node); } break; case 72: #line 382 "cc.y" { yyval.node = new(OLIST, yypt[-1].yyv.node, yypt[-0].yyv.node); } break; case 74: #line 389 "cc.y" { yyval.node = new(OLIST, yypt[-1].yyv.node, yypt[-0].yyv.node); } break; case 75: #line 395 "cc.y" { yyval.node = new(OCASE, yypt[-1].yyv.node, Z); } break; case 76: #line 399 "cc.y" { yyval.node = new(OCASE, Z, Z); } break; case 77: #line 403 "cc.y" { yyval.node = new(OLABEL, dcllabel(yypt[-1].yyv.sym, 1), Z); } break; case 78: #line 409 "cc.y" { yyval.node = Z; } break; case 80: #line 414 "cc.y" { yyval.node = new(OLIST, yypt[-1].yyv.node, yypt[-0].yyv.node); } break; case 82: #line 421 "cc.y" { yyval.node = yypt[-0].yyv.node; } break; case 84: #line 427 "cc.y" { markdcl(); } break; case 85: #line 431 "cc.y" { yyval.node = revertdcl(); if(yyval.node) yyval.node = new(OLIST, yyval.node, yypt[-0].yyv.node); else yyval.node = yypt[-0].yyv.node; } break;
const char *ExtractOuterCf3VarString(const char *str, char *substr) /* Should only by applied on str[0] == '$' */ { const char *sp; int dollar = false; int bracks = 0, onebrack = false; CfDebug("ExtractOuterVarString(\"%s\") - syntax verify\n", str); memset(substr, 0, CF_BUFSIZE); for (sp = str; *sp != '\0'; sp++) /* check for varitems */ { switch (*sp) { case '$': dollar = true; switch (*(sp + 1)) { case '(': case '{': break; default: /* Stray dollar not a variable */ return NULL; } break; case '(': case '{': bracks++; onebrack = true; break; case ')': case '}': bracks--; break; } if (dollar && (bracks == 0) && onebrack) { strncpy(substr, str, sp - str + 1); CfDebug("Extracted outer variable |%s|\n", substr); return substr; } } if (dollar == false) { return str; /* This is not a variable */ } if (bracks != 0) { char output[CF_BUFSIZE]; snprintf(output, CF_BUFSIZE, "Broken variable syntax or bracket mismatch in - outer (%s/%s)", str, substr); yyerror(output); return NULL; } /* Return pointer to first position in string (shouldn't happen) as long as we only call this function from the first $ position */ return str; }
static OBJECT_FILE *object_open( const char *file_name ) { OBJECT_FILE *file; Elf_Scn *section; Elf_Data *symtab; Elf32_Shdr *shdr; int compare; // search for the file in the list of already open objects for (file = objects ; file ; file = file->next_object) { compare = strcmp( file_name, file->name ); if ( compare == 0 ) // if we found it { return file; } else if ( compare < 0 ) // if we didn't find it { break; } } // try to add a new file to the list of open objects file = (OBJECT_FILE *)malloc( sizeof(OBJECT_FILE) ); assert(file); if ( file ) { memset( file, 0, sizeof(*file) ); if ((file->fd = open(file_name, O_RDONLY | O_BINARY)) != -1) { file->elf = elf_begin(file->fd, ELF_C_READ, NULL); if (file->elf) { file->ehdr = elf32_getehdr(file->elf); if (file->ehdr) { if ( file->ehdr->e_machine == out_file_machine ) { Elf_Data *string_data; OBJECT_FILE **scan; int compare; exec_getsection( file->elf, file->ehdr->e_shstrndx, NULL, &string_data ); file->strings = (char *)string_data->d_buf; file->name = strdup( file_name ); section = NULL; while ((section = elf_nextscn(file->elf, section)) != 0) { shdr = elf32_getshdr(section); elfcheck( shdr != NULL ); if (shdr->sh_type == SHT_SYMTAB) { symtab = exec_getdata(section); file->symbols = symtab->d_buf; file->symbol_count = symtab->d_size / sizeof(Elf32_Sym); file->first_global = shdr->sh_info; file->string_index = shdr->sh_link; if ( file->symbol_count > max_symbols ) { max_symbols = file->symbol_count; } break; } } // ordered insert into the file list assert( file->name ); for ( scan = &objects ; *scan ; scan = &(*scan)->next_object ) { compare = strcmp(file_name, (*scan)->name ); // if this file already exists we should have found // it instead of creating it assert( compare != 0 ); if (compare < 0) { break; } } file->next_object = *scan; *scan = file; return file; } else { yyerror( "Input file machine type doesn't match architecture" ); } } else { yyerror( "File %s is not a valid ELF file: %s", file_name, elf_errmsg(-1) ); } elf_end(file->elf); } else { yyerror( "Elf_begin on %s failed: %s", file_name, elf_errmsg(-1) ); } close( file->fd ); } else { yyerror( "File %s not found", file_name ); } free( file ); file = NULL; } return file; }
bool yyparse( void ) { short yypnum; short yyi, yyk, yylhs, yyaction; short yytoken; short yys[MAXDEPTH], *yysp; YYSTYPE yyv[MAXDEPTH], *yyvp; short yyerrflag; yyerrflag = 0; yyaction = 0; yysp = yys; yyvp = yyv; *yysp = YYSTART; yytoken = yylex(); for(;;){ yynewact: yyk = *yysp; while( (yyi = yyk + yytoken) < 0 || yyi >= YYUSED || yychktab[yyi] != yytoken ) if( (yyi = yyk + YYPTOKEN) < 0 || yyi >= YYUSED || yychktab[yyi] != YYPTOKEN ) goto yycheck1; else yyk = yyacttab[yyi]; yyaction = yyacttab[yyi]; if( yyaction == YYNOACTION ){ yycheck1: yyk = *yysp; while( (yyi = yyk + YYDTOKEN) < 0 || yyi >= YYUSED || yychktab[yyi] != YYDTOKEN ) if( (yyi = yyk + YYPTOKEN) < 0 || yyi >= YYUSED || yychktab[yyi] != YYPTOKEN ) goto yycheck2; else yyk = yyacttab[yyi]; yyaction = yyacttab[yyi]; if( yyaction == YYNOACTION ){ yycheck2: switch( yyerrflag ){ case 0: yyerror( "syntax error" ); yyerrlab: case 1: case 2: yyerrflag = 3; while( yysp >= yys ){ yyk = *yysp; while( (yyi = yyk + YYETOKEN) < 0 || yyi >= YYUSED || yychktab[yyi] != YYETOKEN ) if( (yyi = yyk + YYPTOKEN) < 0 || yyi >= YYUSED || yychktab[yyi] != YYPTOKEN ) goto continu; else yyk = yyacttab[yyi]; yyaction = yyacttab[yyi]; if( yyaction < YYUSED ){ *++yysp = yyaction; ++yyvp; goto yynewact; }; continu:; --yysp; --yyvp; }; YYABORT; case 3: if( yytoken == 0 ) /* EOF token */ YYABORT; yytoken = yylex(); goto yynewact; }; }; }; if( yyaction < YYUSED ){ if( yyaction == YYSTOP ){ YYACCEPT; } else { *++yysp = yyaction; *++yyvp = yylval; if( yyerrflag ) --yyerrflag; yytoken = yylex(); }; } else { yypnum = yyaction - YYUSED; yyi = yyplentab[yypnum]; yysp -= yyi; yyvp -= yyi; yylhs = yyplhstab[yypnum]; if( yysp < yys ){ printf( "stack underflow\n" ); YYABORT; }; yyk = *yysp; while( (yyi = yyk + yylhs) < 0 || yyi >= YYUSED || yychktab[yyi] != yylhs ){ if( (yyi = yyk + YYPTOKEN) < 0 || yyi >= YYUSED || yychktab[yyi] != YYPTOKEN ){ printf( "missing nonterminal\n" ); YYABORT; }; yyk = yyacttab[yyi]; }; *++yysp = yyacttab[yyi]; ++yyvp; #ifdef AS_DEBUG_DUMP dump_rule( yypnum ); #endif switch( yypnum ){ default: yyval = yyvp[0]; }; *yyvp = yyval; }; }; }
static void fixup_symbols( void ) { bbtree_node_t *parent; OBJECT_FILE *file; Elf_Scn *section; Elf32_Shdr *shdr; Elf32_Sym *symbol; global_t *global_sym; int i; int compare; char *sym_name; file = objects; while (file) { section = NULL; while ((section = elf_nextscn(file->elf, section)) != 0) { shdr = elf32_getshdr(section); elfcheck( shdr != NULL ); if ( (shdr->sh_type == SHT_PROGBITS || shdr->sh_type == SHT_NOBITS) && (shdr->sh_flags & SHF_REFERENCED) == 0) { yyerror( "Section %s in file %s is not referenced\n", file->strings + shdr->sh_name, file->name ); } } symbol = file->symbols + 1; for ( i = 1 ; i < file->symbol_count ; ++i ) { sym_name = elf_strptr( file->elf, file->string_index, symbol->st_name); if (symbol->st_shndx != SHN_UNDEF) { exec_getsection( file->elf, symbol->st_shndx, &shdr, NULL ); symbol->st_value += shdr->sh_addr; if (i >= file->first_global) { parent = bbtree_preinsert( &globals, sym_name, &compare ); if (!parent || compare != 0) { global_sym = (global_t *)malloc(sizeof(*global_sym)); if (global_sym) { global_sym->file = file; global_sym->name = sym_name; global_sym->symbol = symbol; bbtree_insert( &globals, parent, &global_sym->node, compare ); } else { yyerror( "Failed to allocate memory\n" ); } } else { yyerror( "Global symbol \"%s\" multiply defined\n", sym_name ); } } } else if (i < file->first_global) { yyerror( "Symbol \"%s\" is undefined but local\n", sym_name ); } ++symbol; } file = file->next_object; } }
int StartVSM(int StartAddr, int TraceSW) /* Start VSM */ { int addr, op; Pctr = StartAddr; /* Set Pctr */ SP = Freg = 0; /* Set register flag */ while (1) { if (SP >= STACK_SIZE || SP < 0) { /* check the range of stack pointer */ fprintf(stderr, "Illegal Stack pointer %d\n", SP); return -1; } op = Iseg[Pctr].Op; /* fetch instruction */ addr = Iseg[Pctr].Addr; /* calculate effective address */ if (Iseg[Pctr++].Reg & FP) /* FP register modification */ addr += Freg; /* add FP */ InsCount++; /* Increment the number of instructions */ if (SP > MaxSD) MaxSD = SP; /* check the max SP value */ if (TraceSW) { /* if trace flag is on, make trace */ PrintIns(Pctr-1); printf("%15d %5d %12d\n", addr, SP, Stack[SP]); } switch (op) { /* execute each instruction */ case NOP: continue; case ASSGN: addr = Stack[--SP]; Dseg[addr] = Stack[SP] = Stack[SP+1]; continue; case ADD: BINOP(+); continue; case SUB: BINOP(-); continue; case MUL: BINOP(*); continue; case DIV: if (Stack[SP] == 0) { yyerror("Zero divider detected"); return -2; } BINOP(/); continue; case MOD: if (Stack[SP] == 0) { yyerror("Zero divider detected"); return -2; } BINOP(%); continue; case CSIGN: Stack[SP] = -Stack[SP]; continue; case AND: BINOP(&&); continue; case OR: BINOP(||); continue; case NOT: Stack[SP] = !Stack[SP]; continue; case COMP: Stack[SP-1] = Stack[SP-1] > Stack[SP] ? 1 : Stack[SP-1] < Stack[SP] ? -1 : 0; SP--; continue; case COPY: ++SP; Stack[SP] = Stack[SP-1]; continue; case PUSH: Stack[++SP] = Dseg[addr]; continue; case PUSHI: Stack[++SP] = addr; continue; case REMOVE: --SP; continue; case POP: Dseg[addr] = Stack[SP--]; continue; case INC: Stack[SP] = ++Stack[SP]; continue; case DEC: Stack[SP] = --Stack[SP]; continue; case SETFR: Freg = addr; continue; case INCFR : if ((Freg += addr) >= DSEG_SIZE) { printf("Freg overflow at loc. %d\n", Pctr-1); return -3; } continue; case DECFR : Freg -= addr; if (Freg < MinFR) MinFR = Freg; continue; case JUMP: Pctr = addr; continue; case BLT: if (Stack[SP--] < 0) Pctr = addr; continue; case BLE: if (Stack[SP--] <= 0) Pctr = addr; continue; case BEQ: if (Stack[SP--] == 0) Pctr = addr; continue; case BNE: if (Stack[SP--] != 0) Pctr = addr; continue; case BGE: if (Stack[SP--] >= 0) Pctr = addr; continue; case BGT: if (Stack[SP--] > 0) Pctr = addr; continue; case CALL: Stack[++SP] = Pctr; Pctr = addr; CallC++; continue; case RET: Pctr = Stack[SP--]; continue; case HALT: return 0; case INPUT: scanf("%d", &Dseg[Stack[SP--]]); continue; case OUTPUT: printf("%15d\n", Stack[SP--]); continue; default: printf("Illegal Op. code at location %d\n", Pctr); return -4; } } }
int main(int argc, char *argv[]) { int c, i; Nonterm p; for (i = 1; i < argc; i++) if (strcmp(argv[i], "-T") == 0) Tflag = 1; else if (strncmp(argv[i], "-p", 2) == 0 && argv[i][2]) prefix = &argv[i][2]; else if (strncmp(argv[i], "-p", 2) == 0 && i + 1 < argc) prefix = argv[++i]; else if (*argv[i] == '-' && argv[i][1]) { yyerror("usage: %s [-T | -p prefix]... [ [ input ] output ] \n", argv[0]); exit(1); } else if (infp == NULL) { if (strcmp(argv[i], "-") == 0) infp = stdin; else if ((infp = fopen(argv[i], "r")) == NULL) { yyerror("%s: can't read `%s'\n", argv[0], argv[i]); exit(1); } } else if (outfp == NULL) { if (strcmp(argv[i], "-") == 0) outfp = stdout; if ((outfp = fopen(argv[i], "w")) == NULL) { yyerror("%s: can't write `%s'\n", argv[0], argv[i]); exit(1); } } if (infp == NULL) infp = stdin; if (outfp == NULL) outfp = stdout; yyparse(); if (start) ckreach(start); for (p = nts; p; p = p->link) { if (p->rules == NULL) yyerror("undefined nonterminal `%s'\n", p->name); if (!p->reached) yyerror("can't reach nonterminal `%s'\n", p->name); } emitheader(); emitdefs(nts, ntnumber); emitstruct(nts, ntnumber); emitnts(rules, nrules); emitstring(rules); emitrule(nts); emitclosure(nts); if (start) emitlabel(terms, start, ntnumber); emitkids(rules, nrules); if (!feof(infp)) while ((c = getc(infp)) != EOF) putc(c, outfp); while (memlist) { /* for purify */ struct block *q = memlist->link; free(memlist); memlist = q; } return errcnt > 0; }
int assemble(char *file) { char ofile[100], incfile[20], *p; int i, of; strcpy(ofile, file); p = utfrrune(ofile, pathchar()); if(p) { include[0] = ofile; *p++ = 0; } else p = ofile; if(outfile == 0) { outfile = p; if(outfile){ p = utfrrune(outfile, '.'); if(p) if(p[1] == 's' && p[2] == 0) p[0] = 0; p = utfrune(outfile, 0); p[0] = '.'; p[1] = thechar; p[2] = 0; } else outfile = "/dev/null"; } p = getenv("INCLUDE"); if(p) { setinclude(p); } else { if(systemtype(Plan9)) { sprint(incfile,"/%s/include", thestring); setinclude(strdup(incfile)); } } of = create(outfile, OWRITE, 0664); if(of < 0) { yyerror("%ca: cannot create %s", thechar, outfile); errorexit(); } Binit(&obuf, of, OWRITE); pass = 1; pinit(file); Bprint(&obuf, "%s\n", thestring); for(i=0; i<nDlist; i++) dodefine(Dlist[i]); yyparse(); if(nerrors) { cclean(); return nerrors; } Bprint(&obuf, "\n!\n"); pass = 2; outhist(); pinit(file); for(i=0; i<nDlist; i++) dodefine(Dlist[i]); yyparse(); cclean(); return nerrors; }
void yyserror(const char *str, char *other) { sprintf(errmsg, str, other); yyerror(errmsg); }
int main(int argc, char **argv) { int /*ch, */ i, ii, ret, err_flag = 0; clock_t beg, end, Beg, End; int files = 0; struct tms ts; char buf[256]; char *e; prgname = strrchr(argv[0], '/'); if (prgname) prgname++; else prgname = argv[0]; e = getenv("CLIP_HOSTCS"); if (e && *e) { sourceCharset = targetCharset = strdup(e); } else if (!e) { e = getenv("CLIP_LANG"); if (e == NULL) e = getenv("LANG"); if (!e || !*e || !strcmp(e, "C")) e = getenv("LC_MESSAGES"); if (!e || !*e || !strcmp(e, "C")) e = getenv("LC_ALL"); if (e && *e) { char *s = strrchr(e, '.'); if (s) { snprintf(buf, sizeof(buf), "%s", s + 1); for (s = buf; *s; s++) *s = tolower(*s); sourceCharset = targetCharset = strdup(buf); } } } { e = getenv("CLIP_LANG"); if (e == NULL) e = getenv("LANG"); if (!e || !*e || !strcmp(e, "C")) e = getenv("LC_MESSAGES"); if (!e || !*e || !strcmp(e, "C")) e = getenv("LC_ALL"); if (e && *e) { char *s = strrchr(e, '.'); if (s) { snprintf(buf, sizeof(buf), "%s", s + 1); for (s = buf; *s; s++) *s = tolower(*s); out_charset = strdup(buf); } } } { char *locale; locale = getenv("CLIP_LANG"); if (!locale || !*locale) locale = getenv("LANG"); /*if (locale && *locale && strcasecmp(locale, "C") && strcasecmp(locale, "POSIX")) */ /* setlocale(LC_ALL, locale); */ } if (!sourceCharset) sourceCharset = targetCharset = strdup("c"); getEnvironment(); init_Coll(&includePaths, NULL, NULL); init_Coll(&lib_dirs, NULL, NULL); init_Coll(&arglibs, NULL, NULL); #if 1 insert_Coll(&includePaths, "."); snprintf(buf, sizeof(buf), "%s/include", CLIPROOT); insert_Coll(&includePaths, strdup(buf)); #ifdef STD_LIBDIR snprintf(buf, sizeof(buf), STD_LIB_DIR); insert_Coll(&lib_dirs, strdup(buf)); #endif snprintf(buf, sizeof(buf), "%s/lib", CLIPROOT); insert_Coll(&lib_dirs, strdup(buf)); #endif init_Coll(&predefines, NULL, NULL); init_Coll(&poName, NULL, NULL); init_Coll(&paName, NULL, NULL); init_Coll(&include_files, NULL, NULL); snprintf(buf, sizeof(buf), "__CLIP__=\"%s\"", CLIP_VERSION); append_Coll(&predefines, strdup(buf)); init_module(); { char buf[256], *s; s = getenv("HOME"); if (s && *s) { snprintf(buf, sizeof(buf), "%s/.cliprc", s); getrc(buf); } } getrc(".cliprc"); { char buf[256], *s; DIR *dp; s = CLIPROOT; if (s && *s) { snprintf(buf, sizeof(buf), "%s/.cliprc", s); getrc(buf); } snprintf(buf, sizeof(buf), "%s/cliprc", CLIPROOT); dp = opendir(buf); if (dp) { struct dirent *ep; struct stat st; Coll files; int i; init_Coll(&files, free, strcmp); while ((ep = readdir(dp))) { snprintf(buf, sizeof(buf), "%s/cliprc/%s", CLIPROOT, ep->d_name); if (stat(buf, &st)) continue; if (!S_ISREG(st.st_mode)) continue; if (access(buf, R_OK)) continue; insert_Coll(&files, strdup(buf)); } closedir(dp); for (i = 0; i < files.count_of_Coll; i++) { char *name = (char *) files.items_of_Coll[i]; getrc(name); } destroy_Coll(&files); } } argc--; argv++; get_opt(argc, argv); argc -= optind; argv += optind; if (err_flag) return 1; #if 0 insert_Coll(&includePaths, "."); snprintf(buf, sizeof(buf), "%s/include", CLIPROOT); insert_Coll(&includePaths, strdup(buf)); #ifdef STD_LIBDIR snprintf(buf, sizeof(buf), STD_LIBDIR); insert_Coll(&lib_dirs, strdup(buf)); #endif snprintf(buf, sizeof(buf), "%s/lib", CLIPROOT); insert_Coll(&lib_dirs, strdup(buf)); #endif if (syntax_tree_flag) { write_obj_flag = 0; codegen_flag = 1; compile_flag = 0; pcode_flag = 0; pc_flag = 0; asm_flag = 0; exec_flag = 0; } if (!write_obj_flag) { /*codegen_flag = 0; */ compile_flag = 0; } if (preproc_flag) { write_obj_flag = 0; codegen_flag = 0; syntax_tree_flag = 0; compile_flag = 0; exec_flag = 0; pcode_flag = 0; pc_flag = 0; asm_flag = 0; shared_flag = 0; } if (pcode_flag) { pc_flag = 0; asm_flag = 0; shared_flag = 0; } if (pc_flag) { pcode_flag = 1; #ifdef USE_AS if (use_asm) asm_flag = 1; else asm_flag = 0; #endif } if (xpc_flag) { pcode_flag = 1; pc_flag = 1; #ifdef USE_AS if (use_asm) asm_flag = 0; else asm_flag = 1; #endif } #if 0 if (shared_flag && pcode_flag) { v_printf(0, "conflict between -s and -p flags\n"); exit(1); } #endif if (pcode_flag && c_flag) { v_printf(0, "conflict between -c and -p flags\n"); exit(1); } /*if ( exec_flag && !main_flag && !shared_flag) { v_printf(0, "-e(xec) flag without -M(ain) or -s(hared) flags\n"); exit(2); } */ if (pcode_flag) { compile_flag = 0; } if (nomain_flag && main_flag) { v_printf(0, "conflict between -n and -m flags\n"); exit(1); } if (!exec_flag && oname) { char *e; if (oname[0] == '/') snprintf(buf, sizeof(buf), "%s", oname); else snprintf(buf, sizeof(buf), "%s%s%s", outdir ? outdir : "", outdir ? "/" : "", oname); e = strrchr(buf, '/'); if (e) { *e = 0; outdir = strdup(buf); } } if (!outdir) outdir = "."; if (outdir) { char cdir[256]; getcwd(cdir, sizeof(cdir)); if (!chdir(outdir)) { getcwd(buf, sizeof(buf)); outdir = strdup(buf); chdir(cdir); } else { yyerror("cannot change to output dir '%s': %s", outdir, strerror(errno)); exit(1); } } if (!preproc_flag) { v_printf(2, "set source charset to %s\n", sourceCharset); v_printf(2, "set target charset to %s\n", targetCharset); } init_lex(); init_parser(); if (argc < 1) ii = -1; else ii = 0; Beg = times(&ts); if (argc > 0) { for (i = 0; i < argc; i++) { char *e; e = argv[i]; if (e[0] == '-' && e[1] == 'L') { insert_Coll(&lib_dirs, strdup(e + 2)); continue; } e = strrchr(argv[i], '.'); if (!e) { e = argv[i]; if (e[0] == '-' && e[1] == 'l') /*append_Coll(&arglibs, strdup(e+2)) */ ; else yyerror("unknown file type '' file '%s'", argv[i]); continue; } else if (!strcasecmp(e, ".po")) insert_Coll(&poName, strdup(argv[i])); else if (!strcasecmp(e, ".pa")) insert_Coll(&paName, strdup(argv[i])); else if (strcasecmp(e, ".prg") && strcasecmp(e, ".c") && strcasecmp(e, ".cc") && strcasecmp(e, OBJSUF) && strcasecmp(e, SOBJSUF) && strcasecmp(e, ".a") && strcasecmp(e, ".lib")) { /*yywarning("unknown file type '%s' file '%s'", e, argv[i]); */ continue; } } } for (; clic_errorcount == 0 && ii < argc; ii++) { ++files; if (ii < 0) { v_printf(1, "no input files, so use stdin; -h will help\n"); fflush(stderr); set_locale_name("stdin"); ret = clic_parse("stdin", stdin); add_name("stdin"); } else { char *e; e = strrchr(argv[ii], '.'); add_name(argv[ii]); if (!e) continue; else if (!strcasecmp(e, ".c") || !strcasecmp(e, ".cc") || !strcasecmp(e, ".cpp")) { if (!preproc_flag) { v_printf(1, "process file '%s' ..", argv[ii]); v_neednl = 1; } beg = times(&ts); compile_CFile(argv[ii]); end = times(&ts); if (!preproc_flag) { v_neednl = 0; if (clic_errorcount == 0) v_printf(1, ".. done, %s\n", diff_clock(beg, end)); else pr_errorcount(1); } continue; } else if (strcasecmp(e, ".prg")) { continue; } if (ii > 0) main_flag = 0; if (!preproc_flag) { v_printf(1, "parsing file '%s' ..", argv[ii]); v_neednl = 1; } beg = times(&ts); set_locale_name(argv[ii]); ret = clic_parse(argv[ii], 0); end = times(&ts); if (!preproc_flag) { v_neednl = 0; if (clic_errorcount == 0) v_printf(1, ".. done (%d/%d %s, %d %s, %s)\n", clic_line, all_lines, _clic_ngettext("line", "lines", clic_line), clic_warncount, _clic_ngettext("warning", "warnings", clic_warncount), diff_clock(beg, end)); else vr_printf(1, "%d %s, %d %s\n", clic_errorcount, _clic_ngettext("error", "errors", clic_errorcount), clic_warncount, _clic_ngettext("warning", "warnings", clic_warncount)); } } if (ret) break; if (clic_errorcount == 0 && codegen_flag) { v_printf(2, "codegen file '%s' ..", curFile->name_of_File); v_neednl = 1; beg = times(&ts); codegen_File(curFile); end = times(&ts); v_neednl = 0; if (clic_errorcount == 0) v_printf(2, ".. done, %s\n", diff_clock(beg, end)); else pr_errorcount(2); } if (clic_errorcount == 0 && syntax_tree_flag) { print_File(curFile); } if (clic_errorcount == 0 && write_obj_flag) { if (pcode_flag) { long len; v_printf(1, "writing file '%s' ..", curFile->s_cname_of_File); v_neednl = 1; beg = times(&ts); write_OFile(curFile, &len); write_names(curFile); end = times(&ts); v_neednl = 0; if (clic_errorcount == 0) v_printf(1, ".. done, %ld %s ,%s\n", len, _clic_ngettext("byte", "bytes", len), diff_clock(beg, end)); else pr_errorcount(1); } else { v_printf(2, "writing file '%s' ..", curFile->s_cname_of_File); v_neednl = 1; write_File(curFile); write_names(curFile); v_neednl = 0; if (clic_errorcount == 0) v_printf(2, ".. done\n"); else pr_errorcount(2); } } if (clic_errorcount == 0 && (compile_flag || pc_flag)) { if (ii) main_flag = 0; v_printf(1, "compile file '%s' ..", curFile->s_cname_of_File); v_neednl = 1; beg = times(&ts); compile_File(curFile->cname_of_File); end = times(&ts); v_neednl = 0; if (clic_errorcount == 0) v_printf(1, ".. done, %s\n", diff_clock(beg, end)); else pr_errorcount(1); if (clic_errorcount == 0 && shared_flag && !exec_flag) { v_printf(1, "make shared object '%s' ..", curFile->s_cname_of_File); v_neednl = 1; beg = times(&ts); share_File(curFile->cname_of_File); end = times(&ts); v_neednl = 0; if (clic_errorcount == 0) v_printf(1, ".. done, %s\n", diff_clock(beg, end)); else pr_errorcount(1); } } if (ii < 0) break; delete_File(curFile); curFile = NULL; } if (clic_errorcount == 0 && exec_flag) { char cmd[1024 * 8], *e; char cfuncname[256], ofuncname[256]; char *libroot; int i; Coll ex, nm; init_Coll(&ex, free, strcasecmp); init_Coll(&nm, free, strcasecmp); #ifdef STD_LIBDIR libroot = 0; #else libroot = CLIPROOT; #endif ++files; #ifdef STD_LIBDIR if (eshared_flag || shared_flag) { snprintf(cmd, sizeof(cmd), "-lclip"); add_name(cmd); } else #endif { e = (eshared_flag || shared_flag) ? CLIPSLIB : CLIPLIB; lib_name(cmd, sizeof(cmd), libroot, "lib", e, strlen(e)); add_name(cmd); } for (e = CLIPLIBS; *e;) { int l; l = strspn(e, " \t"); e += l; l = strcspn(e, " \t"); if (!l) break; lib_name(cmd, sizeof(cmd), libroot, "lib", e, l); add_name(cmd); e += l; } for (e = ADDLIBS; *e;) { int l; l = strspn(e, " \t"); e += l; l = strcspn(e, " \t"); if (!l) break; memcpy(cmd, e, l); cmd[l] = 0; add_name(cmd); e += l; } add_name(MATHLIB); add_name(DLLIB); /* generate _cfunctions */ if (asm_flag) sprintf(cfuncname, "%s_ref.s", oname); else sprintf(cfuncname, "%s_ref.c", oname); sprintf(ofuncname, "%s_ref.o", oname); v_printf(1, "generate reference file '%s' ..", cfuncname); v_neednl = 1; beg = times(&ts); write_Cfunc(cfuncname, onum, ovect, &ex, &nm); check_names(&ex, &nm); end = times(&ts); v_neednl = 0; if (clic_errorcount == 0) v_printf(1, ".. done, %s\n", diff_clock(beg, end)); else pr_errorcount(1); if (clic_errorcount) goto end; v_printf(1, "compile file '%s' ..", cfuncname); v_neednl = 1; beg = times(&ts); compile_File(cfuncname); end = times(&ts); v_neednl = 0; if (clic_errorcount == 0) v_printf(1, ".. done, %s\n", diff_clock(beg, end)); else pr_errorcount(1); #ifdef USE_LD if (use_asm && (shared_flag || eshared_flag)) { int ll; const char *ld_prg, *ld_end; if (shared_flag || eshared_flag) { ld_prg = LD_PRG; ld_end = LD_END; } else { ld_prg = LDS_PRG; ld_end = LDS_END; } snprintf(cmd, sizeof(cmd), "%s", ld_prg); ll = strlen(cmd); for (e = cmd + ll, i = 0; i < lib_dirs.count_of_Coll; ++i) { snprintf(e, sizeof(cmd) - ll, " -L%s", (char *) lib_dirs.items_of_Coll[i]); ll = strlen(cmd); e = cmd + ll; } ll = strlen(cmd); snprintf(cmd + ll, sizeof(cmd) - ll, " %s %s %s -o %s", optLevel ? COPT : "", genDebug ? CDBG : "", ofuncname, oname); ll = strlen(cmd); for (e = cmd + ll, i = 0; i < onum; ++i) { snprintf(e, sizeof(cmd) - ll, " %s", ovect[i]); ll = strlen(cmd); e = cmd + ll; } ll = strlen(cmd); snprintf(cmd + ll, sizeof(cmd) - ll, " %s", ld_end); } else #endif { sprintf(cmd, "%s", CC); for (e = cmd + strlen(cmd), i = 0; i < includePaths.count_of_Coll; ++i) { sprintf(e, " %s %s", INCLUDE_FLAG, (char *) includePaths.items_of_Coll[i]); e = cmd + strlen(cmd); } for (e = cmd + strlen(cmd), i = 0; i < lib_dirs.count_of_Coll; ++i) { sprintf(e, " -L%s", (char *) lib_dirs.items_of_Coll[i]); e = cmd + strlen(cmd); } sprintf(cmd + strlen(cmd), " %s %s %s %s %s %s %s", optLevel ? COPT : "", genDebug ? CDBG : "", CFLAGS, ADDCFLAGS, ofuncname, OUT_FLAG, oname); for (e = cmd + strlen(cmd), i = 0; i < onum; ++i) { sprintf(e, " %s", ovect[i]); e = cmd + strlen(cmd); } } v_printf(1, "make file '%s' ..", oname); v_neednl = 1; beg = times(&ts); v_printf(2, "%s\n", cmd); if (system(cmd)) yyerror("C level error in command: %s", cmd); else if (rmc_flag) { unlink(cfuncname); unlink(ofuncname); } end = times(&ts); v_neednl = 0; if (clic_errorcount == 0) v_printf(1, ".. done, %s\n", diff_clock(beg, end)); else pr_errorcount(1); } end: End = times(&ts); resume_parser(); resume_lex(); resume_locale(); if (!preproc_flag) v_printf(1, "clip: %d %s, %s\n", files, _clic_ngettext("file", "files", files), diff_clock(Beg, End)); return clic_errorcount == 0 ? 0 : 1; }
data eval_expr(node expr, symrec ** symTable,list * routineList){ data res; switch (expr.operator) { case SEMICOLON: { //c'è sempre uno statement da valutare //valuto il primo eval(expr.op[0],symTable,routineList); if(expr.noperands>1){ //valuto il secondo, non è possibile per la struttura del parser averne più di due return eval(expr.op[1], symTable, routineList); } } break; case PRINT: { //statement data e = eval(expr.op[0], symTable,routineList); printData(e); res.type = no_op; return res; } break; case EQUALS: //statement { symrec * s = getSymbolFromIdentifier(expr.op[0]->value.id,symTable); //check if the variable is function routine * r = getRoutine(expr.op[0]->value.id.name, routineList); if(s == NULL && r == NULL){ yyerror("during assignment found unknown variable or function"); exit(NO_SUCH_VARIABLE); } //else data res; if(s!=NULL){ res = assignment(s,expr.op[1],symTable,routineList); } if(r!=NULL){ //TODO check if this is a function or a procedure res = r_assignment(r,expr.op[1], symTable,routineList); } return res; } break; case WHILE: //statement { // in ro con ambiente delta valuto <while e to c, omega> --> c <c; while e do c, omega> solo se in ro con ambiente delta posso valutare e a boleano vedi pag 54 semantica opearzionale data bool_guard = eval(expr.op[0],symTable,routineList); //here typechecking for correct return type of bool_guard...must be boolean if(bool_guard.b.b == true){ eval(expr.op[1],symTable,routineList); //ho fatto il comando c, ora rimetto a valutazione la stessa operazione treeNode * newWhile = opr(WHILE,2,expr.op[0],expr.op[1]); eval(newWhile,symTable,routineList); //free(newWhile) } data res; res.type = no_op; return res; } break; case IF: //statement { data bool_guard = eval(expr.op[0],symTable,routineList); //here typechecking for correct return type of bool_guard...must be boolean if(bool_guard.b.b == true){ eval(expr.op[1],symTable,routineList); }else if(expr.noperands == 3){ //se c'è il branch else eval(expr.op[2],symTable,routineList); } data res; res.type = no_op; return res; } break; case FOR: //statement { symrec * s = getSymbolFromIdentifier(expr.op[0]->value.id,symTable); if(s == NULL){ yyerror("NO_SUCH_VARIABLE"); exit(NO_SUCH_VARIABLE); } assignment(s,expr.op[1],symTable,routineList); identifier index; index.name = malloc(strlen(s->name)+1); strcpy(index.name,s->name); data id = eval_identifier(index, symTable,routineList); //consider only LT data guard = eval(expr.op[2],symTable,routineList); data comparison = operation(LT, id,guard); //here happens typechecking if(comparison.b.b == true){ eval(expr.op[3],symTable,routineList); //incremento la variable, assume only integers treeNode * nextValue = constantNode(basic_int_value, id.b.i + 1); //assignment(s,nextValue,symTable); treeNode * newFor = opr(FOR,4,expr.op[0],nextValue,expr.op[2],expr.op[3]); eval(newFor,symTable,routineList); //free(newFor); //free(nextValue); } } break; case UMINUS: { data e1, e2; //typechecking happens here e1= eval(expr.op[0],symTable,routineList); return negate(e1); } case MINUS: { data e1, e2; //typechecking happens here e1= eval(expr.op[0],symTable,routineList); e2= eval(expr.op[1],symTable,routineList); return operation(MINUS, e1,e2); } break; case PLUS : { data e1, e2; //typechecking happens here e1= eval(expr.op[0],symTable,routineList); e2= eval(expr.op[1],symTable,routineList); return operation(PLUS, e1,e2); } break; case MULTIPLY: { data e1, e2; //typechecking happens here e1= eval(expr.op[0],symTable,routineList); e2= eval(expr.op[1],symTable,routineList); return operation(MULTIPLY, e1,e2); } break; case DIVIDE : { data e1, e2; //typechecking happens here e1= eval(expr.op[0],symTable,routineList); e2= eval(expr.op[1],symTable,routineList); return operation(DIVIDE, e1,e2); } break; case LT : { data e1, e2; //typechecking happens here e1= eval(expr.op[0],symTable,routineList); e2= eval(expr.op[1],symTable,routineList); return operation(LT, e1,e2); } break; case GT : { data e1, e2; //typechecking happens here e1= eval(expr.op[0],symTable,routineList); e2= eval(expr.op[1],symTable,routineList); return operation(GT, e1,e2); } break; case GE : { data e1, e2; //typechecking happens here e1= eval(expr.op[0],symTable,routineList); e2= eval(expr.op[1],symTable,routineList); return operation(GE, e1,e2); } break; case LE : { data e1, e2; //typechecking happens here e1= eval(expr.op[0],symTable,routineList); e2= eval(expr.op[1],symTable,routineList); return operation(LE, e1,e2); } break; case NE : { data e1, e2; //typechecking happens here e1= eval(expr.op[0],symTable,routineList); e2= eval(expr.op[1],symTable,routineList); return operation(NE, e1,e2); } break; case EQ : { data e1, e2; //typechecking happens here e1= eval(expr.op[0],symTable,routineList); e2= eval(expr.op[1],symTable,routineList); return operation(EQ, e1,e2); } break; default: yyerror("eval_expr new type not implemented"); exit(NOT_IMPLEMENTED_YET); break; } return res; }
int yylex (void) { unichar *start_token; unichar ch; if (! input_stream_pos) { fatal ("Input stream not setuped.\n"); return -1; } if (mclex_want_line) { start_token = input_stream_pos; if (input_stream_pos[0] == '.' && (input_stream_pos[1] == '\n' || (input_stream_pos[1] == '\r' && input_stream_pos[2] == '\n'))) { mclex_want_line = FALSE; while (input_stream_pos[0] != 0 && input_stream_pos[0] != '\n') ++input_stream_pos; if (input_stream_pos[0] == '\n') ++input_stream_pos; return MCENDLINE; } while (input_stream_pos[0] != 0 && input_stream_pos[0] != '\n') ++input_stream_pos; if (input_stream_pos[0] == '\n') ++input_stream_pos; yylval.ustr = get_diff (input_stream_pos, start_token); return MCLINE; } while ((ch = input_stream_pos[0]) <= 0x20) { if (ch == 0) return -1; ++input_stream_pos; if (ch == '\n') input_line += 1; if (mclex_want_nl && ch == '\n') { mclex_want_nl = FALSE; return NL; } } start_token = input_stream_pos; ++input_stream_pos; if (mclex_want_filename) { mclex_want_filename = FALSE; if (ch == '"') { start_token++; while ((ch = input_stream_pos[0]) != 0) { if (ch == '"') break; ++input_stream_pos; } yylval.ustr = get_diff (input_stream_pos, start_token); if (ch == '"') ++input_stream_pos; } else { while ((ch = input_stream_pos[0]) != 0) { if (ch <= 0x20 || ch == ')') break; ++input_stream_pos; } yylval.ustr = get_diff (input_stream_pos, start_token); } return MCFILENAME; } switch (ch) { case ';': ++start_token; while (input_stream_pos[0] != '\n' && input_stream_pos[0] != 0) ++input_stream_pos; if (input_stream_pos[0] == '\n') input_stream_pos++; yylval.ustr = get_diff (input_stream_pos, start_token); return MCCOMMENT; case '=': return '='; case '(': return '('; case ')': return ')'; case '+': return '+'; case ':': return ':'; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': yylval.ival = parse_digit (ch); return MCNUMBER; default: if (ch >= 0x40) { int ret; while (input_stream_pos[0] >= 0x40 || (input_stream_pos[0] >= '0' && input_stream_pos[0] <= '9')) ++input_stream_pos; ret = mc_token (start_token, (size_t) (input_stream_pos - start_token)); if (ret != -1) return ret; yylval.ustr = get_diff (input_stream_pos, start_token); return MCIDENT; } yyerror ("illegal character 0x%x.", ch); } return -1; }
int yyparse (void) { int yystate; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* The stacks and their tools: 'yyss': related to states. 'yyvs': related to semantic values. Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs; YYSTYPE *yyvsp; YYSIZE_T yystacksize; int yyn; int yyresult; /* Lookahead token as an internal (translated) token number. */ int yytoken = 0; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; yyssp = yyss = yyssa; yyvsp = yyvs = yyvsa; yystacksize = YYINITDEPTH; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); if (yystate == YYFINAL) YYACCEPT; goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yypact_value_is_default (yyn)) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = yylex (); } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yytable_value_is_error (yyn)) goto yyerrlab; yyn = -yyn; goto yyreduce; } /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token. */ yychar = YYEMPTY; yystate = yyn; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: '$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 2: #line 49 "parser.y" /* yacc.c:1646 */ { printf("Valid program. Parsing is Complete.\n");} #line 1278 "parser.tab.c" /* yacc.c:1646 */ break; #line 1282 "parser.tab.c" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires that yytoken be updated with the new translation. We take the approach of translating immediately before every use of yytoken. One alternative is translating here after every semantic action, but that translation would be missed if the semantic action invokes YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an incorrect destructor might then be invoked immediately. In the case of YYERROR or YYBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*--------------------------------------. | yyerrlab -- here on detecting error. | `--------------------------------------*/ yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (YY_("syntax error")); #else # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ yyssp, yytoken) { char const *yymsgp = YY_("syntax error"); int yysyntax_error_status; yysyntax_error_status = YYSYNTAX_ERROR; if (yysyntax_error_status == 0) yymsgp = yymsg; else if (yysyntax_error_status == 1) { if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); if (!yymsg) { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; yysyntax_error_status = 2; } else { yysyntax_error_status = YYSYNTAX_ERROR; yymsgp = yymsg; } } yyerror (yymsgp); if (yysyntax_error_status == 2) goto yyexhaustedlab; } # undef YYSYNTAX_ERROR #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval); yychar = YYEMPTY; } } /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #if !defined yyoverflow || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEMPTY) { /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = YYTRANSLATE (yychar); yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval); } /* Do not reclaim the symbols of the rule whose action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif return yyresult; }
void typecheckrange(Node *n) { int op, et; Type *t, *t1, *t2; Node *v1, *v2; NodeList *ll; // delicate little dance. see typecheckas2 for(ll=n->list; ll; ll=ll->next) if(ll->n->defn != n) typecheck(&ll->n, Erv | Easgn); typecheck(&n->right, Erv); if((t = n->right->type) == T) goto out; n->type = t; switch(t->etype) { default: yyerror("cannot range over %+N", n->right); goto out; case TARRAY: t1 = types[TINT]; t2 = t->type; break; case TMAP: t1 = t->down; t2 = t->type; break; case TCHAN: t1 = t->type; t2 = nil; if(count(n->list) == 2) goto toomany; break; case TSTRING: t1 = types[TINT]; t2 = types[TINT]; break; } if(count(n->list) > 2) { toomany: yyerror("too many variables in range"); } v1 = n->list->n; v2 = N; if(n->list->next) v2 = n->list->next->n; if(v1->defn == n) v1->type = t1; else if(v1->type != T && checkconv(t1, v1->type, 0, &op, &et) < 0) yyerror("cannot assign type %T to %+N", t1, v1); if(v2) { if(v2->defn == n) v2->type = t2; else if(v2->type != T && checkconv(t2, v2->type, 0, &op, &et) < 0) yyerror("cannot assign type %T to %+N", t1, v1); } out: typechecklist(n->nbody, Etop); // second half of dance n->typecheck = 1; for(ll=n->list; ll; ll=ll->next) if(ll->n->typecheck == 0) typecheck(&ll->n, Erv | Easgn); }
// // floating point input // required syntax is [+-]d*[.]d*[e[+-]d*] // void mpatoflt(Mpflt *a, char *as) { Mpflt b; int dp, c, f, ef, ex, eb, zer; char *s; s = as; dp = 0; /* digits after decimal point */ f = 0; /* sign */ ex = 0; /* exponent */ eb = 0; /* binary point */ zer = 1; /* zero */ mpmovecflt(a, 0.0); for(;;) { switch(c = *s++) { default: goto bad; case '-': f = 1; case ' ': case '\t': case '+': continue; case '.': dp = 1; continue; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': zer = 0; case '0': mpmulcflt(a, 10); mpaddcflt(a, c-'0'); if(dp) dp++; continue; case 'P': case 'p': eb = 1; case 'E': case 'e': ex = 0; ef = 0; for(;;) { c = *s++; if(c == '+' || c == ' ' || c == '\t') continue; if(c == '-') { ef = 1; continue; } if(c >= '0' && c <= '9') { ex = ex*10 + (c-'0'); continue; } break; } if(ef) ex = -ex; case 0: break; } break; } if(eb) { if(dp) goto bad; a->exp += ex; goto out; } if(dp) dp--; if(mpcmpfltc(a, 0.0) != 0) { if(ex >= dp) { mppow10flt(&b, ex-dp); mpmulfltflt(a, &b); } else { mppow10flt(&b, dp-ex); mpdivfltflt(a, &b); } } out: if(f) mpnegflt(a); return; bad: yyerror("set ovf in mpatof"); mpmovecflt(a, 0.0); }
static double calluser(struct ufncall *f) { struct symbol *fn = f->s; /* function name */ struct symlist *sl; /* dummy arguments */ struct ast *args = f->l; /* actual arguments */ double *oldval, *newval; /* saved arg values */ double v; int nargs; int i; if(!fn->func) { yyerror("call to undefined function", fn->name); return 0; } /* count the arguments */ sl = fn->syms; for(nargs = 0; sl; sl = sl->next) nargs++; /* prepare to save them */ oldval = (double *)malloc(nargs * sizeof(double)); newval = (double *)malloc(nargs * sizeof(double)); if(!oldval || !newval) { yyerror("Out of space in %s", fn->name); return 0.0; } /* evaluate the arguments */ for(i = 0; i < nargs; i++) { if(!args) { yyerror("too few args in call to %s", fn->name); free(oldval); free(newval); return 0; } if(args->nodetype == 'L') { /* if this is a list node */ newval[i] = eval(args->l); args = args->r; } else { /* if it's the end of the list */ newval[i] = eval(args); args = NULL; } } /* save old values of dummies, assign new ones */ sl = fn->syms; for(i = 0; i < nargs; i++) { struct symbol *s = sl->sym; oldval[i] = s->value; s->value = newval[i]; sl = sl->next; } free(newval); /* evaluate the function */ v = eval(fn->func); /* put the dummies back */ sl = fn->syms; for(i = 0; i < nargs; i++) { struct symbol *s = sl->sym; s->value = oldval[i]; sl = sl->next; } free(oldval); return v; }