00:00:00 --- log: started forth/21.05.02 00:01:30 --- join: wineroots joined #forth 00:07:51 --- quit: wineroots (Remote host closed the connection) 00:19:54 --- join: wineroots joined #forth 01:11:09 --- quit: mtsd (Remote host closed the connection) 01:19:08 --- join: mtsd joined #forth 03:20:50 --- quit: xek (Remote host closed the connection) 03:21:11 --- join: xek joined #forth 05:56:14 --- quit: Zarutian_HTC (Read error: Connection reset by peer) 05:56:18 --- join: Zarutian_HTC1 joined #forth 06:53:16 --- quit: Zarutian_HTC1 (Read error: Connection reset by peer) 07:03:31 --- quit: pbaille (Remote host closed the connection) 07:31:56 --- join: pbaille joined #forth 07:50:39 --- join: Zarutian_HTC joined #forth 08:37:46 --- join: tech_exorcist joined #forth 10:16:40 Afternoon, gentlemen. 10:17:14 mark4: I totally understand about certain very logically important tasks just not being the easy road. :-| 10:24:37 So, what's a good syntax for a way to combine primitives? The "non-next" portion of each primitive would be strung into place, and we'd get a new primitive. 10:27:48 --- quit: gravicappa (Ping timeout: 240 seconds) 10:39:16 I guess the syntax isn't my question - more just the name. Syntax wise it would be something like this: 10:39:41 def-word done-word 10:39:44 :) 10:40:23 and would wind up being a primitive with the "meat" of - with a single NEXT at the end. 10:40:55 Anyway, I see this as the resolution of whether to have that whole flock of conditional returns. 10:41:15 I think I should have just the flag conditional return, and then if I want any of the others I make them using the above. 10:41:43 def-word 0=; 0 = ?; done-word 10:42:48 That still might not be quite as efficient as the other - for one thing, it would still actually push a zero to the stack for the zero check. 10:43:13 I guess def-word 0=; 0= ?; done-word is better. 10:43:47 maybe just prim: and prim; 10:49:25 That Python script I wrote to produce the assembly source for those words has them damn near optimum. There are a couple of places where there are clearly redundant assembly steps, but for the most part it's straight line from A to B. 10:49:55 I figure if I stare at it a little while I can remove those inefficiencies. 10:50:19 There's enough of them that I just couldn't imagine writing them all by hand and not making a few mistakes. 12:59:52 --- quit: mtsd (Ping timeout: 252 seconds) 13:30:20 --- join: LispSporks joined #forth 13:43:34 --- join: Zarutian_HTC1 joined #forth 13:43:34 --- quit: Zarutian_HTC (Read error: Connection reset by peer) 14:28:14 --- quit: Zarutian_HTC1 (Remote host closed the connection) 14:34:02 KipIngram: in an inlining native code forth, one could do something like the following (in zeptoforth) : [inlined] ; as long as , , and were inlined themselves 14:35:21 I see. So still use : and ; - just include the [inlined] word. 14:36:55 So [inlined] would just change the CFA of the just compiled name so that it behaves like a primitive. And then I guess it would loop over the following words, pulling the meat, and finally when it saw ; it would apply next. 14:37:00 That seems simple. 14:40:28 --- join: dave0 joined #forth 14:40:59 maw 14:48:56 --- quit: pbaille (Remote host closed the connection) 14:51:45 --- quit: LispSporks (Quit: My MacBook has gone to sleep. ZZZzzz…) 14:57:16 back 14:57:46 [inlined] just makes an inlined word 14:58:17 note that [inlined] has to go before ; not after because of the way compilation happens for flash 14:59:35 --- quit: tech_exorcist (Remote host closed the connection) 15:01:21 tabemann: ooh does ; copy from ram to flash? 15:01:26 no 15:01:34 ; finishes compiling a word in flash 15:02:14 the problem with stuff like inlined or immediate the ANS way is that there is no way to know when to finally finish writing a word to flash 15:02:34 because in theory inlined or immediate could always be specified later 15:02:53 ; writes the flags field to flash, amongst other things 15:06:24 note that there is also inlined and immediate (without brackets), but they apply to words being compiled while the word they are within is being executed 15:08:09 so inlined is a flag that the compiler notices to, instead of compiling an xt, it copies the word body directly? 15:12:01 i always wanted more control over inlining in c... instead of having a function that is always inlined, i would rather an option to specify inlining for each instance that i call the function 15:12:03 inlined / [inlined] sets a flag where, when the word is called from another word, it compiles the word body into that word rather than compiling a subroutine call 15:12:13 note that there is a big caveat 15:12:36 words that are to be inlined cannot contain subroutine calls, only inlined words and constants 15:12:44 if this is not the case 15:12:58 it ignores inlined / [inlined] 15:13:23 tabemann: are you using subroutine threading? 15:13:34 SRT/NCI 15:13:46 yep 15:14:33 note that a significant portion of primitives appear to be inlined in practice, from looking at disassembled code 15:15:45 do calls use relative offsets? if it was a relative offset you wouldn't be able to copy the contents of the word somewhere else without fixing up the offsets 15:15:58 yes - exactly 15:16:12 that's why inlined words cannot contain subroutine calls 15:17:10 only inlined words and literals 15:17:23 they can contain control constructs though 15:17:34 because branches within an inlined word are allowed 15:17:51 just not branches out of the inlined word 15:18:38 what did you name your conditional branch primitive? the branch-if-false one? 15:19:27 --- join: pbaille joined #forth 15:19:32 hmm i could call it brach-if-false haha i went with 0BRANCH 15:20:50 I don't have a catchy name for it, because it's actually two parts - one to reserve space for a branch to be compiled, and one that actually compiles the branch in that place 15:22:40 and I don't compile any actual word into that place 15:22:47 just a beq instruction 15:22:57 oh that's interesting 15:23:16 well, also a cmp instruction too 15:23:18 you effectively inlined the branch-if-false primitive 15:23:31 yes 15:24:15 there is no 0branch primitives, just primitives for setting up a branch and for actually resolving the branch 15:24:34 --- quit: pbaille (Ping timeout: 240 seconds) 15:25:37 is your unconditional branch compiled to a jmp instruction? 15:25:56 well, to a b instruction, yes 15:26:04 cool 15:26:27 hmmm "b" for branch... is your cpu ARM ? :-) 15:26:32 yep 15:26:35 nice 15:26:45 ARM Cortex-M4 and Cortex M7 15:27:12 I could probably do a port to ARM Cortex-M3, if I really felt like it 15:27:39 ARM Cortex-M0 and Cortex-M0+ are no-goes, though, because they would require significant rewriting of zeptoforth 15:27:41 i once helped a guy make a 64 bit multiply with shifts and adds for an ARM forth... before i actually looked at forth 15:28:21 that made me interested in forth 15:28:50 --- join: Zarutian_HTC joined #forth 15:28:58 I based my 64-bit multiple and divide code on Mecrisp-Stellaris's code (I got permission from Matthias to relicense his code as MIT) 15:29:21 ah let me google for that 15:30:26 bbl - dinner time 15:30:52 byes tabemann 15:37:49 --- join: pbaille joined #forth 15:42:40 --- quit: pbaille (Ping timeout: 252 seconds) 16:05:51 back 16:06:04 wb tabemann 16:07:04 hey 16:08:59 * tabemann is weighing whether he should make a new release just because he fixed a bug in 2! of all things 16:09:57 you could bump the 4th number of your version x.y.z.patchno 16:10:39 I've been currently going with 3 version numbers 16:10:41 x.y.z 16:11:01 and calling z bumps "patch-level releases" 16:11:20 ah you could bump z 16:12:18 tabemann: speaking of multiply & divide, i added a totally excessively silly word... integer square root :-) 16:12:32 i found code on wikipedia 16:12:53 heh 16:13:04 I have square root, but it's fixed point 16:13:44 --- join: pbaille joined #forth 16:14:57 i can't see any use for it, but it sort of resembles multiply and divide so why not :-) 16:15:21 heh 16:18:31 --- quit: pbaille (Ping timeout: 260 seconds) 16:18:43 What's that do? Just give you the nearest integer? 16:18:49 I've been reading up on cordics. 16:18:54 KipIngram: yup 16:18:58 They make a lot of sense. 16:19:44 brb 16:20:02 dave0: Does it just average each guess with product/guess and iterate? 16:25:27 KipIngram: no, it's like long division 16:25:40 guessing is probably faster 16:27:24 KipIngram: https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Example_3 16:27:47 i adapted the c code there 16:27:49 it works! 16:28:40 it was just indulgent :-) 16:28:59 i can't see any need for an integer sqrt lol 16:31:37 a fixed point SQRT is much more useful 16:34:57 and, after all, a 64-bit fixed point SQRT value can easily be turned into a 32-bit integral SQRT value 16:35:47 That's great. x(i+1) = 0.5*(x(i) + product/x(i)) will work too. 16:36:47 It's similar to Newton's method for that function. Or is exactly it - I'm not sure. 16:40:17 this is my implementation of SQRT: https://dpaste.com/4LNCD9CM2 16:41:14 Yeah, I just scratched at it for a minute - I think that's just what Newton's method turns out to give for sqrt. 16:42:08 a lot of naive methods for numerical stuff based on things such as newton's method don't work out very well in practice though, I've found 16:42:26 Yeah, you can get into trouble if you don't watch out. 16:42:53 either they end up having a lot of error when you have only 32 bits to the right of the decimal point, or they converge really slowly, or they have factorials that won't fit in 32 bits to the left of the decimal point 16:42:54 When Newton's method works it works very well, though; once it starts converging you like double the accurate figures on every iteration. 16:43:44 The cordic algorithms are mostly about trig functions - they're designed from the ground up to work well with base 2 digital representation of the angle. 16:43:57 yeah 16:44:51 you can do sqrt and logs with cordic too if you use a different table than trig functions 16:45:07 you can also do division if you're so inclined 16:46:26 i was kind of disappointed when i looked at newton and similar solvers. theres just not anything that always works for everything 16:46:42 Yeah, it seems like a kind of general method. 16:48:13 I've had good luck with Runge-Kutta. 16:48:44 But it is an "explicit" solvers, and they can be unstable for certain types of system. 16:48:57 I've derived most of my trig stuff from sqrt, expm1, and ln 16:49:05 I think the impicit one I've used is Adams-Bashforth. 16:49:25 hmm ya there are equations where newton oscillates forever if thats what you mean 16:51:47 Yeah, it can get stuck in a cycle. 16:52:38 It's been a long time since I learned this stuff; I think the problem equations are the ones where the ratio between the largest and smallest eigenvalues is large. 16:52:51 They call them "stiff" systems. 17:00:04 --- quit: Zarutian_HTC (Read error: Connection reset by peer) 17:00:13 --- join: Zarutian_HTC joined #forth 17:00:47 The logistic equation is a fun one to play with. 17:27:22 --- quit: Lord_Nightmare (Quit: ZNC - http://znc.in) 17:32:41 --- join: pbaille joined #forth 17:33:53 --- quit: dave0 (Quit: dave's not here) 17:36:54 --- quit: pbaille (Ping timeout: 240 seconds) 17:44:48 --- join: Lord_Nightmare joined #forth 18:31:00 --- quit: Lord_Nightmare (Quit: ZNC - http://znc.in) 18:31:20 --- join: LispSporks joined #forth 18:33:22 --- join: pbaille joined #forth 18:34:27 --- join: Lord_Nightmare joined #forth 18:38:59 --- quit: pbaille (Ping timeout: 260 seconds) 18:53:48 --- join: pbaille joined #forth 18:59:28 --- quit: pbaille (Ping timeout: 260 seconds) 19:05:11 --- quit: Lord_Nightmare (Quit: ZNC - http://znc.in) 19:07:51 --- join: Lord_Nightmare joined #forth 19:36:54 --- quit: sts-q (Ping timeout: 240 seconds) 19:40:09 --- join: sts-q joined #forth 19:45:02 --- quit: LispSporks (Ping timeout: 276 seconds) 19:49:59 --- quit: Zarutian_HTC (Read error: Connection reset by peer) 19:50:10 --- join: Zarutian_HTC joined #forth 20:14:12 --- join: pbaille joined #forth 20:18:34 --- quit: pbaille (Ping timeout: 240 seconds) 20:39:52 You know, there's just not a particular clean way to make all the decisions that the outer interpreter needs to make, is there? We parse a word and search for it. We may succeed or fail. If we fail, we check to see if it's a number. If that fails it's an error so we're out of the building. But at this point we need to decide whether to execute or compile and treat it right whether it's a word or a number. 20:39:54 I'm poking around at the control structures around that and they're really just not too tidy. 20:40:39 It really looks like the execute / compile decision has to be made in two places (on the "word" path and the "number" path). 20:41:05 --- join: dave0 joined #forth 20:42:00 In most implementations I've seen EXECUTE is inside INTERPRET, at its level. Then the null word can just do a double return to break the infinite loop in INTERPRET. But if I factor that EXECUTE wants to move downward, and every time it does the null word has to add a level to how far it returns - it has to push execution back up and out of INTERPRET. 20:42:27 Also there can't be any clutter on the stack during this time either. 20:45:04 The number path is fairly clean. 21:14:55 --- join: pbaille joined #forth 21:19:28 --- quit: pbaille (Ping timeout: 260 seconds) 21:20:37 Ok, that's not so awful. I think this covers the bases: 21:20:40 : interpret find check? 0=me execute me ; 21:20:42 : check found? number? ; 21:20:44 : found? .0=; run? .0!=;; swap compile ;; 21:20:46 : run? state @ 0= imm? or ; 21:20:48 : number? num state @ .0=;; literal ; 21:20:50 : literal [compile] (lit) , 0 ; 21:21:18 But I need to stare at it a while to be sure. 21:21:33 At least it's "on the drawing board" now. 21:23:29 Oh, didn't write imm? yet. It just grabs that flag, though. 21:23:33 --- quit: Zarutian_HTC (Ping timeout: 260 seconds) 21:43:24 maw 21:43:34 Hey dave0. 21:43:46 hey KipIngram :-) 21:46:39 --- join: pbaille joined #forth 21:47:19 --- join: Zarutian_HTC joined #forth 21:50:48 --- quit: pbaille (Ping timeout: 240 seconds) 22:01:04 --- join: pbaille joined #forth 22:48:21 KipIngram: oops i only just saw your message 23:04:32 --- quit: pbaille (Ping timeout: 252 seconds) 23:15:24 --- join: gravicappa joined #forth 23:56:14 --- join: pbaille joined #forth 23:59:59 --- log: ended forth/21.05.02