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); } } }