2023-11-20 03:03:12 Maybe someone will like it https://github.com/fuzzballcat/milliForth 2023-11-20 03:05:38 oh that's shorter than my hack of sectorforth 2023-11-20 03:07:20 user51: you dont need `exit` in milliforth/sectorforth ... https://github.com/cesarblum/sectorforth/issues/6 2023-11-20 03:08:36 you can write `exit` in forth 2023-11-20 03:09:00 it's basically r> drop 2023-11-20 03:11:29 dave0: It's not my work, was it implied by accident? 2023-11-20 03:15:51 ah ok 2023-11-20 03:16:12 user51: i thought you might be the author, never mind :-) 2023-11-20 03:19:21 dave0: Darn it, missed my chance to be a prophet! :) 2023-11-20 03:20:38 ehehe 2023-11-20 06:25:30 GeDaMo: Heyo, much appreciated with your help, but with explaining the why/what/how of each word or line, I'm still pretty lost, I'm afraid. :| (Speaking of https://ideone.com/6e631h ) 2023-11-20 06:25:56 The "why" of stack juggling is pretty obtuse to a beginner. 2023-11-20 06:26:25 wait 2023-11-20 06:26:35 Wrong word 2023-11-20 06:26:40 Non-transparent, rather 2023-11-20 06:30:56 without* explaining 2023-11-20 06:30:58 Urgh 2023-11-20 06:31:24 The first line just creates an array called arr with some values, the first value is the number of cells in the array 2023-11-20 06:32:15 amap applies an xt (execution token, basically a function pointer) to each element 2023-11-20 06:33:20 >r moves the xt to the return stack then it loops while the count isn't zero 2023-11-20 06:34:05 in the loop, over copies the address up to the top, r@ copies the xt from the return stack then execute calls the function 2023-11-20 06:34:31 Both the address and count are updated 2023-11-20 06:34:55 After the loop, everything is dropped to clean up the stack 2023-11-20 06:35:45 GeDaMo: Don't you have a blog where you can upload stuff like this? Super-valuable, honestly. 2023-11-20 06:36:12 Sorry, I don't 2023-11-20 06:36:16 Awww 2023-11-20 06:37:11 What about github blog engine? 2023-11-20 06:37:16 github.io 2023-11-20 06:57:16 Well it's a lot more work to turn some replies and examples into a blog 2023-11-20 06:57:27 If you ask GeDaMo they might be willing to let you write an article based on their work 2023-11-20 06:57:56 Yeah, go ahead 2023-11-20 07:06:15 I could extract a blog post Forth word by Forth word, yes. :) 2023-11-20 07:26:49 But would have to happen when I'm not working. 2023-11-20 08:52:55 when designing the vm, is it better to make choices that will optimize the execution of code primitives, or to optimize the nesting of high level words? 2023-11-20 08:54:01 I would say optimise code primitives first 2023-11-20 08:54:06 it seems like one has to make tradeoff decisions between these two things. i without actually having a program to profile, it's hard for me to imagine which one occurs more 2023-11-20 08:54:50 I would guess most of the execution time is spent inside actual code primitives, especially if hot routines are code primitives themselves 2023-11-20 08:55:10 So optimising the threading and execution of those primitives is probably best 2023-11-20 08:55:38 I don't have any data to back that up unfortunately and it's probably hard to test 2023-11-20 08:56:00 i feel like i've heard that before, too, but i wanted to hear it again :) thanks 2023-11-20 08:56:06 What architecture is this for? Or is it actually a 'VM' like a fake architecture? 2023-11-20 08:56:32 amd64 at the moment 2023-11-20 08:57:03 Well that's a hard one to optimise for 2023-11-20 08:57:21 I'm sure everyone's interested if you're able to try different things and get some profiling results 2023-11-20 08:58:13 honestly it doesn't matter. the ultimate goal is to make a compiler for another arch. but forth brings out the worst premature microoptimizer tendencies in me 2023-11-20 08:58:41 Forth itself is a bit of a premature optimisation on desktops :P 2023-11-20 08:58:49 But yeah it's all good fun 2023-11-20 09:06:00 and yeah, x86 is a terrible isa to start with because it's so complex, my imagination runs wild with tricky gimmicks to try to eek out a little more 2023-11-20 09:08:04 I too have attempted to write a few AMD64 forths and get properly stuck in the weeds with it 2023-11-20 09:08:14 It's hard to do it in a way that feels forthy 2023-11-20 09:09:43 My most recent attempt if it's interesting https://github.com/Veltas/Tebbi-Forth/blob/main/tebbi-forth.s 2023-11-20 09:09:57 Or if you have suggestions lol, sure a lot of that can be better 2023-11-20 09:11:59 It's not working but most of that code is correct I think 2023-11-20 09:12:46 My 2 cents, on x86 you're not going to get the fastest output. So you have two good alternatives to aim for 2023-11-20 09:13:01 Either you go for the 'cleanest' solution, or the smallest solution 2023-11-20 09:13:36 Because Forth has the opportunity to strip down to quite a high SNR 2023-11-20 09:48:25 olle: Yes, it does just take practice to get comfortable juggling the stack. It's easy to learn what each individual stack juggling word does, but becoming "intuitive" re: how sequences of them will "get you where you want to go" is just an acquired skill - probably no way to rush it. It's a bit like the difference between knowing how each chess piece moves legally and "seeing sound play strategies" in an 2023-11-20 09:48:27 actual game. 2023-11-20 09:49:08 zelgomer: Yes, I do think there are tradeoffs of that sort you have to make when designing a system. 2023-11-20 09:50:23 One thing to keep in mind is that a system that offers assembly tools will let you write optimized code for performance critical situations. That usually makes me wind up going for what seems like "an elegant system" to me, rather than making every single decision based on performance. 2023-11-20 09:51:12 It's nice if your system offers good profiling capability - then you can find those critical secsions and give them special treatment to squeeze out the best performance. 2023-11-20 09:51:28 s/secsions/sections/ 2023-11-20 09:52:46 veltas: nice! 2023-11-20 09:52:49 on the other hand, I often include more primitives thatn I really have to - plenty of my priitives could have been written in Forth instead. 2023-11-20 09:55:42 my controversial opinion is you shouldnt worry too much about performance in forth since you're going to be way behind C performance no matter what you do. not that it matters on x86. Python is about 50x slower than C as a rule of thumb and people love it. you'll probably do better than that with your forth so dont be too concerned 2023-11-20 09:58:16 I feel the same to some extent - you're not going to be implementing the "fastest system possible." That's a foregone conclusion. On the other hand, I don't go so far as to not worry about performance at all - I still prefer "faster Forth" to "slower Forth." I kind of just follow my feelings. 2023-11-20 09:58:40 If a word is "easy enough" to write as a primitive, I generally will do so. 2023-11-20 10:01:47 I don't think that's too controversial MrMobius 2023-11-20 10:04:33 One thing I'm still not as good at as I'd like to be is recognizing all the possibilities the return stack offers for "clean ways of doing things." That calculator I first learned to program on had a data stack, so I got pretty "intuitive" about the stack juggling and so on. But it did not have a visible return stack - it wasn't really *Forth*. So that part I didn't get a chance to burn in there at the 2023-11-20 10:04:35 outset of my learning in the same way. 2023-11-20 10:05:29 dc(1) still exists 2023-11-20 10:05:59 Several times I've been struggling with one of the more "esoteric" Forth words, like COMPILE, for example, and then one of you guys will pop out a return-stack based beautiful solution, and I'm like... "Oh. Ok." :-) 2023-11-20 10:13:54 veltas: lol, so much of tebbi-forth looks strikingly similar to what i'm writing, but with 32-bit instructions instead of 64. well, until i get to your high level words. i'm not subroutine-threading 2023-11-20 10:14:08 i guess there are only so many ways to write these macros 2023-11-20 10:14:40 What kind of threading are you using, zelgomer? 2023-11-20 10:16:50 for now, i'm keeping all of my code within 64k and compiling 16-bit addresses. i'm taking advantage of the x86* feature that when you write to those 16-bit registers, the high 48 bits of their 64-bit counterparts are undisturbed. so as long as i leave the top 48 bits alone, i can just keep loading the bottom 16 bits and jmp 2023-11-20 10:17:43 Oh, neat. So you can "plunk it down" wherever you want to. 2023-11-20 10:17:45 woe betide if you do need to clear those higher bits 2023-11-20 10:18:49 thrig: sure, but with so many registers available, it's easy to dedicate one for this purpose 2023-11-20 10:19:31 zelgomer: Oh silly me, I forgot it's 32-bit lol 2023-11-20 10:20:29 The first system I wrote in assembly for x86 ran under MacOS. They had a pretty stringent "relocabability" requirement. I wound up doing exactly that - devoted a register to holding the system base address, and then wrote the Forth mostly using offsets. 2023-11-20 10:21:07 Not "optimum" performance, but really only missed that by a couple of instructions required in next and docol. 2023-11-20 10:21:39 MrMobius> my controversial opinion is you shouldnt worry too much about performance in forth since you're going to be way behind C performance no matter what you do. 2023-11-20 10:22:37 conciously i understand this, but the subconcious problem i think i can't get past is knowing that decisions i make with the inner interpreter will impact EVERYTHING. it feels very important to get it right now because of the wide-sweeping ramifications 2023-11-20 10:23:25 right. it certainly feels good to optimize like that 2023-11-20 10:23:32 I totally agree with that. I sweat the "affects everything" bits pretty hard. 2023-11-20 10:24:04 Those are exactly the bits of the system you want to arrange to be 'as good as you can manage.' 2023-11-20 10:29:19 As a counter-point, although there are limits to this logic, the fact you *can* rewrite specific bits in C or assembly later and call them from your code means you might be wasting your time sweating over this too much 2023-11-20 10:29:50 Especially since in AMD64 the performance is a bit counter intuitive anyway sometimes, e.g. people have claimed DTC is faster than STC sometimes etc 2023-11-20 10:42:59 yeah 2023-11-20 10:44:09 historically i'm a c guy. so it's very much ingrained into me to avoid ever writing assembly, since that immediately kills your portability. i have to keep reminding myself to think of forth as a macro assembler and not as a language like c 2023-11-20 10:47:48 I think Forth's most important "offering" is its ability to maintain a completely uniform "feel" throughout all levels of code in a system. C will let you write functions, but they don't behave the same way operators do, for example. In Forth the words you add "behave the same" as the words that are there initially. The way this lets you craft an "application lexicon" - that what I think Forth's strongest 2023-11-20 10:47:50 point is. 2023-11-20 10:47:55 that's 2023-11-20 10:48:56 I think the best goal is to arrive at a wordset that most "elegantly and intuitively" capatures your application, and then you can optimize where needed to bring performance up. 2023-11-20 10:49:25 Although it's not always possible to optimise but I believe most of the time you can where it counts 2023-11-20 10:49:45 That's a more controversial claim 2023-11-20 10:50:11 Comparable with numpy usage, you're using Python but the juicy bits are in C 2023-11-20 10:50:35 Right, Python offers a fairly good compromise in a lot of cases. 2023-11-20 10:51:02 It's "slow," but often it will only be your glue code that really suffers from that. 2023-11-20 10:52:05 And there are a lot of people out there optimizing things akin to numpy. 2023-11-20 10:52:38 Kind of like the standard C compilers - just by using one of htem you become the beneficiary of a LOT of hard optimization work. 2023-11-20 11:03:40 KipIngram: It's not only about practice - to know *why* a specific "swap" was needed you need a lot of context. 2023-11-20 11:04:05 The downside if implicit stack, I guess. :) 2023-11-20 11:05:23 It's often not a problem, depends how it's being used though really 2023-11-20 11:05:46 Alright for some things, not amazing at e.g. searching through a list of strings for a substring 2023-11-20 11:08:39 I meant, without it you'd put the payload in variables, and - hopefully - the variables would describe what the payload contains. 2023-11-20 11:09:00 With an implicit stack, the payload is unnamed and invisible :) 2023-11-20 11:14:04 What I'm saying is it's often clear from usage, but often not 2023-11-20 11:15:00 Hm 2023-11-20 11:35:57 http://www.figuk.plus.com/webforth/En/TutorlT.htm#L15 - this is good stuff - line comments include both a description and a stack description 2023-11-20 11:36:06 BEGIN \ Start loop: i is TOS ( +n i ) 2023-11-20 11:54:04 You guys don't have a standard way to document post- and pre-conditions to words? Like "i must be higher than j" 2023-11-20 11:54:10 or "Pre: i > j" 2023-11-20 11:56:55 any recommendations for an assembler? 2023-11-20 12:22:20 joe9: for x86/amd64? 2023-11-20 12:22:53 olle: Yes, I'm just saying that with practice you start to get more intuitive about those things. 2023-11-20 12:23:29 for amd64 2023-11-20 12:23:47 And you start getting better at anticipating future situations, so you can do a better job of planning earlier work so that things wind up being where you need them to be, rather than requiring stack noodling. 2023-11-20 12:24:02 joe9: I like nasm. Very good macro facility. 2023-11-20 12:24:34 My impression is that there are several good ones, though. 2023-11-20 12:24:51 KipIngram: +1 2023-11-20 12:25:09 I used to use fasm on linux & windows; nasm and (g)as on BSD. 2023-11-20 12:25:11 KipIngram: I am reading up on the At&T syntax and it seems better than the intel syntax 2023-11-20 12:25:23 nasm & fasm both have good macro facilities 2023-11-20 12:25:31 I've really only used the Intel variant. 2023-11-20 12:25:48 I'm kind of "aware" of the differences, but have no experience with AT&T syntax. 2023-11-20 12:26:14 Intel syntax seems to make pc relative operations more cumbersome. 2023-11-20 12:26:23 Or at least it's felt that way to me. 2023-11-20 12:28:39 i use gas with att syntax 2023-11-20 12:28:55 just because it's usually already here on most linux systems 2023-11-20 12:52:31 The main thing I've wished nasm would let me do (and it may just be that I don't know how - might not be nasm's fault) is create multiple sections laid out at precise offsets from one another. So far I've only got it to let me work "within" sections and not "across" sections. 2023-11-20 12:54:10 can't you do times 510 -( $ - $$ ) db 0 type tricks? 2023-11-20 12:54:45 That's not something I'm familiar with - in that case too the issue may be me lacking knowledge. 2023-11-20 12:55:03 but if that's so I'd still then say that it could be documented more clearly. 2023-11-20 12:55:14 Or more "findably." 2023-11-20 12:56:25 http://0x0.st/Hwi4.forth 2023-11-20 12:56:40 A stack in forth. This time I wrote it :) 2023-11-20 13:13:21 Nice. I'm planning to do a dictionary framework with table doubling sometime soon. 2023-11-20 20:32:11 i'm stupid :( 2023-11-20 20:33:37 i can't explain what i'm experiencing right now 2023-11-20 20:33:42 it's like some kind of logical dyslexia 2023-11-20 20:34:01 if TOS is 0, then 0<> should produce true, which is not 0 2023-11-20 20:34:44 no wait 2023-11-20 20:35:06 0 0= . -> t 2023-11-20 20:35:24 why is this confusing me so much? i need to call it a night 2023-11-20 21:17:02 i'm finding it a lot more difficult to understand how I would implement forth in C than in assembler 2023-11-20 21:17:06 it has to be indirect threaded code, because I can't generate machine instructions for direct threaded or subroutine threaded code wihout RWX 2023-11-20 21:17:49 and i dont think it can be token threaded because I certainly want more than e.g. 256 words if i represented a token with a char 2023-11-20 21:19:19 is there some sort of resource I could reference to build an intuition about how to implement ITC in C ? 2023-11-20 21:33:01 kws, i have the same problem. i "get" forth in assembler, but when i try to write it in c, it becomes confusing. 2023-11-20 21:35:39 having said that, my attempts in the past have simply allocated arrays of function pointers. IP is just a void (**ip)(void), and you execute a word with a "while (*ip) (*ip++)();" 2023-11-20 21:36:59 hmm, well im glad im not alone. interesting, i see