2023-05-15 05:31:05 unjust: The joke is Perl is awk 2.0, although I'm not sure irssi is even written in Perl, but its plugins are 2023-05-15 05:35:57 safe to say I was disappointed by the CTCP version response 2023-05-15 05:37:11 I wouldn't be surprised if someone's written at least the message handling code of an irc client in awk though 2023-05-15 05:49:26 this is one is a shell script, riding on top of a program that acts like tee for stdin to merge input from a named pipe, and socat. 2023-05-15 05:55:51 noice 2023-05-15 05:56:27 I can't run stuff like that, my IP has been restricted by libera.chat to only allow a certain authentication protocol 2023-05-15 05:56:32 So I can't use raw IRC to connect 2023-05-15 05:57:03 I'm assuming because digital ocean networks caused a lot of spam during the drama 2023-05-15 05:57:08 Yeah sasl 2023-05-15 05:58:18 It's not that hard to support unencrypted/raw sasl 2023-05-15 05:58:27 But most of these minimalist scripts don't 2023-05-15 05:59:08 that's why i had chosen socat, for the OPENSSL feature it offers 2023-05-15 06:00:09 so all irc input is fed to: socat - OPENSSL:irc.libera.chat:6697 2023-05-15 06:00:23 As far as I know SASL is totally separate to SSL/TLS 2023-05-15 06:00:25 and it deals with the crypto 2023-05-15 06:00:56 i haven't used SASL at all, but i was under the impression it was a means of identifying clients by certificate instead of passphrase 2023-05-15 06:01:01 It's an optional authentication method on top of whatever connection you're using, whether TCP or TLS 2023-05-15 06:01:14 You can use passphrase, certificate, etc 2023-05-15 06:01:19 It's flexible 2023-05-15 06:03:05 are there any irc clients written in forth that you're aware of? 2023-05-15 06:03:58 No, but I don't think it would be too hard to write one as a layer on top of socat or something 2023-05-15 06:04:50 It's an interesting problem, I think, doing it that way. Implementing the whole stack is more tedious 2023-05-15 07:49:55 Well, I found something interesting last night. The vocabulary stuff nominally works, and I did discover my FIND will indeed work in the presence of a multi-vocabulary search path. 2023-05-15 07:50:47 However, if I create a new vocabulary and make it current so it receives new definitions, but then drop it from the search path, then when I compile a bunch of code it exposes a bug. 2023-05-15 07:51:16 This is of course not expected to "work," because later code compiled can't find the definitions created by earlier code. 2023-05-15 07:52:03 But the "bug" is that the error recovery system doesn't catch this cleanly. I should just get a "word not found" error when I try to use a definition in the current vocabulary without that voc in my search path. 2023-05-15 07:52:10 But instead this will crash the system. 2023-05-15 07:52:21 So that's odd - I haven't gotten it sussed out yet. 2023-05-15 07:56:30 This isn't a situation one would normally create - most of the time you will want to have the voc receiving definitions in the search path too. 2023-05-15 07:57:26 But there are "special situations" like cross compiling where you might want to be able to create some word foo but still RUN a previously existing foo in the original system. 2023-05-15 08:01:41 I don't know yet whether the problem is in the existing system code or in the new vocabulary word code. I'll check that by manually creating a multi-vocabulary state without using the voc words. 2023-05-15 08:23:16 Profiling my assembly ilo it's around twice as fast as the C VM, although hard to tell accurately on this server 2023-05-15 08:25:11 crc: As I say above, my assembly ilo is about twice as fast doing a simple increment loop test at first glance (I expect less visible difference on I/O) 2023-05-15 08:25:53 Although it's got some bugs to fix still, I don't mind sharing the state of the code as it is now because it might be interesting to you anyway 2023-05-15 08:26:07 Well I'll do that tonight probably, after work 2023-05-15 08:27:36 veltas: sounds good; I'll look forward to seeing it 2023-05-15 08:28:56 crc: Ah, here it is https://termbin.com/rnct 2023-05-15 08:29:34 Not finished and it's got linux syscalls (probably easy to convert to OpenBSD if you want to try it?) 2023-05-15 08:31:35 But the choices that I'm guessing help performance are all present: using a jump table, more reliance on registers rather than memory, using a TOS register, etc 2023-05-15 08:40:14 Did you upload a web konilo somewhere? 2023-05-15 08:45:59 Ah, found the problem. 2023-05-15 08:46:32 When CREATE calculated the distance back to the previous word, to set the link field, it wasn't checking for the vocabulary being empty. 2023-05-15 08:46:47 It presumed there was a real word there to back-calculate to. 2023-05-15 08:47:09 That was easy to fix - I just factored an lfa - into a new word and put a .0=; at the beginning. 2023-05-15 08:48:36 Now as far as I can tell it works just fine with manually built vocabulary structure. 2023-05-15 09:02:27 veltas: forth.works/demo 2023-05-15 09:02:58 doesn't have saving blocks to IndexedDB working yet; they are cached in RAM currently. 2023-05-15 09:15:03 Nice, thanks 2023-05-15 09:36:35 it looks like there is a bug in the `di` instruction 2023-05-15 09:40:50 Ok, vocabularies seem to be nominally working now. 2023-05-15 09:42:21 The way it works at the moment, "forth" isn't REALLY a vocabulary. It has the data structure of one, but not the runtime behavior. But I may just leave it like that and take the position that forth stays at the bottom of the path. 2023-05-15 09:42:45 vdrop won't drop the last vocabulary in the list, so that effectively means forth is always there. 2023-05-15 09:42:53 crc: Hmmm, that is probably true based on the things that are going wrong, but I can't spot the bug 2023-05-15 09:44:26 Oh maybe the parameters are wrong way around? 2023-05-15 09:44:33 it should be returning the dividend and the remainder, it appears to only be returning one of them (`#100 #90 n:divmod depth/data n:put` shows 1 item; there should be 2) 2023-05-15 09:44:39 Oh okay 2023-05-15 09:45:06 I need to not subtract from rbx and move remainder to stack 2023-05-15 09:45:25 That explains why the stack's being depleted by konilo then, thanks for finding that! 2023-05-15 09:46:38 no problem :) 2023-05-15 09:47:38 So replace line "sub $4, %rbx" with "mov %edx, (%rbx)" 2023-05-15 09:47:47 And now I can list blocks lol 2023-05-15 09:48:32 I'm interested to know if you do any profiling to see how it compares 2023-05-15 10:06:27 just one quick test for now: forth.works/temp/bench.txt 2023-05-15 10:07:21 Nice 2023-05-15 10:07:31 it's noticeably faster at generating the mandelbrots. i/o performance seems pretty similar. 2023-05-15 10:34:04 updated w/something that reflects i/o performance on reading the blocks a bit more. Your implementation is faster on that as well. 2023-05-15 10:49:55 Lovely, although not quite as much of a difference, which is what I expect 2023-05-15 12:12:57 You know, it's quite handy to be able to do a conditional return regardless of the state of the stack and know that a stack frame above will take care of cleaning things up. 2023-05-15 12:13:17 That wasn't the "point" for which I designed my stack frame thing, but it turns out to be a damn pleasant side benefit. 2023-05-15 12:13:51 My vocabulary word looks like this: 2023-05-15 12:14:02 : voc builds> 0 , 0 , 0 , does> { .voc 1 } ; 2023-05-15 12:14:23 That frame around .voc guarantees the right stack on exit, so it just doesn't matter what's on the stack when control arrives back there. 2023-05-15 12:14:46 So control can come back there from various places, with different stack states. But it just "gets handled." 2023-05-15 12:15:53 The voc address is on the stack when we get to that does> code - the 1 before } tells it to drop that. So it's guaranteed to leave a clean stack. 2023-05-15 12:16:40 For this little task I used two stack frames, but didn't use the actual stack access words (the whole original point of the feature) at all. 2023-05-15 12:17:20 It means I don't have to complicate the code to ensure balanced returns. 2023-05-15 12:40:23 veltas: http://forth.works/temp/ilo-amd64-openbsd.s is adapted to work on openbsd (or http://forth.works/temp/ilo-amd64-openbsd.patch for a diff); I'll be able to adapt this for FreeBSD & NetBSD tonight if my n 2023-05-15 12:40:33 wrist pain subsides a bit 2023-05-15 12:44:40 Awesome 2023-05-15 12:46:33 for freebsd, it'll just need to remove the .note.openbsd.ident section and update the syscall numbers. I'll have to check to see if netbsd requires an ident section. 2023-05-15 13:16:33 it's slow at work, so I try to adapt this for freebsd, but am getting an error: 2023-05-15 13:16:33 ilo-amd64-freebsd.s:264:9: error: invalid operand for instruction 2023-05-15 13:26:35 sounds like clang 2023-05-15 13:26:45 repe cmpsl probably works 2023-05-15 13:27:26 Couldn't you also do repe cmps 2023-05-15 13:27:37 where calls out the size of the argument? 2023-05-15 13:28:03 I think that's how I do it; I've got an s= word that does a counted string compare. 2023-05-15 13:28:39 it might complain about being unable to infer which size you might 2023-05-15 13:28:44 want 2023-05-15 13:29:19 well, you'd tell it, with something like dword [rsi] or something. 2023-05-15 13:29:51 if all else fails, just feed it f3 a7 :) 2023-05-15 13:29:51 Oh, no I didn't do that - I just used repe cmpsb 2023-05-15 13:30:41 In the old days I used the MSB of the count byte as a flag, and that kept me from being able to use a rep string compare. 2023-05-15 13:31:11 But later I migrated that flag into the link field precisely so that I could do a clean compare of dictionary name strings with parsed word strings. 2023-05-15 13:31:42 I've got three flags in hte link field; bits 0, 1, and 15. 2023-05-15 13:32:26 what's special about 15 that it didn't fall into bit 2? 2023-05-15 13:32:44 One's an immediate flag, one is to identify words that need to have an offset back to the start of the definition compiled after then, and one is a "temporary word" flag - those are the ones I compiled with .: that get pruned out of the list by .wipe. 2023-05-15 13:33:05 Speaking of .wipe, I should write that. 2023-05-15 13:33:33 these are not the words you are looking for 2023-05-15 14:03:22 crc: If you still haven't got the right syntax, try looking at what objdump calls it on OpenBSD 2023-05-15 14:03:50 My code was originally written for nasm, and then I converted it, so some of the mnemonics might just be newer compatibility intel mnemonics 2023-05-15 14:04:07 Might be older gas can't build it 2023-05-15 14:05:33 objdump's at&t syntax usually matches what gas wants, or something close 2023-05-15 14:06:15 I find it highly annoying that someone decided to give x86 a different set of mnemonics than what was in Intel's manuals 2023-05-15 14:49:48 Ok, .wipe is written, and words as well (needed that to see that .wipe was actually doing what it should). 2023-05-15 14:53:20 .wipe has a couple of limitations. 2023-05-15 14:53:59 First, the last defined word has to be NOT a temporary word. This one doesn't bother me - it will generally be the case anyway. 2023-05-15 15:01:57 Second, though, it works on the first vocabulary in the search path, and the OLDEST word in that list has to also not be a hidden word. 2023-05-15 15:02:22 That does feel like a limitation to me - I could easily see creating a vocabularly and wanting to immediately start defining helper words that would later get wiped. 2023-05-15 15:02:39 At the moment it's not smart enough to pull that zero from the last word up into the oldest non-hidden word. 2023-05-15 15:02:44 But I can probably sneak that in. 2023-05-15 15:03:23 code is here: 2023-05-15 15:03:27 https://pastebin.com/idm0frjg 2023-05-15 15:42:16 Ok, got limitation 2 removed. 2023-05-15 15:43:28 Now it's an acceptable tool. 2023-05-15 15:45:04 veltas: I inlined the byte sequence, but it's still not working (just exits on startup); I'll have to look and see if FreeBSD 13 changed anything in the syscalls (my last assembly on freeBSD was on an early 12.x release) 2023-05-15 16:13:35 Limitation #1 isn't really a limitation, because it would make no sense to run .wipe when the most recent definition was temporary. It would be discarded unused. 2023-05-15 16:33:39 crc: I've seen something suggesting registers like r8 are cleared by FreeBSD when doing a syscall 2023-05-15 16:33:57 So some different register usage or saving to stack might be required to support FreeBSD 2023-05-15 16:36:46 if only there were a system v abi that folks don't follow 2023-05-15 16:40:56 I had just hoped the BSD's would act similarly to Linux, apparently FreeBSD is different 2023-05-15 16:42:05 also freebsd uses clang's assembler nowadays instead of gas, which is why it was whinging about repe cmpsd 2023-05-15 16:57:52 veltas: it is a common mistake to make 2023-05-15 16:59:18 also linux is a wacky mix of bsd and sysv so is pretty weird 2023-05-15 17:14:00 heard good things of the rather unfortunately named CloudABI 2023-05-15 17:25:34 that's an inspiration for wasm 2023-05-15 17:31:08 Well I didn't write it for BSD's, I just hoped porting it to BSD's would be easy 2023-05-15 17:31:22 The syscall ABI for Linux is documented in the sysv supplemental 2023-05-15 17:32:58 It's different to the sysv ABI itself which is for functions, not kernel calls 2023-05-15 17:33:33 Conveniently Linux saves most registers between syscalls, and FreeBSD doesn't seem to save some of the ones Linux does 2023-05-15 17:33:43 Which it's allowed to do, there's no standard kernel ABI 2023-05-15 17:34:36 The kernel really has two choices with registers, either save them or set them to a known value like zero. Anything else could expose privileged information about the kernel 2023-05-15 17:35:43 Usually they will save most registers and set a couple to zero. That couple might be used internally to handle the syscall exception initially, before registers can be saved 2023-05-15 17:43:51 Looks like I've got 398 words in my system, after I load up the editor and these other little "finishing out" tools that I've added the last day or so. 2023-05-15 17:44:16 I'm sure if I look through it carefully, though, I'll see words that I intended to be temporary but failed to flag as such. 2023-05-15 18:06:06 There's not a lot of docs, I'd have to literally read the assembler source of FreeBSD to know the convention 2023-05-15 18:06:24 Handbook says it's just the C convention, but that's x86, don't know if it's same for AMD64 2023-05-15 18:06:58 It's like FreeBSD is aiming to be different for the sake of it sometimes 2023-05-15 18:54:49 FreeBSD/amd64 is supposed to use System V ABI, like Linux and OpenBSD, but it definitely doesn't seem to be the same. 2023-05-15 18:55:56 I have it partially working, by adding a set of helper functions to do the syscall. I can do everything non-block related now, but I have to call a function that calls the actual function that runs the syscall instruction. 2023-05-15 18:58:50 in netbsd the registers to pass arguments and stuff are the same as in mac os 2023-05-15 18:59:23 So, I'm fuzzy on something. What exactly is the distinction between compile and [compile], and what would their source look like if implemented in Forth? 2023-05-15 18:59:51 I mainly used a tutorial for mac os to know what registers had to use in netbsd to translate the examples of the programming from the ground up book 2023-05-15 19:00:36 I want ." to compile the (.") runtime into the word ." appears in. Is that compile or [compile]? 2023-05-15 19:01:01 I'm pretty sure that should be. [compile] (.") 2023-05-15 19:01:27 though I should check dpANS 2023-05-15 19:02:12 That seems more likely to me too. 2023-05-15 19:04:35 at face value, i'd imagine COMPILE as possibly: ' WORD , ; and [COMPILE] as: [ ' WORD , ] ; IMMEDIATE 2023-05-15 19:05:50 Yes, and that latter is what I think I want. 2023-05-15 19:06:08 : ." [compile] (.") ... 2023-05-15 19:06:20 ... ; immediate 2023-05-15 19:06:39 With some string copying and so on in the ... slots. 2023-05-15 19:07:21 [compile] clearly has to be immediate, because it needs to parse the (.") out of the stream. But what exactly will it put in the definition of ."? 2023-05-15 19:07:46 Does it compile that xt as a literal and then compile , ? 2023-05-15 19:08:21 "Skip leading space delimiters. Parse name delimited by a space. Find name. If name has other than default compilation semantics, append them to the current definition; otherwise append the execution semantics of name. An ambiguous condition exists if name is not found." 2023-05-15 19:09:00 It seems like it ought to be 2023-05-15 19:09:23 : [compile] find , ; immediate 2023-05-15 19:11:00 doesn't seem to be though; under gforth if I do something like : a 1 . ; : b [compile] a ; see b I get : b a ; or : b postpone a ; if a was immediate 2023-05-15 19:14:09 Ok, so wait. 2023-05-15 19:14:21 I don't want (.") compiled into the definition of ." 2023-05-15 19:14:33 I want ." to compile it into the word ." is used in. 2023-05-15 19:14:40 So maybe that should be compile? 2023-05-15 19:15:50 It still has to be immediate, though, because the (.") is in the source of ." - it has to get scanned while we're defining ." 2023-05-15 19:16:09 this is the same sort of stuff I was hassling with on builds> does> - that extra layer of removal. 2023-05-15 19:16:54 So compile has to set ." up so that IT compiles (.") when the final word that "does" the ." is being compiled. 2023-05-15 19:17:36 ANS doesn't define a behavior for compile 2023-05-15 19:18:09 Seems to me that either needs a runtime such that the def of ." contans or else it compiles it as a literal followed by , 2023-05-15 19:18:55 F79 defines it as: 2023-05-15 19:19:05 https://www.irccloud.com/pastebin/OMVQoWez 2023-05-15 19:23:58 Is there an example the source for it there anywhere? 2023-05-15 19:24:40 But consider that partial def of ." again: 2023-05-15 19:24:55 : ." compile (.") ... ; immediate 2023-05-15 19:25:04 : foo ." test" ; 2023-05-15 19:25:25 So ." executes while I'm compiling foo, and that is exactly where I want the (.") to be compiled. 2023-05-15 19:25:31 the [COMPILE] word ; IMMEDIATE pattern seems like it might fit what you described you wanted: 2023-05-15 19:25:38 : <."> [COMPILE] ." ; IMMEDIATE ok 2023-05-15 19:25:38 : TEST <."> Does it work?" ; ok 2023-05-15 19:25:43 TEST Does it work? ok 2023-05-15 19:25:43 SEE TEST 2023-05-15 19:25:46 But compile MUST BE IMMEDIATE, because it has to run at a time when (.") is in the input stream. 2023-05-15 19:25:49 : TEST .\" Does it work?" ; ok 2023-05-15 19:25:57 : TEST .\" Does it work?" ; ok 2023-05-15 19:26:19 sorry, double paste 2023-05-15 19:27:03 So since compile RUNS while ." is being compiled, but we want its action while foo is being compiled, what goes in the code stream of ." ? 2023-05-15 19:27:27 Does compile have a runtime that it compiles into .", and the xt of (.") follows that? 2023-05-15 19:28:21 Or do I cause ." to contain the code <(.") xt> <, xt> 2023-05-15 19:28:49 See, if I define a constant 2023-05-15 19:29:01 find (.") constant [(.")] 2023-05-15 19:29:14 and then put [(.")] b, in .", that works great. 2023-05-15 19:29:25 It just seems awfully round-about. 2023-05-15 19:29:41 I want to say that I KNOW there's a better way, but I'm fuzzy on it. 2023-05-15 19:30:55 I'm going to go upstairs and see if I can find my McCabe volume 2. 2023-05-15 19:31:03 It's got source for most of this stuff in it. 2023-05-15 19:31:53 :0 2023-05-15 19:34:57 Ok, no. It's not immediate and it does not use FIND. 2023-05-15 19:35:59 compile and (.") both just get compiled. When compile runs, it uses the return address, which is now pointing at (.") to get it and it compiles it where we are now. 2023-05-15 19:36:07 Bumps the return address past it, and that's that. 2023-05-15 19:36:31 Really it's the same solution Zarutian_iPad was trying to tell me on builds> does> the other night. 2023-05-15 19:36:46 You'd have thought I'd be quicker on the uptake this time. :-( 2023-05-15 19:38:12 On my system, with the separate header and body areas and the 32-bit xt sizes, it will look like this: 2023-05-15 19:38:16 : compile r> .h@++ b, >r ; 2023-05-15 19:40:45 KipIngram: re: source; `: compile ?com r> dup 2 >r @ , ;` (translating from an old assembly implementation printout) 2023-05-15 19:41:28 Yes, similar to what I found in McCabe. 2023-05-15 19:41:48 I've got some fancy postincrement @ stuff going on, so I used .h@++ 2023-05-15 19:42:07 A . prefix like that means it keeps the address as well as the fetched data. 2023-05-15 19:42:20 And in this case increments it by the data size, which is four bytes. 2023-05-15 20:02:27 Here's the whole shooting match: 2023-05-15 20:02:29 https://pastebin.com/adHKP29D 2023-05-15 22:37:35 Looks like the 4kB block I've been putting this recent code in can hold order of 120 lines of code, in my typical writing style. 2023-05-15 23:01:46 I just described .: / .wipe to my wife. She's not a Forth programmer or anything, but she's been around me long enough to know that definitions begin with : and end with ; 2023-05-15 23:02:03 When I told her what .wipe did, she prompty said "Oh, it gives it a colonoscopy." 2023-05-15 23:02:21 there's no python? 2023-05-15 23:02:24 That definitely got a laugh out of me. :-)