2023-05-25 09:15:03 I wrote up (create) for this new dictionary structure I'm planning. Just used some dummy variables so it built headers into some disk blocks. 2023-05-25 09:15:24 Seems to work quite nicely, and supports creation of both permanent and transient words. 2023-05-25 09:21:23 Recall (crerate) expects an address on the stack that it will point the new word's CFA at. The PFA is pointed at the next dictionary byte. 2023-05-25 09:21:47 For primitives the CFA would point there too (PFA field is wasted in this design for primitives). 2023-05-25 09:22:18 Header layout is 2023-05-25 09:22:31 Index just increments for each new word. 2023-05-25 09:22:52 And a word's xt is its index. 2023-05-25 09:23:12 It's like a 16-bit "token." 2023-05-25 09:23:44 The thing's going to basically be just like a byte code interpreter, except it will be a word code interpreter. 2023-05-25 09:24:57 I've also talked at times about incorporating words that reflect old HP calculator instruction names. 2023-05-25 09:25:09 On those calculators the stack registers were named x y z t 2023-05-25 09:26:16 I'm going to put those names in; basically x would be a synonym for dup (and shorter). y will be a synonym for over. z would basically be equivalent to 2 pick and t to 3 pick. 2023-05-25 09:26:36 and along with swap there will be <>y <>z <>t. 2023-05-25 09:27:44 I don't know how far I'll go with that - the calculators I used to use offered a LOT of stuff in that zone. RCL IND, STO IND, ST+ IND, etc. etc. etc. 2023-05-25 09:28:18 I like how short x y z t make things. 2023-05-25 09:30:25 Here's how nice the code wound up looking, if anyone is interested: 2023-05-25 09:30:34 https://pastebin.com/07KTJcHD 2023-05-25 09:31:59 .word will wind up being word - it just will work slightly differently in the new system and not show there is the def of .word to implement that. 2023-05-25 09:32:36 I'm going to have it take the address to place the word as a parameter, in addition to the character to parse on. 2023-05-25 09:32:59 Since I need to be able to put it in either the "permanent word place" or the "transient word place." 2023-05-25 09:33:10 Or somewhere else, in other applications. 2023-05-25 09:34:03 The transient zone pointer is zero when no transient words exist - if I create a transient word then it will get set to the next available header byte plus 4kB. 2023-05-25 09:34:15 And then additional transient words will just march it along. 2023-05-25 09:36:37 It's also smart enough to set the link field to zero for the first word in a vocabulary. 2023-05-25 09:43:09 Anyway, to create a primitive header I'd just use bp @ (create) 2023-05-25 09:44:07 I've never arrives at a name for that that I really like. I know :code or code: is common, but that's awfully long and ugly. 2023-05-25 09:44:36 I'm more inclined toward c: or -: or :: or something along those lines. 2023-05-25 09:45:06 And it really should be something that would still look reasonable with a . out in front of it. 2023-05-25 09:45:21 I think I like :: best out of those. 2023-05-25 10:38:58 And, I just got .wipe for that structure working. :-) 2023-05-25 13:46:26 Looks like it's time to give some serious thought to strings and how to work with them in Forth. 2023-05-25 13:46:46 I'll need to build and manipulate strings for these "generator scripts." 2023-05-25 13:47:16 I still like the idea of a circular buffer that I just rely on to be big enough to hold my work. 2023-05-25 13:47:52 Only I think it needs to be able to hold not just strings, but arrays of strings too, for splits and so on. 2023-05-25 13:48:26 Have things like 2023-05-25 13:49:00 s" " s" " cat count type 2023-05-25 13:49:26 s" this is a multi-word test string" bl split 3 s[] count type 2023-05-25 13:49:28 etc. 2023-05-25 13:51:43 Also, my (create) stuff isn't quite what I want. It has bl word embedded down in it, which means it's only capable of taking the word name from the input stream. 2023-05-25 13:52:27 But I want to be able to hand it a string I have constructed to be used as the new word name. So I need to re-work it so that bl word is at the very beginning, and then I can have an alternative entry that expects the string address to already be on the stack. 2023-05-25 14:04:33 I like the use of a circular buffer for hi 2023-05-25 14:04:35 this 2023-05-25 14:06:24 in my current system, strings and arrays are basically the same internally, so they use the same buffer region 2023-05-25 14:06:43 Yes. 2023-05-25 14:07:11 Do you have a dedicated buffer, or do you use space up above the dictionary? 2023-05-25 14:09:01 I'm debating internally about whether to do any operations "in place" vs. treating stuff already written to the buffer as immutable. 2023-05-25 14:09:15 E.g., copy to split, vs. split in place. 2023-05-25 14:13:08 I have a dedicated buffer 2023-05-25 14:13:43 KipIngram: split? like split on character or? 2023-05-25 14:13:51 Yes. 2023-05-25 14:14:07 Like Python .split() 2023-05-25 14:14:32 in retro, the buffer is resizable, allocated at end of memory; in konilo the buffer is fixed in size & location 2023-05-25 14:14:42 It would be easy to implement that in place - the split chars would become the count bytes of the new strings. 2023-05-25 14:14:42 if you have strings represented on stack as pointer length pairs then you do not need to copy anything around 2023-05-25 14:15:07 Hmmm. 2023-05-25 14:15:30 Well, I'd still need to put the results array of a split somewhere, but you are right about that. 2023-05-25 14:15:50 I was thinking in terms of the usual layout of a Forth counted string. 2023-05-25 14:15:58 And on stack there would just be the address. 2023-05-25 14:16:09 having a split word that splits a given string into two parts. First part is to the first split char and second part is rest. Would work 2023-05-25 14:16:28 That's true - that's a possibility as well. 2023-05-25 14:16:49 That is a bit how input lines are treated. 2023-05-25 14:16:55 Just one word peeled off at a time. 2023-05-25 14:17:22 : SPLIT ( ins inl splitter — firsts firstl seconds secondl ) ; 2023-05-25 14:17:59 or the results other way around for more ease of use 2023-05-25 14:18:48 this means you are mostly just doing pointer and length arithmetic 2023-05-25 14:18:57 I don't like the idea of addre/length on the stack much. 2023-05-25 14:19:01 Maybe it'll grow on me. 2023-05-25 14:19:57 heck you could factor SPLIT into a FIRST and SLICE 2023-05-25 14:20:26 I only keep a pointer to the string on the stack; never liked the addr/len pair approach from a stack management perspective 2023-05-25 14:20:50 FIRST finds the splitter char in the string and returns the index 2023-05-25 14:20:54 Yeah. I'd just naturally gravitated toward emulating the basic function structure that I'm familiar with in Python. But that's not necessarily the best way. 2023-05-25 14:21:38 ya not looking from the hw perspective nor how the older forths did it 2023-05-25 14:23:13 perhaps working with MCUs and 16 bit address spaces (cell or byte addressed, mainly the former) has coloured my thinking there 2023-05-25 14:23:34 I am also thinking ahead to how I want later things to work. When I'm supporting more advanced capabilities. 2023-05-25 14:24:11 I like the idea of the "one entity" on the stack giving me a handle on any kind of data structure I might want to have out there. 2023-05-25 14:24:34 string, array, list, etc. 2023-05-25 14:24:41 one reason why I came up with my object system in zeForth is that if I am going to work with things, they might as well be objects in a gc’ed memory region. 2023-05-25 14:24:41 blob 2023-05-25 14:25:24 Right, and eventually that's where I expect to land, though I'm contemplating shortcutting out the gc for these simple string apps by using the circular buffer. 2023-05-25 14:25:33 one class of objects are the ones for implementing utf-8 strings and bytestrings as ropes. 2023-05-25 14:27:19 I have a mechanism in this object system that objects can opt in to get notified if one of their references has gone linear. That is that reference is the only one pointing to the referenced object. 2023-05-25 14:28:09 have not gotten around making WeakRefs and Finalizers by using that as one of the building blocks. 2023-05-25 14:30:09 but it means that an rope slice object pointing to a big rope segment object can become just a segment with its slice copied over, freeing the originally big segment object 2023-05-25 14:31:07 just as an example of what is possible 2023-05-25 14:32:31 notabene, this object system does not use classes, each object is more like a closure that often dispatches on the first argument as the method selector. 2023-05-25 14:33:55 Yeah - I've got later plans for ropes. 2023-05-25 14:34:13 ropes are neat data structures. 2023-05-25 14:34:26 I rather do an indirect jump, run the dispatcher code of that object, than doing inflexible vlist crap that legacy C++ does. 2023-05-25 14:37:07 btw objects are basically header, xt, refs segment, data segment. 2023-05-25 14:37:43 header says it is an object, how big the two segments are. And that basically it. 2023-05-25 14:38:25 xt points to the dispatching code of the object 2023-05-25 14:39:13 so this object system is inspired in part by BUILDS> DOES> 2023-05-25 14:46:42 As far as my long-term plans go, what I've envisioned is that objects will be represented by pointers on the stack. I'll be able to follow that pointer and part of what I'll have out there will be the "type" of the object. 2023-05-25 14:47:11 So I'll know the types on the stack, and I envision using that as part of my word search criteria. Only words that match what's on the stack will get found. 2023-05-25 14:47:20 So I'll be able to overload names. 2023-05-25 14:47:54 The main goal here is to be able to use sensible math nomenclature to do math on ints, floats, vectors, matrices, etc. 2023-05-25 14:48:10 Without having to have a flock of "prefixes" on my math operators. 2023-05-25 14:48:21 But I want all that to be compile time decisions. 2023-05-25 14:48:56 Which implies a compiler that will be able to track what the stack is going to look like during various parts of a definition. 2023-05-25 15:06:52 I also want the ropes overhead to be "to the side." For example, if I have a string pointer on the stack and I KNOW it's a short string that will fit in one ropes chunk, then I want to be able to treat it exactly like I would if I weren't using ropes. 2023-05-25 15:07:38 Strings aren't necessarily a good fit with that, though - that counted string structure is only good for short strings. 2023-05-25 15:07:59 I really haven't given it all the necessary amount of thought yet. 2023-05-25 15:08:26 And right now my interest isn't in that "full on" system - I'm just looking for a modest set of operations on short strings. 2023-05-25 15:08:47 Just the necessary stuff to build the name strings for these generated words. 2023-05-25 17:13:17 I was a little wrong yesterday when I proposed I could just set six registers and start Forth. The CFA and PFA pointer tables also have to be adjusted. I might be able to work up a way to run temporarily with an alternate NEXT to make it run pre-adjustment, but I'm not sure how much payoff there is in that.