⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 assembler.cpp

📁 c语言的简化编译器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
  if (strcmp(token, "iload") == 0) {
    addCode(iloadC);
    intparam = atoi(getToken(sourceFILE));
    addInt16(intparam);
  } else
  if (strcmp(token, "istore") == 0) {
    addCode(istoreC);
    intparam = atoi(getToken(sourceFILE));
    addInt16(intparam);
  } else
  if (strcmp(token, "dup") == 0) {
    addCode(dupC);
  } else
  if (strcmp(token, "pop") == 0) {
    addCode(popC);
  } else
  if (strcmp(token, "iconst_0") == 0) {
    addCode(iconst_0C);
  } else 	
  if (strcmp(token, "iconst_1") == 0) {
	  addCode(iconst_1C);
 	} else 
  if (strcmp(token, "iconst_2") == 0) {
	  addCode(iconst_2C);
	} else 
  if (strcmp(token, "iconst_3") == 0) {
	  addCode(iconst_3C);
	} else 
  if (strcmp(token, "iconst_4") == 0) {
	  addCode(iconst_4C);
	} else 
  if (strcmp(token, "iconst_5") == 0) {
   	addCode(iconst_5C);
  } else 
  if (strcmp(token, "ldc_int") == 0) {
    addCode(ldc_intC);
    intparam = atoi(getToken(sourceFILE));
    /* index to constant pool */
    addIndex(getIntConstNr(intparam));
  } else	 
  if (strcmp(token, "ldc_string") == 0) {
    addCode(ldc_stringC);
    param = getStringToken(sourceFILE); 
    /* index to constant pool */
    addIndex(getStrConstNr(param));
  } else
  if (strcmp(token, "call") == 0) {
    addCode(callC);
    param = getToken(sourceFILE);
    /* index to constant pool */
    addIndex(getStrConstNr(param));
  } else
  if (strcmp(token, "setint_mdl") == 0) {
    addCode(setint_mdlC);
  } else
  if (strcmp(token, "setint_particle") == 0) {
    addCode(setint_particleC);
  } else
  if (strcmp(token, "setint_ply") == 0) {
    addCode(setint_plyC); 
  } else
  if (strcmp(token, "setint_light") == 0) {
    addCode(setint_lightC);
  } else
  if (strcmp(token, "setint_cam") == 0) {
    addCode(setint_camC);
  } else
  if (strcmp(token, "sleep") == 0) {
    addCode(sleepC);
  } else     
  if (strcmp(token, "sleep_trig") == 0) {
    addCode(sleep_trigC);
  } else     
  if (strcmp(token, "cast_inttostring") == 0) {
    addCode(cast_inttostringC);
  } else         
  if (strcmp(token, "cast_stringtoint") == 0) {
    addCode(cast_stringtointC);
  } else
  if (strcmp(token, "cast_booltostring") == 0) {
  	// This opcode is needed even if bools are represented by ints in the VM (can you think why?)
    addCode(cast_booltostringC);
  }             
  else {
    printf("FATAL ERROR - unhandled opcode in assembler '%s'\n", token);
  }
}



// Write the constant pool chunk to the output file.
void emitConstants() {
  char id = CONSTANTS_ID;
  CONSTANT *constantList = asmConstants;	
  char ctype;
  int intval;
  
  // write ID 
  fwrite(&id, 1, 1, emitFILE);
  
  // write number of constants 
  fwrite(&nextconst, sizeof(unsigned int), 1, emitFILE);
  
  // Loop over all constants 
  while (constantList) {
   ctype = constantList->type;
   fwrite(&ctype, 1, 1, emitFILE);
   switch (ctype) {
    case INT_CONST:
     intval = constantList->val.intval;
     fwrite(&intval, sizeof(int), 1, emitFILE);
     break;
    case ZSTRING_CONST:
     writeZString(constantList->val.str, emitFILE);
     break;
   }   	
   constantList = constantList->next;	
  }
}


// Write the code segment chunk to the file.
void emitCodeSegment() {
 char id = CODE_ID;
 
 /* write ID */
 fwrite(&id, 1, 1, emitFILE);
 
 /* write codesize */
 fwrite(&codeposition, sizeof(unsigned int), 1, emitFILE);  
  
 /* write bytecode */ 
 fwrite(bytecode, 1, codeposition, emitFILE);  
}




/* ****************** ASSEMBLER ******************* */

void AssembleFile(char *fn) 
{
  char *token = NULL;
  sourceFILE = fopen("emitted.a","r");
  emitFILE = fopen(fn, "wb");
  
  if (sourceFILE == NULL) {
  	printf("ERROR - Couldn't open source file 'emitted.a'\n");
  	return;
  }
  
  if (emitFILE == NULL) {
  	printf("ERROR - Couldn't open output file '%s'\n", fn);
  	return;
  }
  
  
  /* initialize the byte code buffer */
  curCodeArraySize = START_SIZE;
  bytecode = (unsigned char *)Malloc(START_SIZE);
  
  token = getToken(sourceFILE);  
      
  while (token != NULL) {
   // Which top-level token did we read?
   if (strcmp(token, ".function") == 0)
    AssembleFunction();
   else
   if (strcmp(token, ".program") == 0)
    AssembleProgram();
   else
    reportError(line, "Illegal top-level token in assembly file");	
  
   /* Get next top-level */  	
   token = getToken(sourceFILE);	
  }
  
  /* fill in the plugs */
  fillPlugs();
  
  /* Now emit all constants and code */
  emitConstants();
  emitCodeSegment();
    
  fclose(emitFILE);
  fclose(sourceFILE);	
}



