예제 #1
0
 public override void Generate(AsmCode asmCode, SymTable symTable)
 {
     if (Subprogram is FunctionSymbol fs &&
         (fs.ReturnType is RecordTypeSymbol || fs.ReturnType is ArrayTypeSymbol))
     {
         throw new NotImplementedException();
     }
     foreach (var prm in Childs.AsEnumerable().
              Reverse().
              Zip(
                  Subprogram.Parameters.AsEnumerable().Reverse(),
                  (node, symbol) => (node, symbol)))
     {
         if (prm.symbol.ParameterModifier == ParameterModifier.Value)
         {
             prm.node.Generate(asmCode, symTable);
         }
         else
         {
             ((DesignatorNode)prm.node).GenerateLValue(asmCode, symTable);
         }
     }
     if (asmCode.SubprogramStack.Count > 0 &&
         asmCode.SubprogramStack.Peek() == Subprogram)
     {
         asmCode.Add(
             AsmCmd.Cmd.Mov,
             AsmReg.Reg.Eax,
             new AsmOffset(-8, 4, AsmReg.Reg.Ebp));
         asmCode.Add(AsmCmd.Cmd.Push, AsmReg.Reg.Eax);
     }
     else
     {
         asmCode.Add(AsmCmd.Cmd.Push, AsmReg.Reg.Ebp);
     }
     asmCode.Add(AsmCmd.Cmd.Call, Subprogram.Label.ToArgString());
     if (Subprogram is FunctionSymbol functionSymbol)
     {
         if (functionSymbol.ReturnType == TypeSymbol.IntTypeSymbol ||
             functionSymbol.ReturnType == TypeSymbol.CharTypeSymbol)
         {
             asmCode.Add(AsmCmd.Cmd.Push, AsmReg.Reg.Eax);
         }
         if (functionSymbol.ReturnType == TypeSymbol.RealTypeSymbol)
         {
             asmCode.Add(AsmCmd.Cmd.Sub, AsmReg.Reg.Esp, 8);
             asmCode.Add(
                 AsmCmd.Cmd.Movsd,
                 new AsmOffset(0, 8, AsmReg.Reg.Esp),
                 AsmReg.Reg.Xmm0);
         }
     }
 }