Devine Lu Linvega <aliceffekt@gmail.com> wrote:
> First, Charlie had an AMAZING idea yesterday, that goes something like this:> > > What if you could pad by/to a label's position.> > That's it. That's the idea. But if you're like me an use lots of> structs and enums in your projects, it's kind of a pain to nest them> into each other, but this tiny change allows for things like:> > |0 @pos &x $2 &y $2 &size> |0 @player &name $2 &position $pos/size &hp $1 &mp $1> > I've started migrating Oquonie to nested enums and it's a big little> change. The implementation in drifblim was one byte longer:> > https://git.sr.ht/~rabbits/drifblim/commit/a9446ceeb63246671229496fb67d9fe828e533ed
OK, I suppose this can sometimes be helpful (so far, I have not needed such
a thing, but that doesn't mean it is not helpful at all; myself and others
can use such a thing in future if it is useful for them). I will add it to
my fork of the assembler for compatibility with standard Uxn programs.
> Before I leave, there's one thing that's been on my mind, I'm going to> put it here, but don't freak out, I'm not 100% sure that it is even> feasible yet and I realize that saying this one right after talking> about casting things in amber is doing a total disfavor to the idea> *cough* but let's carry on. So, you know how: #0012 NIP makes a byte> from a short, now imagine if #12 NIPk made a short from a byte:> > - If for destructive opcodes(NIP/POP), their keep mode distance(see> new core's SET) were flipped around.> - And a null byte was written just beyond the stack pointer.> - It would mean that these two opcodes, which, let's be honest, NOBODY> has ever used ever, would do this:> - #12 NIPk -> #0012 ( NIPk would become the mirror image of NIP, it> would transform a byte into a short, think of all the #00 SWP that> could be removed that way )> - #12 POPk -> #00 ( it would erase the byte and put a zero in its place )> > So like I said, I'm not sure if this is a possible change yet, but if> you have ideas on this, let me know.
There is some sense in it, because it is true that those opcodes are not
very useful as they are, and I agree with you that the suggested effects
seems like they would probably be useful.
However, I checked now and found that in the programs I have written (one
of which is incomplete and unpublished so far), I had never needed the
patterns you describe, so maybe it is not so important? (However, the
programs written by other people do often use such things.)
Furthermore, I think that the symmetry is also important (that some
implementations might take advantage of, and which also makes the Uxn
specification shorter and easier to understand and cleaner, which also
seems relevant), so due to this, it might not be worth it.
And then, there is the opcode names; the existing opcode names would not
be very good for the suggested changes to the meaning. If you do wish to
change this meaning in this way, then changing the name would also be good;
it would be less confusing that way.
There is also existing implementations, which can break things in this way;
although, as you say those opcodes are almost certainly not used anyways so
it is unlikely to break any existing programs (but I am not 100% certain; I
don't know if there are some unusual kinds of self-modifying code that will
calculate opcodes and have the advantage in this case, but such a thing
seems unlikely to me).
Therefore, there are arguments both ways.
--
Don't laugh at the moon when it is day time in France.
On NIP/NIPk symmetry, I've had a bit of time to test the idea since I
wrote the first email, and implement it. Don't get too attached, it
might not stay:
https://git.sr.ht/~rabbits/uxn/commit/b4fd8480edaad54fd827db5c5399fc479ca1d311
Here are the cases I looked at(but I focused my testing on Oquonie):
https://paste.sr.ht/~rabbits/330577cd5ca404deb31c121b08f0089220c055ae
The way I try to look at this is that destructive opcodes "wash off"
the data they should be POPing, so the second byte of NIPk becomes
0x00, the first byte of POPk becomes 0x00.
I found that in Oquonie, it made things faster and smaller, the
implementation doesn't seem to be slowing things down on the playdate.
The majority of "POP #00" and "#00 SWP" instances are in speed
critical loops, where I'm turning a byte into a short, so that's a big
win. I noticed that "#00 SWP" fired thousands of times per update
sometimes.
So the implementation difference is minimal, but there's an issue,
it's also why I don't think that if this change to destructive opcodes
remain that we should rename the NIP opcode. The problem is that it
doesn't "really" turn a byte into a short. To demonstrate:
#12 NIPk -> Error: Stack Underflow
In all the projects that I've tested, only one(my wiki) out of 23, had
an issue where I was using #00 SWP right in the reset vector with a
stack with only one byte(which probably is an issue of program design
more than anything) but that means that if the opcode change remains,
we can't forget that it's actually popping two items.
So, on one hand, I really like the NIP <---> NIPk symmetry that lets
me transform bytes into shorts and back. But the underflow error is a
bit weird, weird enough that I might not want to keep this.
Anyways, I'll keep experimenting with this, I'm planning to implement
this in vm.tal(beetbug/bicycle) today to see if this change is
portable to non register machine uxn core layouts.
Send me your thoughts! Thanks for reading :)
On 4/6/23, news@zzo38computer.org.invalid
<news@zzo38computer.org.invalid> wrote:
> Devine Lu Linvega <aliceffekt@gmail.com> wrote:>> First, Charlie had an AMAZING idea yesterday, that goes something like>> this:>>>> > What if you could pad by/to a label's position.>>>> That's it. That's the idea. But if you're like me an use lots of>> structs and enums in your projects, it's kind of a pain to nest them>> into each other, but this tiny change allows for things like:>>>> |0 @pos &x $2 &y $2 &size>> |0 @player &name $2 &position $pos/size &hp $1 &mp $1>>>> I've started migrating Oquonie to nested enums and it's a big little>> change. The implementation in drifblim was one byte longer:>>>> https://git.sr.ht/~rabbits/drifblim/commit/a9446ceeb63246671229496fb67d9fe828e533ed>> OK, I suppose this can sometimes be helpful (so far, I have not needed such> a thing, but that doesn't mean it is not helpful at all; myself and others> can use such a thing in future if it is useful for them). I will add it to> my fork of the assembler for compatibility with standard Uxn programs.>>> Before I leave, there's one thing that's been on my mind, I'm going to>> put it here, but don't freak out, I'm not 100% sure that it is even>> feasible yet and I realize that saying this one right after talking>> about casting things in amber is doing a total disfavor to the idea>> *cough* but let's carry on. So, you know how: #0012 NIP makes a byte>> from a short, now imagine if #12 NIPk made a short from a byte:>>>> - If for destructive opcodes(NIP/POP), their keep mode distance(see>> new core's SET) were flipped around.>> - And a null byte was written just beyond the stack pointer.>> - It would mean that these two opcodes, which, let's be honest, NOBODY>> has ever used ever, would do this:>> - #12 NIPk -> #0012 ( NIPk would become the mirror image of NIP, it>> would transform a byte into a short, think of all the #00 SWP that>> could be removed that way )>> - #12 POPk -> #00 ( it would erase the byte and put a zero in its place )>>>> So like I said, I'm not sure if this is a possible change yet, but if>> you have ideas on this, let me know.>> There is some sense in it, because it is true that those opcodes are not> very useful as they are, and I agree with you that the suggested effects> seems like they would probably be useful.>> However, I checked now and found that in the programs I have written (one> of which is incomplete and unpublished so far), I had never needed the> patterns you describe, so maybe it is not so important? (However, the> programs written by other people do often use such things.)>> Furthermore, I think that the symmetry is also important (that some> implementations might take advantage of, and which also makes the Uxn> specification shorter and easier to understand and cleaner, which also> seems relevant), so due to this, it might not be worth it.>> And then, there is the opcode names; the existing opcode names would not> be very good for the suggested changes to the meaning. If you do wish to> change this meaning in this way, then changing the name would also be good;> it would be less confusing that way.>> There is also existing implementations, which can break things in this way;> although, as you say those opcodes are almost certainly not used anyways so> it is unlikely to break any existing programs (but I am not 100% certain; I> don't know if there are some unusual kinds of self-modifying code that will> calculate opcodes and have the advantage in this case, but such a thing> seems unlikely to me).>> Therefore, there are arguments both ways.>> --> Don't laugh at the moon when it is day time in France.>
So I'm in favor of some kind of change like this, both because I do
find myself needing to do #00 SWP a fair amount and also because
POPk and NIPk are otherwise not very useful.
I think that if we made this change it might be nice to rename them to
avoid a "false" symmetry with the existing POP/NIP. I might call POPk
"NUL" (it turns the top item on the stack into zero i.e. null) and
NIPk either "PAD" (it pads the top item of the stack with a zero
behind it) or "PIN" (which is NIP in reverse).
Similarly, if we made this change it would be better to make signature
of PAD/PIN ( a -> 0 a ) instead of ( a b -> a 0 b ). Once we break
symmetry a little bit holding onto the rest of the similarity to NIP
feels confusing and unproductive.
So if we did make a change my proposal would be:
- POPk ( a^ -> a^ ) becomes NUL ( a^ -> 00 )
- POPkr ( [a^] -> [a^] ) becomes NULr ( [a^] -> [00] )
- POP2k ( a* -> a* ) becomes NUL2 ( a* -> 0000 )
- POP2kr ( [a*] -> [a*] ) becomes NUL2r ( [a*] -> [0000] )
- NIPk ( a^ b^ -> a^ b^ b^ ) becomes PAD ( a^ -> 00 a^ )
- NIPkr ( [a^ b^] -> [a^ b^ b^] ) becomes PADr ( [a^] -> [00 a^] )
- NIP2k ( a* b* -> a* b* b* ) becomes PAD2 ( a* -> 0000 a* )
- NIP2kr ( [a* b*] -> [a* b* b*] ) becomes PAD2r ( [a*] -> [0000 a*] )
Looking forward to seeing where this leads!
-- d_m
On Thu, Apr 06, 2023 at 11:04:30AM -0700, Hundred Rabbits wrote:
> On NIP/NIPk symmetry, I've had a bit of time to test the idea since I> wrote the first email, and implement it. Don't get too attached, it> might not stay:> > https://git.sr.ht/~rabbits/uxn/commit/b4fd8480edaad54fd827db5c5399fc479ca1d311> > Here are the cases I looked at(but I focused my testing on Oquonie):> > https://paste.sr.ht/~rabbits/330577cd5ca404deb31c121b08f0089220c055ae> > The way I try to look at this is that destructive opcodes "wash off"> the data they should be POPing, so the second byte of NIPk becomes> 0x00, the first byte of POPk becomes 0x00.> > I found that in Oquonie, it made things faster and smaller, the> implementation doesn't seem to be slowing things down on the playdate.> The majority of "POP #00" and "#00 SWP" instances are in speed> critical loops, where I'm turning a byte into a short, so that's a big> win. I noticed that "#00 SWP" fired thousands of times per update> sometimes.> > So the implementation difference is minimal, but there's an issue,> it's also why I don't think that if this change to destructive opcodes> remain that we should rename the NIP opcode. The problem is that it> doesn't "really" turn a byte into a short. To demonstrate:> > #12 NIPk -> Error: Stack Underflow> > In all the projects that I've tested, only one(my wiki) out of 23, had> an issue where I was using #00 SWP right in the reset vector with a> stack with only one byte(which probably is an issue of program design> more than anything) but that means that if the opcode change remains,> we can't forget that it's actually popping two items.> > So, on one hand, I really like the NIP <---> NIPk symmetry that lets> me transform bytes into shorts and back. But the underflow error is a> bit weird, weird enough that I might not want to keep this.> > Anyways, I'll keep experimenting with this, I'm planning to implement> this in vm.tal(beetbug/bicycle) today to see if this change is> portable to non register machine uxn core layouts.> > Send me your thoughts! Thanks for reading :)> > > > On 4/6/23, news@zzo38computer.org.invalid> <news@zzo38computer.org.invalid> wrote:> > Devine Lu Linvega <aliceffekt@gmail.com> wrote:> >> First, Charlie had an AMAZING idea yesterday, that goes something like> >> this:> >>> >> > What if you could pad by/to a label's position.> >>> >> That's it. That's the idea. But if you're like me an use lots of> >> structs and enums in your projects, it's kind of a pain to nest them> >> into each other, but this tiny change allows for things like:> >>> >> |0 @pos &x $2 &y $2 &size> >> |0 @player &name $2 &position $pos/size &hp $1 &mp $1> >>> >> I've started migrating Oquonie to nested enums and it's a big little> >> change. The implementation in drifblim was one byte longer:> >>> >> https://git.sr.ht/~rabbits/drifblim/commit/a9446ceeb63246671229496fb67d9fe828e533ed> >> > OK, I suppose this can sometimes be helpful (so far, I have not needed such> > a thing, but that doesn't mean it is not helpful at all; myself and others> > can use such a thing in future if it is useful for them). I will add it to> > my fork of the assembler for compatibility with standard Uxn programs.> >> >> Before I leave, there's one thing that's been on my mind, I'm going to> >> put it here, but don't freak out, I'm not 100% sure that it is even> >> feasible yet and I realize that saying this one right after talking> >> about casting things in amber is doing a total disfavor to the idea> >> *cough* but let's carry on. So, you know how: #0012 NIP makes a byte> >> from a short, now imagine if #12 NIPk made a short from a byte:> >>> >> - If for destructive opcodes(NIP/POP), their keep mode distance(see> >> new core's SET) were flipped around.> >> - And a null byte was written just beyond the stack pointer.> >> - It would mean that these two opcodes, which, let's be honest, NOBODY> >> has ever used ever, would do this:> >> - #12 NIPk -> #0012 ( NIPk would become the mirror image of NIP, it> >> would transform a byte into a short, think of all the #00 SWP that> >> could be removed that way )> >> - #12 POPk -> #00 ( it would erase the byte and put a zero in its place )> >>> >> So like I said, I'm not sure if this is a possible change yet, but if> >> you have ideas on this, let me know.> >> > There is some sense in it, because it is true that those opcodes are not> > very useful as they are, and I agree with you that the suggested effects> > seems like they would probably be useful.> >> > However, I checked now and found that in the programs I have written (one> > of which is incomplete and unpublished so far), I had never needed the> > patterns you describe, so maybe it is not so important? (However, the> > programs written by other people do often use such things.)> >> > Furthermore, I think that the symmetry is also important (that some> > implementations might take advantage of, and which also makes the Uxn> > specification shorter and easier to understand and cleaner, which also> > seems relevant), so due to this, it might not be worth it.> >> > And then, there is the opcode names; the existing opcode names would not> > be very good for the suggested changes to the meaning. If you do wish to> > change this meaning in this way, then changing the name would also be good;> > it would be less confusing that way.> >> > There is also existing implementations, which can break things in this way;> > although, as you say those opcodes are almost certainly not used anyways so> > it is unlikely to break any existing programs (but I am not 100% certain; I> > don't know if there are some unusual kinds of self-modifying code that will> > calculate opcodes and have the advantage in this case, but such a thing> > seems unlikely to me).> >> > Therefore, there are arguments both ways.> >> > --> > Don't laugh at the moon when it is day time in France.> >
>On Thu, 06 Apr 2023 10:35:11 -0700>news@zzo38computer.org.invalid wrote:>> Devine Lu Linvega <aliceffekt@gmail.com> wrote:> > So, you know how: #0012 NIP makes a byte from a short, now imagine> > if #12 NIPk made a short from a byte:> However, I checked now and found that in the programs I have written> (one of which is incomplete and unpublished so far), I had never> needed the patterns you describe, so maybe it is not so important?> (However, the programs written by other people do often use such> things.)
Funny detail, in trainleave I not only convert from 8-bit to 16,
but actually in some places use a sign-extend version of the routine for
converting from 8-bit to 16-bit. xD
@to-short ( byte -- short* )
DUP #80 LTH ,&positive JCN
#ff ,&common JMP
&positive
#00
&common
SWP
RET
This is used in routines for calculating the layout of elements on the
screen, when a 8-bit signed offset needs to be applied to a 16-bit
position.
( %ToShort { ;to-short JSR2 } )
( advance the x of the glyphs in this render unit, and ... )
STH2kr LDA ToShort
DUP2
;unicode-layout/originx LDA2k ROT2 ADD2 SWP2 STA2
( ... add up the x advance for the render unit )
;unicode-layout/advancex LDAk2 ROT2 ADD2 SWP2 STA2
BTW, I don't have a particular opinion on the proposed changes. Nesting
seems like a good idea. NIPk and POPk... I dunno, if you want to do it,
do it. However sign-extend instructions (that haven't been proposed
but if they ever do get proposed) for converting 8-bits into 16-bits are
probably a bad idea. They increase complexity of the interpreter and
probably don't add enough value to justify that.
--
Svi moji e-mailovi su kriptografski potpisani. Proverite ih.
All of my e-mails are cryptographically signed. Verify them.
--
You don't need an AI for a robot uprising.
Humans will do just fine.
--