// Assemble a function
void AssembleFunction() {
 char id;
 char *token;
 char *tmp;
 int end = 0;
 
 // Create a new function header struct
 FUNCTIONHEADER *header = NEW(FUNCTIONHEADER);
 
 // The functions code will start here:
 header->startCode = codeposition;
 
    
 // First get name token and extract parameter info from it 
 token = getToken(sourceFILE);
 tmp = token;
 header->inputs = 0;
 header->outputs = 0;
 
 // Search for end of name.
 while (*tmp != '(') {
  end++;
  tmp++;
 } 
 
 // Count number of inputs to this function
 while (*tmp != ')') {
  tmp++;
  header->inputs++;
 }
 header->inputs--; // We counted one too much in the above.
 
 // Check if there is a return value from this function
 tmp++;
 if (*tmp != 'V') // Check if return type is non-VOID 
  header->outputs = 1;
 
 // Zero-terminate token where the name ends.
 token[end] = 0;
 header->name = token; 
 
 // the prefix for our label lookup. The function name is unique 
 currentName = header->name; 
   
 // Now assemble the function  
 do {
  token = getToken(sourceFILE);		
 	
  if (isLabel(token)) { 
    token[strlen(token)-1] = 0;
    setLabelPosition(token);	
  }	
  else
  if (strcmp(token, ".limit_locals") == 0) {
    token = getToken(sourceFILE);	
    header->localLimit = atoi(token);
  }
  else
  if (strcmp(token, ".limit_stack") == 0) {
    token = getToken(sourceFILE);	
    header->stackLimit = atoi(token);
  }
  else
  if (strcmp(token, ".end_function") == 0) {
    // Do nothing
  }
  else {
   // If nothing else matches this must be a token from the functions code body. 
   asmCODE(token);
 	}
 } while (token != NULL && (strcmp(token, ".end_function") != 0));
 
 // This is where the code ends (points to the first byte code AFTER the function)
 header->endCode = codeposition;
 
   
 // Write function to the output file 
 id = FUNCTION_ID;
 fwrite(&id, 1, 1, emitFILE); // Write a function chunk.
 // write header 
 writeZString(header->name, emitFILE);
 fwrite(&header->inputs, 1, 1, emitFILE);
 fwrite(&header->outputs, 1, 1, emitFILE);
 fwrite(&header->localLimit, 1, 1, emitFILE);
 fwrite(&header->stackLimit, sizeof(unsigned short int), 1, emitFILE);
 fwrite(&header->startCode, sizeof(unsigned int), 1, emitFILE);
 fwrite(&header->endCode, sizeof(unsigned int), 1, emitFILE);

 // Echo some of the info to the screen. 
 printf("func : '%s', inputs %i, outputs %i, codesize %i\n", 
        header->name, header->inputs, header->outputs,  header->endCode - header->startCode ); 
  
}


// Pretty much the same as above. Look for the changes yourself
void AssembleProgram() {
 char id;
 char *token = NULL;
 PROGRAMHEADER *header = NEW(PROGRAMHEADER);
 header->startCode = codeposition;
 header->triggerArgument = NULL;
 
 // read name 
 header->name = getToken(sourceFILE);
 
 // the prefix for our label lookup 
 currentName = header->name; 
   
 do {
  token = getToken(sourceFILE);		
 
  if (isLabel(token)) { 
    token[strlen(token)-1] = 0;
    setLabelPosition(token);	
  }	
  else
  if (strcmp(token, ".limit_locals") == 0) {
    token = getToken(sourceFILE);	
    header->localLimit = atoi(token);
  }
  else
  if (strcmp(token, ".limit_stack") == 0) {
    token = getToken(sourceFILE);	
    header->stackLimit = atoi(token);
  }
  else
  if (strcmp(token, ".trigger_never") == 0) {
    header->triggertype = trigger_neverK;
  }
  else
  if (strcmp(token, ".trigger_on_init") == 0) {
    header->triggertype = trigger_on_initK;
  }
  else
  if (strcmp(token, ".trigger_on_click") == 0) {
    header->triggertype = trigger_on_clickK;
    token = getStringToken(sourceFILE); 
    header->triggerArgument = token;
  }
  else
  if (strcmp(token, ".trigger_on_collide") == 0) {
    header->triggertype = trigger_on_collideK;
    token = getStringToken(sourceFILE); 
    header->triggerArgument = token; 
  }
  else
  if (strcmp(token, ".trigger_on_pickup") == 0) {
    header->triggertype = trigger_on_pickupK;
    token = getStringToken(sourceFILE); 
    header->triggerArgument = token;
  }
  else 
  if (strcmp(token, ".end_program") == 0) {
  	// Do nothing
  }	
  else {
    asmCODE(token);
 	}
 } while (token != NULL && (strcmp(token, ".end_program") != 0));

 
 header->endCode = codeposition;
 
 // Write program 
 id = PROGRAM_ID;
 fwrite(&id, 1, 1, emitFILE);
 // write header 
 writeZString(header->name, emitFILE);
 fwrite(&header->localLimit, 1, 1, emitFILE);
 fwrite(&header->stackLimit, sizeof(unsigned short int), 1, emitFILE);
 fwrite(&header->triggertype, 1, 1, emitFILE);
 writeZString(header->triggerArgument, emitFILE);
 fwrite(&header->startCode, sizeof(unsigned int), 1, emitFILE);
 fwrite(&header->endCode, sizeof(unsigned int), 1, emitFILE);

 // Echo to screen
 printf("triggertype = %i, trigger Argument '%s'\n", header->triggertype, header->triggerArgument);
 printf("prog : '%s' - codesize %i\n", header->name, header->endCode - header->startCode ); 
}

/* ***************************************************

   ** And we're done!  That wasn't so hard was it?? **

   ** Congrats on completing your compiler!         **
   
   *************************************************** */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -