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

📄 tinyc.c

📁 一个非常小的C语言编译器!!! !!! !!! !!!!
💻 C
📖 第 1 页 / 共 2 页
字号:
      // At exit, ';' or '}' is read if return value is 0.      // At exit, a token next to ';' or '}' is read if return value is 1.{  Reg_symP lLeftPart, lExpReg;  SymbolP  lSym;  int      lNextRead = 0;              // 1: The next symbol is already read.    returnStmt = 0;                      // Reset return statement flag.  if ((pSymp->Kind() == tknVar)||      (pSymp->Kind() == tknParam)) {   // Variable "=" Expression ";"    lLeftPart = Variable(pSymp, reg_ti0, lValue);    if (sym_curr == sym_assign) {      // It is "="      sym_curr = sym_tbl.Get('?');     // Get 1st symbol of the expression,      lExpReg = Expression(reg_ti0);   // evaluate it, (reg_ti0: default reg.)      ac_curr->Store(lLeftPart, lExpReg);  // and store the result.    }  }else if (pSymp->Kind() == tknFunc) { // Function call.    lExpReg = SubCall(pSymp);  }else if (pSymp == sym_if) {         // "if"    lNextRead = IfStatement();         // 0 if with else, 1 if without else.  }else if (pSymp == sym_while)        // "while"     WhileStatement();  else if (pSymp == sym_lbrace)        // "{"    Block();  else if (pSymp == sym_return) {      // Statement::= "return" ";"    sym_curr = sym_tbl.Get('?');    if (sym_curr != sym_scolon)        // Not ";", with return value.      lExpReg = Expression(reg_ri);    // Use the return value register reg_ri.    else      lExpReg = NULL;    GenCode(acRs, opEpilog, lExpReg, NULL, NULL, subCurrent, 0);    GenCode(acS,  opReturn, NULL,    NULL, NULL, subCurrent, 0);    returnStmt = 1;                   // Set return flag.  }  if ((sym_curr != sym_rbrace)&&(lNextRead == 0))     Expect(sym_scolon);               // ";" is expected.  return lNextRead;                   // 1 if the next symbol is read.} //---- ExecStatement end ----////--------------------// // Process a variable.Reg_symP Variable(       // Variable::= Name {"["Expression"]"}  SymbolP  pSymp,        //   Header name of the variable.  Reg_symP pRegCand,     //   Register candidate  Ac_lrT   pType)        //   lValue/rValue/aValue.           // Return resultant register            // (or variable if lValue and the variable is simple name).           // At entry, variable name is read.           // At exit, the next token following the variable is read.{  Reg_symP lRegIndex, lRegVar;  Ac_lrT   lType = lValue;    if (pType == rValue) lType = rValue;  sym_curr = sym_tbl.Get('?');         // Get the next symbol.  if (sym_curr == sym_lbracket) {      // With subscript exp.    sym_curr = sym_tbl.Get('?');    lRegIndex = Expression(reg_ti0); // Process the subscript.    lRegVar = ac_curr->Load(pSymp, pRegCand, lRegIndex, 0, lType);    Expect(sym_rbracket);              // "]" is expected.    sym_curr = sym_tbl.Get('?');  }else {                  // Simple variable.    if (pType == lValue)   //   If lValue, return the variable itself      return pSymp;        //   for using it as an operand of store.    lType = (pSymp->VarP()->ElemCount() > 1 ? lValue : lType);    lRegVar = ac_curr->Load(pSymp, pRegCand, NULL, 0, lType);  }  return lRegVar;          // Return a register corresponding to the variable.} //---- Variable end ----// //--------------------// // Process a factor.Reg_symP Factor(         // Factor::= IntConst|Variable|"("Expression")"  Reg_symP pRegCand)     //   Candidate register.            // At entry, first token is read.            // At exit, the next token following the factor is read.{  Reg_symP lReg;  Ac_lrT   lType = rValue;  if (sym_curr == sym_and) {    lType = aValue;    sym_curr = sym_tbl.Get('?');  }  if ((sym_curr->Kind() == tknVar)||(sym_curr->Kind() == tknParam))  {    lReg = Variable(sym_curr, pRegCand, lType);    lReg->RegP()->RegStatSet(regHold);   //##031121  // else if (sym_curr->Kind() == tknSubp) { } // Not Yet Implemented.   } else {    if (sym_curr->Kind() == tknIntC) {   // Integer constant.      lReg = reg_tbl.RegAlloc(pRegCand, NULL, sym_curr->IValue(),              regConstVal);      if (lReg->RegP()->reusable == false) //##030309        GenCode(acRc, opLoad, lReg, NULL, NULL, NULL, sym_curr->IValue());      lReg->RegP()->RegStatSet(regHold);   //##031121    }else if (sym_curr == sym_lpar) {   // "(" Expression ")"      sym_curr = sym_tbl.Get('?');      // 1st symbol of the expression.      lReg = Expression(pRegCand);      Expect(sym_rpar);                 // ")" is expected.    }else {                             // undefined symbol ## 010828      sym_curr->Error(90, "Undefined symbol");      lReg = reg_tbl.RegAlloc(reg_ti0, NULL, 1, regConstVal); //## 010828    }    sym_curr = sym_tbl.Get('?');        // Get the next symbol.  }  return lReg;              // Return a register containing the factor value.} //---- Factor end ----////--------------------// // Process a term.Reg_symP Term(           // Term::= Factor {["*"|"/"|"&"|"<<"|">>"] Factor} ...  Reg_symP pRegCand)     //   Candidate register.            // At entry, the first token is read.            // At exit, a token next to the term is read.{  Reg_symP lReg, lReg2;  Sym_opCodeT lOpCode;    lReg = Factor(pRegCand);  while ((sym_curr == sym_mult)||	 (sym_curr == sym_div)){    lOpCode  = sym_curr->OpCode();    sym_curr = sym_tbl.Get('?');    lReg2    = Factor(reg_ti0);   // Use the default register reg_ti0.    GenCode(acRrr, lOpCode, lReg, lReg, lReg2, NULL, 0);  }  return lReg;    // Return a register containing the value of the term.} //---- Term end ----////--------------------// // Process an expression.Reg_symP Expression(     // Expression::= {"+"|"-"}Term {["+"|"-"] Term} ...  Reg_symP pRegCand)     //   Candidate register.            // At entry, first symbol of the expression is read.            // At exit, the token next to the expression is read.{  Reg_symP    lReg, lReg1, lReg2;  Sym_opCodeT lOpCode;    lReg1 = NULL;  if (sym_curr == sym_sub)   {    // Unary "-"     lReg1 = reg_tbl.RegAlloc(reg_ti0, NULL, 0, regConstVal);    GenCode(acRc, opLoad, lReg1, NULL, NULL, NULL, 0);    sym_curr = sym_tbl.Get('?');  }else if (sym_curr == sym_add)  // Unary "+"    sym_curr = sym_tbl.Get('?');  lReg = Term(pRegCand);   if (lReg1 != NULL)     GenCode(acRrr, opSub, lReg, lReg1, lReg, NULL, 0);  while ((sym_curr == sym_add)||	 (sym_curr == sym_sub)) {    lOpCode = sym_curr->OpCode();    sym_curr = sym_tbl.Get('?');    lReg2 = Term(reg_ti0);       // Use the default register.    GenCode(acRrr, lOpCode, lReg, lReg, lReg2, NULL, 0);  }  return lReg;   // Return a register containing the expression value.} //---- Expression end ----////--------------------// // Process a conditional expression.void Condition(          // ConditionExp::= Expression CompOper Expression  SymbolP pFalseLab)     //   Branch label for false jump.          // At entry, 1st symbol or '(' of conditional exp is read.          // At exit, the token next to conditional exp is read.{  Reg_symP lReg, lReg2;  Sym_opCodeT lOpCode;    sym_curr = sym_tbl.Get('?');  lReg = Expression(reg_ti0);   if (sym_curr->Kind() == tknOper) {    lOpCode = sym_curr->OpCode();   // Get the operation code for the operator.    sym_curr = sym_tbl.Get('?');    lReg2 = Expression(reg_ti0);    GenCode(acRrr, opComp, lReg, lReg, lReg2, NULL, 0);     // Compare.    GenCode(acRs, lOpCode, lReg, NULL, NULL, pFalseLab, 0); // jump false.  }  if (sym_curr == sym_rpar)    sym_curr = sym_tbl.Get('?');   // Read a symbol next to ")".} // Condition end ----////--------------------// // "if" "(" ConditionExp ")" Statementint IfStatement()        // { "else" Statement }      // At entry, "if" is read.       // At exit, a token after ';' is read if without "else" (return 1).      // At exit, ';' is read if without "else" (return 0).{  Reg_symP lRegCond;  SymbolP  lFalseLab, lIfEndLab;  int      lNextRead;    lFalseLab = ac_curr->LabelGen(); // Get labels.  lIfEndLab = ac_curr->LabelGen();  sym_curr = sym_tbl.Get('(');     // Read '(' enclosing ConfitionExp.  Condition(lFalseLab);            // Generate instructions for it.  lNextRead = ExecStatement(sym_curr);  // "then" part. Token after ';' is read.  GenCode(acS, opJump,  NULL, NULL, NULL, lIfEndLab, 0);  GenCode(acS, opLabel, NULL, NULL, NULL, lFalseLab, 0);  reg_tbl.RegFreeAll();  if (lNextRead == 0) {            // Read the next token.    sym_curr = sym_tbl.Get('?');   // Token after ';' or '}' is read.    lNextRead = 1;                 // Indicate that the next token is read.  }  if (sym_curr == sym_else) {      // "else" Statement    sym_curr = sym_tbl.Get('?');    lNextRead = ExecStatement(sym_curr);   //  ';' or '}' is read.  }  GenCode(acS, opLabel, NULL, NULL, NULL, lIfEndLab, 0);  reg_tbl.RegFreeAll();  returnStmt = 0;  return lNextRead;} //---- IfStamenent end ----////--------------------// // Process a subprogram call.Reg_symP SubCall(        // FuncName "(" Expression {"," Expression} ...")"  SymbolP pSym)          //   Symbol pointer of the subprogram.          // At entry, '(' is read. At exit, ')' is read.{  SymbolP lParam, lParamType;  // Parameter name & type.  Reg_symP  lParamReg;         // Parameter register.  sym_curr = sym_tbl.Get('?');  lParam   = pSym->FuncP()->ParamChain();  // The first formal parameter.//  lParamType = lParam->VType();  lParamReg  = reg_ai0;        // reg_ai0: first parameter register.  lParamReg  = reg_ai0;        // ## 010830  while ((sym_curr != sym_rpar)&&(sym_curr != sym_scolon)&&         (lParam != NULL)&&(lParamReg != NULL)) {    if ((sym_curr == sym_comma)||(sym_curr == sym_lpar))      sym_curr = sym_tbl.Get('?');  // Get the first token of the expression.//    if (lParamReg == NULL)          // Allocate a parameter register.//      lParamReg = reg_tbl.RegAlloc(reg_ai0, NULL, 0, regEmpty);    lParamReg->RegP()->RegStatSet(regReserved); // Reserve the param reg.    lParamReg = Expression(lParamReg);          // Evaluate the parameter.    if (lParamReg->RegP()->RegNumb() >= REG_paramReg) {   //## 010901      GenCode(acRc, opStack, lParamReg, NULL, NULL, NULL, (lParamReg->RegP()->RegNumb()-REG_paramReg)*COM_sizeInt);  //## 010901    }                                                    //## 010901    lParam = lParam->VarP()->ParamChain();      // The next formal param.    lParamReg = lParamReg->RegP()->RegChain();  // Get the next param reg.  }    Expect(sym_rpar);                             // ")" is expected.  GenCode(acS, opCall, NULL, NULL, NULL, pSym, 0);  reg_tbl.RegFreeAll();  return reg_ri;     // reg_ri: return value register.} //---- SubCall end ----////--------------------//void WhileStatement() // "while" "(" ConditionExp ")" Statement                      // At entry, 'while' is read.                      // At exit, ';' or '}' is read.{  SymbolP  lLoopStartLab, lLoopEndLab;  Reg_symP lReg;  lLoopStartLab = ac_curr->LabelGen();  // Generate loop-start label.  lLoopEndLab   = ac_curr->LabelGen();  // Generate loop-end   label.  GenCode(acS, opLabel, NULL, NULL, NULL, lLoopStartLab, 0);  reg_tbl.RegFreeAll();                 // Free registers.  sym_curr = sym_tbl.Get('(');  Condition(lLoopEndLab);  // At exit, the next token is read.  ExecStatement(sym_curr);              // Loop body.  GenCode(acS, opJump,  NULL, NULL, NULL, lLoopStartLab, 0);  GenCode(acS, opLabel, NULL, NULL, NULL, lLoopEndLab, 0);  reg_tbl.RegFreeAll();} //---- WhileStatement end ----//

⌨️ 快捷键说明

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