2021-12-04 04:40:06 dave0: In my opinion the dictionary is just another stack, just more flexible than the other stacks 2021-12-04 04:40:16 , is your push 2021-12-04 04:40:25 -4 allot is your pop 2021-12-04 04:40:41 And you can push/pop other things than cells, including words 2021-12-04 04:40:55 It's turtles all the way down 2021-12-04 04:46:18 maw veltas 2021-12-04 04:47:02 allot is simplicity itself 2021-12-04 04:47:25 my allot is : allot here +! ; 2021-12-04 04:47:38 Yep 2021-12-04 04:47:55 In most forths the variable is h 2021-12-04 04:48:08 So you'd do : allot h +! ; : here h @ ; 2021-12-04 04:48:36 I guess you've got some kind of interesting stuff happening with values or something? 2021-12-04 04:48:44 oh i just made here a normal variable 2021-12-04 04:49:32 So you have to do here @ to get the dp? 2021-12-04 04:49:59 veltas: nothing interesting.. i read the 2012 standard and did it in a way i thought of as sensible 2021-12-04 04:50:07 yeah 2021-12-04 04:50:28 hang on i'll bring up my code 2021-12-04 04:50:47 Okay but I will say here is one of those words people expect to just give them the next dictionary address 2021-12-04 04:51:15 Of course, you can always add an optional compatibility library for your forth, to make words align closer to convention 2021-12-04 04:51:38 that's what i was thinking 2021-12-04 04:51:45 That's my plan, because I (for example) am avoiding doubles because I think they're pointless for a 64-bit forth 2021-12-04 04:52:58 veltas: my number and the pictured words don't use double 2021-12-04 04:53:12 Yep same here 2021-12-04 04:53:26 And I'm naming negate and invert: minus and not 2021-12-04 04:53:33 the only doubles i have are m+ um* um/mod umsqrt 2021-12-04 04:53:53 oh i can't believe invert! 2021-12-04 04:54:12 Why um/mod? 2021-12-04 04:54:35 um/mod for pictured # 2021-12-04 04:54:49 I'm not using doubles for # 2021-12-04 04:55:45 i'm trying to remember my reasons 2021-12-04 04:56:46 : # ( n -- n) 0 base @ um/mod swap dup 9 > IF 39 + THEN [char] 0 + hold ; 2021-12-04 04:56:52 sm/rem and fm/mod are alternative forms of what was called m/mod in old forths 2021-12-04 04:56:53 i pushed a 0 2021-12-04 04:56:59 And you had m/ as well 2021-12-04 04:57:16 i think i copied it from jonesforth 2021-12-04 04:57:55 um/mod takes a double and divides it by a single 2021-12-04 04:58:07 So your # right now expects a double, not a single 2021-12-04 04:58:20 Oh no I'm wrong 2021-12-04 04:58:23 You put 0 in there 2021-12-04 04:58:35 I think he uses it because there's no u/mod in standard forth 2021-12-04 04:59:09 i found i could write all the multiply and divide primities with um* and um/mod 2021-12-04 04:59:16 I'm writing my forth pretty much entirely in assembly so I'm just using div 2021-12-04 04:59:19 Yes you can 2021-12-04 04:59:42 Except m*/ 2021-12-04 04:59:46 oh and also it was a nod to arbitrary precision 2021-12-04 04:59:58 But you don't want m*/ if you're not doing doubles 2021-12-04 05:00:36 arbitrary precision you really want to go to assembly and just take advantage of carry/overflow 2021-12-04 05:01:35 that's how i implemented m+ um* um/mod 2021-12-04 05:01:46 with adc 2021-12-04 05:01:53 What arch? 2021-12-04 05:02:08 x86 2021-12-04 05:02:17 64-bit too? 2021-12-04 05:02:57 yes at first but i am currently concentrating on my 32 bit 8086 code (it runs under msdos ie. dosbox) 2021-12-04 05:03:34 i started a 128 bit amd64 forth that runs under *nix 2021-12-04 05:04:08 i wrote lots of assembly primitives, but then i started over with 8086 2021-12-04 05:04:51 when i finish the 8086 version i will take what i learned and finish the amd64 version 2021-12-04 05:05:08 Well good luck with that 2021-12-04 05:05:17 DOS is easier in my opinion, so maybe it's good practice 2021-12-04 05:05:18 thanks :-) 2021-12-04 05:05:45 32-bit in 8086 is harder though 2021-12-04 05:06:22 In 64-bit um/mod is literally just the div instruction 2021-12-04 05:06:23 yes 2021-12-04 05:06:32 sm/rem is just idiv 2021-12-04 05:07:03 yes but the amd64 div instruction is really a 128 bit divided by 64 bit instruction 2021-12-04 05:07:13 so it matches um/mod perfectly 2021-12-04 05:07:15 Yes 2021-12-04 05:07:20 That's what I said 2021-12-04 05:07:22 I will admit dave0 that I've been kind of learning and cheating by getting clang/gcc to write many basic ops for me in compiler explorer 2021-12-04 05:07:56 Also got good ideas for how to optimise producing 0/-1 on comparisons etc 2021-12-04 05:08:13 nice 2021-12-04 05:08:39 i enjoy assembly a lot 2021-12-04 05:09:03 yes msdos is easier for assembly 2021-12-04 05:09:16 I know the basic set of instructions but some of the more specific x86, especially boolean stuff, it's useful to just build stuff and see what the right instructions are 2021-12-04 05:09:46 x86 has only got more complicated 2021-12-04 05:10:00 Also there are some x86 instructions you want to avoid because they're just slower 2021-12-04 05:10:10 Not so much on an 8086 2021-12-04 05:10:42 i don't actually know how to code for msdos 2021-12-04 05:11:10 but i studied ralf browns interrupt list and learned how to write a master boot record 2021-12-04 05:11:44 There's just a load of interrupt-based calls you can do 2021-12-04 05:11:53 yep 2021-12-04 05:12:07 It's kind of like Linux tbh, 32-bit Linux syscalls were implemented with interrupts 2021-12-04 05:12:17 what os are you developing your forth on? 2021-12-04 05:12:24 Linux, 64-bit 2021-12-04 05:12:27 ah okay 2021-12-04 05:12:35 i'm on netbsd 2021-12-04 05:12:50 If I finish it I would consider porting to BSDs 2021-12-04 05:13:04 how did you implement emit ? 2021-12-04 05:13:21 i called back to C for emit and key 2021-12-04 05:13:41 I've not done that yet but I will somewhere be using the write syscall 2021-12-04 05:13:45 so i use the c functions putchar and getchar and i don't use syscalls 2021-12-04 05:13:51 ah yes 2021-12-04 05:14:02 syscalls are too low level for me 2021-12-04 05:14:12 That's what you use in dos though 2021-12-04 05:14:16 Maybe you'd prefer it 2021-12-04 05:14:27 true 2021-12-04 05:14:44 but dos doesn't run on amd64 :-p 2021-12-04 05:16:20 My emit runs type 2021-12-04 05:16:26 I have a user variable 'type 2021-12-04 05:16:39 So you can override what type (and emit) does anywhere 2021-12-04 05:16:47 nice 2021-12-04 05:16:59 so you could switch from the keyboard to a file? 2021-12-04 05:17:13 I'm not sure how I'll do input but I want to start with basic I/O, not all the fancy key/at etc you get with a normal forth 2021-12-04 05:17:36 Which will call read on stdin 2021-12-04 05:18:09 dave0: Yes 2021-12-04 05:19:06 Also you could do 'type @ 2write 'type ! ." this will go to stderr" 'type ! 2021-12-04 05:19:17 i wrote a simple C file that the assembly interfaces with.. my emit actually saved all the registers and called the c function conputc which is a c function int conputc() { putchar(character); } 2021-12-04 05:19:36 Or 3write whatever stderr is 2021-12-04 05:19:56 syscalls are not portable between linux and netbsd 2021-12-04 05:20:11 Yeah 2021-12-04 05:20:21 which is important because i originally started on linux (until the computer blew up :-) then continued on netbsd 2021-12-04 05:20:28 I'm willing to write different syscall bits for different kernels 2021-12-04 05:20:52 In the back of my head I want to try porting to OpenBSD 2021-12-04 05:21:04 Kip Ingram uses macosx and i remember him struggling with macosx syscalls 2021-12-04 05:21:10 I think it will be easy, as long as syscall stuff is properly isolated 2021-12-04 05:21:50 i've never tried openbsd but they all have a common ancestor 2021-12-04 05:22:10 linux didn't 2021-12-04 05:22:11 openBSD is a fork of netBSD 2021-12-04 05:22:26 The AMD64 version of both is older than the fork, so they could be different 2021-12-04 05:22:31 Probably not though 2021-12-04 05:22:41 Sorry newer than fork I mena 2021-12-04 05:23:13 have you implemented ' ['] postpone in your forth? 2021-12-04 05:24:04 I did in zenv I think 2021-12-04 05:24:24 ' and ['] can be implemented in standard forth 2021-12-04 05:24:48 i'm trying to get my head around how they work 2021-12-04 05:24:55 What part? 2021-12-04 05:24:58 because i have come to a point where i need them 2021-12-04 05:25:39 ' just looks a word up, you need find (or a version of find that takes a string and not a counted string) 2021-12-04 05:26:01 ['] does the same immediately and then compiles value with LITERAL 2021-12-04 05:26:30 What kind of threading do you have? 2021-12-04 05:26:36 indirect 2021-12-04 05:26:41 Classic 2021-12-04 05:26:51 yes 2021-12-04 05:27:53 because it's dos, you have to fuss around with segment registers 2021-12-04 05:28:16 I don't mean classic in a bad way 2021-12-04 05:28:20 I think they're all legit 2021-12-04 05:28:54 yep i got that vibe 2021-12-04 05:30:32 Mine is subroutine threaded because eventually I want to do some simple optimisations 2021-12-04 05:30:39 Or I'd just do direct threading 2021-12-04 05:31:17 ooh have you seen taliforth ? 2021-12-04 05:31:23 No 2021-12-04 05:31:25 it is subroutine threaded for the C64 2021-12-04 05:31:41 I don't know how nice subroutine threading is on 6502 2021-12-04 05:31:50 https://github.com/scotws/TaliForth2 2021-12-04 05:32:19 That sounds like a really bad idea, gut feeling 2021-12-04 05:32:25 lol 2021-12-04 05:32:32 6502 is very verbose already, I would immediately go to direct threading 2021-12-04 05:33:15 I don't want a 50% overhead or worse on every colon def 2021-12-04 05:33:39 It's not an 8-bit mindset IMO 2021-12-04 05:34:16 oh i see what you're saying yeah it is a jmp xxxx 3 bytes instead of 2 2021-12-04 05:34:22 or call xxxx 2021-12-04 05:34:39 it does inlining 2021-12-04 05:34:44 lol 2021-12-04 05:34:53 That's already too complicated for 8-bit 2021-12-04 05:35:25 You don't have room to write the logic for inlining, especially not in 6502 which is fat 2021-12-04 05:37:19 could i write this? : ' word find 0= IF ." unknown word" abort THEN ; 2021-12-04 05:37:57 my word and find are non-standard but the idea is just look up the next word and leave the xt on the stack 2021-12-04 05:38:29 i am confident i can write ' without too much trouble ... but i want to build on ' to write ['] 2021-12-04 05:38:38 I prefer parse-name over word 2021-12-04 05:39:28 : ' parse-name sfind ?dup 0= if what? then drop ; 2021-12-04 05:39:37 yeah my word actually is parse-name .. it parses with whitespace and pushes a string c-addr n on the stack 2021-12-04 05:39:37 That's zenv's tick 2021-12-04 05:39:43 Cool 2021-12-04 05:40:06 my find is : find ( c-addr n -- xt true | false) 2021-12-04 05:40:11 So basically the same as you then 2021-12-04 05:40:25 yep 2021-12-04 05:40:43 i have my head around the parsing words and searching the dictionary 2021-12-04 05:40:58 And then : [' 2021-12-04 05:40:58 but the compiler is harder 2021-12-04 05:41:01 Whoops 2021-12-04 05:41:14 And then : ['] ' postpone literal ; immediate 2021-12-04 05:41:31 aha 2021-12-04 05:42:14 so ['] is immediate, but ' is not, correct? 2021-12-04 05:42:50 these 3 words makes my head spin 2021-12-04 05:43:23 Yes 2021-12-04 05:43:44 is this right? : postpone ' compile, ; immediate 2021-12-04 05:43:58 No 2021-12-04 05:44:04 doh 2021-12-04 05:44:18 https://github.com/Veltas/zenv/blob/master/src/zenv.asm 2021-12-04 05:44:29 line 5097 2021-12-04 05:44:50 ooh XZ spectrum! 2021-12-04 05:45:11 That's the last forth I wrote 2021-12-04 05:45:25 oops i bumped the letters :-p ZX 2021-12-04 05:45:33 direct threading with optional tokenising 2021-12-04 05:47:49 ah okay i'm looking at 5097, you have the forth code in the comments 2021-12-04 05:48:09 Yes 2021-12-04 05:48:49 It's there to help write a cross forth to build it if I ever decide to 2021-12-04 05:49:05 so if the postponed word is immediate, you do compile, 2021-12-04 05:49:15 Yes 2021-12-04 05:49:47 what do you do if the postponed word is not immediate? 2021-12-04 05:50:14 (PP) instead compiles a word when run 2021-12-04 05:50:39 Line 5079 2021-12-04 05:50:48 Line 5076 * 2021-12-04 05:52:31 : (pp) r> dup @ compile, cell+ >r ; 2021-12-04 05:53:34 okay i need to think about that 2021-12-04 05:54:07 So r> takes the address of the embedded word in the colon definition 2021-12-04 05:54:22 (the next address in colon def is the 'return address' normally) 2021-12-04 05:55:01 It uses it to get the embedded word, compiles that, and then adds to the address to get the actual next address to return to before putting it back on return stack 2021-12-04 05:55:37 When (pp) is used the colon word will contain: <(pp)> 2021-12-04 05:55:55 So address of is in return stack when (pp) is called 2021-12-04 05:56:05 When we leave address of is left on return stack 2021-12-04 05:56:13 And value of has been sent to compile, 2021-12-04 05:56:20 Okay g2g, hope that explains it lol 2021-12-04 05:56:27 okay thanks veltas 2021-12-04 05:56:42 cya laters 2021-12-04 05:56:45 Cya 2021-12-04 09:43:34 A lot of 'raw' words are like that, manipulate return address to get embedded data and update return address to follow that data 2021-12-04 14:30:15 How do people usually handle BASE being out of bounds? e.g. if the user does `37 BASE ! asdf .' should the text interpreter just bail out? 2021-12-04 14:57:03 Or I guess alternatively, I could consider there to be no parsable base-0 numbers, and no digits for base>36, but still allow parsing of base-37 numbers 2021-12-04 23:11:27 https://github.com/nineties/planckforth this is neat. 2021-12-04 23:16:39 this is more instructive, imo, than jonesforth.