2023-05-13 02:19:19 I like free code 2023-05-13 02:19:27 Like : FREE ... ; 2023-05-13 02:20:01 you can have your memory address and free it too 2023-05-13 02:23:45 I think 8K is a reasonable standard for 8-bit forths, modern arch's are just larger so will be closer to 16K just because of that 2023-05-13 02:23:51 The instructions are just larger 2023-05-13 02:24:12 Your average Z80 instruction is what... 2 bytes. Average x86 is more like 4 bytes. 2023-05-13 02:24:38 And how much do we gain with smarter instructions like mul... not much, if you only have one or two multiply routines written 2023-05-13 02:25:01 I guess it's also because you expect more features on a modern computer as well, though 2023-05-13 02:25:22 also them pointers are kinda big on 64-bit 2023-05-13 02:25:25 My Z80 Forth is just under 8K right now 2023-05-13 02:25:45 Yeah but you don't put a lot of 64-bit literals in x86-64 2023-05-13 02:26:07 It's mostly 32-bit displacements 2023-05-13 02:26:31 But on 64-bit a lot of registers need a prefix byte to use 2023-05-13 07:00:41 That's exactly how mine is made. 32-bit "innards," but 64-bit data stacks / cell size. 2023-05-13 07:41:34 This slows things down a little, since when I pick up those 32-bit items I have to convert them into 64-bit addresses before using them. The implementation got going this way in my case because it was the only way I could make it work on MacOS. 2023-05-13 07:42:27 In this new one, though, this is exactly why I'm considering 64-bit table entries - I'll just convert the initial table of offsets into a table of 64 bit addresses all in one shot. Or, I could have 32-bit table entries and convert them as needed during execution. 2023-05-13 07:46:56 I thought a little more about builds> does>. I think builds> needs to allocate that extra pfa field in the new word's header and aim it at the does> code. But when builds> is compiled, we don't know where that is yet. 2023-05-13 07:47:46 So builds> will just execute a literal and store it's value into that field. When does> is compiled, we'll now know where that code is going to be, so it'll need to back-edit the value of the literal. 2023-05-13 07:48:04 A bit of self-modifying code. 2023-05-13 07:48:13 veltas: I have wondered about code size a lot lately. I remember you posted a link once about older architectures. any idea which ones compile to small C code? 2023-05-13 07:48:41 someone also posted a comparison of modern architectures (ARM etc) compiling mysql. surprisingly little different in size between those 2023-05-13 07:52:02 I think this means builds> will look something like this: 2023-05-13 07:54:24 : builds> 0 literal h, create (does) cfa! ; 2023-05-13 07:54:42 cfa! is a word that takes the value on the stack and stores it in the cfa field of the most recently created word. 2023-05-13 07:55:05 (does) is just a literal that gives the runtime of the code that handles such words. 2023-05-13 07:55:37 does> will actually go back and change the value of that initial literal, so that when that code actually runs it puts the right value in the extra pfa slot. 2023-05-13 07:56:32 The (does) runtime will do exactly what the variable runtime does, save IP on the return stack, and aim IP using the extra pfa slot. 2023-05-13 08:04:00 So basically "dodoes" will just do dovar using the pfa that CREATE makes, followed by docol using the extra pfa. 2023-05-13 08:12:03 MrMobius: I would guess biggest consideration for small C code is how efficient stack manipulation and access is 2023-05-13 08:12:39 Which I don't know an 8-bit arch which is particularly good at this honestly, I don't think Z80 or 6502 are 2023-05-13 08:13:30 Z80's good for push/pop but its indexed access of the stack is quite verbose, and adding/subtracting more than 2 from stack involves multiple instructions 2023-05-13 08:13:41 Ya probably for those 8 bitters. I think the RISC arches get away with very little stack access 2023-05-13 08:14:02 True 2023-05-13 08:15:07 Of course, you could also change the kind of C code you write, use more globals etc 2023-05-13 08:18:44 and static instead of automatic variables wherever possible 2023-05-13 08:19:09 Yeah, depending on what you're doing 2023-05-13 08:20:47 and maybe write everything to avoid using passing arguments to functions altogether 2023-05-13 08:20:55 -using 2023-05-13 08:21:46 The most effective use of space would probably be generating some kind of threaded runtime to do all this more succinctly than the native arch will 2023-05-13 08:23:32 that makes sense. and if you really wanted to cheap out on stack access, maybe you could ditch the concept of functions altogether and just rely on labels + gotos. with all of the code written in main(), or maybe even better would be _start itself 2023-05-13 08:46:09 My mandatory extra time is over now so I'm celebrating by doing some ilo-amd64 debugging 2023-05-13 08:46:35 And I think I'll make some pizza later, got stuff for the dough and all that 2023-05-13 09:08:21 prepare the dough yourself? 2023-05-13 09:09:02 flour, water, salt, yeast time (and a bit of effort). maybe oil if you're going for a thin crust, etc 2023-05-13 09:11:07 one of those things that has a few ingredients but a ton of variables 2023-05-13 09:12:11 hydration %, choice/lack of fat, rising time, type of oven used, etc. 2023-05-13 09:12:50 unjust: Yes 2023-05-13 09:13:38 You can control those variables a bit if you use the right proportions, timings, and the same oven each time 2023-05-13 09:14:13 I am not tasteful enough to tell though, I just pull it thin and cook it till it's crispy 2023-05-13 09:14:17 it's cool to experiment with that, i've had drastically different results just between ovens used though 2023-05-13 09:14:31 Yeah but to be fair there are a lot of really shit ovens out there 2023-05-13 09:14:40 Ovens that will just leave half your food raw all day 2023-05-13 09:15:52 i've found the shit ones require a different cooking technique, rather than "baking" as such 2023-05-13 09:16:20 ie. using the grill (or broiler?) element and a steel baking sheet 2023-05-13 09:20:03 I do feel though at the end of the day, if it's got the right stuff in it then it should taste nice 2023-05-13 09:20:13 It might not be quality every time but it will be decent 2023-05-13 09:20:36 as long as it's cooked enough, definitely 2023-05-13 09:20:36 I got some pepperoni for it too, not sure what I was thinking about there 2023-05-13 09:21:10 I should have got some real meat but f*** it I'm sure it will be nice anyway 2023-05-13 10:39:23 Well, this code needs to be cleaned and tidied a little, but it appears to work: 2023-05-13 10:39:27 https://pastebin.com/AWBhnu19 2023-05-13 10:40:04 I tested it with this: 2023-05-13 10:40:17 : varecho builds> 8 dp.b +! does> 64 emit ; 2023-05-13 10:40:56 And that just declares a variable such that an @ is emitted each time the variable word is run. 2023-05-13 10:41:23 I'm missing some words that would make it cleaner. 2023-05-13 10:41:52 I haven't paid much attention to this portion of the system so far, so I just don't have all the "graceful words" for such things yet. 2023-05-13 10:42:20 Specifically around definitions that add code to the dictionary themselves. 2023-05-13 10:42:52 Not shown is that "dodoes" runtime I described earlier. 2023-05-13 10:43:16 But it's literally exactly what I said - it expects two pfas, and dovars one of them and docols the other. 2023-05-13 10:57:17 Yeah that is a bit cleaner than CREATE/DOES> 2023-05-13 10:57:30 In that you can (presumably?) remove the overhead from CREATE 2023-05-13 10:58:08 Although there is some advantage with CREATE/DOES> that you can call CREATE at any time in the DOES> word, or out of it 2023-05-13 10:59:26 Yes, that's true. I need to have builds> first, so that that literal that gets backpatched is in a known location. 2023-05-13 10:59:58 But those words, builds> and does>, have a symmetry and both sort of look like "introductions" to what comes next. 2023-05-13 11:00:57 Now I want to give some thought to the messy aspects and see if I can arrive at something cleaner. 2023-05-13 11:01:52 I know in traditional forth I'd have something like "compile h, compile create..." 2023-05-13 11:02:06 But I don't really love that either - if you do much of anything it gets long. 2023-05-13 11:03:20 It would be nice to be able to say something like "comp{ x:beef h, create does cfa! }" 2023-05-13 11:03:57 But that makes comp{ a whole compiler loop of its own. 2023-05-13 11:27:56 I usually have something like that, and it's not a sophisticated loop 2023-05-13 11:28:12 It's just "COMPILE, this until }" 2023-05-13 11:28:33 I actually do it with POSTPONE but I'll admit POSTPONE is a bit gross 2023-05-13 11:29:38 Yeah, it's on Chuck's no likey list. 2023-05-13 11:31:40 I don't really get its point, it's actually kind of confusing to use, and harder to implement 2023-05-13 11:45:37 I don't think I've ever implemented it. 2023-05-13 11:45:42 Say, I watched this last night: 2023-05-13 11:45:45 https://www.youtube.com/watch?v=NAIzQFZACcw 2023-05-13 11:45:49 It was pretty good. 2023-05-13 11:46:40 I *usually* enjoy Statham movies. He's made a few that get a little ridiculous, but more often than not they're entertaining. 2023-05-13 11:48:14 Also, for a movie (not Statham - this one's got Clive Owen) that actuall does cross over into ridiculous but still manages to be good, check out "Shoot 'Em Up." 2023-05-13 11:48:40 It's over the top beyond the bounds of believability, but somehow I liked it. 2023-05-13 11:48:58 Kind of like when a joke is good BECAUSE it's unbelievably corny. 2023-05-13 11:49:41 Shoot 'Em Up manages to jump the shark so far that it's impressive. 2023-05-13 12:14:10 Also, if I were going to implement postpone, I'd certainly seek a shorter name. 2023-05-13 12:14:23 A symbol, if possible. 2023-05-13 12:29:00 plenty of kanji to pick from 2023-05-13 12:30:20 I believe 您的法典夫不好 is a traditional greeting among progammers 2023-05-13 12:48:05 :-) I'd more likely go with something readily accessible on my keyboard. I've got a bunch of apl chars. 2023-05-13 12:49:27 ya got a space cadet keyboard? 2023-05-13 12:50:04 I forget exactly how I activated the mode it's in now. It took a little research, but in the end wasn't that hard. 2023-05-13 12:50:17 thrig: I can understand why you appreciate vi 2023-05-13 12:50:31 actually its keybindings are good once you get used it 2023-05-13 12:50:41 I like how mnemonic are ^ and $ 2023-05-13 12:50:44 :D 2023-05-13 12:51:23 but I'm used to emacs and I try to use emacs bindings instead, which is annoying 2023-05-13 12:51:37 appreciate, or have yet another bug report in to OpenBSD about vi 2023-05-13 12:51:40 anyways I can see that vi is actually very good 2023-05-13 12:52:09 thrig: what bug? seems to work fine on netbsd 2023-05-13 12:52:24 the whole thing about vi is the router died when I was reinstalling netbsd 2023-05-13 12:52:41 so I was stuck with posix tools + ctwm and I had to survive 2023-05-13 12:52:41 xD 2023-05-13 12:52:42 can you search backwards for ? with "set extended" enabled? 2023-05-13 12:54:23 RE error: repetition-operator operand invalid 2023-05-13 12:54:25 this? 2023-05-13 12:54:44 I can 2023-05-13 12:54:49 that bug 2023-05-13 12:54:53 with \\? 2023-05-13 12:54:57 and N 2023-05-13 12:55:11 /\? 2023-05-13 12:55:32 I've set extended, which idk what is 2023-05-13 12:55:48 but for search backwards you meant N? 2023-05-13 12:55:58 I mean is just to /\? and N 2023-05-13 12:56:12 I can iterate trough them with n and N 2023-05-13 12:56:45 this error only appears if I don't escape ? with \ 2023-05-13 12:56:58 so not a bug 2023-05-13 12:57:22 vi is actually cool 2023-05-13 12:57:29 this is nvi from netbsd base 2023-05-13 12:57:40 idk how much differs from openbsd's base vi 2023-05-13 12:57:59 it's a bug. ?\? causes an error message. /\? and then N might wrap you around and then you're on some wrong match 2023-05-13 12:58:37 I'm just used to emacs and I'm not willing to change, but at the end vi seems much better than emacs in almost all senses 2023-05-13 12:58:45 and I hate emacs xD 2023-05-13 12:59:02 I also discovered awk in my posix journey 2023-05-13 12:59:09 I kind of love it 2023-05-13 12:59:22 I see it as a overpowered input switch case 2023-05-13 12:59:27 and a better lex 2023-05-13 13:00:28 I was going to learn awk long time ago because I thought as a unix user wanting to "master" unix I should learn awk along with the other posix tools 2023-05-13 13:00:51 but I chose perl instead because it was like an evolved awk, and even had awk and sed emulation 2023-05-13 13:01:05 the only benefit of awk seemed to be posix 2023-05-13 13:01:26 which is a huge one actually, but perl is/was omnipresent 2023-05-13 13:01:49 but now that I see a bit of awk, I love how it is 2023-05-13 13:02:05 nope I have had to install perl on systems that did not have it 2023-05-13 13:02:20 Zarutian_iPad: yeah, that's the main benefit of awk over perl 2023-05-13 13:02:32 awk is part of posix, so any posix compliant system will have it 2023-05-13 13:02:47 awk isn't really portable, or the posix subset is... eh, I'll just install perl 2023-05-13 13:02:51 also vi, but some linux distro seem to not have it 2023-05-13 13:03:06 thrig: I see awk as a better lex 2023-05-13 13:03:22 and it kind of resonates with my goal, which is to end having a transpiler 2023-05-13 13:03:38 a half transpiler, half interpreter 2023-05-13 13:03:53 the ultimate goal being a cross transpiler 2023-05-13 13:04:18 cross langage transpiler* 2023-05-13 13:04:23 lang* 2023-05-13 13:04:24 xD 2023-05-13 13:04:53 I always liked the idea of sticking to posix and the unix philosophy 2023-05-13 13:05:25 which is mainly to glue commands, and the shell is the embodiment of that philosophy, even if it sucks as a general purpose language 2023-05-13 13:06:10 I like the way you can make a piece of a program in any language you choose and it will cooperate perfectly with other pieces no matter what those pieces are or come from 2023-05-13 13:07:45 the shell does that, but it lacks stuff you would expect from a general purpose language 2023-05-13 13:08:16 if you stick to posix, awk looks like the best candidate 2023-05-13 14:14:33 Well, got that new Raspberry Pi set up in the media room. It's doing the "big post-install package update" now. 2023-05-13 14:14:45 Which is very big, because I've had it sitting on the shelf for quite a while. 2023-05-13 15:24:44 awk doesn't get enough credit 2023-05-13 15:44:12 that's probably because most people never learn to use it beyond just printing a single column 2023-05-13 16:37:47 I installed the default OS that the Pi bundle recommended, and then installed Kodi. 2023-05-13 16:38:11 Kodi is fairly nice. Slick interface. 2023-05-13 16:39:59 The hard drive I used with the old Pi is still up there - I just plugged it in and all the old content is still ready to roll. 2023-05-13 16:40:14 Took me a minute to figure out how to get Kodi to scan it. 2023-05-13 18:52:33 https://termbin.com/4frxg 2023-05-13 18:52:41 a rpn interpreter in awk 2023-05-13 18:52:42 xd 2023-05-13 18:52:56 the clauses are the dictionary 2023-05-13 18:53:16 awk -f this.file 2023-05-13 18:53:19 1 2 3 + .s 2023-05-13 18:53:50 for some reason in my machine it won't execute the last word unless I put a space at the end of the line or give it another line 2023-05-13 18:55:19 the last line is wrong I guess 2023-05-13 19:09:17 does not work in mawk or gawk xD 2023-05-13 19:10:06 https://termbin.com/9sui this works in gawk and nawk, but not mawk 2023-05-13 19:10:45 mawk can't length(array) so I'll avoid that from now on 2023-05-13 19:11:23 it needs a trailing space to execute the last word of every line cause I'm messing with RS 2023-05-13 19:11:52 instead of reading by lines I'm making it read by words, so every regex will try to match for every word 2023-05-13 19:19:29 there's that pesky awk portability 2023-05-13 20:26:40 You know, the thing that makes this create> does> stuff hard is that when you're doing normal compilation, you just copy information direction from the source stream to the compile stream. You don't have to save it in any way; it's a direct transcription. 2023-05-13 20:27:12 But create does> inserts another layer in there where you no longer have access to the source but you're not ready to emit compiled code yet. 2023-05-13 20:28:10 So the whole hasdle is figuring out how to hold that information in the intermediate layer, and the fairly obvious way to do it is as a stream of literals in the intermediate layer. 2023-05-13 20:28:43 So that more or less doubles the volume, because you have to have not only the information items themselves but also the literal prefixes. 2023-05-13 20:29:07 hmm? I thought those two resulted in compiled code when the word contained them was compiled 2023-05-13 20:30:07 Well, what I'm noting is that in that middle layer you no longer have the source but you're also not ready to write the final stuff. You have to create an intermediate stream. 2023-05-13 20:30:49 if you are doing partial evaluation or constant propagation, no? 2023-05-13 20:32:09 iirc in eForth when create> runs at the time the containing word runs it does a few things: 2023-05-13 20:32:21 In my case I am calling out words at level 0, and I want level 1 to compile those words into level 2. 2023-05-13 20:32:59 So level 1 still has to have some record of them, which winds up being (in my case) a stream of literals / , pairs. 2023-05-13 20:33:10 1. read the next word “token” from the input stream 2023-05-13 20:33:36 2. create a dictionary entry 2023-05-13 20:33:38 Level 0 has to write those literal / , pairs into level 1, so that when level 1 runs it will , those items into the code stream. 2023-05-13 20:33:55 It's not hard to see what has to be done, it's just awfully tedious. 2023-05-13 20:34:03 And somewhat bulky. 2023-05-13 20:34:30 3. and leaves the HERE of the cell just after that dictionary entry header 2023-05-13 20:35:18 often a (does) or (jmp) gets put in front of that 2023-05-13 20:35:28 I'm not puzzled about how to do it. I'm just seeing it for what it is now that I've thought about it for a day. 2023-05-13 20:35:51 It's harder to factor that middle layer of code. 2023-05-13 20:36:46 then does> takes that HERE and patches in there the address following the does> and then it does an EXIT 2023-05-13 20:37:07 Yes - I've had it working since late morning. 2023-05-13 20:37:20 Spent the afternoon trying to make it "clean and tidy," and that's a whole different story. 2023-05-13 20:37:37 -end of eForth explanation of how it does create> does> - 2023-05-13 20:37:42 And I've just been mulling over WHY it's hard to make it clean and tidy. 2023-05-13 20:38:18 My definitions of builds> and does> are around twice as long as I like for my definitions to be. Not quite, but almost. 2023-05-13 20:38:29 but then there is tricks of using EVAL and literal string and such. 2023-05-13 20:39:10 Yeah, just as I was typing my first message a few minutes ago I was wondering if some completely different approach, where I stored something in a string / buffer would work better. 2023-05-13 20:39:16 Haven't really delved into it enough to know yet. 2023-05-13 20:39:50 I.e., does that middle layer HAVE to be pure code? 2023-05-13 20:39:52 Maybe not. 2023-05-13 20:40:31 but I prefer the name builds> instead of create> 2023-05-13 20:41:15 why? because the word that has builds> in it is actually ‘building’ a definition when it is run 2023-05-13 20:42:53 it is that the definition it is building has an call to the address following the does> 2023-05-13 20:43:34 heck you can have a building word that builds building words 2023-05-13 20:44:03 confusing as hell to read first time around though 2023-05-13 20:44:12 I like builds> too. 2023-05-13 20:45:35 note though I only ported eForth to dcpu16 but I understood quite a lot of how it works afterwards 2023-05-13 20:45:49 As veltas pointed out earlier, though, I have to have builds> first in the definition. 2023-05-13 20:46:00 really? 2023-05-13 20:46:26 Just because of my design. 2023-05-13 20:46:57 builds> has a literal field in it that gets modified by does> 2023-05-13 20:47:05 does> has to be able to know where it is. 2023-05-13 20:47:29 : ble 42 builds> >R , R> does> @ ; \ should work 2023-05-13 20:47:49 I'm referring only to the design I wrote this morning. 2023-05-13 20:47:59 oh, I see. 2023-05-13 20:48:06 : builds> 0 lit [h,] b, [create] b, (does) lit [cfa!] b, ; immed 2023-05-13 20:48:20 That 0 right at the beginning gets changed later by does> 2023-05-13 20:48:33 I see 2023-05-13 20:48:38 Since does> knows where the code following does> is going to be. 2023-05-13 20:49:30 builds> allocates an extra pfa field before running create. that spare pfa gets set to the address of the post does> code. 2023-05-13 20:49:41 the eForth version does it like how the control structure words do it, only not immediately nor at compile time. 2023-05-13 20:50:09 So when builds> RUNS, it gets that address onto the stack and ,'s it into the spare pfa field. 2023-05-13 20:50:14 you have to think of when builds> is to run 2023-05-13 20:50:32 Yes - and I think all of this is right on the margin of our ability to keep up with in our head. 2023-05-13 20:50:57 and that way you gave looks way too complicated 2023-05-13 20:51:17 Haven't thought of anything better yet. 2023-05-13 20:51:28 The informatoin flow is as low as it can be. 2023-05-13 20:51:40 Builds> has to know how to build the final word's header. 2023-05-13 20:51:53 And when builds> is compiled, the information isn't available yet. 2023-05-13 20:51:58 naah, the other kind if programming I like to do is asynchronous eventual sends kind of stuff that breaks the brains of most folks 2023-05-13 20:52:02 It's not available until does> is compiled. 2023-05-13 20:52:35 So there has to be somekind of "comm channel" from does> compile time to builds> runtime. 2023-05-13 20:52:51 And in my case it's the data field of that literal. 2023-05-13 20:53:26 I think you could get away with builds> not being an immediate word 2023-05-13 20:53:36 It's not that different from how you can't finish compiling IF until you come to then. In that case the stack is the channel. 2023-05-13 20:53:59 But I can't use the stack for this, because there's no telling what will happen in between does> compile and builds> run. 2023-05-13 20:54:04 but I do not know how you lay out your dictionary entries 2023-05-13 20:54:15 Can't count on a balanced stack across that interval. 2023-05-13 20:54:39 pfa cfa link count name 2023-05-13 20:54:57 So for these words, it's pfa2 pfa1 cfa link ... 2023-05-13 20:55:15 When the final word runs, the runtime does dovar on pfa1 and docol on pfa2. 2023-05-13 20:55:42 pfa is what again? 2023-05-13 20:56:11 (too many acronyms I know) 2023-05-13 20:56:22 It's a historical term - I've always assumed it stood for "parameter field address." It's the field that points to the actual definition list of a colon definition. 2023-05-13 20:56:34 oh I see 2023-05-13 20:56:37 Whereas cfa points to the machine code that gets run. 2023-05-13 20:57:07 In old FIG systems the pfa wasn't a "pointer" like it is in my system - the "parameter field" just immediately followed the code pointer. 2023-05-13 20:57:38 I'm happy with the things that get "allowed" by making it a pointer instead, though. 2023-05-13 20:57:45 eForth fig-forth style dispenses with both pfa and cfa 2023-05-13 20:57:55 For example, this solution of builds> does> - I couldn't do it like htis in a FIG design. 2023-05-13 20:58:10 I also couldn't fall from one definition into the next just by leaving out the return. 2023-05-13 20:58:18 Because that next word's header would be in the way. 2023-05-13 20:58:33 FIG had the headers mixed in with the rest. 2023-05-13 20:58:43 eforth fig-forth style dict entry: link count name actual-code 2023-05-13 20:58:43 But it is the absolute minimum storage way to do it. 2023-05-13 20:59:00 FIND returns a pointer to the word's CFA. 2023-05-13 20:59:18 Kind of nice for primitives because I can leave the pfa out entirely. 2023-05-13 21:00:33 oh, you not doing direct threaded code but indirect threaded code? 2023-05-13 21:02:40 plus the eForth variant I ported had originally split dictionary of the kind: cfa link count name 2023-05-13 21:03:15 but HERE never pointed into that but in the code section of program memory 2023-05-13 21:04:03 this allows for words execution falling through to the next defined word code 2023-05-13 21:04:45 but made SEE much slower and did not allow for nested definitions 2023-05-13 21:15:54 so the dict entry variant I ended up with was: (jmp) ble link count&flags name count actual-code 2023-05-13 21:16:11 Mine's indirect threaded - right. 2023-05-13 21:16:24 I wrote one direct threaded system, once, but otherwise have only ever written indirect ones. 2023-05-13 21:16:28 I just like it better. 2023-05-13 21:16:37 Feels more "graceful" to me. 2023-05-13 21:17:07 I have two HERE's. 2023-05-13 21:17:21 One for the "code" region, and one for the "headers and pointers" region. 2023-05-13 21:17:29 My CFA and PFA pointers are in the word headers. 2023-05-13 21:17:57 I'm changing that on this next one though - they're going to get regions of their own. I'll have a CFA table and a PFA table, and the headers will call out an index into those tables. 2023-05-13 21:18:06 The tables will point into the code region. 2023-05-13 21:18:18 Where machine code and definitions will both reside. 2023-05-13 21:18:37 it feels too much execution overhead to me but then again I am targetting fcpu-16 which is meant to be implemented as sequential boolean logic circuit run ontop of secure multi party computation 2023-05-13 21:18:49 But I'll try to keep code and definitions as separate as possible, mostly just by defining all of my primitives first. 2023-05-13 21:19:47 so your builds> just need to communicate the address of the pfa of the word it is building to the does> ? 2023-05-13 21:20:01 It is less performant (usually - I've seen exceptions on some old processors), but it's still quite fast, and I figure if I need to squeeze out that last bit of performance I can write inner loops in custom assembly. 2023-05-13 21:20:08 I want to have a very good profiling system. 2023-05-13 21:20:26 And I kind of know how I plan to implement that already. 2023-05-13 21:21:13 Actually the NEXT for this next system will only be two instructions. 2023-05-13 21:21:24 One's a complex instruction, though, with fancy addressing. 2023-05-13 21:22:21 ACTION awaits an answer 2023-05-13 21:23:32 So the code that gets executed by the final word begins immediately after the does>. We don't know where that is until we are compiling does. But builds> needs it when it runs. 2023-05-13 21:23:59 So builds> calls out a literal; i.e., in the code stream, in a known fixed location. 2023-05-13 21:23:59 and when does builds> run? 2023-05-13 21:24:14 does> overwrites that literal value with the code address. 2023-05-13 21:24:27 Then when builds> RUNS it puts that value into the extra pfa field of the final word. 2023-05-13 21:24:52 I won't claim it's the perfect solution, but I don't think it's too far from ideal. 2023-05-13 21:24:58 from minimal, that is. 2023-05-13 21:25:22 I am telling ya builds> does not need to be an IMMEDIATE word 2023-05-13 21:25:37 The final resting place of that information, the final word's second pfa field, doesn't EXIST until builds> runtime. 2023-05-13 21:26:25 So at builds> compile time, we just make a blank spot to drop that info into. 2023-05-13 21:27:12 It shows up on the stack at builds> runtime, so the code there can just , it into that extra pfa field, which handles allocating it and setting it in one shot. 2023-05-13 21:27:33 then CREATE makes the normal pfa/cfa/link/name immediately following. 2023-05-13 21:27:57 And these words have their own runtime handler - one that does dovar and docol to the pfa fields. 2023-05-13 21:28:00 here is an example : CONST+42 builds> 1 ALLOT does> @ 42 + ; 2023-05-13 21:28:34 Well, that doesn't show us what builds> DOES. 2023-05-13 21:28:46 That's just a case specific thing. 2023-05-13 21:28:58 The machinery is hidden inside builds> and does>. 2023-05-13 21:29:09 And the runtime. 2023-05-13 21:29:15 "dodoes" 2023-05-13 21:29:23 in this example builds> does not need to run until say CONST+42 foo is executed from source 2023-05-13 21:29:39 Sure, the same for me. 2023-05-13 21:29:52 builds> doesn't RUN until you use the defining word to define a final word. 2023-05-13 21:30:11 And by then it will know what to set that extra pfa to. 2023-05-13 21:30:20 but your builds> runs when CONST+42 is being compiled, no? 2023-05-13 21:30:57 Oh, well, yes - that's true. The stuff INSIDE builds> runs at the time the defining word is defined. 2023-05-13 21:31:03 builds> is immediate in my system. 2023-05-13 21:31:06 as is does> 2023-05-13 21:31:37 But my builds> doesn't actually build the data structure for the final word. 2023-05-13 21:31:55 and I think having them both as immediate is what is complicating a lot for you 2023-05-13 21:32:05 It just wires up the harness. The code that follows builds> but is before does> declares the data structure, and it doesn't run until the defining word is RUN. 2023-05-13 21:32:24 I think it's required. 2023-05-13 21:32:45 Look I described the flow of information. 2023-05-13 21:32:57 We know where the action code will be at does> compile time. Not before. 2023-05-13 21:33:22 builds> has to be able to build the final word's header, so it's got to have that information. 2023-05-13 21:33:49 I shouldn't say it's "required." But the steps I'm achieving have to be achieved somehow. 2023-05-13 21:33:53 There may be other ways. 2023-05-13 21:34:04 I think what I've done is close to a "local optimum." 2023-05-13 21:34:15 There may be other optima further off in design space that I just haven't thought about. 2023-05-13 21:34:27 iirc : does> ( pfa - - ) R> SWAP ! ; 2023-05-13 21:34:48 in eForth 2023-05-13 21:35:09 I can't comment on it - I'm not familiar enough with the overall design. 2023-05-13 21:35:14 which took me a bit to figgure out how it works 2023-05-13 21:35:44 sorry ( addr(pfa) - - ) that stack diagram is supposed to be 2023-05-13 21:35:46 If does> isn't immediate, how does a return get put at the end of the data declaration code between builds> and does>? 2023-05-13 21:36:27 My does> dompiles one, and then it stores the action code address in that literal field that builds> declared. 2023-05-13 21:36:31 That's all it does. 2023-05-13 21:36:32 that was what puzzled me at first 2023-05-13 21:36:51 Yeah, first thing does> does is (;) b, 2023-05-13 21:37:36 I might be able to shorten my does a little if I passed the address of the 2nd pfa field throughon the stack instead of extracting it from the dictionary. 2023-05-13 21:37:40 Just noticed that just now. 2023-05-13 21:37:50 I'll have to think a little about that. 2023-05-13 21:37:56 note that the version I gave poped does> return address of the return stack 2023-05-13 21:38:19 Might just take a HERE in builds> and a swap ! in does. 2023-05-13 21:38:40 That would be sweet. 2023-05-13 21:38:42 which causes the implict exit added by ; to exit the building word 2023-05-13 21:39:00 But you don't have a ; until after everything, right? 2023-05-13 21:39:04 At the end of the does> code? 2023-05-13 21:39:11 the ; in the defintion of does> that is 2023-05-13 21:39:57 But that ; got compiled back when you defined does - does an extra ; appear in another place in your code? 2023-05-13 21:40:33 my thought was “but if does> pops off its return address then to where does execution return to when does> is done” 2023-05-13 21:40:34 Ugh. Now I'm finding hard to think about anything other than seeing if I can pass this address through on the stack. 2023-05-13 21:42:07 Hang on - I just made that change; testing it. 2023-05-13 21:43:13 No, not quite. Still might work, though. 2023-05-13 21:43:16 note that both builds> and does> need to be non-immediate for this to work 2023-05-13 21:43:21 Just have to stare at it a little. 2023-05-13 21:45:08 heck, I made a version of builds> that expected an str address and length on the stack for the name 2023-05-13 21:45:20 string* 2023-05-13 21:46:53 which meant it just passed it onto CREATE variant which is the word that makes the dictionary entry 2023-05-13 21:48:48 Oh, no - that's a non-starter idea (what I was just working on). I was trying to skip over that middle layer again. 2023-05-13 21:50:39 But, I think I did just modify it so that it works. 2023-05-13 21:50:55 does> is now down to this: 2023-05-13 21:50:59 : does> (;) b, here swap 4- h! ; immed 2023-05-13 21:51:32 Had to load the value onto the stack in a slightly different place. 2023-05-13 21:52:15 Yeah, that works. 2023-05-13 21:52:59 builds> is the complex piece. But it's the piece that has to create that whole intermediate storage setup. 2023-05-13 21:53:10 I keep telling you. Do it without builds> and does> having IMMEDIATE in their flags 2023-05-13 21:53:26 I don't at the moment see any way to do that. 2023-05-13 21:53:46 In my system at least. 2023-05-13 21:55:11 I'll think about it some more - it would remove some problems if builds> didnt need to be immediate. does> is short enough now that I don't care that much, but the complexity is coming in in builds> 2023-05-13 21:55:30 think of when the CONST+42 runs iff both builds> and does> are just normal non immediate words, what exactly happens 2023-05-13 21:55:42 Give me a minute to get my thoughts together and I'll see if I can verbalize why I think builds> needs to be immediate, the way I'm doing it riht now. 2023-05-13 21:58:24 Ok, it has to be immediate because it compiles that literal into the defining word where I store that address. So tell me how your way of thinking about it gets the action code address to the final word. 2023-05-13 21:58:49 If it wasn't immediate then there wouldn't be a place in the defining word to store that information. 2023-05-13 21:59:23 How does the final word know where the code it's supposed to run is in your approach? 2023-05-13 21:59:47 store which address? 2023-05-13 22:00:02 Example: 2023-05-13 22:00:18 : varecho builds> 8 dp.b +! does> 64 emit ; 2023-05-13 22:00:21 varecho alpha 2023-05-13 22:00:36 alpha will print an @ when it's executed, along with leaving a variable address on the stack. 2023-05-13 22:00:44 How does the address of the 64 emit get into alpha? 2023-05-13 22:01:14 There's nowhere in varecho to put it if builds> isn't immediate. 2023-05-13 22:01:23 I see your confusion 2023-05-13 22:02:09 But in my way of doing it, builds> inserts a code phrase into varecho, and there is a place in that phrase for does> to store that address. 2023-05-13 22:02:34 lets say both builds> and does> are non immediate 2023-05-13 22:02:40 Let's say. 2023-05-13 22:03:00 And when alpha runs, it has to have that address. 2023-05-13 22:03:42 so varecho gets defined above and neather builds> or does> runs. 2023-05-13 22:04:09 Sure, if they're not immediate. And they each occupy one slot in varecho. 2023-05-13 22:04:26 but when we encounter varecho alpha things start with varecho running 2023-05-13 22:04:41 Yes. 2023-05-13 22:04:53 varecho will create alpha. 2023-05-13 22:05:08 Where is that address at that point in time? 2023-05-13 22:05:09 you are skipping ahead 2023-05-13 22:05:35 Don't mean to be. It will eventually create alpha, but it can do other things first. 2023-05-13 22:05:53 I was really just agreeing with you that varecho runs first. 2023-05-13 22:05:57 okay we are running varecho . First word it calks is builds> 2023-05-13 22:06:03 Yes. 2023-05-13 22:06:06 calls 2023-05-13 22:07:17 Maybe does> could set that field in the new word. 2023-05-13 22:07:24 builds> reads the next word from the input stream builds the dictionary entry and leaves the address of the ofa cell on the stack when it exits. 2023-05-13 22:07:48 s/ofa/pfa/ 2023-05-13 22:08:10 fricking onscreen ipad keyboard 2023-05-13 22:08:25 Heh. I remember trying to use tablets. 2023-05-13 22:08:43 I think there may actually be a way through this - lemme try a couple of things. 2023-05-13 22:09:29 so the words in varecho need to keep that address around for does> to get it 2023-05-13 22:11:14 when does> runs inside varecho it just patches in the return address it should have returned to into that pfa cell 2023-05-13 22:11:55 and when does> exits it actually exits to the caller of varecho 2023-05-13 22:12:31 and that is it 2023-05-13 22:13:21 the code the cfa in that dict entry builds> made needs to handke 2023-05-13 22:14:16 handle calling the code after does> in the varecho definition 2023-05-13 22:14:47 s/the cfa/the cfa points to/ 2023-05-13 22:16:52 Ok - one minute. 2023-05-13 22:18:54 Yes - I got it mostly built, and was not noticing that that return address was sitting there hand. 2023-05-13 22:18:58 This does the job: 2023-05-13 22:19:11 : builds> dp.h @ 0 h, create (does) cfa! ; 2023-05-13 22:19:12 : does> r> base.b @ - swap h! ; 2023-05-13 22:19:26 And that's quite beautiful - so thank you for staying after me. 2023-05-13 22:20:01 It would be shorter still in an absolute address system; I have to do those converstions of offsets and so on. 2023-05-13 22:20:02 you are quite welcome 2023-05-13 22:21:08 and if I am not mistaken then this version of builds> does not need to be the first word in an defining word 2023-05-13 22:23:21 Well, I need to run create before I allocate space. 2023-05-13 22:23:34 Because create will aim the pfa at the next byte to be allocated. 2023-05-13 22:23:47 But I guess if you WANTED to have the address be in the middle of something, you could. 2023-05-13 22:24:06 You're right - I no longer need to "plug something into it," so I don't have to have it in any particular place now. 2023-05-13 22:24:13 but do also note that this means any code after does> inside [ ] will run at the time of defining the defing word and not when the defineing word is being used to define a wird 2023-05-13 22:24:24 s/wird/word/ 2023-05-13 22:24:41 Right. 2023-05-13 22:28:15 Ah, I rearranged it a little and got rid of the need for that helper word cfa!. 2023-05-13 22:28:21 : builds> (does) dp.h @ 0 h, create ; 2023-05-13 22:28:23 : does> r> base.b @ - over h! 8+ h! ; 2023-05-13 22:28:41 (does) is the code address of the "dovar+docol" machine code routine. 2023-05-13 22:28:48 It's a constant in my system.