2021-12-08 01:47:02 imode: Various stacks are "(stack-id: before -- after)", where stack-id is C (control), S (data), R (return). But if it's obvious, can be omitted. 2021-12-08 01:47:12 maw 2021-12-08 01:48:20 https://forth-standard.org/standard/notation#section.2.2 2021-12-08 01:48:53 (I originally found it in some old article, but I'm not sure which; but there it is on the blagoblags) 2021-12-08 03:46:17 I tend to use ( R: x - y) 2021-12-08 03:46:38 So you know not to do that ;) 2021-12-08 03:47:37 I like the syntax FORTH Inc tend to use, which is leaving the final space out, using one dash, and only having the dash and part after if stuff is left on the stack 2021-12-08 03:47:53 And not having a comment when nothing is passed/left 2021-12-08 03:49:53 i.e. : a ( n1 n2 - n1+n2) + ; : b ( n) >in +! ; : c 1 >in +! ; 2021-12-08 03:54:01 : rdrop ( R: x) postpone r> postpone drop ; immediate 2021-12-08 03:54:45 i had an idea.. like variable or constant, what if there was a similar thing to define a string? 2021-12-08 03:56:22 i haven't thought through the syntax, but it might look like string hello "hello world" so when you execute hello, it pushes c-addr n on the stack.. you could hello type it 2021-12-08 03:57:54 it would copy the string 2021-12-08 03:58:55 like : hello s" hello world" ; 2021-12-08 05:44:20 dave0: I've got s, which puts a counted string in the dictionary, so you could do: create hello '"' parse hello world" s, hello count type 2021-12-08 05:46:01 For your forth maybe you can have something like `s,"` to parse next string and put it in dictionary, leave address and size on stack, then you can do `2constant hello` after 2021-12-08 05:46:45 So something like `s," hello world" 2constant hello hello type` 2021-12-08 05:47:28 Adding a string to the dictionary is a pretty common operation I find 2021-12-08 05:56:18 you can declare numbers and doubles as variables, so why not strings :-) 2021-12-08 05:56:36 No you can't 2021-12-08 05:56:46 You can't declare a specific number/double as a variable 2021-12-08 05:57:04 You can just say "reserve space for a number", "reserve space for a double" 2021-12-08 05:57:16 oh 2021-12-08 05:57:27 So 9 times out of 10 I find myself writing `create x 0 ,` instead of `variable x 0 x !` 2021-12-08 05:57:55 I find `variable` et al to be quite useless 2021-12-08 05:58:20 hmm 2021-12-08 05:58:44 I don't like `value`, I think it overcomplicates it, the standard is lacking a word to get the address of the value in-memory 2021-12-08 05:59:32 do you use `constant` and `2constant` ? 2021-12-08 05:59:38 Yes 2021-12-08 05:59:56 i should call my idea `sconstant` 2021-12-08 06:00:08 Maybe 2021-12-08 06:00:11 sconstant" 2021-12-08 06:00:22 Always end the word name with " if it's going to parse to " 2021-12-08 06:00:42 ah nice tip! let me check my code 2021-12-08 06:00:59 As you know forth is very dogmatic and we all write the exact same way ;) 2021-12-08 06:01:06 No but that is a good convention, in my opinion 2021-12-08 06:03:07 I'm not just saying this because my forth syntax highlighting script for vim uses that as a cue to highlight a string.... (promise) 2021-12-08 06:03:33 i don't have any counted strings, but i wrote a non-standard `"literal,` which takes c-addr n and copies it into the dictionary 2021-12-08 06:04:24 it actually copies `"literal` before the string, which at runtime pushes c-addr n on the data stack 2021-12-08 06:04:52 and skips the string 2021-12-08 06:05:14 so it doesn't really work for `sconstant"` 2021-12-08 06:05:30 Maybe cstring, or something, I don't expect to see '"' unless some string is getting parsed right now 2021-12-08 06:05:49 I would prefix string stuff with 's' over '"' 2021-12-08 06:05:57 ah 2021-12-08 06:05:59 `cstring,` I mean 2021-12-08 06:06:13 i didn't know what not to do so i copied gforth 2021-12-08 06:06:15 Or `name,` 2021-12-08 06:06:43 jonesforth is probably better to copy than gforth, if you want something clean and factored 2021-12-08 06:06:43 sorry, but i hate counted strings :-) 2021-12-08 06:06:48 I know 2021-12-08 06:07:01 But you have a backwards version of them in your dictionary for names, right? 2021-12-08 06:07:12 `name,` I think is probably the best name for that operation 2021-12-08 06:08:51 right now i have a different linked list for the length of each name 2021-12-08 06:09:03 organized as an array of lists 2021-12-08 06:09:06 ohhhh 2021-12-08 06:10:14 keep it stupid, simple 2021-12-08 06:11:09 yesterday and today i was thinking about how to redesign the lists of headers 2021-12-08 06:11:42 it needs more thought :-) 2021-12-08 06:11:49 The most important thing to remember is to not optimise it for performance 2021-12-08 06:12:20 Because a dumb linked list was fast enough for a bloody 80s 8-bit micro, so it's fast enough for you 2021-12-08 06:14:05 On any modern machine a dictionary within an order of 1000 entries is going to appear to compile code from nice and fast, and do a line of lookups 'instantly' 2021-12-08 06:15:22 having 31 linked lists for each different name length /is/ a bit of an optimization but not super complicated 2021-12-08 06:15:40 and it only takes up 128 bytes 2021-12-08 06:16:07 but it makes it difficult to redesign 2021-12-08 06:16:08 It's not a very good optimisation IMO, and complicates it 2021-12-08 06:16:30 You might as well put in 32 lists according to hash%32 2021-12-08 06:16:43 it's not quite a hash 2021-12-08 06:17:02 and it saves a comparison of the length in `find` 2021-12-08 06:17:07 Length is a (bad) hash 2021-12-08 06:17:12 True 2021-12-08 06:17:35 But have you thought about how you will implement wordlists? 2021-12-08 06:17:37 you have a point about not optimizing yet 2021-12-08 06:17:54 no, not even thought about wordlists! 2021-12-08 06:18:15 I only have one list to traverse, names and bodies are both on that list. A new wordlist for me is as simple as starting a new list entry point 2021-12-08 06:18:24 You'd have to add a whole new 128 byte array 2021-12-08 06:19:11 wordlists are a powerful datastructure IMO, and useful for organising code, even though the standard words for manipulating them are a bit unloved they are a good idea overall 2021-12-08 06:19:30 i am not up to that yet :-p 2021-12-08 06:20:44 the next thing to code is `variable` and `constant` 2021-12-08 06:21:30 one thought on the dictionary was to not even use a linked list, and instead use a table 2021-12-08 06:22:25 : variable create 0 , ; : constant create , does> @ ; \ (don't actually do this, it's faster to add an appropriate code field for constant) 2021-12-08 06:22:41 aha i haven't written `create` yet 2021-12-08 06:23:05 That would make more sense to do first 2021-12-08 06:23:19 right 2021-12-08 06:24:21 The variable above is fine, constant deserves an optimized code field word (like create will have) 2021-12-08 06:24:37 I'm assuming you've not done does> or (does) yet either? 2021-12-08 06:24:49 correct. no does yet 2021-12-08 07:10:49 okay that took forever 2021-12-08 07:12:29 veltas: how do you feel about defined constant like `: myconst >r : r> postpone literal postpone ; ;` the >r r> shuffle worked on gforth 2021-12-08 07:12:41 instead of using `create` ? 2021-12-08 07:15:07 defining* 2021-12-08 07:19:08 That's the right way to do it on a subroutine threaded forth 2021-12-08 07:19:44 What is yours? Indirect? 2021-12-08 07:19:56 yes indirect threaded 2021-12-08 07:20:14 You should have a special routine for constants, to put in the code field 2021-12-08 07:20:31 Have a word that swaps the current code field with the given word 2021-12-08 07:22:04 is that better than generating code with `:` ? i know it wastes a couple of words, but is there another reason? 2021-12-08 07:22:48 ( Do something like... ) : constant create -1 cells allot ['] (constant) , , ; 2021-12-08 07:22:58 Wasting words would be the reason 2021-12-08 07:23:13 On a subroutine threaded forth it's actually optimal to just compile a colon word 2021-12-08 07:23:29 ahh 2021-12-08 07:23:37 Assuming your literal is properly optimised, which it'd better be!!! 2021-12-08 07:23:52 yeah right it would just be a move? 2021-12-08 07:24:03 push eax ; mov eax,constant 2021-12-08 07:24:11 Yeah something like that 2021-12-08 07:24:25 Or a xor eax, eax if you push 0 2021-12-08 07:24:38 The right opcode for different sizes, i.e. if it's imm8 2021-12-08 07:24:39 ahaha nice optimization 2021-12-08 07:25:25 i think you said your forth was subroutine threaded? which cpu do you target? 2021-12-08 07:25:33 A subroutine threaded forth doesn't have 0 or 1 as words, indirect/direct threaded will tend to have them to reduce dictionary size 2021-12-08 07:25:36 amd64 2021-12-08 07:25:57 cool 2021-12-08 07:26:10 okay i'll be back in a few minutes, i'm gonna make some toast 2021-12-08 08:08:57 aha my string idea is in principle possible (but the syntax is ugly) `: sconstant" : [char] " parse postpone sliteral postpone ; ;` 2021-12-08 08:10:30 so that would be `sconstant" msg hello world"` and then `msg type` 2021-12-08 08:11:02 ugly that the name of the word `msg` isn't part of the string 2021-12-08 08:13:10 In my forth you would just `: msg s" hello world" ;` 2021-12-08 08:14:54 ah yes that's nice and standard :-) 2021-12-08 08:16:06 but in theory you could do the same technique for `5 constant test` and `: test 5 ;` 2021-12-08 08:16:40 it's a bit academic though 2021-12-08 08:16:54 With STC that would do the same thing 2021-12-08 08:19:56 The question is, when do I want a string-constant? It's not something I've wanted very often 2021-12-08 08:20:06 Usually I'm okay inlining a string where it is 2021-12-08 08:21:15 If you parse the first word up to '"' then you can make your syntax a little nicer/hackier: `sconstant msg" hello world" msg type` 2021-12-08 08:21:36 oh that's tricky! 2021-12-08 08:21:47 Since you're writing your own forth you can work around the fact `:` expects a name 2021-12-08 08:21:59 In standard forth it does indeed get tricky 2021-12-08 08:23:01 But I don't like that syntax much, but I like it more than the alternative 2021-12-08 08:23:54 i had another silly idea that when you use `2constant` that it parses the number at the start and make the constant that long heh.. `5 6 7 3constant xx` and `9 9 9 9 4constant yy` but this is getting silly :-) 2021-12-08 08:25:15 Don't implement this word until you actually want it 2021-12-08 08:25:21 I suspect you won't 2021-12-08 08:25:29 maybe an interesting use of the `sconstant"` would be to define the prompt ... sconstant" ok bueno" 2021-12-08 08:25:33 It's not worth it to replace one or two : x s" msg" ; 2021-12-08 08:25:54 Just make the prompt a 2variable, not a 2constant 2021-12-08 08:26:09 ah good idea yes 2021-12-08 08:27:06 Here's an idea: : msg [' 2021-12-08 08:27:09 Whoops 2021-12-08 08:27:12 Ignore that 2021-12-08 08:27:21 I've given up on idea already lol, bad enter 2021-12-08 08:27:21 :-) 2021-12-08 08:27:44 okay i gotta brush my teeth brb 2021-12-08 08:27:46 forth is not about creating a master set of words you can use to write any program, that's not the idea at all 2021-12-08 08:27:52 It's about crafting the right words for the right problem 2021-12-08 08:28:14 And then maybe after you've nailed down a number of programs you might have a good idea of words that are actually worth reusing 2021-12-08 08:38:18 that's different to what i'm used to 2021-12-08 08:42:30 Yeah it takes some getting used to, it's easier to learn that while trying to write forth programs rather than implementing a forth 2021-12-08 08:42:57 Because forth is kind of a big forth program anyway and it's often easier to learn stuff with short/sweet programs you don't sweat over quite as much 2021-12-08 08:45:16 i'm very much a forth newbie 2021-12-08 08:46:11 okay i've put the string constant thing aside 2021-12-08 09:22:19 I'm a newbie compared to some of the dragons lurking around here 2021-12-08 09:22:39 Only been writing forth for a couple years or so 2021-12-08 09:50:48 Interesting, mentions fixed point as well https://blog.segger.com/algorithms-for-division-part-4-using-newtons-method/ 2021-12-08 09:51:23 No idea how relevant it is though, if you've got a division instruction probably not 2021-12-08 12:44:50 do forths usually have repls that show stack effect comments when moving the cursor over words? that seems like it might be useful? 2021-12-08 12:46:33 ecraven: I've explored that with editors, but not in a repl 2021-12-08 12:47:06 I'm specifically wondering whether Emacs could maybe do this ;) 2021-12-08 15:11:44 It seems like for an STC Forth on x86 that uses CALL rel32 (0xE8 xxxxxxxx) for subroutine calls, implementing COMPILE (Std. 79/83) requires reading the PC register to reconstruct the code address of the next "call token" in the thread. 2021-12-08 15:12:55 The thread looks like this: call COMPILE \ call SOME_WORD. COMPILE should read SOME_WORD, but it's encoded as relative to current PC. 2021-12-08 15:15:22 Uh nevermind! PC is already in the return stack. 2021-12-08 16:44:50 What we really need is a forth text editor 2021-12-08 16:49:17 to block edit? 2021-12-08 16:58:36 like emacs, but with forth instead of lisp? 2021-12-08 17:00:03 veltas: Absolutely 2021-12-08 17:00:08 potatoalienof13: Yes 2021-12-08 17:01:05 Does : FOO 42 ; and : FOO [ 42 ] LITERAL ; compile exactly the same thing? 2021-12-08 17:01:55 https://github.com/ForthHub/ForthFreak/blob/master/VIBE exists, but its very bare bones 2021-12-08 17:04:04 neuro_sys_: you can always `SEE` it :P 2021-12-08 17:09:31 Hah good reminder. 2021-12-08 17:19:50 neuro_sys_: Not necessarily 2021-12-08 17:19:58 Depends on the forth, optimizations 2021-12-08 17:20:04 should do same thing though 2021-12-08 17:20:45 neuro_sys_: not really good as I suspect one could be compiled slightly differently, as veltas notices 2021-12-08 17:30:27 Right 2021-12-08 17:31:00 Off-topic but, meanwhile in another place, three birds are sleeping at -23 Celcius: https://www.youtube.com/watch?v=LsYC99Z5Coc 2021-12-08 17:31:08 cute! 2021-12-08 18:04:04 Brisk 2021-12-08 18:04:33 I hope they don't freeze! Poor birbs 2021-12-08 19:56:08 maw