Tabs should be allow for inside of strings, because there is reason to want them in communications with external stuff or whatever serial protocols might be needed. They just shouldn't be allowed as whitespace in code.
I just realized that with the first long of an instance's VARs being a pointer to pbase, out-of-range VAR access will quickly wreak havoc by destroying pbase pointers. This also means that general VAR space must be interspersed with pointers everywhere. It can't just all be cleared to 0's on startup. This is going to massively increase runtime sizes - unless we put some kind of initialization routine in which sprays the pointers everywhere they need to go.
Have pbase start with a long pointer to the base of all of its instances' VAR blocks. The next long tells how long each instance's VAR block is in bytes (a multiplier). Pbase data follows. Then, you only need to know the pbase address and the instance number, which can, together, fit into 32 bits {12'InstanceNumber, 20'PbaseAddress} for your object pointer.
That conserves a long per object instance, which means you can have object instance arrays which only grow exactly by their VAR space. No pointers needed throughout VAR space. Simpler and more compact. You are just limited to arrays of 4096 instances.
Chip,
Each object instance can initialize it's VAR space as needed. All the static/global ones can be done when the program first starts up, and any that get created at runtime could do it then.
The VAR spaces can be all zeros at startup.
Wouldn't such a routine be just like the clear to zero one? A bit of housekeeping before the program starts?
That's not such a bad thing. If a really fast startup is needed, people can use PASM, or optimize their program.
As for out of range, it's arguably worse havoc, but still havoc anyway, pointers or not. Either there is the penalty of bounds checking during run time, or we are back to putting the pointers somewhere safer and in need of the big pointer again...
I don't like packing the pointer like you describe, that limits the size of overall memory in the future and the number of instances. Future chip versions could have more memory, and then this won't work.
We can setup the pbase pointer in the var space before it ever gets used.
Chip,
Each object instance can initialize it's VAR space as needed. All the static/global ones can be done when the program first starts up, and any that get created at runtime could do it then.
The VAR spaces can be all zeros at startup.
Wouldn't that take special code in each object? Or, it's a chicken-and-egg problem, it seems.
Depends on what the object is for, I can see wanting many instances of objects in some cases. You are correct that a typical object from P1 is unlikely to need many instances, but given this new ability, different types of object could be made that might want lots of instances.
Depends on what the object is for, I can see wanting many instances of objects in some cases. You are correct that a typical object from P1 is unlikely to need many instances, but given this new ability, different types of object could be made that might want lots of instances.
I could see some math/variable object having 50k instances, since it was coded to exploit object behavior, as opposed to needing to think about arrays of pure data.
Chip,
To be clear, what we are talking about is exactly like vtable pointers in C++. Those get initialized when the object instance is declared. So, the ones in VAR spaces would be global and initialized when the program first starts, and when a function starts and has one as a local it would be at the start of the function to init the pointer in the var space for the object instance.
Also, we only need this extra pointer in the VAR space for objects are are declared with the TYPE (or = ) thing.
OBJ
a : "ObjectA" 'object instance
b = "ObjectB" 'object type
Interesting thing about having vbase start with a pbase pointer, and having object 'types' is that you could create new objects at any time in VAR space.
Interesting thing about having vbase start with a pbase pointer, and having object 'types' is that you could create new objects at any time in VAR space.
Chip,
To be clear, what we are talking about is exactly like vtable pointers in C++. Those get initialized when the object instance is declared. So, the ones in VAR spaces would be global and initialized when the program first starts, and when a function starts and has one as a local it would be at the start of the function to init the pointer in the var space for the object instance.
With garbage cleanup, we could have infinite dynamic object creation/destruction. Having some stuff done automatically is kind of like babying the programmer. It could ALL be manual, couldn't it?
Chip,
Are you serious?! :P Garbage cleanup is not the answer, ever! :P
C++ native does not do that, it does have a heap with allocation and freeing, but that isn't required either for this feature.
If you are really against the pointer in the VAR space, then the other solution with big pointers for objects that have both the pbase and the vbase in them would work. It's not something that needs to be exposed to the users though, they just have the pointer type and assign it an object instance and we take care of the details. instead of the type being OBJ, maybe POBJ?
Interesting thing about having vbase start with a pbase pointer, and having object 'types' is that you could create new objects at any time in VAR space.
Like say, fetch them from storage?
You have OBJ's and their related VAR's. They could be completely set up and taken down and run time. Maybe there's some REPL possibility here?
Also, we only need this extra pointer in the VAR space for objects are are declared with the TYPE (or = ) thing.
OBJ
a : "ObjectA" 'object instance
b = "ObjectB" 'object type
Interesting thing about having vbase start with a pbase pointer, and having object 'types' is that you could create new objects at any time in VAR space.
Chip,
Are you serious?! :P Garbage cleanup is not the answer, ever! :P
C++ native does not do that, it does have a heap with allocation and freeing, but that isn't required either for this feature.
If you are really against the pointer in the VAR space, then the other solution with big pointers for objects that have both the pbase and the vbase in them would work. It's not something that needs to be exposed to the users though, they just have the pointer type and assign it an object instance and we take care of the details. instead of the type being OBJ, maybe POBJ?
I really like the vbase-starts-with-pbase idea, as it provides a means for stuff to happen completely dynamically, doesn't it? Heap/garbage, I probably don't know what I'm talking about.
Also, we only need this extra pointer in the VAR space for objects are are declared with the TYPE (or = ) thing.
OBJ
a : "ObjectA" 'object instance
b = "ObjectB" 'object type
Interesting thing about having vbase start with a pbase pointer, and having object 'types' is that you could create new objects at any time in VAR space.
Heaps can work several different ways. Typically you have a block of memory that is the heap, and it's managed as a set of allocated blocks and a linked list of free blocks. Initially you have a single free block entry that is all of the memory, then as you allocate you find a large enough free block and divide the free block into two pieces one for the allocation and the other to stay in the free list (or just use the whole block for the allocation if it's fits. Later, If you free a block you add it to the free list. You can do some extra work at free time to combine consecutive free blocks.
There are other more advanced schemes that try to reduce fragmentation, etc. I'm not sure we need a heap for Spin. We can just have global scope (in VARs) object instances all be pre allocated. And dynamic ones can be either locals in the stack, or the user can provide a buffer space for it (like using a byte array VAR space to hold dynamic instances of a given object type).
Chip,
YES! dynamic creation of object instances as locals (so on the stack) or into a given buffer of memory. There's lots of potential here.
That would be awesome and it's pretty simple. It just needs to be understood by the programmer, without throwing him into the deep end of the pool.
I think all that needs to be explained is that an OBJect has code and a set of VARiables that can be instantiated in any number to create "instances". Each instance contains a pointer to the OBJect and the VARiables follow. We could have some simple constructor mechanism, but what about a destructor? In the case of local variables being the context, it doesn't matter, but in parental VAR space, there might be some impetus to recycle memory.
Heaps can work several different ways. Typically you have a block of memory that is the heap, and it's managed as a set of allocated blocks and a linked list of free blocks. Initially you have a single free block entry that is all of the memory, then as you allocate you find a large enough free block and divide the free block into two pieces one for the allocation and the other to stay in the free list (or just use the whole block for the allocation if it's fits. Later, If you free a block you add it to the free list. You can do some extra work at free time to combine consecutive free blocks.
There are other more advanced schemes that try to reduce fragmentation, etc. I'm not sure we need a heap for Spin. We can just have global scope (in VARs) object instances all be pre allocated. And dynamic ones can be either locals in the stack, or the user can provide a buffer space for it (like using a byte array VAR space to hold dynamic instances of a given object type).
Makes sense. I really like the idea of dynamically created and destroyed objects. You could even have a heap for OBJects, couldn't you? Maybe that's unnecessary, but it would allow for really big programs, where OBJects get pulled in from memory, as needed.
Comments
Right. That would have been a mess.
-Phil
I think so too. This is super clean.
Have pbase start with a long pointer to the base of all of its instances' VAR blocks. The next long tells how long each instance's VAR block is in bytes (a multiplier). Pbase data follows. Then, you only need to know the pbase address and the instance number, which can, together, fit into 32 bits {12'InstanceNumber, 20'PbaseAddress} for your object pointer.
That conserves a long per object instance, which means you can have object instance arrays which only grow exactly by their VAR space. No pointers needed throughout VAR space. Simpler and more compact. You are just limited to arrays of 4096 instances.
Each object instance can initialize it's VAR space as needed. All the static/global ones can be done when the program first starts up, and any that get created at runtime could do it then.
The VAR spaces can be all zeros at startup.
That's not such a bad thing. If a really fast startup is needed, people can use PASM, or optimize their program.
As for out of range, it's arguably worse havoc, but still havoc anyway, pointers or not. Either there is the penalty of bounds checking during run time, or we are back to putting the pointers somewhere safer and in need of the big pointer again...
Unless there is another solution?
We can setup the pbase pointer in the var space before it ever gets used.
Wouldn't that take special code in each object? Or, it's a chicken-and-egg problem, it seems.
So that's 8 bits in a BYTE, 32 bits in a WORD, 64 bits in a LONG, and 128 bits in an OBJ?
What do people use for 16 bits?
I could see some math/variable object having 50k instances, since it was coded to exploit object behavior, as opposed to needing to think about arrays of pure data.
BYTE = 8 bits
WORD = 16 bits
LONG = 32 bits
OBJ = was going to be 64 bits (needs another name to not trigger OBJ block)
To be clear, what we are talking about is exactly like vtable pointers in C++. Those get initialized when the object instance is declared. So, the ones in VAR spaces would be global and initialized when the program first starts, and when a function starts and has one as a local it would be at the start of the function to init the pointer in the var space for the object instance.
Interesting thing about having vbase start with a pbase pointer, and having object 'types' is that you could create new objects at any time in VAR space.
Like say, fetch them from storage?
With garbage cleanup, we could have infinite dynamic object creation/destruction. Having some stuff done automatically is kind of like babying the programmer. It could ALL be manual, couldn't it?
Are you serious?! :P Garbage cleanup is not the answer, ever! :P
C++ native does not do that, it does have a heap with allocation and freeing, but that isn't required either for this feature.
If you are really against the pointer in the VAR space, then the other solution with big pointers for objects that have both the pbase and the vbase in them would work. It's not something that needs to be exposed to the users though, they just have the pointer type and assign it an object instance and we take care of the details. instead of the type being OBJ, maybe POBJ?
You have OBJ's and their related VAR's. They could be completely set up and taken down and run time. Maybe there's some REPL possibility here?
or create them as local vars to a method!
I really like the vbase-starts-with-pbase idea, as it provides a means for stuff to happen completely dynamically, doesn't it? Heap/garbage, I probably don't know what I'm talking about.
Oh, that's crazy. I like that!
Garbage collection is what makes everything herky-jerky. Every modern system seems to suffer from it.
How does a heap work? Does it just build and build, with interstitial gaps forming as stuff gets canceled?
YES! dynamic creation of object instances as locals (so on the stack) or into a given buffer of memory. There's lots of potential here.
There are other more advanced schemes that try to reduce fragmentation, etc. I'm not sure we need a heap for Spin. We can just have global scope (in VARs) object instances all be pre allocated. And dynamic ones can be either locals in the stack, or the user can provide a buffer space for it (like using a byte array VAR space to hold dynamic instances of a given object type).
That would be awesome and it's pretty simple. It just needs to be understood by the programmer, without throwing him into the deep end of the pool.
I think all that needs to be explained is that an OBJect has code and a set of VARiables that can be instantiated in any number to create "instances". Each instance contains a pointer to the OBJect and the VARiables follow. We could have some simple constructor mechanism, but what about a destructor? In the case of local variables being the context, it doesn't matter, but in parental VAR space, there might be some impetus to recycle memory.
Makes sense. I really like the idea of dynamically created and destroyed objects. You could even have a heap for OBJects, couldn't you? Maybe that's unnecessary, but it would allow for really big programs, where OBJects get pulled in from memory, as needed.