Esempio n. 1
0
 public InstructionBinder(AstBodyBuilder bodyBuilder, ImmutableDictionary <int, AstLocal> addressToLocalMap, int ramStart)
 {
     this.bodyBuilder       = bodyBuilder;
     this.addressToLocalMap = addressToLocalMap;
     this.addressToLabelMap = new Dictionary <int, AstLabel>();
     this.ramStart          = ramStart;
 }
Esempio n. 2
0
        public static GlulxFunction Read(Memory memory, int address, int ramStart)
        {
            var scanner           = memory.CreateScanner(address);
            var type              = ReadType(scanner);
            var bodyBuilder       = new AstBodyBuilder();
            var addressToLocalMap = ReadLocals(scanner, bodyBuilder);
            var binder            = new InstructionBinder(bodyBuilder, addressToLocalMap, ramStart);

            ReadBody(scanner, binder);
            var body = bodyBuilder.ToBody();

            return(new GlulxFunction(type, address, body));
        }
Esempio n. 3
0
        public void return_add_expression()
        {
            var builder = new AstBodyBuilder();
            var label   = builder.NewLabel();

            builder.MarkLabel(label);
            builder.Return(
                AstFactory.ConstantExpression(19).Plus(23));

            var function = new TestFunction(builder.ToBody());

            var machine     = new TestMachine();
            var interpreter = new Interpreter(machine);

            var result = interpreter.Evaluate(function);

            Assert.Equal(42u, result);
        }
Esempio n. 4
0
        private static ImmutableDictionary <int, AstLocal> ReadLocals(MemoryScanner scanner, AstBodyBuilder bodyBuilder)
        {
            var map     = ImmutableDictionary.CreateBuilder <int, AstLocal>();
            var address = 0;

            while (true)
            {
                var sizeByte  = scanner.NextByte();
                var countByte = scanner.NextByte();

                if (sizeByte == 0 && countByte == 0)
                {
                    break;
                }

                var size = SizeByteToValueSize(sizeByte);

                // The Glulx spec states that locals will have padding to bring values
                // to their natural alignment. We should account for that here. Note that
                // the spec guarantees that the locals will start at a 4-byte boundary.
                if (size != ValueSize.Byte && address % sizeByte != 0)
                {
                    address += sizeByte;
                }

                for (int i = 0; i < countByte; i++)
                {
                    var local = bodyBuilder.DeclareLocal(size);
                    map.Add(address, local);
                    address += sizeByte;
                }
            }

            return(map.ToImmutable());
        }