2022-03-21 00:20:13 I've read the first 100 pages of that book 2022-03-21 00:20:30 the mcabe * 2022-03-21 00:38:06 Looks like Chuck initially was putting Forth together to serve as a "control language." While he already advocated writing your own subroutienes for a lot of things, particularly proble-specific data input, he acknowledged the value of some pre-existing subroutines (he singled out sqrt as a prime example and recommended that one capitalize on the prior work that had gone into solving that problem). I think 2022-03-21 00:38:09 he had it in mind that your program would consist of a set of subroutines, and the "language" he's describing is how you "knit them together" into a problem solution. 2022-03-21 01:17:35 did not write more code 2022-03-21 01:17:57 actually I wrote such horrible code because I wanted to have "something" before going to sleep xD 2022-03-21 02:53:42 now I want a forth for everything :/ 2022-03-21 02:54:55 I want to use free hostings but don't want to touch php 2022-03-21 02:55:37 could make a forth in php but don't want to write php 2022-03-21 02:55:52 but I could make a forth transpiler to php :D 2022-03-21 03:04:41 some free hostings accept perl so I'll go for that 2022-03-21 03:50:10 I have this https://termbin.com/g6ps 2022-03-21 03:50:27 I think I'll always try to avoid having a return stack 2022-03-21 03:50:39 it's a perl module 2022-03-21 03:51:11 I have an array with a list of words to execute, I could add words there at runtime 2022-03-21 03:51:36 I think could be useful to do some basic cgi stuff or alike 2022-03-21 04:02:52 If you don't have a return stack, how will you define more than one level deep? 2022-03-21 04:03:48 idk what you mean 2022-03-21 04:04:15 the program get's to an array named words_to_execute and I can add words to this array at runtime 2022-03-21 04:04:53 and even when I see a forth word I just add those words to this array 2022-03-21 04:05:50 so the array just grows dynamically and the "interpreter" executes one word at a time of that list 2022-03-21 04:06:08 while executing one word this array can grow 2022-03-21 04:08:24 like (1 2 someword 3 4) if someword is a forth word, will execute 1 2, then the array is (someword 3 4) the words of someword will get expanded into that array like if : someword 5 6 ; the array now will be (5 6 3 4) 2022-03-21 04:08:47 and I could provide a way to add words to execution 2022-03-21 04:09:08 I can quote words and push them to the stack too (not implemented yet, but just a regex) 2022-03-21 04:09:37 I don't think if I'll run into troubles by doing this with the array of execution btw 2022-03-21 04:10:49 I don't know* 2022-03-21 04:11:18 but tried that in the past not seen any trouble although I didn't tested carefully 2022-03-21 04:11:55 but also by having this I don't see a need of a return stack or a lisp macro feature 2022-03-21 04:12:23 as any word could add words to execution, but I think there's a flaw there 2022-03-21 04:12:59 if a word adds to execution those words would get added before the rest of the word has been execute 2022-03-21 04:13:00 d 2022-03-21 04:15:38 like : someword 5 4 'another-word add-to-execution 1 2 3 ; (someword) should expand to (5 4 'another-word add-to-execution 1 2 3) which in turn will execute 5 and 4, then push 'another-word to the stack, then add-to-execution will add this so would be now (another-word 1 2 3) 2022-03-21 04:16:23 if another-word is a forth word it also would get expanded 2022-03-21 04:16:39 idk if this can give me troubles later 2022-03-21 05:20:16 I mean say you write this: 2022-03-21 05:20:33 : foo 2 * ; 2022-03-21 05:20:42 : bar foo 7 + ; 2022-03-21 05:21:10 and execute bar. It will call foo. When foo is done, how do you get back to the "7 +"? 2022-03-21 05:21:18 without a return stack? 2022-03-21 05:23:03 If you just have an array of words you define in perl and you can't compose those words into new words, then that wouldn't really be Forth. Just naming the words Forth style names wouldn't change that. It might be useful to you, though. 2022-03-21 05:24:23 I'm a little picky about that aspect, though - I actually have a hard time calling subroutine threaded systems "Forth." After all, that's just doing the same thing every C program does. 2022-03-21 05:25:05 I begrudgingly accept direct threading, but I don't like it nearly as much as indirect threading. 2022-03-21 05:27:41 I might agree with the first remark, but for me the inner interpreter is just a matter of optimization (speed vs size, etc.). 2022-03-21 05:28:26 I think on x86, STC makes sense. 2022-03-21 05:29:29 I just find it to be awfully "standard." It's also just not nearly so elegant - you can work around and figure out how to make it work, but the way indirect threading gets everything about the word into one place just has a more elegant feel (to me). 2022-03-21 05:29:47 I did find dave0's ret-based direct threaded system intriguing, though. 2022-03-21 05:30:02 That just had a "cleverness" to it that was appealing. 2022-03-21 05:30:10 maw KipIngram ! 2022-03-21 05:30:12 Indirect threading is almost undoubtedly more elegant. 2022-03-21 05:30:26 Definitely just my personal feelings in play here. 2022-03-21 05:30:54 https://www.youtube.com/watch?v=M-Xt1ShKW3c 2022-03-21 05:31:05 Some random Forth video with multitasking. 2022-03-21 05:31:09 I worked for a while on a direct threaded system once; never finished it, but I did get pretty far along. I remember create/does> being kind of kludgy and painful. 2022-03-21 05:31:23 maw dave0 2022-03-21 05:32:22 dave0, remind me how you stored the pfas you needed for nesting to deeper definitions in that system? Did you just stick them inline right after the code address of docol? 2022-03-21 05:33:00 Oh, wait - you put a copy of docol right before each definition list, right? 2022-03-21 05:33:02 what's pfa :-p 2022-03-21 05:33:18 It's the space the actual definition address list goes in (for a : def). 2022-03-21 05:33:33 : foo bar bam ; 2022-03-21 05:33:51 Somewhere you have "address of bar, address of bam, address of "Forth return." 2022-03-21 05:33:56 (parameter field address) 2022-03-21 05:33:59 yeah the first cell was actually 2 bytes of machine code that was jmp bp and bp always pointed to docol 2022-03-21 05:34:10 Oh, right - sorry. That should have been response #1. 2022-03-21 05:34:20 yep yep i got it :-) 2022-03-21 05:34:41 jmp didn't fit in a cell 2022-03-21 05:34:42 Ok. So we tinkered with using instruction pointer relative addressing, right? 2022-03-21 05:36:29 ah i think you're asking how i got the address of the definition list? 2022-03-21 05:36:34 Yes. 2022-03-21 05:36:39 On x86 relative jump caused me some ugly I remember for my STC Forth. 2022-03-21 05:36:41 i fetched it from the caller 2022-03-21 05:37:11 But you didn't call from anywhere - you ret'ed. 2022-03-21 05:37:22 Oh, the stack pointer's pointing at it. 2022-03-21 05:37:30 yep 2022-03-21 05:37:43 Ok, right - so it's just inline after the address you ret'ed to. 2022-03-21 05:37:48 From, I mean. 2022-03-21 05:38:01 yes 2022-03-21 05:38:07 So you could pop it. 2022-03-21 05:38:10 so for amd64 it was [rsp-8] 2022-03-21 05:38:25 Yeah. 2022-03-21 05:38:36 it made `execute` more difficult 2022-03-21 05:38:41 Yeah. 2022-03-21 05:40:26 i used self-modifying code in execute .. : execute ' LIT [ here 0 , ] ! [ here swap ! 0 , ] ; 2022-03-21 05:40:54 Anyway, when I first "found Forth" back in the early 1980's it was its RPN nature that enticed me (HP calculator and all). But over time the nature of its internal operation took first place with me. 2022-03-21 05:41:18 i learned RPN first from unix `dc` ! 2022-03-21 05:43:32 KipIngram: i haven't done much on my amd64 forth for a while, instead i did some coding on my 32 bit forth for x86 realmode 2022-03-21 05:44:09 it works quite well, but still not finished 2022-03-21 05:44:50 i managed to make the memory into a flat address space of 1meg 2022-03-21 05:45:43 there are two words >segment and segment> to convert back and forth to the segmented memory 2022-03-21 05:46:01 also it is indirect threaded 2022-03-21 05:46:37 it runs on dosbox but is noticably slow 2022-03-21 05:48:01 probably the most notable missing thing is does> 2022-03-21 05:49:38 and it's not standard.. i named my words after the 2012 standard, but a lot of the interfaces are different 2022-03-21 05:50:06 for example `word` doesn't return a counted string, it returns an c-addr n pair 2022-03-21 05:51:19 and `find` takes a c-addr n pair instead of a counted string 2022-03-21 05:52:03 and i have an `immediate?` word which takes an xt and returns a flag, instead of returning a flag with `find` 2022-03-21 05:52:29 but me being me, i'll probably think of a different way to do it and then change everything again :-p 2022-03-21 05:53:32 Ah, interesting. Man, I was pretty happy to see that memory model fade into the past. 2022-03-21 05:53:35 also lately i've been thinking about how forth can meta-compile itself 2022-03-21 05:53:45 KipIngram: lol yes 2022-03-21 05:53:59 Ah yes - meta compilation is a major goal I've got. 2022-03-21 05:54:33 It's mostly a bookkeeping chore - you have various addresses of importance in your "running system" and also in your "target image," and you've got to keep them straight. 2022-03-21 05:54:56 I've got some of the necessary plumbing for it in my current system, but I have no idea if I caught everything. 2022-03-21 05:55:18 once it's built, do you just dump the memory image to a file? 2022-03-21 05:55:33 Like when you're compiling a target word, you have to be sure you're only including in it addresses that are in the target. 2022-03-21 05:55:35 Etc. 2022-03-21 05:56:32 Well, I'm not that far along, but basically yes - except in my case I'll dump it to disk blocks. It may also be necessary to have some relocation information along with it. 2022-03-21 05:56:54 Some of the values in the image will need to be adjusted, depending on where in RAM you place it when you go to run it. 2022-03-21 05:57:03 yeah 2022-03-21 05:57:11 That's actually a spot where the x86 real mode addressing would help. 2022-03-21 05:57:19 You'd just set the segment registers right, and that would be that. 2022-03-21 05:57:53 But that's basically what an executable file format is - an image, along with a list of spots in the image to "punch up" with relocation adjustments. 2022-03-21 05:57:55 i cheated by copying everything to an absolute address :-) 2022-03-21 05:58:08 :-) Hey, that would work. 2022-03-21 05:58:17 hehe 2022-03-21 05:58:21 well it's dos 2022-03-21 05:58:29 dos aint much of an operating system 2022-03-21 05:58:35 And honestly, if you're cross-compilng for some gadget, it would completely do the job. 2022-03-21 05:59:06 Well, .com files in DOS are inherently location independent to start with. 2022-03-21 05:59:22 i kinda like .com 2022-03-21 05:59:33 just dump raw binary somewhere and JMP to it 2022-03-21 05:59:40 Oh yeah - it was simple and handy. You were always at 0x100. 2022-03-21 05:59:57 yep 2022-03-21 06:00:04 Well, and set your segment regs. 2022-03-21 06:00:12 and cos it's dos, you can use all the memory any way you want 2022-03-21 06:00:53 KipIngram: i used every register, including segment registers, in my 32 bit dos forth 2022-03-21 06:00:56 I enjoyed how straightforward "hacking" was in those days. Everything was just laid right out, and you could touch any of it. 2022-03-21 06:01:26 really, unix comes from that era too 2022-03-21 06:01:32 I've used all of my 64-bit regs except for three. Those three get "used" too, but only for temporary scratch stuff. No persistence. 2022-03-21 06:02:15 right now I don't do anything to rsp - I just use whatever system stack Linux sets me up with. It only gets used at all when I do syscalls. 2022-03-21 06:02:25 remind me, are you on amd64 macos? 2022-03-21 06:02:30 But a dozen regs I have specific purposes for. 2022-03-21 06:02:48 No, I was on Intel MacOS, but now I'm on Intel Linux. The Mac is my work computer. 2022-03-21 06:02:55 aah ok cool 2022-03-21 06:03:03 Nice to be back to real Linux. 2022-03-21 06:03:18 Console work on MacOS is awfully similar, but not quite exactly the same. 2022-03-21 06:04:50 i did do a little bit of coding last week on my amd64 forth... it was cleaning up my coroutines... i created a specific forth word `coroutine` which is to the C language functions what execute is to forth 2022-03-21 06:05:26 At one point near the end Apple pulled a sudden toolchain change on me, right out of the blue, and my Forth wouldn't link anymore. 2022-03-21 06:05:34 Had to do some backflips to get it running again. 2022-03-21 06:05:42 That was part of what drove my decision to buy a Linux box. 2022-03-21 06:05:57 whoops 2022-03-21 06:05:57 I was pretty busy with mine last week. I was on vacation, and put a good bit of work into it. 2022-03-21 06:06:07 oh cool 2022-03-21 06:06:18 yeah i didn't see you on irc for a while 2022-03-21 06:06:34 It was so so close to being "really ready to roll" - mostly was missing disk I/O (BLOCK, LOAD, etc.) I got those added and they seem to be very solid now. 2022-03-21 06:06:53 nice 2022-03-21 06:07:04 So now I can load code from blocks. Next step is to port my editor from the Mac version and then I'll be ready to "develop" stand-alone. 2022-03-21 06:07:20 Then the meta-compilation really will become job #1. 2022-03-21 06:07:33 And once I accomplish that, I should be able to kiss nasm goodbye, permanently. 2022-03-21 06:07:44 lol 2022-03-21 06:07:57 Not that I'm particularly unhappy with nasm, or anything. 2022-03-21 06:08:05 it's a fine assembler 2022-03-21 06:08:12 I got a really nice set of macros set up that handle all the dictionary bookkeeping for me. 2022-03-21 06:10:03 MacOS had strict relocatability requirements that forced me to make pretty much the whole system based on offsets instead of addresses. 2022-03-21 06:10:20 It's still like that, post Linux port. I'm torn over whether to try to change it or not. 2022-03-21 06:10:34 It's slightly lower performance, but really not much lower. 2022-03-21 06:11:07 Leaning the other way, I also have a temptation to try to make it completely relocatable, so that I could literally move a sleeping process to a new location and have it wake up and run. 2022-03-21 06:11:27 But that smells a little like the kind of thing that winds up leading me into messy waters. 2022-03-21 06:12:23 I think I could readily keep up with all the addresses in "the system itself." But the problem is that the sleeping process might have addresses on its data stack, and I wouldn't know to correct thos. 2022-03-21 06:12:25 so is your inner interpreter like.. lodsq / add rax,r10 / jmp rax where r10 is the base of your memory? 2022-03-21 06:12:39 And if I use the return stack for anything other than addresses, I'd face the same problem in the other direction. 2022-03-21 06:13:03 No, I timed it and found that lodsq was a little slower. 2022-03-21 06:13:19 Plus those items in my system are 32 bits, so it would be lodsd. 2022-03-21 06:13:27 ah ok 2022-03-21 06:13:29 I just increment the IP manually. 2022-03-21 06:14:03 This is my next: 2022-03-21 06:14:14 yeah intel is a bit weird like that... you'd expect lodsd to be fast 2022-03-21 06:14:32 next_c: geti rrW, rrIP ; Fetch next icell 2022-03-21 06:14:35 radd rrW, rrHB ; Offset -> address 2022-03-21 06:14:37 inci rrIP ; Bump instruction pointer 2022-03-21 06:14:39 geti rrTMP, rrW ; Fetch CFA offset 2022-03-21 06:14:41 radd rrTMP, rrBB ; Offset -> address 2022-03-21 06:14:43 rjmp rrTMP ; Go there 2022-03-21 06:14:51 those weird opcodes are macros that codify some of the cell size aspects. 2022-03-21 06:15:24 The radd ? rr?B are the "relocation" stuff. 2022-03-21 06:15:55 rrHB is a register alias - that reg contains the base address of the header block. rrBB is similar, but the base address of the "body block." 2022-03-21 06:16:29 So those two add instructions are the primary "relocatability overhead." 2022-03-21 06:16:35 you know what's interesting about standard forth and the rule that you are not allowed to access the data and return stacks as though they were memory? you can move them at run time, and just update the pointers to the new address 2022-03-21 06:16:37 There's a couple adds of that nature in docol too. 2022-03-21 06:16:56 Sure. 2022-03-21 06:17:33 but that's cool because if the program runs out of stack, you just allocate a bigger one 2022-03-21 06:17:34 I've broken that rule, though - I do have a handful of words that index into the stack. Except not using the "stack pointer" - I have a reg I keep a "frame pointer" in. 2022-03-21 06:17:40 And I can index from it. 2022-03-21 06:17:47 i just used pick and roll 2022-03-21 06:17:56 The payoff of the frame is that the stuff doesn't "move around" as I diddle the stack. 2022-03-21 06:18:08 ah 2022-03-21 06:18:11 I open and close frames with my { and } words. 2022-03-21 06:18:34 is your frame part of the data stack? 2022-03-21 06:18:53 I try to use that mechanism as little as possible - I do believe in the "don't index the stack" dictum. In a place or two or three, though, I just found it to be the best wayout of a thorny knot. 2022-03-21 06:19:03 Sometimes there's just more than 2-3 quantities of immediate interest. 2022-03-21 06:19:13 i use 2 pick a lot! 2022-03-21 06:19:26 However, I don't do anything that is like ROLL. 2022-03-21 06:19:34 ROLL is a lot uglier than PICK. 2022-03-21 06:20:01 yep roll needs a loop 2022-03-21 06:20:16 Yeah, and moves everything. 2022-03-21 06:20:45 I do have rot and -rot. 2022-03-21 06:20:57 Well, actually I don't, in this new one yet. 2022-03-21 06:21:02 But I did in the last one. 2022-03-21 06:21:46 HP calculator called those RDN and RUP, except the UP printed as a little upward s loping arrow symbol. 2022-03-21 06:22:19 rot-down and rot-up ? :-) 2022-03-21 06:22:24 And it had just a four-deep stack - stuff would "push off the top" or duplicate on pop. 2022-03-21 06:22:42 Yeah. 2022-03-21 06:22:47 RDN and RUP is still better than CDR and CAR ;-) 2022-03-21 06:23:08 The calculator let you directly access all four registers - they were x, y, z, t. 2022-03-21 06:23:28 I may include such words in this system. Generally speaking I'm inclined to include a good bit of the HP ecosystem. 2022-03-21 06:23:36 is that calculate actually a forth? 2022-03-21 06:23:41 No. 2022-03-21 06:23:42 calculator 2022-03-21 06:23:46 oh ok 2022-03-21 06:24:16 Not pure, at least, though there were certainly similarities. It didn't define new things like Forth does, where the new stuff behaves exactly like the built-in stuff. 2022-03-21 06:24:35 You defined labels and either JMPed to them or XEQ'ed them. 2022-03-21 06:24:51 Though you could also jump to or call "line numbers." 2022-03-21 06:25:06 I think - I may be making that last up. 2022-03-21 06:26:04 What I'm remembering there may be that you could use numbers for labels, and then if you stored one of those numbers in a register you could jump or call indirect through that register. 2022-03-21 06:29:00 Oh, what I said up there - that's also something that "characterizes" real Forth for me: when you add a word to the dictionary, it's 100% a "first class citizen" of the system and behaves in every way like the native words. 2022-03-21 06:29:26 One simple set of rules for EVERYTHING. 2022-03-21 06:30:05 i didn't appreciate that for a long time 2022-03-21 06:30:12 Which almost has to be the case once you strip anything remotely resembling "syntax" away from the system. 2022-03-21 06:30:13 i thought it's just a function 2022-03-21 06:30:37 Yeah, it's radically different from, say, C or Python. 2022-03-21 06:30:59 Where a function "looks different" from an expression or a for loop or whatever. 2022-03-21 06:41:45 dave0: Traditional Forth dodges location-based problems by just having you load everything from source every time. 2022-03-21 06:41:53 No notion of "compiled code" on disk. 2022-03-21 06:44:40 KipIngram: i had to hand compile a lot of forth words... 2022-03-21 06:45:14 i wrote them twice.. once as a list of addresses in the assembly source, and then again in forth ... that's why i started thinking about meta-compiling 2022-03-21 06:46:02 main issue w meta compiling for me to grok was resolving offsets 2022-03-21 06:51:45 Oh yeah - I've got mucho hand compilation in the nasm source. Fortunately the macros make that a very clean process. 2022-03-21 06:51:53 : foo bar bam ; 2022-03-21 06:51:57 would become 2022-03-21 06:52:10 def "foo", foo 2022-03-21 06:52:22 run bar, bam, dosem 2022-03-21 06:52:38 oops. mangled the spacing there. But you see how simple it is. 2022-03-21 06:52:54 The def macro does the whole job of building the dictionary entry. 2022-03-21 06:53:10 The run macro handles all the "offset" stuff transparently. 2022-03-21 06:53:58 The main nuisance is that I have to count back and set jump offsets manually. 2022-03-21 06:54:13 then if I edit the list of stuff jumped over and forget to recount, there's a bug. 2022-03-21 07:05:13 So part of my hesitation to remove the offset-based logic is that as far as I can tell it's solid as a rock. Everything just "works." Making an invasive change like that - I'm not sure how straightforward that would be. 2022-03-21 07:05:23 Maybe I should copy the whole project and give it a go. 2022-03-21 07:06:44 Total s hot in the dark here, but my gut says it would gain me 5%-10% performance. 2022-03-21 07:14:22 But one issue is that in many "internal" respects I've built a 32-bit system. The definition cells are 32 bits. I add that number to a base value to get a full 64-bit address. 2022-03-21 07:14:40 That was deliberate, to cut the size of the system. 2022-03-21 07:15:16 So those spots in the image aren't really fit to be stand-alone addresses. 2022-03-21 07:15:55 I'd really need to promote them to 64 bits, and that's a whole other change, and might take back some of the performance I got by not doing the adds. 2022-03-21 07:49:05 I just "reminded myself" that this system's (lit) compiles a 32-bit cell as the literal value. So it won't compile 64-bit literals - just uses the low order 32 bits, though when that loads it sign extends to 64 bits. 2022-03-21 07:49:18 I can't really think of when I might *need* to compile a 64-bit literal. 2022-03-21 07:49:36 const values are stored as 64 bits, and that works just fine. 2022-03-21 07:50:38 I went with var and const rather than variable and constant. 2022-03-21 07:50:57 And will go with voc instead of vocabulary. 2022-03-21 07:51:33 And I've got path and curr instead of context and current. 2022-03-21 07:56:22 One of the things Chuck talks about in that old book is "word dissection." The general idea is that if you parse a word and search the dictionary for it and fail, you drop the last character and try again, and continue doing that until you either find a word or don't. I can see all kinds of potential gotchas there, as well as the performance impact on compiling, but the payoff would be that you could lose 2022-03-21 07:56:25 some spaces. 2022-03-21 07:56:32 It doesn't surprise me that the idea didn't catch on. 2022-03-21 07:57:05 It occurred to me that a refinement of that idea might be to have a list of regular expressions you applied to the parsed word, and exactly what you did with its pieces might depend on which regex matched. 2022-03-21 07:57:29 didn't chuck have words that are 3 characters+length and match on that? 2022-03-21 07:57:32 That could get fairly sophisticated, and it eliminates some the aforementioned "gotchas." 2022-03-21 07:57:53 Um, it wasn't uncommon to only store the count byte and the first three characters, to save RAM. 2022-03-21 07:58:04 So it was the three chars AND THE COUNT. 2022-03-21 07:58:27 That kind of fell out of favor as RAM got cheaper. 2022-03-21 07:58:31 yeah that's interesting 2022-03-21 07:58:35 ah ok 2022-03-21 07:58:54 It means you can do the compare with one 32-bit operation, which would really speed up the dictionary search. 2022-03-21 07:59:19 My FIND is written totally in Forth - I imagine it's not going to break any speed records. 2022-03-21 07:59:53 i don't think it has to be slow 2022-03-21 08:00:57 Well, in general this system is pretty fast; I've been happy with it. But I have no doubt I could speed it up if I wrote it in assembly. But it's a fairly complex routine - three nested loops. 2022-03-21 08:01:07 i haven't profiled my dos forth, but just by looking, i found that `number` was very slow.. much slower than `find` 2022-03-21 08:01:16 A loop across vocabularies, a loop through words of a vocabulary, and a loop across characters of the word. 2022-03-21 08:01:21 I definitely want that to be portable. 2022-03-21 08:02:12 It uses what I regard as my most advanced control flow feature. It uses multiple levels of stack frames, but it also uses a "longjmp" style exit on success. 2022-03-21 08:02:16 5 5 5 5 5 5 . was noticably slower than compiling 6 forth words 2022-03-21 08:02:50 Because when you realize you've found the word successfully, you're way down in that most deeply nested loop. Rather than "pass success up" through all those layers, I have an ability to just leap all the way back out in one shot. 2022-03-21 08:02:56 KipIngram: i can't follow your conditional exits :-p 2022-03-21 08:03:02 Return stack gets cleaned up, etc. 2022-03-21 08:03:20 Well, the simplest case is easy enough. Instead of 2022-03-21 08:03:34 : foo IF ...code... THEN ; 2022-03-21 08:03:49 I'd have :foo bar ; 2022-03-21 08:03:59 : bar 0=; ...code... ; 2022-03-21 08:04:14 If the flag is zero, return and don't run ...code... 2022-03-21 08:04:48 Except I have a bunch of different such conditional returns, so I can be more flexible about the condition. 2022-03-21 08:05:37 And since I can define "temporary" names, that extra definition doesn't clutter the dictionary long term. 2022-03-21 08:06:28 I don't really like having the temporary name continue to occupy space (even though it's removed from search), but that's just how it is on this system. 2022-03-21 08:07:02 I may fix that at some point - in the previous system I put those headers in a dynamically allocated block, which I deallocated when I removed the names. 2022-03-21 08:07:59 The thing that complicates that, though, is that the header contains not only the name and link, which I could get rid of, but also the CFA/PFA pointer pair, which I can't get rid of. 2022-03-21 08:08:23 So doing that involves being smart enough to have some headers split into two pieces. 2022-03-21 08:09:25 I resolved that last time by putting the CFA/PFA in the usual place, and having a pointer to that in the remote name/link section. But that gets different handling from a normal definition, so it's a bit to keep up with. 2022-03-21 08:10:47 I solved it once - might get around to solving it again. 2022-03-21 08:13:05 Hmmm. Right now I have a bunch of such "disposable" word names in the nasm source. They all have a bit set that identifies them as such, so I can unlink them later. But if I made a set of slightly modified macros I really could avoid that altogether. Those words don't get "searched for" by nasm, so their names and links are utterly unnecessary. 2022-03-21 08:13:12 I should have done that long ago. :-| 2022-03-21 08:14:33 I can probably make those macros conditional on the parameter that causes that bit to be set, and in that case just not run the namem/link part of the macro. 2022-03-21 08:35:31 I'm a little impressed with how powerful that regex matching notion could potentially be. So powerful it scares me a little - you could very quickly depart quite a long way from "usual Forth" if you starting messing around on that front. Because you could regexes that recognized practically anything. 2022-03-21 08:35:41 could "add" 2022-03-21 08:35:50 I use QUIT/ABORT a lot to clean up my return stack 2022-03-21 08:36:29 If I did regex's they would be similar to ed's regexs, greedy and simplistic 2022-03-21 08:36:34 :-) 2022-03-21 08:36:38 Hey - it works. 2022-03-21 08:36:54 But in this case I don't want "all the way" out - just a long way out. 2022-03-21 09:01:08 I'll use exceptions for that sometimews 2022-03-21 09:01:25 rdrop exit if it's simple enough 2022-03-21 09:02:19 What the heck. All of a sudden this morning "watch" no longer works in my MacOS console. 2022-03-21 09:02:42 Yes, I regard this set up as an "exception handler." 2022-03-21 09:03:01 In this particular case, when you're exhaustively searching the whole dictionary, the "exception" is "success." 2022-03-21 09:03:37 All the in-between layers don't have to know anything about that - they just navigate their lists, to the end. 2022-03-21 09:03:50 Simpler logic - shorter definitions. 2022-03-21 10:06:25 it's sad because I'll only have one stack so I won't be welcomed here :/ 2022-03-21 10:09:23 ACTION cries and leaves 2022-03-21 13:06:50 So, got rid of those unneeded names. All I had to do was add an %if line and an %endif line around the contents of one macro - poof. 2022-03-21 13:07:25 I like it when things are "no muss, no fuss." 2022-03-21 16:18:50 Does anyone know about shadow blocks? 2022-03-21 16:27:16 Yeah - the original basic idea was that you used odd numbered blocks for code and even numbered blocks for documentation (or vice versa). 2022-03-21 16:27:26 That way you always know where your docs are. 2022-03-21 16:29:18 It seems that polyforth for one has a constant SHADOWS that is used as an offset to get a shadow block 2022-03-21 16:29:21 with Q 2022-03-21 16:29:48 Ok - I guess that works too. Really any way of having a one-to-one association between pairs of blocks. 2022-03-21 16:29:49 I don't really get the advantage, I guess you can put the blocks that need docs nearer the front and use less space overall? 2022-03-21 16:30:16 I have always just assumed it's about knowing exactly where the comments for a given bit of code are. 2022-03-21 16:30:41 I'm interested in setting up a sort of "linked" version, where I can link spots in the code to points in a "wiki" like structure. 2022-03-21 16:30:51 So, same idea but more generic. 2022-03-21 16:31:04 b-trees look like they could hold that mapping handily. 2022-03-21 16:31:30 Blocks tend to already be trees 2022-03-21 16:31:45 Yeah. 2022-03-21 16:32:14 Because people will have a load block, and that lists ranges of blocks that contain different source, etc 2022-03-21 17:13:33 : K 64. ?DO 'INS I + @ 'FND I + @ 'INS I + ! 'FND I + ! LOOP 2022-03-21 17:13:36 #INS @ #FND @ #INS ! #FND ! ; 2022-03-21 17:13:53 I'm trying to swap two buffers, as seen above, is there a briefer way to write this? 2022-03-21 17:15:57 Oh I've got this wrong as well, the top line @ should be C@ and ! should be C! 2022-03-21 17:16:21 I guess I could have a VSWAP word that swaps the content of two addressed variables, and CSWAP to swap two chars 2022-03-21 17:20:45 SWAP! and CSWAP! might be better names for those? 2022-03-21 17:32:20 Is this a 64-bit or 32 bit system? 2022-03-21 17:34:30 If it's 64, and your buffers are 64 bytes and called A and B I might look into something like A PAD 8 MOVE B A 8 MOVE PAD B 8 MOVE 2022-03-21 17:35:05 It's been years since I've used MOVE - I'm assuming it moves N cells. 2022-03-21 17:39:34 It moves bytes I think 2022-03-21 17:40:01 I don't want to use an intermediate buffer, for the somewhat arbitrary reason that I'm trying to make it relatively portable and not affect transient buffers 2022-03-21 17:40:09 I think that cmove. 2022-03-21 17:40:32 that's 2022-03-21 17:40:45 CMOVE copies one-by-one 2022-03-21 17:41:06 Right, byte-by-byte, so you can have some odd number of bytes that's not a multiple of anything. 2022-03-21 17:41:28 It's so you can have overlapping source/dest with defined behavior 2022-03-21 17:41:31 But if you're moving some number of cells, you can use MOVE, and 1/cellsize the operation count. 2022-03-21 17:41:38 Or at least you used to be able to. 2022-03-21 17:41:45 I wouldn't know what the standards have done to it. 2022-03-21 17:42:09 Those usually come in different flavors, like cmove and One starts at one end of the buffer; the other at the other. 2022-03-21 17:43:06 cmove starts low and moves up; For non-overlapping buffers you can use either. 2022-03-21 17:43:59 I just assumed your buffers didn't overlap, since you're swapping. 2022-03-21 17:45:38 I take it these buffers have some external significance? 2022-03-21 17:46:00 If they're only internal to the program then I'd just reverse their usage downstream. 2022-03-21 18:47:05 KipIngram: My buffers don't overlap, so MOVE would work, I was just telling you that MOVE works on bytes not cells 2022-03-21 18:48:08 CMOVE and as it's known in ANS) are for overlapping buffers, either to copy up/down the buffer, or to generate a repeated pattern or memset 2022-03-21 18:49:20 Old FORTH MOVE uses bytes, but FORTH-79 uses a cell count 2022-03-21 18:49:49 FORTH-79 is pretty much meaningless it deviated so much from conventional forths and was abandoned by later standards 2022-03-21 18:50:01 The standards are a mess in FORTH 2022-03-21 18:51:32 That is contrary to what those words used to mean. Moving by bytes doesn't buy you anything on overlapping buffers. Moving overlapping buffer the wrong way will munge things just as surely moving bytes sa it will moving cells. 2022-03-21 18:51:52 Sketch it out on a piece of paper and see. 2022-03-21 18:52:19 I mean you have to pick the right one depending on the direction 2022-03-21 18:52:58 If you're shifting memory up a buffer use CMOVE> and if you're shifting down then use CMOVE 2022-03-21 18:53:11 Yeah, the right "< or >," not the right move size. 2022-03-21 18:54:19 Out of all the standardized Forths, Forth 79 was the one I looked at the most - I actually have a copy of the standard somewhere. So that may make my memory tainted. But here I'm just thinking about what the move does - not recollecting what the standard said. 2022-03-21 18:54:37 MOVE moving cells and CMOVE moving bytes - I guess I may recall that from the standard. 2022-03-21 18:54:41 Well FORTH 79 was a mistake because it broke so much 2022-03-21 18:54:52 And then FORTH 83 was a mistake because it broke FORTH 79 so hard 2022-03-21 18:54:57 And ANS, and 200x etc etc 2022-03-21 18:55:05 Funny - I liked that standard. But I didn't use any "external" Forth 79 Forths - I just read the standard for guidance on writing some of my words. 2022-03-21 18:55:35 And I never tried to run any "legacy code" on it - I always would have been writing new code to run on whatever system I had in front of me at the time. 2022-03-21 18:56:01 Yeah I really dislike the standards but nevertheless use my understanding of them to try writing 'portable' code 2022-03-21 18:56:11 That's what you mean by "broke so much," right? Existing code that wouldn't run on a 79 system? 2022-03-21 18:56:23 Yeah 2022-03-21 18:56:46 Stuff that's not machine-specific like MOVE shouldn't break 2022-03-21 18:57:14 A good standard should unify what people are already doing, but FORTH-79 tried to lead, and that always just creates pain 2022-03-21 18:57:28 But anyway, if the buffers overlap but the target has a higher starting address, you want to start at the top of the buffers and run down; if target is lower, you start at the bottom and run up. 2022-03-21 18:57:33 But its sins are only as great as any of the other standards 2022-03-21 18:57:37 Move bytes, cells, whatever you want. 2022-03-21 18:58:17 Both old and 79 MOVE would move cells at a time 2022-03-21 18:58:36 Just old MOVE would take bytes as the length 2022-03-21 18:59:01 Ok. I guess that may be - only the amount moved per operation varies. 2022-03-21 18:59:24 SOMEWHERE I've seen move that moved cells. 2022-03-21 18:59:30 Not sure where it might have been. 2022-03-21 18:59:39 Oh, hang on I'll check something. 2022-03-21 18:59:41 ANS' MOVE copies up or down automatically based on whether the second address is lower or higher 2022-03-21 19:01:11 Well, that's smart. Seems right for a standard word. Chuck might frown, but oh well. 2022-03-21 19:02:50 In zenv MOVE is : MOVE -ROT 2DUP < IF ROT CMOVE> ELSE ROT CMOVE THEN ; 2022-03-21 19:04:13 But I think I try to avoid assuming MOVE works like this in my code 2022-03-21 19:08:02 This site: 2022-03-21 19:08:04 https://forth-standard.org/standard/core/MOVE 2022-03-21 19:09:10 says MOVE moves n "address units." I would equate that to bytes, but it may be arguable so I regard that as vague. Maybe address units are defined somewhere else. That glossary doesn't define CMOVE. 2022-03-21 19:09:31 On the other hand, by FIG Forth book defines CMOVE but not MOVE, and says bytes. 2022-03-21 19:09:32 "address unit" means the same thing as "byte" 2022-03-21 19:09:42 I would agree with that. 2022-03-21 19:09:49 Since that's what you can address. 2022-03-21 19:09:49 I just say byte because I'm not anal like the standard 2022-03-21 19:09:57 Thank you for that. :-) 2022-03-21 19:10:15 I want people to understand what I say 2022-03-21 19:11:21 Ok, I found a Forth 79 glossary - here: 2022-03-21 19:11:26 https://www.tim-mann.org/trs80/doc/forth.pdf 2022-03-21 19:11:36 It says MOVE moves n "numbers." I would say that's cells. 2022-03-21 19:11:46 and CMOVE n bytes. 2022-03-21 19:11:54 So I no doubt recall that from my 79 standard. 2022-03-21 19:12:03 Yes FORTH 79 uses cells 2022-03-21 19:12:32 Again, I don't know why they didn't say cells, I think that terminology was already conventional 2022-03-21 19:12:43 But I don't think FORTH 79 was trying to be conventional 2022-03-21 19:12:43 There's no figuring standards. 2022-03-21 19:12:52 They get all tangled up over things. 2022-03-21 19:13:06 Yeah I don't know what the aims of these standards are, it almost feels like the aim is to annoy me :P 2022-03-21 19:13:12 Yeah - I think they were aggressively trying to "fix Forth." 2022-03-21 19:13:45 If it's a committee vs the evolved forth of the wild at any time in history, the evolved forth always won 2022-03-21 19:13:59 Yes, and that's the usual outcome. 2022-03-21 19:14:07 Committees suck, almost universally. 2022-03-21 19:14:18 But the damn things just won't die.