inttoktype yylex() { register ptrall bufptr; register inttoktype val; register struct exp *locxp; /* * No local variables to be allocated; this saves * one piddling instruction.. */ static int Lastjxxx; bufptr = tokptr; /*copy in the global value*/ top: if (bufptr < tokub){ gtoken(val, bufptr); switch(yylval = val){ case PARSEEOF: yylval = val = PARSEEOF; break; case BFINT: case INT: if (xp >= &explist[NEXP]) yyerror("Too many expressions; try simplyfing"); else locxp = xp++; locxp->e_number = Znumber; locxp->e_number.num_tag = TYPL; glong(locxp->e_xvalue, bufptr); makevalue: locxp->e_xtype = XABS; locxp->e_xloc = 0; locxp->e_xname = NULL; yylval = (int)locxp; break; case BIGNUM: if (xp >= &explist[NEXP]) yyerror("Too many expressions; try simplyfing"); else locxp = xp++; gnumber(locxp->e_number, bufptr); goto makevalue; case NAME: gptr(yylval, bufptr); lastnam = (struct symtab *)yylval; break; case SIZESPEC: case REG: gchar(yylval, bufptr); break; case INSTn: case INST0: gopcode(yyopcode, bufptr); break; case IJXXX: gopcode(yyopcode, bufptr); /* We can't cast Lastjxxx into (int *) here.. */ gptr(Lastjxxx, bufptr); lastjxxx = (struct symtab *)Lastjxxx; break; case ILINESKIP: gint(yylval, bufptr); lineno += yylval; goto top; case SKIP: eatskiplg(bufptr); goto top; case VOID: goto top; case STRING: case ISTAB: case ISTABSTR: case ISTABNONE: case ISTABDOT: case IALIGN: gptr(yylval, bufptr); break; } #ifdef DEBUG if (toktrace){ char *tok_to_name(); printf("P: %d T#: %4d, %s ", passno, bufptr - firsttoken, tok_to_name(val)); switch(val){ case INT: printf("val %d", ((struct exp *)yylval)->e_xvalue); break; case BFINT: printf("val %d", ((struct exp *)yylval)->e_xvalue); break; case BIGNUM: bignumprint(((struct exp*)yylval)->e_number); break; case NAME: printf("\"%.8s\"", FETCHNAME((struct symtab *)yylval)); break; case REG: printf(" r%d", yylval); break; case IJXXX: case INST0: case INSTn: printf("%.8s", FETCHNAME(ITABFETCH(yyopcode))); break; case STRING: printf("length %d, seekoffset %d, place 0%o ", ((struct strdesc *)yylval)->sd_strlen, ((struct strdesc *)yylval)->sd_stroff, ((struct strdesc *)yylval)->sd_place ); if (((struct strdesc *)yylval)->sd_place & STR_CORE) printf("value\"%*s\"", ((struct strdesc *)yylval)->sd_strlen, ((struct strdesc *)yylval)->sd_string); break; } /*end of the debug switch*/ printf("\n"); } #endif DEBUG } else { /* start a new buffer */ if (useVM){ if (passno == 2){ tok_temp = emptybuf->tok_next; emptybuf->tok_next = tok_free; tok_free = emptybuf; emptybuf = tok_temp; } else { emptybuf = emptybuf->tok_next; } bufno += 1; if (emptybuf == 0){ struct tokbufdesc *newdallop; int i; if (passno == 2) goto badread; emptybuf = newdallop = (struct tokbufdesc *) Calloc(TOKDALLOP, sizeof (struct tokbufdesc)); for (i=0; i < TOKDALLOP; i++){ buftail->tok_next = newdallop; buftail = newdallop; newdallop += 1; } buftail->tok_next = 0; } /*end of need to get more buffers*/ (bytetoktype *)bufptr = &(emptybuf->toks[0]); if (passno == 1) scan_dot_s(emptybuf); } else { /*don't use VM*/ bufno ^= 1; emptybuf = &tokbuf[bufno]; ((bytetoktype *)bufptr) = &(emptybuf->toks[0]); if (passno == 1){ /* * First check if there are things to write * out at all */ if (emptybuf->tok_count >= 0){ if (writeTEST((char *)emptybuf, sizeof *emptybuf, 1, tokfile)){ yyerror("Unexpected end of file writing the interpass tmp file"); exit(2); } } scan_dot_s(emptybuf); } else { /*pass 2*/ if (readTEST((char *)emptybuf, sizeof *emptybuf, 1, tokfile)){ badread: yyerror("Unexpected end of file while reading the interpass tmp file"); exit(1); } } } /*end of using a real live file*/ (char *)tokub = (char *)bufptr + emptybuf->tok_count; #ifdef DEBUG firsttoken = bufptr; if (debug) printf("created buffernumber %d with %d tokens\n", bufno, emptybuf->tok_count); #endif DEBUG goto top; } /*end of reading/creating a new buffer*/ tokptr = bufptr; /*copy back the global value*/ return(val); } /*end of yylex*/
// ============================================================================ // pxpByteCode // ============================================================================ pxpByteCode::pxpByteCode( pkgDecompiler* decompiler ) : Decompiler(decompiler) , CToken(NULL) , CTokenTree(NULL) , CTokenGroup(NULL) , CTokenGroupTree(NULL) , CTokenItem(NULL) , CTokenItemTree(NULL) , CTokenGroupCnd(NULL) , CTokenGroupCndTree(NULL) , unXmlParser() { // temp tree nodes unXmlParseTree bytecode ( wxT("bytecode") ); unXmlParseTree bgroup ( wxT("group") ); unXmlParseTree gname ( wxT("name") ); unXmlParseTree gmemo ( wxT("memo") ); unXmlParseTree gtoken ( wxT("token") ); unXmlParseTree tcode ( wxT("code") ); unXmlParseTree tname ( wxT("name") ); unXmlParseTree tdesc ( wxT("desc") ); unXmlParseTree tdata ( wxT("data") ); unXmlParseTree titem ( wxT("item") ); unXmlParseTree itype ( wxT("type") ); unXmlParseTree iname ( wxT("name") ); unXmlParseTree ttext ( wxT("text") ); unXmlParseTree gcond ( wxT("gcond") ); unXmlParseTree cif ( wxT("if") ); unXmlParseTree ceq ( wxT("eq") ); unXmlParseTree cthen ( wxT("then") ); unXmlParseTree cleft ( wxT("left") ); unXmlParseTree cright ( wxT("right") ); unXmlParseTree ctstream ( wxT("tstream") ); unXmlParseTree cnum ( wxT("num") ); unXmlParseTree nfunc ( wxT("nativefunctions") ); unXmlParseTree ffirst ( wxT("first") ); unXmlParseTree fextended ( wxT("extended") ); // token group - pre bgroup.AddCommand( new_xpObjCreate<pkgTokenGroup>(txpParseTree) ); bgroup.AddCommand( new_xpFunc1( this, &pxpByteCode::SetTokenGroup, txpTokenGroupObject ) ); bgroup.AddCommand( new_xpFunc1( this, &pxpByteCode::SetTokenGroupTree, txpParseTree ) ); gname.AddCommand( new_xpFunc1( txpTokenGroup, &pkgTokenGroup::SetName, txpNodeName(txpParseTree) ) ); gname.AddPostCommand( new_xpFunc1( Decompiler, &pkgDecompiler::AddTokenGroup, txpTokenGroup ) ); // token group - post bgroup.AddPostCommand( new_xpObjClear(txpParseTree) ); bgroup.AddPostCommand( new_xpFunc0( this, &pxpByteCode::ClearTokenGroup ) ); bgroup.AddPostCommand( new_xpFunc0( this, &pxpByteCode::ClearTokenGroupTree ) ); // gcond = pre gcond.AddCommand( new_xpObjCreate<pkgTokenCondition>(txpParseTree) ); gcond.AddCommand( new_xpFunc1( this, &pxpByteCode::SetTokenGroupCnd, txpTokenGroupCndObject ) ); gcond.AddCommand( new_xpFunc1( this, &pxpByteCode::SetTokenGroupCndTree, txpParseTree ) ); // gcond = post gcond.AddPostCommand( new_xpObjClear(txpParseTree) ); gcond.AddPostCommand( new_xpFunc0( this, &pxpByteCode::ClearTokenGroupCnd ) ); gcond.AddPostCommand( new_xpFunc0( this, &pxpByteCode::ClearTokenGroupCndTree ) ); // token - pre gtoken.AddCommand( new_xpObjCreate<dtToken>(txpParseTree) ); gtoken.AddCommand( new_xpFunc1( this, &pxpByteCode::SetToken, txpTokenObject ) ); gtoken.AddCommand( new_xpFunc1( this, &pxpByteCode::SetTokenTree, txpParseTree ) ); tcode.AddCommand( new_xpFunc1( txpTokenTreeObject, &dtToken::SetTokenData, txpNodeData(txpParseTree) ) ); tname.AddCommand( new_xpFunc1( txpTokenTreeObject, &dtToken::SetTokenName, txpNodeName(txpParseTree) ) ); tdesc.AddCommand( new_xpFunc1( txpTokenTreeObject, &dtToken::SetDesc, txpNodeName(txpParseTree) ) ); tdesc.AddCommand( new_xpFunc1( txpTokenGroup, &pkgTokenGroup::AddToken, txpToken ) ); tdesc.AddCommand( new_xpFunc2( Decompiler, &pkgDecompiler::AddToken, txpToken, txpTokenGroupCnd ) ); // token - post gtoken.AddPostCommand( new_xpFunc0( txpToken, &dtToken::DumpInfo ) ); gtoken.AddPostCommand( new_xpObjClear(txpParseTree) ); gtoken.AddPostCommand( new_xpFunc0( this, &pxpByteCode::ClearToken ) ); gtoken.AddPostCommand( new_xpFunc0( this, &pxpByteCode::ClearTokenTree ) ); // titem - pre titem.AddCommand( new_xpFunc1( this, &pxpByteCode::SetTokenItemTree, txpParseTree ) ); itype.AddCommand( new_xpObjFactory( txpTokenItemTree, &GDataTypeFactory, &pkgDataTypeFactory::Create, txpNodeName(txpParseTree) ) ); itype.AddCommand( new_xpFunc1( this, &pxpByteCode::SetTokenItem, txpTokenItemTreeObject ) ); iname.AddCommand( new_xpFunc1( txpTokenItem, &pkgDataType::SetDesc, txpNodeName(txpParseTree) ) ); // titem - post titem.AddPostCommand( new_xpFunc1( txpToken, &dtToken::AddItem, txpTokenItem ) ); titem.AddPostCommand( new_xpObjClear(txpParseTree) ); titem.AddPostCommand( new_xpFunc0( this, &pxpByteCode::ClearTokenItem ) ); titem.AddPostCommand( new_xpFunc0( this, &pxpByteCode::ClearTokenItemTree ) ); ffirst.AddCommand( new_xpFunc1( Decompiler, &pkgDecompiler::SetFunctionIdFirst, txpNodeData(txpParseTree) ) ); fextended.AddCommand( new_xpFunc1( Decompiler, &pkgDecompiler::SetFunctionIdExtended, txpNodeData(txpParseTree) ) ); // construct tree starting from leaves // ie: node on right side *cannot* appear anywhere below on left side // token gtoken.AddChild( tcode, pl::one ); gtoken.AddChild( tname, pl::one ); gtoken.AddChild( tdesc, pl::one ); titem.AddChild( itype, pl::one ); titem.AddChild( iname, pl::one ); tdata.AddChild( titem, pl::minone ); tdata.AddChild( ttext, pl::maxone ); gtoken.AddChild( tdata, pl::maxone ); // if cleft.AddChild( ctstream, pl::maxone ); cleft.AddChild( cnum, pl::maxone ); cright.AddChild( ctstream, pl::maxone ); cright.AddChild( cnum, pl::maxone ); ceq.AddChild( cleft, pl::one ); ceq.AddChild( cright, pl::one ); cif.AddChild( ceq, pl::one ); // then cthen.AddChild( gtoken, pl::any ); // group bgroup.AddChild( gname, pl::one ); bgroup.AddChild( gmemo, pl::any ); gcond.AddChild( cif, pl::one ); gcond.AddChild( cthen, pl::one ); bgroup.AddChild( gcond, pl::maxone ); bgroup.AddChild( gtoken, pl::any ); // native functions nfunc.AddChild( fextended, pl::one ); nfunc.AddChild( ffirst, pl::one ); // bytecode bytecode.AddChild( bgroup, pl::minone ); bytecode.AddChild( nfunc, pl::maxone ); ParseTree = new unXmlParseTree( bytecode ); }
toktype yylex() { register ptrall bufptr; register toktype val; register struct exp *locxp; bufptr = tokptr; /*copy in the global value*/ top: if (bufptr < tokub){ gtoken(val, bufptr); switch(yylval = val){ case PARSEEOF : yylval = val = PARSEEOF; break; case INT: locxp = xp++; glong(locxp->xvalue, bufptr); makevalue: locxp->xtype = XABS; locxp->xloc = 0; locxp->xname = NULL; yylval = (int)locxp; break; case FLTNUM: /*case patched on 3-Jan-80*/ locxp = xp++; gdouble(locxp->doubval.dvalue, bufptr); /* * We make sure that locxp->xvalue * is not in the range suitable for * a short literal. The field * xvalue is only used for * integers, not doubles, but when * we test for short literals * in ascode.c, we look * at the field xvalue when * it encounters an in line * floating number. Ergo, * give it a bad value. */ locxp->xvalue = -1; goto makevalue; case NAME: gptr(yylval, bufptr); lastnam = (struct symtab *)yylval; break; case SIZESPEC: case REG: case INSTn: case INST0: gchar(yylval, bufptr); break; case IJXXX: gchar(yylval, bufptr); gptr(lastjxxx, bufptr); break; case ILINESKIP: gint(yylval, bufptr); lineno += yylval; goto top; case SKIP: eatskiplg(bufptr); goto top; case VOID: goto top; case STRING: strptr = &strbuf[strno ^= 1]; strptr->str_lg = *((lgtype *)bufptr); movestr(&strptr->str[0], (char *)bufptr + sizeof(lgtype), strptr->str_lg); eatstrlg(bufptr); yylval = (int)strptr; break; case ISTAB: case ISTABSTR: case ISTABNONE: case ISTABDOT: case IALIGN: gptr(yylval, bufptr); break; } /*end of the switch*/ #ifdef DEBUG if (toktrace) switch(val){ case INT: printf("Class integer val %d\n", ((struct exp *)yylval)->xvalue); break; case FLTNUM: printf("Class floating point num value %4.3f\n", ((struct exp *)yylval) -> doubval.dvalue); break; case NAME: printf("Class name, \"%.8s\"\n", ((struct symtab *)yylval)->name); break; case REG: printf("Class register, number %d\n", yylval); break; case INSTn: printf("Class INSTn, %.8s\n", itab[0xFF &yylval]->name); break; case IJXXX: printf("Class IJXXX, %.8s\n", itab[0xFF &yylval]->name); break; case INST0: printf("Class INST0, %.8s\n", itab[0xFF &yylval]->name); break; case STRING: printf("Class string, length %d\n", ((struct strdesc *)yylval)->str_lg); break; default: printf("Pass: %d Tok: %d Other class: %d, 0%o, '%c'\n", passno, bufptr - firsttoken, val,val, val); break; } /*end of the debug switch*/ #endif } /*end of this buffer*/ else { if (useVM){ bufno += 1; emptybuf = emptybuf->tok_next; if (emptybuf == 0){ struct tokbufdesc *newdallop; int i; if (passno == 2) goto badread; emptybuf = newdallop = (struct tokbufdesc *)sbrk( TOKDALLOP*sizeof (struct tokbufdesc)); if (emptybuf == (struct tokbufdesc *)-1) goto badwrite; for (i=0; i < TOKDALLOP; i++){ buftail->tok_next = newdallop; buftail = newdallop; newdallop += 1; } buftail->tok_next = 0; } /*end of need to get more buffers*/ (toktype *)bufptr = &(emptybuf->toks[0]); if (passno == 1) scan_dot_s(emptybuf); } else { /*don't use VM*/ bufno ^= 1; emptybuf = &tokbuf[bufno]; ((toktype *)bufptr) = &(emptybuf->toks[0]); if (passno == 1){ /* * First check if there are things to write * out at all */ if (emptybuf->tok_count >= 0){ if (fwrite(emptybuf, sizeof *emptybuf, 1, tmpfil) != 1){ badwrite: yyerror("Unexpected end of file writing the interpass tmp file"); exit(2); } } scan_dot_s(emptybuf); } else { /*pass 2*/ if (fread(emptybuf, sizeof *emptybuf, 1, tmpfil) != 1){ badread: yyerror("Unexpected end of file while reading the interpass tmp file"); exit(1); } } /*end of pass2*/ } /*end of using a real live file*/ (char *)tokub = (char *)bufptr + emptybuf->tok_count; #ifdef DEBUG firsttoken = bufptr; if (debug) printf("created buffernumber %d with %d tokens\n", bufno, emptybuf->tok_count); #endif goto top; } /*end of reading/creating a new buffer*/ tokptr = bufptr; /*copy back the global value*/ return(val); } /*end of yylex*/