Beispiel #1
0
        public static Command FunctionCall(
            string name, int argc, LabelGenerator generator)
        {
            var label = generator.Generate("ret");

            return(new Command(
                       $"call {name} {argc}",
                       new[]
            {
                label.Address,
                "D=A",
                "@R13",
                "M=D",

                '@' + argc.ToString(),
                "D=A",
                "@R14",
                "M=D",

                '@' + name,
                "D=A",
                "@R15",
                "M=D",

                "@CALL",
                "0;JMP",

                label.Declaration
            }));
        }
Beispiel #2
0
 public Function(string fileName, string name, int argc)
 {
     FileName       = fileName;
     Name           = name;
     Argc           = argc;
     LabelGenerator = new LabelGenerator(name);
     _commands.Add(Commands.DeclareFunction(name, argc));
 }
        private static IEnumerable <string> Bootstrapper()
        {
            var labelGenerator = new LabelGenerator("bootstrapper");

            return(new[]
            {
                "@256",
                "D=A",
                "@SP",
                "M=D"
            }.Concat(Commands
                     .FunctionCall("Sys.init", 0, labelGenerator).HackInstructions));
        }
Beispiel #4
0
        public static Command Parse(string fileName, string line, LabelGenerator generator)
        {
            var parts   = line.Split(' ');
            var command = parts[0];
            var arg1    = parts.Length > 1 ? parts[1] : null;
            var arg2    = parts.Length > 2 ? int.Parse(parts[2]) : 0;

            switch (command)
            {
            case "add": return(Commands.Arithmetic.Add());

            case "sub": return(Commands.Arithmetic.Sub());

            case "neg": return(Commands.Arithmetic.Neg());

            case "and": return(Commands.Bitwise.And());

            case "or": return(Commands.Bitwise.Or());

            case "not": return(Commands.Bitwise.Not());

            case "eq": return(Commands.Comparsion.Equal(generator));

            case "gt": return(Commands.Comparsion.GreateThan(generator));

            case "lt": return(Commands.Comparsion.LessThan(generator));

            case "function": return(Commands.DeclareFunction(arg1, arg2));

            case "call": return(Commands.FunctionCall(arg1, arg2, generator));

            case "return": return(Commands.FunctionRetrun());

            case "goto": return(Commands.Goto(arg1));

            case "if-goto": return(Commands.IfGoto(arg1));

            case "label": return(Commands.Label(arg1));

            case "push":
            {
                switch (arg1)
                {
                case "constant": return(Commands.Push.Constant(arg2));

                case "local": return(Commands.Push.Local(arg2));

                case "argument": return(Commands.Push.Argument(arg2));

                case "this": return(Commands.Push.This(arg2));

                case "that": return(Commands.Push.That(arg2));

                case "temp": return(Commands.Push.Temp(arg2));

                case "pointer": return(Commands.Push.Pointer(arg2));

                case "static": return(Commands.Push.Static(fileName, arg2));

                default: throw new ArgumentException("Invalid segment");
                }
            }

            case "pop":
            {
                switch (arg1)
                {
                case "local": return(Commands.Pop.Local(arg2));

                case "argument": return(Commands.Pop.Argument(arg2));

                case "this": return(Commands.Pop.This(arg2));

                case "that": return(Commands.Pop.That(arg2));

                case "temp": return(Commands.Pop.Temp(arg2));

                case "pointer": return(Commands.Pop.Pointer(arg2));

                case "static": return(Commands.Pop.Static(fileName, arg2));

                default: throw new ArgumentException("Invalid segment");
                }
            }

            default: throw new InvalidOperationException("Invalid command");
            }
        }
Beispiel #5
0
 public static Command LessThan(LabelGenerator generator) =>
 Compare("lt", "JGT", generator.Generate("lt"));
Beispiel #6
0
 public static Command GreateThan(LabelGenerator generator) =>
 Compare("gt", "JLT", generator.Generate("gt"));
Beispiel #7
0
 public static Command Equal(LabelGenerator generator) =>
 Compare("eq", "JEQ", generator.Generate("eq"));