Пример #1
0
        public IEnumerable <string> ToAssembly(string line)
        {
            var parts = line.Split(' ');

            if (parts.Length < 3)
            {
                throw new InvalidOperationException("Call command must be of the form 'call foo 2'");
            }

            var functionName = parts[1];
            var nArgs        = parts[2];
            var callCount    = callCounter.GetCount(functionName);

            var assembly = new []
            {
                $"// {line}",
                $"// push {functionName}$ret.{callCount}",
                $"@{functionName}$ret.{callCount}",
                "D=A",
                "@SP",
                "A=M",
                "M=D",
                "@SP",
                "M=M+1",
                "// push LCL",
                "@LCL",
                "D=M",
                "@SP",
                "A=M",
                "M=D",
                "@SP",
                "M=M+1",
                "// push ARG",
                "@ARG",
                "D=M",
                "@SP",
                "A=M",
                "M=D",
                "@SP",
                "M=M+1",
                "// push THIS",
                "@THIS",
                "D=M",
                "@SP",
                "A=M",
                "M=D",
                "@SP",
                "M=M+1",
                "// push THAT",
                "@THAT",
                "D=M",
                "@SP",
                "A=M",
                "M=D",
                "@SP",
                "M=M+1",
                "// ARG = SP-5-nArgs",
                "@SP",
                "D=M",
                "@5",
                "D=D-A",
                $"@{nArgs}",
                "D=D-A",
                "@ARG",
                "M=D",
                "// LCL = SP",
                "@SP",
                "D=M",
                "@LCL",
                "M=D",
                $"// goto {functionName}",
                $"@{functionName}",
                "0;JMP",
                $"({functionName}$ret.{callCount})",
                ""
            };

            callCounter.IncrementCount(functionName);

            return(assembly);
        }