3 ms·
That Cell class looks a bit odd, and I can't imagine it's doing good things for your memory use. Perhaps you could simplify it by making your registers a list o
by anthonyb 15y ago
That Cell class looks a bit odd, and I can't imagine it's doing good things for your memory use. Perhaps you could simplify it by making your registers a list or a dictionary, rather than a tuple?
ie.
self.registers = { 'A': 0x0000, ... }
then you could access it directly:
self.registers['A'] = 0x0001
- jerf 15y agoMemory use isn't the problem, it's the added code complexity. Not having self.registers = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] instead is adding ".value" all over the place where it isn't necessary. I haven't actually tried this but it looks like dropping the Cell class entirely, putting that line in as the definition of registers, then s/.values//g ought to work, or very nearly work. PC, SP, and O are already defined as variables containing the index for that register, a fine way to do it.
- anthonyb 15y agoUsing the array module for registers and memory might be even better - you're not likely to want to randomly add a register or memory bank.
- masklinn 15y agoDoes not fix the issue jtauber pointed out: you can't pass around a section of an array "by reference" so that people can set stuff in e.g. register A.
- jtauber 15y agoThe reason for the Cell() is explained in a comment; I have to be able to pass around references to registers and memory locations distinct from their value. I'm open to alternatives but the above won't work as how do you pass in "register A" or "memory location 0x1000" as the arg to an instruction method in that case?
- masklinn 15y agoCouldn't cells be split from "normal", and used as proxies only when needed (when the cell actually needs to be passed around)? And lazily instantiated (but memoized so they can be reused)?
- lloeki 15y agoAs soon as the spec popped up, I've been into implementing DCPU-16 in Python on my own too, and I quickly encountered the same issue. Currently, my Cell-equivalent class (which I called Pointer) defines __call__, so I can do a() to read and a(data) to set. It arguably sucks less, but I'm looking for something better and currently trying various solutions involving __getitem__, closures, function attributes, decorators and a sprinkle of metaprogramming to keep things nicely separated and much less C-ish. I've already defined opcodes this way (decorator+func) which makes it very descriptive and almost reduces the opcode dispatcher to a one-liner.
- lloeki 15y agoHere's my latest tentative approach to the values problem, where you use cpu[value_code] to get and set, dispatching being done behind the scenes. https://github.com/lloeki/python-dcpu_16/blob/e78f4b8af895dba34627e4a3f57e6a8771460ee6/dcpu_16.py https://github.com/lloeki/python-dcpu_16/blob/e78f4b8af895db... Note that this may cause some problems with evaluation order (notably in SET), as spec says a should always be evaluated before b.
- ralph 15y agoI haven't read the spec. or followed the topic in general, but from a quick glance at it: the size of the registers isn't given, and the registers aren't memory-mapped. Why not use an integer instead of Cell? 42 is memory address 42, -3 is register R, including for SP, PC, etc. Or addresses >= 0x10000 are registers, then you can just have def ife(self, a, b): m = self.mem self.skip = m[a] != m[b] with Python's native indexing of the mem[] list, which could be an array().
- jtauber 15y ago