Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===== ”« £¨ ª®¬¯¨«ï樨
  2. #pragma option w32c
  3. #stack 0x8000
  4. #argc TRUE
  5.  
  6. //===== ®¤ª«îç ¥¬ë¥ ¬®¤ã«¨
  7. #include "wapi.h--"
  8. #include "enums.h--"
  9. #include "data.h--"
  10. #include "opcodesc.h--"
  11. #include "tree.h--"
  12. #include "directiv.h--"
  13. #include "tokscan.h--"
  14. #include "exe.h--"
  15. #include "generate.h--"
  16. #include "parser.h--"
  17.  
  18. //===== ƒ« ¢­ ï äã­ªæ¨ï ¯à®£à ¬¬ë
  19. main()
  20. dword count,pari,cmdline;
  21. {
  22.         stdout=GetStdHandle(STD_OUTPUT_HANDLE);
  23.         WRITESTR("\n32-Compiler  Version 0.01\tXAC (C) 1999.");
  24.         WRITESTR("\nBased on SPHINX C-- Compiler Peter Cellik (C) 1995.\n");
  25. //  §¡®à ª®¬¬ ­¤­®© áâப¨: 32.exe <SourceFileName> [/map] [/debug]
  26.         pari=@PARAMCOUNT();
  27.         for(count=1;count<pari;count++){        //®¡à ¡®âª  ª®¬ ­¤­®© áâப¨
  28.                 cmdline=@PARAMSTR(count);
  29.                 CharUpperA(EAX);
  30.                 CharToOemA(cmdline,cmdline);    // à¥®¡à §ã¥¬ ¢ ‡€ƒ‹ ¢ OEM ª®¤à®¢ª¥
  31.                 ESI=cmdline;
  32.                 IF(DSBYTE[ESI]=='/'){
  33.                         ESI++;
  34.                         IF(lstrcmpA("MAP",ESI)==0)makemapfile = 1;
  35.                         ELSE IF(lstrcmpA("DEBUG",ESI)==0)dbg=1;
  36.                         ELSE{
  37.                                 WRITESTR("ERROR > Unknown command line option: '");
  38.                                 WRITESTR(cmdline);
  39.                                 WRITESTR("'\n");
  40.                                 ExitProcess(e_unknowncommandline);
  41.                         }
  42.                 }
  43.                 ELSE{ // Š®¯¨à㥬 ¨¬ï ¨á室­®£® ä ©«  ¡¥§ à áè¨à¥­¨ï
  44.                         EDI=#rawfilename;
  45.                         for(;;){
  46.                                 $LODSB
  47.                                 IF(AL=='.')||(AL==0)BREAK; // …áâì à áè¨à¥­¨¥?
  48.                                 $STOSB;
  49.                         }
  50.                         AL=0;
  51.                         $STOSB;
  52.                         lstrcpyA(#inputfile,cmdline); // Š®¯¨à㥬 ¨¬ï ¢å®¤­®£® ä ©«  á à áè¨à¥­¨¥¬
  53.                 }
  54.         }
  55.         IF(rawfilename[0]==0){
  56.                 errmsg();
  57.                 WRITESTR("No input file specified");
  58.                 pari=1;
  59.         }
  60.         IF(pari < 2){
  61.                 WRITESTR("\nUsage: 32.exe [/MAP] [/DEBUG] <Source file>");
  62.                 WRITESTR("\n\t/MAP\t<< generate map file");
  63.                 WRITESTR("\n\t/DEBUG\t<< generate .TDS - debug info file\n");
  64.                 ExitProcess(e_noinputspecified);
  65.         }
  66.         GetMem();       // ¢ë¤¥«¥­¨¥ ¯ ¬ï⨠¤«ï ª®¬¯¨«ï樨
  67.         TokInit();              // ¨­¨æ¨ «¨§ æ¨ï ᯨ᪮¢
  68.         Compile();
  69.         IF( error == 0 )EAX=e_ok;
  70.         ELSE EAX=e_someerrors;
  71.         ExitProcess(EAX);
  72. }
  73.  
  74. //===== Š®¬¯¨«ïâ®à
  75. Compile()
  76. {
  77.         IF(makemapfile)StartMapfile();
  78.         WRITESTR("Compiling ...\n");
  79.         Preview(#inputfile);
  80.         CompileAll();
  81. /*if( endifcount > 0 )
  82.         preerror("#endif expected before end of file");
  83. if( outptr%16 != 0 )    // paragraph align the end of the code seg
  84.         outptr += 16 - outptr%16;*/
  85.         DoLink();       // ”®à¬¨à®¢ ­¨¥ link
  86.         IF(posts > 0)DoPosts(); // Ž¡­®¢«¥­¨¥ ¢á¥å post  ¤à¥á®¢
  87.         SeekUndefined(treestart);
  88.         if(error==0){
  89.                 wsprintfA(#mapstr,"\nCOMPILING FINISHED.\tErrors: %d\tLines:    %u\n",error,totallines);
  90.                 WRITESTR(#mapstr);
  91.                 runfilesize = outptr-output;
  92.                 postsize += postsize%2;
  93.                 PrintMemsizes(GetStdHandle(STD_OUTPUT_HANDLE));
  94.                 IF(WriteEXE()==0) {
  95.                         wsprintfA(#mapstr,"\nRun File Saved (%ld bytes).\n",runfilesize);
  96.                         WRITESTR(#mapstr);
  97.                         wsprintfA(#mapstr,"DLL: %d\tAPI: %d \n",DLLcount,APIcount);
  98.                         WRITESTR(#mapstr);
  99.                 }
  100. //      if(dbg)
  101. //              dotds();        // do turbo debugger line info
  102.         }
  103.         IF(makemapfile)FinishMapfile();
  104. }
  105.  
  106. // ---- à¥¤¢ à¨â¥«ì­ ï ®¡à ¡®âª  ä ©« 
  107. Preview(dword filename)
  108. long hold;
  109. char trialfilename[FILENAMESIZE];
  110. {
  111.         lstrcpyA(#trialfilename,filename);
  112.         hold = LoadInputfile(#trialfilename);
  113.         IF(EAX==-2)unabletoopen(#trialfilename);
  114.         IF(hold!=0)ExitProcess(e_cannotopeninput);
  115.         lstrcpyA(#currentfilename,#trialfilename);
  116.         module++;
  117.         IF(module<MAXMDL) {
  118.                 lstrcpyA(FILENAMESIZE*module+#modules,#currentfilename);
  119.                 currmod = module;
  120.         }
  121.         IF(makemapfile){
  122.                 EBX=inptr;
  123.                 cha=DSBYTE[EBX];
  124.                 wsprintfA(#mapstr,"File %s included.\n\n%c",#currentfilename,cha);
  125.                 fprint(mapfile,#mapstr);
  126.         }
  127.         ShowSrcLine();
  128.         NextChar();
  129.         cha2 = cha;
  130.         inptr2=inptr;
  131.         linenum2 = 1;
  132.         NextTok();
  133.         WHILE(tok!=tk_eof){ // ®ª  ­¥ ª®­ç¨âáï ¢å®¤­®© ¡ãä¥à
  134.                 IF(tok==tk_directive){
  135.                         GetDirAddr(#Jmp_Directives,number);
  136.                         EAX();
  137.                 }
  138.                 ELSE IF(tok==tk_command){
  139.                         GetDirAddr(#Jmp_Commands,number);
  140.                         EAX();
  141.                 }
  142.                 ELSE IF(tok==tk_id)GetProc(tk_void);
  143.                 ELSE IF(tok==tk_void){
  144.                         NextTok();
  145.                         GetProc(tk_void);
  146.                 }
  147.                 ELSE{
  148.                         preerror("unuseable input");
  149.                         NextTok();
  150.                 }
  151.         }
  152.         LocalFree(input);
  153. }
  154.  
  155. // ---- Š®¬¯¨«ïæ¨ï ®¤­®© ¯à®æ¥¤ãàë ¨«¨ ®¡ê¥­¨ï ¤ ­­ëå
  156. CompileSrc(dword ptr)
  157. {
  158.         EAX=src;
  159.         if(EAX){
  160.                 inptr = EAX;
  161.                 inptr2 = EAX;
  162.                 endoffile = 0;  //   ­ ç «® ¡ãä¥à 
  163.                 linenum2 = modline&0xFFFF;
  164.                 currmod=modline>>16;
  165.                 lstrcpyA(#currentfilename,FILENAMESIZE*currmod+#modules);
  166.                 NextChar();
  167.                 cha2 = cha;
  168.                 inptr2=inptr;
  169.                 IF(tok==tk_proc){
  170.                         Proc(cpt_near);
  171.                         DoPoststrings();
  172.                 }
  173.                 ELSE IF(tok==tk_var)GlobalVar(type);
  174.                 ELSE preerror("Bad input format\n");
  175.         }
  176.         ELSE{ // post-¯¥à¥¬¥­­ ï ¡¥§ à §¬¥à­®áâ¨
  177.                 ESI=ptr;
  178.                 DSDWORD[ESI+recnumber] = postsize;
  179.                 DSDWORD[ESI+recpost] = 1;
  180.                 postsize+=TypeSize(type);
  181.         }
  182. }
  183.  
  184. // ---- Š®¬¯¨«ïæ¨ï ¢á¥å ¯à®æ¥¤ãà ¨ ®¡ê¥­¨© ¤ ­­ëå
  185. CompileAll()
  186. {
  187.         IF(SearchTree(#tok,#type,#src,#post,"main",#number))AX=3; // Console
  188.         ELSE IF(SearchTree(#tok,#type,#src,#post,"WinMain",#number))AX=2; // GUI
  189.         ELSE{
  190.                 preerror("Main not found");
  191.                 return;
  192.         }
  193.         OptSubSystem=AX;
  194.         OptEntryPointRVA=OptBaseOfCode+outptr-output;
  195.         CompileSrc(treeptr);    // Š®¬¯¨«ïæ¨ï main
  196.         WHILE(SeekToDo(treestart)){
  197.                 ESI=treeptr;
  198.                 wsprintfA(#mapstr,"==>%3d %8lXh %8lXh %6Xh\t%s\n",DSDWORD[ESI+rectok],
  199.                         DSDWORD[ESI+rectype],DSDWORD[ESI+recnumber],DSDWORD[ESI+recpost],
  200.                         DSDWORD[ESI+recid]);
  201.                 fprint(mapfile,#mapstr);
  202.                 CompileSrc(treeptr);    // Š®¬¯¨«ïæ¨ï ¨á室­¨ª®¢
  203.         }
  204.         IF(makemapfile)
  205.         fprint(mapfile,"Compile all sources\n");
  206. }
  207.  
  208. // ---- Ž¡à ¡®âª  ¯ à ¬¥â஢ ¯à¨ ®¡ê¥­¨¨ ¯à®æ¥¤ãàë
  209. DeclareParams()
  210. dword paramtok,paramtype;
  211. {
  212. LL:
  213.         IF(tok==tk_command)GetDirAddr(#Jmp_Commands,number);
  214.         ELSE EAX=-1;
  215.         IF(EAX==#CmdShort){
  216.                 paramtok = tk_param;
  217.                 paramtype=tk_short;
  218.         }
  219.         ELSE IF(EAX==#CmdWord){
  220.                 paramtok = tk_param;
  221.                 paramtype=tk_word;
  222.         }
  223.         ELSE IF(EAX==#CmdChar){
  224.                 paramtok = tk_param;
  225.                 paramtype=tk_char;
  226.         }
  227.         ELSE IF(EAX==#CmdByte){
  228.                 paramtok = tk_param;
  229.                 paramtype=tk_byte;
  230.         }
  231.         ELSE IF(EAX==#CmdInt){
  232.                 paramtok = tk_param;
  233.                 paramtype=tk_int;
  234.         }
  235.         ELSE IF(EAX==#CmdDword){
  236.                 paramtok = tk_param;
  237.                 paramtype=tk_dword;
  238.         }
  239.         ELSE{
  240.                 datatype_expected();
  241.                 NextTok();
  242.         }
  243.         for(;;){
  244.                 NextTok();
  245.                 IF(tok==tk_id ){
  246.                         paramsize += 4;
  247.                         AddLocalvar(#string,paramtok,paramtype,paramsize);
  248.                 }
  249.                 ELSE IF(tok==tk_semicolon){
  250.                         NextTok();
  251.                         $JMP LL
  252.                 }
  253.                 ELSE IF(tok==tk_closebracket)BREAK;
  254.                 ELSE IF(tok!=tk_comma)idexpected();
  255.         }
  256. }
  257.  
  258. // ---- Ž¡à ¡®âª  «®ª «ì­ëå ¯¥à¥¬¥­­ëå ¯à¨ ®¡ê¥­¨¨ ¯à®æ¥¤ãàë
  259. DeclareLocals()
  260. dword size;
  261. dword loctok,loctype;
  262. {
  263. LL:
  264.         IF(tok==tk_command)GetDirAddr(#Jmp_Commands,number);
  265.         IF(EAX==#CmdShort){
  266.                 loctok = tk_local;
  267.                 loctype=tk_short;
  268.                 size = 2;
  269.         }
  270.         else IF(EAX==#CmdWord){
  271.                 loctok = tk_local;
  272.                 loctype=tk_word;
  273.                 size = 2;
  274.         }
  275.         else IF(EAX==#CmdChar){
  276.                 loctok = tk_local;
  277.                 loctype=tk_char;
  278.                 size = 1;
  279.         }
  280.         ELSE IF(EAX==#CmdByte){
  281.                 loctok = tk_local;
  282.                 loctype=tk_byte;
  283.                 size = 1;
  284.         }
  285.         ELSE IF(EAX==#CmdInt){
  286.                 loctok = tk_local;
  287.                 loctype=tk_int;
  288.                 size = 4;
  289.         }
  290.         ELSE IF(EAX==#CmdDword){
  291.                 loctok = tk_local;
  292.                 loctype=tk_dword;
  293.                 size = 4;
  294.         }
  295.         ELSE IF(tok==tk_eof)||(tok==tk_openbrace)$JMP L1
  296.         ELSE{
  297.                 datatype_expected();
  298.                 NextTok();
  299.                 goto LL;
  300.         }
  301.         for(;;){
  302.                 NextTok();
  303.                 IF(tok==tk_id){
  304.                         AddLocalvar(#string,loctok,loctype,localsize);
  305.                         IF(tok2==tk_openblock){
  306.                                 NextTok();
  307.                                 NextTok();
  308.                                 localsize += DoConstLongMath()*size;
  309.                                 EAX=localsize;
  310.                                 $TEST EAX,3;
  311.                                 IF(NOTZEROFLAG){
  312.                                         EAX=EAX>>2+1<<2;
  313.                                         localsize=EAX;  // ‚ëà ¢­¨¢ ­¨¥ ­  dword
  314.                                 }
  315.                                 expecting(tk_closeblock);
  316.                         }
  317.                         ELSE localsize+=4;
  318.                 }
  319.                 ELSE IF(tok==tk_semicolon){
  320.                         NextTok();
  321.                         $JMP LL
  322.                 }
  323.                 ELSE IF(tok==tk_openbrace)||(tok==tk_eof)BREAK;
  324.                 ELSE IF(tok!=tk_comma)idexpected();
  325.         }
  326. L1:
  327.         IF(paramsize==0)Asm("push ebp; mov ebp,esp;");
  328.         wsprintfA(#mapstr,"sub esp,%d;",localsize);
  329.         Asm(#mapstr);
  330. }
  331.  
  332. // ---- Ž¡à ¡®âª  ®¡à é¥­¨ï ª 㦥 ®¯¨á ­­®© ¯à®æ¥¤ãà¥
  333. DoAnyProc()
  334. byte s[80];
  335. {
  336.         wsprintfA(#s,"call %s;",#string);
  337.         NextTok();
  338.         DoParams();
  339.         Asm(#s);
  340. }
  341.  
  342. // ---- Ž¡à ¡®âª  à ­¥¥ ®¡ê¢«¥­­®©, ­® ¯®ª  ­¥ ¨§¢¥áâ­®© ¬¥âª¨
  343. dword DoAnyUndefproc(dword expectedreturn)
  344. byte s[80];
  345. {
  346.         IF( tok2 == tk_colon ){ // ¬¥âª 
  347.                 number = outptr-output+OptImageBase+OptBaseOfCode;
  348.                 tok = tk_proc;
  349.                 ESI=treeptr;
  350.                 DSDWORD[ESI+rectok] = tok;
  351.                 DSDWORD[ESI+recnumber] = number;
  352.                 DSDWORD[ESI+recpost] = 0;
  353.                 NextTok();      // move past id
  354.                 NextTok();      // move past :
  355.                 RETURN(tokens);
  356.         }
  357.         IF( tok2 == tk_openbracket ){
  358.                 wsprintfA(#s,"call %s;",#string);
  359.                 NextTok();
  360.                 DoParams();
  361.                 Asm(#s);
  362.                 RETURN(tk_dword);
  363.         }
  364.         undefinederror();
  365.         NextTok();
  366.         return(tk_int);
  367. }
  368.  
  369. // ---- Ž¡à ¡®âª  ®¡à é¥­¨ï ª API ä㭪樨
  370. dword doAPI()
  371. dword hold;
  372. byte s[IDLENGTH];
  373. {
  374.         if( tok2 == tk_openbracket ){
  375.                 hold = treeptr;
  376.                 GetVarname(#s);
  377.                 NextTok();
  378.                 DoParams();
  379.                 IF(posts>=MAXPOSTS){
  380.                         preerror("maximum number of API procedure calls exceeded");
  381.                         return(tokens);
  382.                 }
  383.                 EBX=hold;
  384.                 IF(DSDWORD[EBX+recpost]==0) { // ¥à¢ë© ¢ë§®¢ API?
  385.                         DSDWORD[EBX+recpost]=1; // ®â¬¥â¨¬ ¢ë§®¢ ¤ ­­®© API
  386.                         APIcount++;
  387.                         EAX=DSDWORD[EBX+rectype]; // “ª § â¥«ì ­  DLL, ¢ ª®â®à®¬ ­ å®¤¨âáï API
  388.                         DSDWORD[EAX+recmodline]++;      // “¢¥«¨ç¨¬ áç¥â稪 API, ¢ë§¢ ­­ëå ¨§ DLL
  389.                 }
  390.                 OUTWORD(0x15FF);        // call [dword]
  391.                 SetPost(hold,POST_API);
  392.                 OUTDWORD(0);
  393.                 IF(list){
  394.                         fprint(mapfile,"\t//\tcall ");
  395.                         fprint(mapfile,#s);
  396.                         fprint(mapfile,"\n");
  397.                 }
  398.                 return(tk_int);
  399.         }
  400.         undefinederror();
  401.         NextTok();
  402.         return(tokens);
  403. }
  404.  
  405. // ---- Ž¡à ¡®âª  ¯à®£à ¬¬­®£® ¡«®ª  {...}
  406. void DoBlock()
  407. {
  408.         expecting(tk_openbrace);
  409.         for(;;){
  410.                 IF(tok==tk_eof){
  411.                         unexpectedeof();
  412.                         BREAK;
  413.                 }
  414.                 IF(tok == tk_closebrace){
  415.                         NextTok();
  416.                         BREAK;
  417.                 }
  418.                 DoCommand();
  419.         }
  420. }
  421.  
  422. // ---- Ž¡à ¡®âª  ®¤­®© ª®¬ ­¤ë ¢­ãâਠ¡«®ª 
  423. DoCommand()
  424. {
  425. LL:
  426.         FastSearch(#string,#St_Sizes);// â® à §¬¥à ®¯¥à ­¤ ?
  427.         IF(CARRYFLAG){  // „ : byte,word ¨«¨ dword
  428.                 type=EAX<<1+tk_byte;
  429.                 string[0]=0;
  430.                 tok=tk_var;
  431.                 GOTO LL;
  432.         }
  433.         IF(tok==tk_mnemonics){
  434.                 DoMnemonics();
  435.                 NextTok();
  436.         }
  437.         else IF(tok==tk_directive){
  438.                 GetDirAddr(#Jmp_Directives,number);
  439.                 EAX();
  440.         }
  441.         else IF(tok==tk_command){
  442.                 GetDirAddr(#Jmp_Commands,number);
  443.                 EAX();
  444.         }
  445.         else IF(tok==tk_id){
  446.                 DoId(tk_void);
  447.                 IF(EAX!=tokens)NextSemiNext();
  448.         }
  449.         else IF(tok==tk_undefproc){
  450.                 DoAnyUndefproc(tk_void);
  451.                 IF(EAX!=tokens)NextSemiNext();
  452.         }
  453.         else IF(tok==tk_proc){
  454.                 DoAnyProc();
  455.                 NextSemiNext();
  456.         }
  457.         else IF(tok==tk_API){
  458.                 IF(doAPI()!=tokens)NextSemiNext();
  459.         }
  460.         else IF(tok==tk_var)||(tok==tk_local)||(tok==tk_param)||(tok==tk_reg)DoVar(type);
  461.         ELSE IF(tok==tk_openblock)DoVar(tk_dword);
  462.         ELSE IF(tok==tk_string){
  463.                 Macros();
  464.                 NextSemiNext();
  465.         }
  466.         ELSE IF(tok==tk_locallabel)DoLocalPost();
  467.         ELSE IF(tok==tk_openbrace)DoBlock();
  468.         ELSE IF(tok==tk_comma)||(tok==tk_semicolon)NextTok();
  469.         ELSE IF(tok==tk_eof)unexpectedeof();
  470.         /*      case tk_from:
  471.                 NextTok();      DoFrom(0);      NextSemiNext();  break;
  472.         case tk_extract:
  473.                 NextTok();      DoExtract(0);  SemiNext();      break;
  474.         */
  475. }
  476.  
  477. // ---- Ž¡à ¡®âª  ­®¢ëå ¨¤¥­â¨ä¨ª â®à®¢
  478. dword DoId(dword expectedreturn)
  479. byte s[80];
  480. {
  481.         IF(tok2 == tk_colon){ // ¬¥âª ?
  482.                 number = outptr-output+OptImageBase+OptBaseOfCode;
  483.                 tok = tk_proc;
  484.                 post = 0;
  485.                 AddToTree(#string);
  486.                 NextTok(); NextTok(); // ¯à®¯ãá⨬ ¨¤¥­â¨ä¨ª â®à ¨ :
  487.                 EAX=tokens;
  488.         }
  489.         ELSE IF(tok2 == tk_openbracket){        // ¢ë§®¢ ¯à®æ¥¤ãàë
  490.                 wsprintfA(#s,"call %s;",#string);
  491.                 tok = tk_undefproc;
  492.                 number=0;
  493.                 post=1;
  494.                 AddToTree(#string);
  495.                 NextTok();
  496.                 DoParams();
  497.                 Asm(#s);
  498.                 EAX=expectedreturn;
  499.         }
  500.         ELSE{
  501.                 undefinederror();
  502.                 NextTok();
  503.                 EAX=tk_int;
  504.         }
  505. }
  506.  
  507. // ---- Ž¡à ¡®âª  ¯ à ¬¥â஢ ¯à¨ ¢ë§®¢¥ ¯à®æ¥¤ãàë
  508. DoParams()
  509. {
  510.         IF(tok==tk_openbracket){
  511.                 inptr2--;
  512.                 DoParam();
  513.                 NextTok();
  514.         }
  515.         ELSE expecting(tk_openbracket);
  516. }
  517.  
  518. // ---- Ž¡à ¡®âª  <Var> ...
  519. DoVar(dword vartype)
  520. dword next,vtok;
  521. byte varName[2*IDLENGTH];
  522. byte varName2[2*IDLENGTH];
  523. {
  524.         next=1;
  525.         vtok=GetVarname(#varName);
  526.         NextTok();
  527.         IF(tok==tk_assign){
  528.                 NextTok();
  529.                 IF(tok2notstopper()){
  530.                         DoExpr(#varName,vtok,vartype,"mov");
  531.                         next=0;
  532.                 }
  533.                 ELSE GetIntoVar(#varName,vtok,vartype);
  534.         }
  535.         else IF(tok==tk_minusminus){    // Var--;
  536.                 wsprintfA(#mapstr,"dec %s",#varName);
  537.                 Asm(#mapstr);
  538.         }
  539.         else IF(tok==tk_plusplus){      // Var++;
  540.                 wsprintfA(#mapstr,"inc %s",#varName);
  541.                 Asm(#mapstr);
  542.         }
  543.         else IF(tok==tk_plusequals){    // Var+=Expr;
  544.                 NextTok();
  545.                 DoExpr(#varName,tk_var,vartype,"add");
  546.                 next=1;
  547.         }
  548.         else IF(tok==tk_minusequals){ // Var-=Expr;
  549.                 NextTok();
  550.                 DoExpr(#varName,tk_var,vartype,"sub");
  551.                 next=1;
  552.         }
  553.         else IF(tok==tk_andequals){ // Var&=Expr;
  554.                 NextTok();
  555.                 DoExpr(#varName,tk_var,vartype,"and");
  556.                 next=1;
  557.         }
  558.         else IF(tok==tk_xorequals){ // Var^=Expr;
  559.                 NextTok();
  560.                 DoExpr(#varName,tk_var,vartype,"xor");
  561.                 next=1;
  562.         }
  563.         else IF(tok==tk_orequals){      // Var|=Expr;
  564.                 NextTok();
  565.                 DoExpr(#varName,tk_var,vartype,"or");
  566.                 next=1;
  567.         }
  568.         else if(tok==tk_swap){          // Var><Var;
  569.                 NextTok();
  570.                 GetVarname(#varName2);
  571.                 IF(tok==tk_reg){
  572.                         wsprintfA(#mapstr,"xchg %s,%s",#string,#varName);
  573.                         Asm(#mapstr);
  574.                 }
  575.                 else if(tok==tk_var)&&(tok2notstopper()==0){
  576.                         IF(vartype==tk_dword)||(vartype==tk_int){
  577.                                 wsprintfA(#mapstr,"xchg %s,eax",#varName);
  578.                                 Asm(#mapstr);
  579.                                 wsprintfA(#mapstr,"xchg %s,eax",#varName2);
  580.                                 Asm(#mapstr);
  581.                                 wsprintfA(#mapstr,"xchg %s,eax",#varName);
  582.                         }
  583.                         else IF(vartype==tk_word)||(vartype==tk_short){
  584.                                 wsprintfA(#mapstr,"xchg %s,ax",#varName);
  585.                                 Asm(#mapstr);
  586.                                 wsprintfA(#mapstr,"xchg %s,ax",#varName2);
  587.                                 Asm(#mapstr);
  588.                                 wsprintfA(#mapstr,"xchg %s,ax",#varName);
  589.                         }
  590.                         ELSE IF(vartype==tk_byte)||(vartype==tk_char){
  591.                                 wsprintfA(#mapstr,"xchg %s,al",#varName);
  592.                                 Asm(#mapstr);
  593.                                 wsprintfA(#mapstr,"xchg %s,al",#varName2);
  594.                                 Asm(#mapstr);
  595.                                 wsprintfA(#mapstr,"xchg %s,al",#varName);
  596.                         }
  597.                         Asm(#mapstr);
  598.                 }
  599.                 ELSE swaperror();
  600.         }
  601.         else IF(tok==tk_llequals){      // Var<<=Expr;
  602.                 NextTok();
  603.                 IF(tok == tk_number) wsprintfA(#mapstr,"shl %s,%d",#varName,DoConstMath());
  604.                 ELSE{
  605.                         Expression("cl",tk_reg,tk_byte);
  606.                         wsprintfA(#mapstr,"shl %s,cl",#varName);
  607.                         next=0;
  608.                 }
  609.                 Asm(#mapstr);
  610.         }
  611.         ELSE IF(tok==tk_rrequals){      // Var>>=Expr;
  612.                 NextTok();
  613.                 IF(tok == tk_number)wsprintfA(#mapstr,"shr %s,%d",#varName,DoConstMath());
  614.                 ELSE{
  615.                         Expression("cl",tk_reg,tk_byte);
  616.                         wsprintfA(#mapstr,"shr %s,cl",#varName);
  617.                         next=0;
  618.                 }
  619.                 Asm(#mapstr);
  620.         }
  621.         ELSE operatorexpected();
  622.         IF(next)NextSemiNext();
  623.         ELSE SemiNext();
  624. }
  625.  
  626. // ---- Ž¡à ¡®âª  ááë«®ª ¢¯¥à¥¤
  627. DoPosts()
  628. dword addhold,i;
  629. {
  630.         i=0;
  631.         while(i<posts){
  632.                 ECX=i<<2;
  633.                 ESI=posttype+ECX;
  634.                 EAX=DSDWORD[ESI];
  635.                 ESI=postloc+ECX;
  636.                 EBX=DSDWORD[ESI];
  637.                 ESI=postnum+ECX;
  638.                 ECX=DSDWORD[ESI];
  639.                 IF(EAX==POST_DATA){
  640.                         IF(DSDWORD[ECX+recpost]){
  641.                                 GetDword(EBX);
  642.                                 EAX=EAX+DSDWORD[ECX+recnumber]+OptImageBase+OptBaseOfCode+outptr-output;
  643.                         }
  644.                         ELSE{
  645.                                 GetDword(EBX);
  646.                                 EAX+=DSDWORD[ECX+recnumber];
  647.                         }
  648.                         SetDword(EBX,EAX);
  649.                 }
  650.                 ELSE IF(EAX==POST_CALL){
  651.                         EAX=DSDWORD[ECX+recnumber]-OptImageBase-OptBaseOfCode-EBX; //  áç¥â ®â­®á¨â¥«ì­®£® ᬥ饭¨ï EAX-=addvalue;
  652.                         EAX+=output;
  653.                         SetDword(EBX,EAX-4);
  654.                 }
  655.                 ELSE IF(EAX==POST_LOC){
  656.                         EAX=ECX; EAX-=OptImageBase;
  657.                         EAX-=OptBaseOfCode; EAX-=EBX; //  áç¥â ®â­®á¨â¥«ì­®£® ᬥ饭¨ï EAX-=addvalue;
  658.                         EAX+=output; SetDword(EBX,EAX-4);
  659.                 }
  660.                 ELSE IF(EAX==POST_API){
  661.                                 addhold = OptImageBase + DSDWORD[ECX+recmodline];
  662.                                 SetDword(EBX,addhold);
  663.                 }
  664.                 ELSE preerror("Bad post type\n");
  665.                 i++;
  666.         }
  667. }
  668.  
  669. // ---- ëáâàë© ¯®¨áª ¯® â ¡«¨æ¥
  670. // OUTPUT: EAX=No.& CARRYFLAG - success
  671. dword FastSearch(dword probe,table)
  672. byte ident[IDLENGTH];
  673. {
  674.         $PUSH ECX,ESI,EDI,EDX
  675.         lstrcpyA(#ident,probe);
  676.         CharUpperA(#ident);
  677.         lstrlenA(#ident);
  678.         EDX=EAX-1;
  679.         $JZ HET // ident ¨§ ®¤­®£® ᨬ¢®« 
  680.         EBX=0;
  681.         BL=ident;//[0]; // à®¢¥à¨¬ ¯¥à¢ë© ᨬ¢®« ¢ ident
  682.         BL-='A';
  683.         $JC HET         // ¥ ¡ãª¢ 
  684.         $CMP BL,'Z'-'A';
  685.         $JA HET // ¨ ­¥ 'A'...'Z'
  686.         EAX=0;
  687.         EBX=EBX<<2+table;
  688.         EDI=DSDWORD[EBX]; // ‚§ïâì  ¤à¥á § ¯¨á¨ ¨§ table
  689.         $OR EDI,EDI;
  690.         $JE HET // ¥â § ¯¨á¨ ¤«ï â ª®£® ident...
  691. TRY0:
  692.         AH=DSBYTE[EDI];
  693.         EDI++;  // ®¬¥à § ¯¨á¨ ¨§ table ¨ ­  áâப㠢 table
  694. TRY1:
  695.         ESI=#ident+1;
  696.         ECX=EDX;        // ‚§ïâì ident   ¤«¨­ã - 1
  697.         $REPE $CMPSB;
  698.         $JNE    NXT // ‘à ¢­¨¬ á § ¯¨áìî ¢ table
  699.         $JCXZ YES1              // ‘®¢¯ «¨ ¯® ¤«¨­¥ probe
  700. NXT:
  701.         EDI--;
  702. LOOK:
  703.         AL=DSBYTE[EDI];
  704.         EDI++;
  705.         $OR AL,AL;
  706.         $JE TRY0        // à®¢¥à¨¬ á«¥¤ãîéãî § ¯¨áì
  707.         $CMP AL,'/';
  708.         $JE NEAR TRY1 // à®¢¥à¨¬ ALIAS
  709.         $CMP AL,_END;
  710.         $JE NEAR HET    // Š®­¥æ â ¡«¨æë - ¢ë室
  711.         GOTO LOOK;
  712. HET:
  713.         $CLC;
  714.         GOTO EX;                // ident ­¥ ­ ©¤¥­ ¢ table
  715. YES1:
  716.         $CMP DSBYTE[EDI],0;
  717.         $JZ YES;
  718.         $CMP DSBYTE[EDI],_END;
  719.         $JZ YES;
  720.         $CMP DSBYTE[EDI],'/';
  721.         $JZ YES;
  722.         GOTO NXT;
  723. YES:
  724.         AL=AH;
  725.         AH=0;
  726.         $STC    // ident ­ ©¤¥­ ¢ table
  727. EX:
  728.         $POP EDX,EDI,ESI,ECX;
  729. }
  730.  
  731. // ---- ‚뢮¤ áâ â¨á⨪¨ ¯® ª®¬¯¨«ï樨
  732. FinishMapfile()
  733. {
  734.         fprint(mapfile,"\n");
  735.         DisplayTree();
  736.         fprint(mapfile,"Component Sizes:\n");
  737.         PrintMemsizes(mapfile);
  738.         wsprintfA(#mapstr,"Run file size: %ld bytes\n",runfilesize);
  739.         fprint(mapfile,#mapstr);
  740.         wsprintfA(#mapstr,"\nEND OF MAP FILE    FOR %s.%s\n\n",#rawfilename,"EXE");
  741.         fprint(mapfile,#mapstr);
  742.         _lclose(mapfile);
  743.         mapfile=0;
  744.         list=0;
  745. }
  746.  
  747. // ---- ‚뢮¤ ¢ ä ©«
  748. fprint(dword handle,str)
  749. {
  750.         _lwrite(handle,str,lstrlenA(str));
  751. }
  752.  
  753. // ---- ‚뤥«¥­¨¥ ¯ ¬ï⨠¤«ï ª®¬¯¨«ï樨. à¨ ­¥ã¤ ç¥ ¢ë室 ¨§ ª®¬¯¨«ïâ®à 
  754. GetMem()
  755. {
  756.         output=LocalAlloc(0x40,MAXDATA);
  757.         IF(EAX==NULL)outofmemory2();
  758.         LocalUnlock(output);
  759.         outptr=output;
  760.         startptr=output;
  761.         postloc=LocalAlloc(0x40,MAXPOSTS*4);
  762.         IF(EAX==NULL)outofmemory2();
  763.         postnum=LocalAlloc(0x40,MAXPOSTS*4);
  764.         IF(EAX==NULL)outofmemory2();
  765.         posttype=LocalAlloc(0x40,MAXPOSTS);
  766.         IF(EAX==NULL)outofmemory2();
  767.         dbginfo=LocalAlloc(0x40,MAXDBGS*dbg_size);
  768.         IF(EAX==NULL)outofmemory2();
  769.         dbgs=dbginfo;
  770. }
  771.  
  772. // ---- —⥭¨¥ ¤¢®©­®£® á«®¢ 
  773. dword GetDword(dword ptr)
  774. {
  775.         ESI><ptr;
  776.         $LODSD;
  777.         ESI><ptr;
  778. }
  779.  
  780. // ---- ˆ­¨æ¨ « § æ¨ï ᯨ᪠
  781. // „«ï keylist = {"ZAK",0,"AAD",0,"ABC",0,"BAR",0,"AAA",0,"ZZ",0,"BAC",_END};
  782. // áä®à¬¨àã¥âáï áâàãªâãà  ¢ ¯ ¬ï⨠᫥¤ãî饣® ¢ ¤ :
  783. //      table
  784. // +-----+
  785. // | 'A' | ---> db 4,'AA',1,'AD',2,'BC',_END
  786. // +-----+
  787. // | 'B' | ---> db 6,'AC',3,'AR",_END
  788. // +-----+
  789. // | ... |
  790. // +-----+
  791. // | 'Z' | ---> db 0,'AK',5,'Z',_END
  792. // +-----+
  793. InitList(dword keylist,table)
  794. dword ptr;
  795. {
  796.         ptr=LocalAlloc(0x40,SORTSIZE*256);
  797.         IF(EAX==NULL)outofmemory2();
  798.         EDI><EAX; //ptr;
  799.         ESI=keylist;
  800.         ECX=0;
  801.         BL=0;
  802. // ‡ ­¥á¥­¨¥ áâப ¨§ keylist ¢ ptr
  803.         for(;;){
  804.                 for(;;){
  805.                         $PUSH EDI;
  806.                         IF(DSBYTE[ESI]!='-')BREAK;
  807.                         ESI+=2;
  808.                         BL++;
  809.                         $POP EDI;
  810.                 }
  811.                 AL=BL;
  812.                 $STOSB  // ‘®åà ­¨¬ ¯®à浪®¢ë© ­®¬¥à áâப¨
  813.                 for(;;){
  814.                         $LODSB                  // ‘ª®¯¨à㥬 áâப㠢 ptr
  815.                         IF(AL<' ')BREAK;
  816.                         $STOSB;
  817.                 }
  818.                 IF(AL==_END)BREAK;
  819.                 $STOSB;
  820.                 $POP EDI;
  821.                 BL++;
  822.                 EDI+=SORTSIZE;
  823.                 ECX++;
  824.         }
  825.         ESI=ptr;
  826.         $PUSH ECX // Š®¯¨à®¢ ­¨¥ ¢ ptr § ª®­ç¥­®. ‘®åà ­¨¬ ª®«-¢® áâப
  827.         ECX--;
  828.         IF(NOTZEROFLAG){// ‚ᥣ® ®¤­  áâப ? - á®àâ¨à®¢ª  ­¥ ­ã¦­ 
  829. // ‘®àâ¨à®¢ª  áâப ¢ ptr
  830.                 loop(ECX){
  831.                         $PUSH ESI,ECX;
  832.                         EDI=ESI+SORTSIZE;
  833.                         loop(ECX){
  834.                                 $PUSH ECX,ESI,EDI;
  835.                                 ECX=SORTSIZE;
  836.                                 ESI++;
  837.                                 EDI++;
  838.                                 $REPE $CMPSB;
  839.                                 $POP EDI,ESI;
  840.                                 IF(NOTCARRYFLAG){ // ¯à®¢¥à¨â ãá«®¢¨¥ ????????????‘à ¢­¥­¨¥ ¤¢ãå áâப
  841.                                         EAX=ESI;
  842.                                         EDX=EDI;
  843.                                         EDI=#Buffer16;
  844.                                         ECX=SORTSIZE/4; //  è«¨ ¬¥­ìèãî áâபã
  845.                                         $REP $MOVSD;
  846.                                         ESI=EDX;
  847.                                         EDI=EAX;
  848.                                         ECX=SORTSIZE/4;         // -¯®¬¥­ï¥¬ ¬¥áâ ¬¨
  849.                                         $REP $MOVSD;
  850.                                         ESI=#Buffer16;
  851.                                         EDI=EDX;
  852.                                         ECX=SORTSIZE/4;
  853.                                         $REP $MOVSD;
  854.                                         ESI=EAX;
  855.                                         EDI=EDX;
  856.                                 }
  857.                                 EDI+=SORTSIZE;
  858.                                 $POP ECX;
  859.                         }
  860.                         $POP ECX,ESI;
  861.                         ESI+=SORTSIZE;
  862.                 }
  863.         }
  864. // ‘®àâ¨à®¢ª  ¢¢¥¤¥­­ëå áâப ¢ ¡ãä¥à¥ ptr § ª®­ç¥­ 
  865.         EDI=table;
  866.         ECX=26;
  867.         EAX=0;
  868.         $REP $STOSD; // Ž¡­ã«¥­ ¥ table
  869.         $POP ECX;
  870.         ESI=ptr;
  871.         EDI=ESI;
  872.         $PUSH ESI;
  873.         GOTO L42; // ”®à¬ à㥬 â ¡«¨æã
  874.         loop(ECX){
  875.                 $PUSH ESI;
  876.                 IF(AH!=DSBYTE[ESI+1]){
  877.                         EDI--;
  878.                         AL=_END;
  879.                         $STOSB          // Žâ¬¥â¨¬ ª®­¥æ â ¡«¨æë ¤«ï ¤ ­­®£® ᨬ¢®«  ¢ AH
  880. L42:
  881.                         AH=DSBYTE[ESI+1];
  882.                         EBX=0;
  883.                         BL=AH;
  884.                         BL-='A';
  885.                         EBX=EBX<<2+table;                               //¤ «ì襠       ¨¤¥â ªà å
  886.                         DSDWORD[EBX]=EDI;       // ‡ ¯¨áì 㪠§ â¥«ï ¢ table
  887.                 }
  888.                 $MOVSB          // ‡ ¯®¬­¨¬ ¯®à浪®¢ë© ­®¬¥à áâப¨
  889.                 ESI++;          // à®¯ã᪠¯¥à¢®£® ᨬ¢®«  - ®­ 㦥 ¨§¢¥á⥭
  890.                 do{
  891.                         $LODSB;
  892.                         $STOSB;
  893.                 }while(AL!=0); // Š®¯¨à㥬 áâப㠢 table
  894.                 $POP ESI;
  895.                 ESI+=SORTSIZE;
  896.         } // à®¤®«¦¨¬ ¤«ï á«¥¤ãî饩 áâப¨
  897.         EDI--;
  898.         AL=_END;
  899.         $STOSB                  // table áä®à¬¨à®¢ ­ . Žâ¬¥â¨¬ ª®­¥æ
  900. }
  901.  
  902. // ---- à®¢¥àª  ­  æ¨äàã
  903. dword IsNumber(dword ch)
  904. {
  905.         IF(ch<'0')||(ch>'9')EAX=0;
  906.         ELSE EAX=1;
  907. }
  908.  
  909. // ---- —⥭¨¥ ¢å®¤­®£® ä ©«  ¢ ¡ãä¥à
  910. long LoadInputfile(dword infile)
  911. dword fhandle, size;
  912. {
  913.         fhandle=_lopen(infile,0);
  914.         IF(EAX==-1){
  915.                 GetLastError();
  916.                 return(-2);
  917.         }
  918.         EAX=GetFileSize(EAX,0);
  919.         IF(EAX==-1){
  920.                 unabletoopen(infile);
  921.                 _lclose(fhandle);
  922.                 return(-1);
  923.         }
  924.         size=EAX;
  925.         input=LocalAlloc(0x40,EAX+2);   // ‡ ¯®«­¥­­ ï ­ã«ï¬¨
  926.         IF(EAX==NULL){
  927.                 preerror("Not enough memory for input buffer");
  928.                 _lclose(fhandle);
  929.                 RETURN(-1);
  930.         }
  931.         EAX=_lread(fhandle,input,size);
  932.         IF(EAX!=size){
  933.                 preerror("File Read error");
  934.                 _lclose(fhandle);
  935.                 RETURN(-1);
  936.         }
  937.         _lclose(fhandle);
  938.         inptr = input;
  939.         inptr2 =        input;
  940.         endoffile = 0;  //   ­ ç «¥ ä ©« 
  941.         return(0);
  942. }
  943.  
  944. // ---- Ž¡à ¡®âª  ¬ ªà®á 
  945. Macros()
  946. byte holdcha;
  947. byte s[STRLEN],s2[STRLEN];
  948. {
  949.         IF(makemapfile){
  950.                 fprint(mapfile,#string);
  951.                 fprint(mapfile,"\n");
  952.         }
  953.         holdcha=cha2;
  954.         $PUSH linenum2,inptr2,number,tok2,tok,input,inptr,currmod,
  955.                 linenumber,endoffile,displaytokerrors;
  956.         lstrcpyA(#s,#string);
  957.         lstrcpyA(#s2,#string2);
  958.         input=#s;
  959.         inptr=input;
  960.         inptr2=input;
  961.         endoffile=0;    //   ­ ç «¥ ä ©« 
  962.         NextChar();
  963.         cha2=cha;
  964.         inptr2=inptr;
  965.         linenum2 = 1;
  966.         NextTok();
  967.         for(;;){
  968.                 IF(tok==tk_eof)BREAK;
  969.                 DoCommand();
  970.         }
  971.         lstrcpyA(#string,#s);
  972.         lstrcpyA(#string2,#s2);
  973.         $POP displaytokerrors,endoffile,linenumber,currmod,inptr,input,tok,tok2,
  974.                 number,inptr2,linenum2;
  975.         cha2=holdcha;
  976. }
  977.  
  978. // ---- Žç¨á⪠ ᯨ᪠ «®ª «ì­ëå ¯¥à¥¬¥­­ëå
  979. KillLocals()
  980. dword ptr1,ptr2;
  981. {
  982.         ptr2=locallist;
  983.         WHILE( ptr2 != NULL ){
  984.                 ptr1=ptr2;
  985.                 IF( DSDWORD[EAX+localtok]==tk_locallabel) // à®¢¥àª  ­  ­¥§ ªàëâë¥ ¬¥âª¨
  986.                         localunresolved(EAX+localid);
  987.                 EAX=ptr2;
  988.                 ptr2=DSDWORD[EAX+localnext];
  989.                 GlobalFree(ptr1);
  990.         }
  991.         locallist = NULL;
  992.         paramsize = 0;
  993.         localsize = 0;
  994. }
  995.  
  996. // ---- ‡ ¢¥à襭¨¥ ⥫  ¯à®æ¥¤ãàë
  997. LeaveProc()
  998. {
  999.         IF(localsize > 0)Asm("leave");
  1000.         ELSE{
  1001.                 IF(paramsize > 0)Asm("pop ebp");
  1002.         }
  1003.         IF( current_proc_type == cpt_far ){
  1004.                 IF(paramsize == 0)EAX="retf";
  1005.                 ELSE{
  1006.                         wsprintfA(#mapstr,"retf %d;",paramsize);
  1007.                         EAX=#mapstr;
  1008.                 }
  1009.         }
  1010.         ELSE{
  1011.                 IF(paramsize == 0)EAX="ret";
  1012.                 ELSE{
  1013.                         wsprintfA(#mapstr,"ret %d;",paramsize);
  1014.                         EAX=#mapstr;
  1015.                 }
  1016.         }
  1017.         Asm(EAX);
  1018. }
  1019.  
  1020. // ---- —⥭¨¥ ®ç¥à¥¤­®£® ᨬ¢®«  ¨§ ¢å®¤­®£® ¡ãä¥à 
  1021. NextChar()
  1022. {
  1023.         ESI><inptr;
  1024. //      EAX=0;
  1025.         $LODSB
  1026.         cha=AL;
  1027.         inptr><ESI; // ‡ ¯®¬­¨¬ ⥪ãéãî ¯®§ æ¨î ¢ ¡ãä¥à¥
  1028.         IF(AL==0)||(AL==26)endoffile = 1;
  1029.         IF(AL == 13){   // CR
  1030.                 linenumber++; // Ž¡­ à㦥­ ª®­¥æ áâப¨
  1031.                 totallines++;
  1032.                 ShowSrcLine();
  1033.                 NextChar();
  1034.         }
  1035. }
  1036.  
  1037. // ---- ®«ã祭¨¥ ®ç¥à¥¤­®£® token
  1038. void NextTok()
  1039. {
  1040.         inptr = inptr2;
  1041.         linenumber = linenum2;
  1042.         cha = cha2;
  1043.         displaytokerrors = 1;
  1044.         TokScan(#tok,#type,#src,#post,#string,#number);
  1045.         IF(linenumber!=linenum2){ // ®¢ ï áâப ?
  1046.                 IF(dbg){                        // ’ॡã¥âáï ®â« ¤ª ?
  1047.                         $PUSH ESI
  1048.                         ESI=dbgs*dbg_size+dbginfo;
  1049.                         EAX=currmod;
  1050.                         $CMP EAX,DSDWORD[ESI+dbg_mod];
  1051.                         $JNE DIFF // ’ॡã¥âáï § ¯®¬­¨âì ¨­ä®à¬ æ¨î ¯® ­®¢®© áâப¥
  1052.                         EAX=linenumber;
  1053.                         $CMP EAX,DSDWORD[ESI+dbg_line]
  1054.                         $JNE DIFF                       // ’ॡã¥âáï § ¯®¬­¨âì ¨­ä®à¬ æ¨î ¯® ­®¢®© áâப¥
  1055.                         DSDWORD[ESI+dbg_line]=linenumber; // ‡ ¯®¬­¨¬ ­®¬¥à áâப¨
  1056.                         GOTO ALL;
  1057. DIFF:
  1058.                         dbgs++;
  1059.                         ESI+=dbg_size;
  1060.                         DSDWORD[ESI+dbg_mod]=currmod;
  1061.                         DSDWORD[ESI+dbg_line]=linenumber;
  1062.                         DSDWORD[ESI+dbg_loc]=outptr;
  1063. ALL:
  1064.                         $POP ESI
  1065.                 }
  1066.         }
  1067.         inptr2 = inptr;
  1068.         linenum2 = linenumber;
  1069.         cha2 = cha;
  1070.         displaytokerrors = 0; // ¥§ ¢ë¢®¤  á®®¡é¥­¨© ®¡ ®è¨¡ª å
  1071.         TokScan(#tok2,#type2,#src2,#post2,#string2,#number2);
  1072.         linenumber = linenum2;
  1073. }
  1074.  
  1075. // ---- ‘«¥¤ãî騩 token § ªàëâë© ;
  1076. NextSemiNext ()
  1077. {
  1078.         NextTok();
  1079.         SemiNext();
  1080. }
  1081.  
  1082. // ---- ‡ ªà뢠î騩 ; ¨ token §  ­¨¬
  1083. SemiNext ()
  1084. {
  1085.         IF(tok != tk_semicolon)expected(';');
  1086.         NextTok();
  1087. }
  1088.  
  1089. // ---- ‡ ¯¨áì ¡ ©â  ¢ CODE
  1090. OP()
  1091. {
  1092.         EDI><outptr;
  1093.         $STOSB;
  1094.         outptr><EDI;
  1095. }
  1096.  
  1097. // ---- ‡ ¯¨áì á«®¢  ¢ CODE
  1098. OUTWORD()
  1099. {
  1100.         EDI><outptr;
  1101.         $STOSW;
  1102.         outptr><EDI;
  1103. }
  1104. // ---- ‡ ¯¨áì ¤¢®©­®£® á«®¢  ¢ CODE
  1105. OUTDWORD()
  1106. {
  1107.         EDI><outptr;
  1108.         $STOSD;
  1109.         outptr><EDI;
  1110. }
  1111.  
  1112. // ---- ‚뢮¤ à §¬¥à®¢ CODE&DATA
  1113. PrintMemsizes(dword handle)
  1114. {
  1115.         wsprintfA(#mapstr,"Code:%u bytes,\tPost: %u bytes\n",outptr-output,postsize);
  1116.         fprint(handle,#mapstr);
  1117. }
  1118.  
  1119. // ---- Ž¡à ¡®âª  ¯à®æ¥¤ãà
  1120. Proc(dword proc_type)
  1121. {
  1122.         current_proc_type = proc_type;
  1123.         tok = tk_proc;
  1124.         number = outptr-output+OptImageBase+OptBaseOfCode;
  1125.         ESI=treeptr;
  1126.         DSDWORD[ESI+rectok] = tok;
  1127.         DSDWORD[ESI+recnumber] = number;
  1128.         DSDWORD[ESI+recpost] = 0;
  1129.         NextTok();
  1130.         expecting(tk_openbracket);
  1131.         IF(tok!=tk_closebracket)DeclareParams();
  1132.         NextTok();
  1133.         IF(paramsize > 0)Asm("push ebp;mov ebp,esp");
  1134.         IF( tok != tk_openbrace )DeclareLocals();
  1135.         DoBlock();                              // Ž¡à ¡®âª  ⥫  ¯à®æ¥¤ãàë { ... }
  1136.         LeaveProc();
  1137.         KillLocals();
  1138. }
  1139.  
  1140. // ---- ‡ ¯¨áì ¤¢®©­®£® á«®¢  ¯®  ¤à¥áã
  1141. SetDword(dword ptr, value)
  1142. {
  1143.         EDI><ptr;
  1144.         EAX><value;
  1145.         $STOSD;
  1146.         EDI><ptr;
  1147.         EAX><value;
  1148. }
  1149.  
  1150. // ---- ‚뢮¤ áâப¨ ¨á室­®£® ⥪áâ 
  1151. ShowSrcLine()
  1152. byte str[STRLEN];
  1153. {
  1154.         IF(list){
  1155.                 ESI><inptr;
  1156.                 $PUSH EDI,ESI;
  1157.                 ESI++;
  1158.                 EDI=#str;
  1159.                 for(;;){
  1160.                         $LODSB;
  1161.                         IF(AL==13)||(AL==0)BREAK;
  1162.                         $STOSB;
  1163.                 }
  1164.                 AL=0;
  1165.                 $STOSB
  1166.                 $POP ESI,EDI;
  1167.                 ESI><inptr;
  1168.                 IF(displaytokerrors){
  1169.                         fprint(mapfile,#str);
  1170.                         fprint(mapfile,"\n");
  1171.                 }
  1172. //              AL=cha;
  1173.         }
  1174. }
  1175.  
  1176. // ---- ‘®§¤ ­¨¥ ä ©«  áâ â¨á⨪¨
  1177. StartMapfile()
  1178. byte mapfilename[80];
  1179. {
  1180.         wsprintfA(#mapfilename,"%s.MAP",#rawfilename);
  1181.         mapfile=_lcreat(#mapfilename,0x1000);
  1182.         IF(EAX==0){
  1183.                 errmsg();
  1184.                 WRITESTR("Unable to create map file");
  1185.                 WRITESTR(#mapfilename);
  1186.                 ExitProcess(e_cannotopenmapfile);
  1187.         }
  1188.         wsprintfA(#mapstr,"MAP FILE FOR %s.%s\n\n",#rawfilename,"EXE");
  1189.         fprint(mapfile,#mapstr);
  1190. }
  1191.  
  1192. // ---- ˆ­¨æ¨ «¨§ æ¨ï ᯨ᪮¢ १¥à¢­ëå á«®¢
  1193. TokInit()
  1194. {
  1195.         InitList(#Mnemonics,#St_Mnemonics);
  1196.         InitList(#Registers,#St_Registers);
  1197.         InitList(#Directives,#St_Directives);
  1198.         InitList(#Sizes,#St_Sizes);
  1199. }
  1200.  
  1201. // ---- ‚®§¢à é ¥â à §¬¥à ¤«ï § ¤ ­­®£® ⨯  ¤ ­­ëå
  1202. dword TypeSize(dword vartype)
  1203. char holdstr[60];
  1204. {
  1205.         IF(vartype==tk_void)    RETURN(0);
  1206.         IF(vartype==tk_char)||(vartype==tk_byte)        RETURN(1);
  1207.         IF(vartype==tk_short)||(vartype==tk_word) RETURN(2);
  1208.         IF(vartype==tk_dword)||(vartype==tk_int) RETURN(4);
  1209.         wsprintfA(#holdstr,"vartype=%d in TypeSize()",vartype);
  1210.         internalerror(holdstr);
  1211.         return(-1);
  1212. }
  1213.  
  1214. // ---- à®¯ã᪠¯à®¡¥«®¢ ¨ â ¡ã«ï権
  1215. WhiteSpaces()
  1216. {
  1217.         for(;;){
  1218.                 AL=cha;
  1219.                 IF(AL!=32)&&(AL!=10)&&(AL!=9)BREAK;
  1220. NXT:
  1221.                 NextChar();
  1222.         }
  1223.         IF(AL == 13){   // CR
  1224.                 linenumber++; // Ž¡­ à㦥­ ª®­¥æ áâப¨
  1225.                 totallines++;
  1226.                 ShowSrcLine();
  1227.                 GOTO NXT;
  1228.         }
  1229. }
  1230.  
  1231. // ---- ‚뢮¤ ­  stdout
  1232. WRITESTR()
  1233. {
  1234.         fprint(stdout,EAX);
  1235. }
  1236.  
  1237. //===== Ž¡à ¡®âª  ®è¨¡®ª
  1238. // ----
  1239. datatype_expected()
  1240. {
  1241.         preerror("byte, word, short, char, dword or int expected");
  1242. }
  1243.  
  1244. // ----
  1245. errmsg()
  1246. {
  1247.         WRITESTR("\nERROR> ");
  1248. }
  1249.  
  1250. // ----
  1251. expected(dword ch)
  1252. byte hstr[80];
  1253. {
  1254.         wsprintfA(#hstr,"'%c' expected",ch);
  1255.         preerror(#hstr);
  1256. }
  1257.  
  1258. // ----
  1259. expectederror(dword str)
  1260. byte hstr[80];
  1261. {
  1262.         IF(displaytokerrors){
  1263.                 wsprintfA(#hstr,"'%s' expected",str);
  1264.                 preerror(#hstr);
  1265.         }
  1266. }
  1267.  
  1268. // ---- à®¢¥àª  ⥪ã饣® token ­  § ¤ ­­ë© ⨯
  1269. expecting(dword want)
  1270. {
  1271.         if(want!=tok){
  1272.                 IF(want==tk_closebracket)  expected(')');
  1273.                 else IF(want==tk_openbracket)   expected('(');
  1274.                 ELSE IF(want==tk_semicolon)     expected(';');
  1275.                 ELSE IF(want==tk_colon)         expected(':');
  1276.                 ELSE IF(want==tk_openblock)     expected('[');
  1277.                 ELSE IF(want==tk_closeblock)            expected(']');
  1278.                 ELSE IF(want==tk_openbrace)     expected('{');
  1279.                 ELSE IF(want==tk_closebrace)            expected('}');
  1280.                 ELSE IF(want==tk_comma)         expected(',');
  1281.                 ELSE    preerror("expecting a different token");
  1282.         }
  1283.         NextTok();
  1284. }
  1285.  
  1286. // ----
  1287. /*idalreadydefined()
  1288. byte holdstr[80];
  1289. {
  1290.         wsprintfA(#holdstr,"identifier %s already defined",#string);
  1291.         preerror(#holdstr);
  1292.         NextTok();
  1293. } */
  1294.  
  1295. // ----
  1296. idexpected()
  1297. {
  1298.         preerror("undefined 'identifier' expected");
  1299. }
  1300.  
  1301. // ---- ‚­ãâ७­ïï ®è¨¡ª  ª®¬¯¨«ïâ®à 
  1302. internalerror(dword str)
  1303. {
  1304.         error++;
  1305.         wsprintfA(#mapstr,"%s(%d)#%d> *** SERIOUS COMPILER INTERNAL ERROR ***\n>%s.\n",
  1306.                 #currentfilename,linenumber,error,str);
  1307.         WRITESTR(#mapstr);
  1308.         wsprintfA(#mapstr,"STRING:%s\n",#string);
  1309.         WRITESTR(#mapstr);
  1310.         wsprintfA(#mapstr,"TOK:%d\tPOST:%d\tnumber:%ld\n",tok,post,number);
  1311.         WRITESTR(#mapstr);
  1312.         wsprintfA(#mapstr,"STRING2:%s\n",#string2);
  1313.         WRITESTR(#mapstr);
  1314.         wsprintfA(#mapstr,"TOK2:%d\tPOST2:%d\tnumber2:%ld\n",tok2,post2,number2);
  1315.         WRITESTR(#mapstr);
  1316.         WRITESTR("Oh no.\n");
  1317.         IF(makemapfile)CloseHandle(mapfile);
  1318.         ExitProcess(e_internalerror);
  1319. }
  1320.  
  1321. // ----
  1322. localunresolved(dword str)
  1323. byte holdstr[80];
  1324. {
  1325.         wsprintfA(#holdstr,"local jump label '%s' unresolved",str);
  1326.         preerror(#holdstr);
  1327. }
  1328.  
  1329. // ----
  1330. maxwordpostserror ()
  1331. {
  1332.         preerror("maximum number of word post location references exceeded");
  1333. }
  1334.  
  1335. // ----
  1336. /*notyet()
  1337. {
  1338.         preerror("specified syntax not handled in this version!!!");
  1339. } */
  1340. // ----
  1341. numexpected()
  1342. {
  1343.         preerror("'number' expected");
  1344. }
  1345.  
  1346. // ----
  1347. operatorexpected ()
  1348. {
  1349.         preerror("operator identifier expected");
  1350. }
  1351. // ----
  1352. outofmemory()
  1353. {
  1354.         preerror("Compiler out of memory");
  1355.         IF( makemapfile )CloseHandle(mapfile);
  1356.         ExitProcess(e_outofmemory);
  1357. }
  1358.  
  1359. // ----
  1360. outofmemory2()
  1361. {
  1362.         errmsg();
  1363.         WRITESTR("Not enough memory for the compiler's buffers.\n");
  1364.         ExitProcess(e_outofmemory );
  1365. }
  1366.  
  1367. // ---- Žè¨¡ª  ¢ ⥪ã饩 áâப¥: ¯®ª § ­®¬¥à  áâப¨ ¨ ¨¬¥­¨ ä ©« 
  1368. preerror(dword str)
  1369. {
  1370.         IF(error < maxerrors){
  1371.                 error++;
  1372.                 wsprintfA(#mapstr,"%s (%d)#%d> %s.\n",#currentfilename,linenumber,error,str);
  1373.                 WRITESTR(#mapstr);
  1374.                 IF(makemapfile)fprint(mapfile,#mapstr);
  1375.         }
  1376.         ELSE toomanyerrors();
  1377. }
  1378.  
  1379. // ----
  1380. /*regnameerror()
  1381. {
  1382.         preerror("register name cannot be used as an identifier");
  1383.         NextTok();
  1384. } */
  1385.  
  1386. // ---- ’ॡã¥âáï áâப 
  1387. stringexpected()
  1388. {
  1389.         preerror("'string' expected");
  1390. }
  1391.  
  1392. // ---- ¥¤®¯ãáâ¨¬ë© ®¯¥à ­¤ ¤«ï swap
  1393. swaperror ()
  1394. {
  1395.         preerror("invalid or incompatable swap item");
  1396. }
  1397.  
  1398. // ---- à¥¤¥«ì­®¥ ç¨á«® ®è¨¡®ª - ¢ë室
  1399. toomanyerrors()
  1400. {
  1401.         IF( makemapfile )CloseHandle(mapfile);
  1402.         ExitProcess( e_toomanyerrors );
  1403. }
  1404.  
  1405. // ----
  1406. unabletoopen(dword str)
  1407. byte hstr[80];
  1408. {
  1409.         wsprintfA(#hstr,"unable to open file '%s'",str);
  1410.         preerror(#hstr);
  1411. }
  1412.  
  1413. // ----
  1414. undefinederror()
  1415. byte holdstr[80];
  1416. {
  1417.         wsprintfA(#holdstr,"'%s' undefined",#string);
  1418.         preerror(holdstr);
  1419. }
  1420.  
  1421. // ----
  1422. unexpectedeof()
  1423. {
  1424.         preerror("unexpected END OF FILE");
  1425. }
  1426. // ----
  1427. warning(dword str)
  1428. {
  1429.         wsprintfA(#mapstr,"%s (%d)Warning> %s.\n",#currentfilename,linenumber,str);
  1430.         WRITESTR(#mapstr);
  1431.         IF(makemapfile)fprint(mapfile,#mapstr);
  1432. }
  1433. /*
  1434. void TestProc()
  1435. char buf[20];
  1436. {
  1437.         $pushad
  1438.         wsprintfA(#buf,"%08X\n",SSDWORD[EBP+4]);
  1439.         WRITESTR(#buf);
  1440.         $popad
  1441. } */
  1442.