2022-04-20 05:46:41 any opinions on multi stack forth's? 2022-04-20 05:49:49 all forths are multi stack 2022-04-20 05:49:58 return and parameter 2022-04-20 05:50:00 I mean multiple data stacks 2022-04-20 05:50:06 eh 2022-04-20 05:50:19 registers A and B are enough 2022-04-20 06:29:48 I'd say don't do it. One of the primary reasons Forth code is compact is because operand addressing is implicit. Also, list items in compiled Forth definitions are basically addresses. If you had multiple data stacks, you have to somehow specify in each one of those which stack it should use. Also, each word would then have to make a decision in its implementation code, and in Forth you're encouraged to 2022-04-20 06:29:50 avoid that where possible. 2022-04-20 06:30:39 In all the years I've wandered around looking at Forth I've only seen one or two multi-data-stack Forths. And I can't even find those references these days - they apparently just "didn't catch on." 2022-04-20 06:34:09 Bit of an aside, but I also think that the reason a "small amount of Forth" can go such a long way - and here I'm talking about basically the amount of ink on the printed page when you look at the source code for some functionality - is because you don't write out long parameter lists like you do in C. In C every function call has to call out its parameters, and every function header has to list them all out 2022-04-20 06:34:11 again. 2022-04-20 06:34:19 All of that just vanishes from Forth source code. 2022-04-20 06:36:11 That's not totally an aside - it relates to implicit operand addressing. 2022-04-20 06:36:31 I love programming in forth. 2022-04-20 06:36:50 What I struggle with is understanding why it is slower than C (even using a compiling forth). 2022-04-20 06:37:18 I know, right? So what is your environment like? Do you have any sort of "integrated" one, or are you using a separate editor to write your source out? 2022-04-20 06:39:19 Writing an editor is one of my soon-to-do tasks. When the Forth compiler finds an error, it knows exactly where the error is - block # / file and offset into that. So I want to rig mine so that it can open the editor right up to that spot as part of the error response. 2022-04-20 06:39:45 that is what acme/sam do using plumber on plan9? 2022-04-20 06:39:57 filename:line 2022-04-20 06:40:05 Yes, like that. 2022-04-20 06:40:11 right click on it and it opens that file and line in the editor. 2022-04-20 06:40:32 I actually want to do a whole debugging environment eventually, with breakpoints, single step, stack and ram monitoring, etc. 2022-04-20 06:41:37 And *eventually* eventually I want to be able to have documentation and extended comments "wiki linked" into the source, with the editor able to find that and open it in a separate panel. 2022-04-20 06:42:00 That'll be hierarchical - again like a wiki. 2022-04-20 06:42:01 that is what 9front (plan9 derivative) already does. 2022-04-20 06:42:20 or, even a vanilla plan9 2022-04-20 06:42:24 Ok - cool. So you've got a helpful environment. That makes it even more fun. 2022-04-20 06:42:51 try it out, if you have an hour or so. 2022-04-20 06:43:11 it seems to have all that you are talking about except it is C based. 2022-04-20 06:43:22 The C is not mostrous as GCC. 2022-04-20 06:43:29 It is more comprehensible. 2022-04-20 06:43:33 :-) 2022-04-20 06:44:08 Does your Forth have FORGET or does it use "markers"? 2022-04-20 06:44:21 Older Forths used FORGET; a lot of newer ones went to markers. 2022-04-20 06:45:38 A marker is a word you define at some particular point in your code. Later, executing that word will prune the dictionary back to there. 2022-04-20 06:45:57 Same basic idea, but you have to "set up" for your forgetting. 2022-04-20 06:50:58 So hey - in the Wikipedia article on UTF-8, it has an encoding table up near the top of the article that shows the format of one byte / two bytes / three bytes / four bytes characters. But then down in the guts of the article it has a subsection on "FSS UTF-8" which shows other encodings supporting up to five and six bytes. So, what exactly is "UTF-8" in widespread usage? 2022-04-20 06:52:40 The latter ones are technically in the "History" section, so I figure the one near the top is likely the "real" one. 2022-04-20 10:58:45 I been perusing the IBM 370 PoOp and I found three unprivledged instructions that look to me like subroutines implemented in hardware (most likely in microcode) 2022-04-20 10:59:33 MOVE LONG , COMPARE LONG and TRANSLATE 2022-04-20 11:07:44 all have common that they use down counters as part of their state and are interruptable 2022-04-20 11:09:17 meaning that with the updated state in the registers they use at interruption they can be safely re-executed 2022-04-20 11:10:08 now I am curious if this might been an inspiration to Blit-ing 2022-04-20 11:10:36 and Single Instruction Multiple Data 2022-04-20 11:13:21 one idea I had many years back is to use SIMD vector instructions to implement many small forth virtual machines that run in parallel and concurrently 2022-04-20 11:14:47 basically there is a loop of SIMD instructions that implements the fetch execute cycle of these vns 2022-04-20 11:14:58 VMs* 2022-04-20 11:19:57 Wouldn't that mean they all had to be executing the same code? 2022-04-20 11:20:20 Seems like a great idea for the NEXT part. 2022-04-20 11:20:44 Maybe you could share that part and then handle the per-vm part of each one individually? 2022-04-20 11:21:43 What would happen when you finished NEXT and came to the part where you had four or eight different CFAs to execute? 2022-04-20 11:22:24 I was thinking the other day about using those instructions to do a "vector Forth." 2022-04-20 11:27:41 it is lower level than that 2022-04-20 11:29:42 say instead of an MOV (x86) instruction to get the forth 'instruction' into the 'instruction' register an GATHER instruction is used 2022-04-20 11:30:26 Yeah, I see that part. All of the "figuring out the next word to run." That seems like it would parallelize quite well. 2022-04-20 11:31:29 Do the SIMD instructions let you use the contents of the vector registers as addresses? 2022-04-20 11:31:53 the first, source, vector is the forth 'instruction' pointers of the VMs while the second, destination, vector are their forth 'instruction' 'registers' 2022-04-20 11:32:39 yes, as far as I understand GATHER and SCATTER 2022-04-20 11:33:23 That's pretty cool. That at least looks like you could do NEXT for multiple machines for the price of one. 2022-04-20 11:34:00 Though I guess the actual RAM accesses can't go in parallel. 2022-04-20 11:34:11 But all of the internal register diddling could. 2022-04-20 11:34:15 and I think there is an SIMD equiv to C's trinary ?: operator 2022-04-20 11:36:23 so, the trick is to turn execution of the not selected forth 'instruction's into effective no ops in that part of the loop of SIMD instructions implementing the fetch-exec of the forth VMs 2022-04-20 11:37:42 effective noops for those particular VMs 2022-04-20 11:40:05 this means there is bit more of instruction latency per vm 2022-04-20 11:40:45 s/instruction/'instruction'/ 2022-04-20 11:42:31 how would intervm communication occur? 2022-04-20 11:42:41 but it means that you can have x many forh VMs each with wildly diffrent evolved thread-of-execution/process without care by the programmers of that code 2022-04-20 11:45:05 eris[m]: either fullblown shared memory or just through dedicated 'memory' locations in each vm, probably in Von Neuman neighbour style like GA144 but without blocking other than via spin lock 2022-04-20 11:48:23 re IBM 370: heck I think I see how I could use TRANSLATE to implement Substitution Boxes and Permuration Boxes of Adcanced Encryption Standard 2022-04-20 11:48:45 s/dca/dva/ 2022-04-20 11:50:21 actually, how would BRANCH work? 2022-04-20 12:03:03 in fcpu-16 and fcpu-32 I did not implement BRANCH or JMP as primitives 2022-04-20 12:04:25 I have SKip if Zero primitive that skips next 'instruction' if TOS is zero (it pops it of the datastack) 2022-04-20 12:05:13 im still curious what that looks like 2022-04-20 12:06:16 which can easily be implemented in the SIMD above as a conditional move into the register/place of the 'instruction pointer' addend 2022-04-20 12:08:27 i suppose the thing im having trouble with is visualising how 8 different instructions could be executed at omce using simd 2022-04-20 12:08:33 in sequential and combinatorial boolean logic I implement that as an extra incr of pc if the 0=TOS comparator output is high 2022-04-20 12:09:48 eris[m]: think of the SIMD code implementing the emulator loop for the forth machines 2022-04-20 12:11:18 but there is no control flow branching at the SIMD code level 2022-04-20 12:12:02 only dataflow conditional moves 2022-04-20 12:12:55 yea, but how do you execute say, an add and a skip at the same time 2022-04-20 12:13:09 pc_addends = is_toses_zero ? 2 : 1 2022-04-20 12:13:46 m? 2022-04-20 12:13:46 aah, no. Hence the added 'instruction' latency 2022-04-20 12:13:58 I think this is a damn interesting idea worth poking at some. Just knowing how far in this direction things could be pushed would be nice. 2022-04-20 12:14:59 eris[m]: that is an example of a SIMD conditional move 2022-04-20 12:15:01 eris: re: trouble visualizing, that's exactly where I'm stuck as well. At some point the different vms will need to do different things. 2022-04-20 12:16:16 so, a part of the simd loop is implementing the um+ primitive, while other parts implement other primitives 2022-04-20 12:17:31 one need to arrange the dataflows in such a way that, per vm, the primitives not selected by that vm effectually become noops for that vm 2022-04-20 12:17:38 so the emulator executes every instruction? 2022-04-20 12:18:52 yep every instruction in the SIMD loop just like how many DigitalSignalProcessors are used 2022-04-20 12:20:50 so if primitives can share parts of their implementations then the 'instruction' latency can be reduced 2022-04-20 12:25:58 if you think about it, the fetch-execute cycle of a processor core is just doing this kind of a loop when the thing is running 2022-04-20 12:35:21 joe9: wrt being slower, I suspect most compiling Forths don't optimize things like ( addr ) 0 OVER ! @ to 0 SWAP ! 0 2022-04-20 12:36:00 in terms of the machine code that generates, doesn't matter much, but it helps a _lot_ with letting further optimizations run 2022-04-20 12:36:44 but this is one of those optimizations that needs alias analysis, which since most Forths shy away from having lots of undefined behavior, is hard in non-trivial cases 2022-04-20 12:39:07 remexre: why the hell do you need undefined behaviour for effective alias analysis for that kind of optimization? 2022-04-20 12:40:10 to me, undefined behaviour is just a sign of unfinished specifcation 2022-04-20 12:41:16 the example you gave can be detected in peephole optimization 2022-04-20 12:44:11 heck I heard of a compiler that had loads of these kind of peephole optimizations snippets and the whole gammut of them where run again and again until either some optimzation loop counter reached zero or the code optimized reached, as data, some fixed point 2022-04-20 12:46:51 I think it is better to start out with an interpreter and apply Futamura Projections to that interpreter and your code 2022-04-20 12:47:43 see http://blog.sigfpe.com/2009/05/three-projections-of-doctor-futamura.html 2022-04-20 13:11:54 Zarutian_HTC: in that particular case, yeah; optimizing through loads/stores in general is tricky without effective alias analysis 2022-04-20 13:12:23 the case it comes down to (pardon the C syntax) is *a = 1; *b = 2; use(*a) 2022-04-20 13:18:12 actually a case that might be more relevant for idiomatic forth: when can a VARIABLE be kept in a register -- you'd need to be able to prove it never gets written to 2022-04-20 13:18:46 which if you're allowed to do VARIABLE a VARIABLE b : foo b CELL - ; (and that works) gets hard really fast 2022-04-20 13:19:36 (assuming headers aren't in the data space; if they are, replace CELL with 32 or whatever's appropriate) 2022-04-20 13:24:49 wrt "unfinished specification" that applies more to un_specified_ behavior than undefined behavior 2022-04-20 13:26:05 e.g. in C99, if sizeof(int) == 4, there's no guarantee what you'll get from int x = -20; char* y = (char*)&x; printf("%02x%02x%02x%02x", y[0], y[1], y[2], y[3]); 2022-04-20 13:26:30 but the implementation has to print 8 hex digits 2022-04-20 13:26:42 (ignoring the possiblity of printf returning an error) 2022-04-20 13:27:32 versus if I write int x = 0, y = 3; int* z = &x; *(z + 4) = 4; printf("%d", y); 2022-04-20 13:28:04 there's no guarantee of any behavior; it could print 3, print 4, go into an infinite loop, reboot the computer, [...] 2022-04-20 13:28:22 not because those are reasonable ways to translate that directly to assembly 2022-04-20 13:28:37 but because the optimizer is allowed to assume that a write to a pointer derived from &x doesn't modify y 2022-04-20 13:30:04 former is unspecified, latter is undefined 2022-04-20 13:40:42 the two C examples you gave shows that C is ambigious 2022-04-20 13:41:52 in a formal or informal sense of the word ambiguous? 2022-04-20 13:42:42 the optimizer can not assume either way as pointer dervived from &x can indeed point into or overlap where y is stored 2022-04-20 13:44:07 in the sense that the compiler or its author does not have an unambigious way to translate that code or equiv to assembly 2022-04-20 13:48:21 C is trying to be both low level and higher level at the same time. For instance, is that int type four bytes little endian twos compliment? who knows, depends on the compiler and its target architecture 2022-04-20 13:50:02 if you treat addresses and pointers as being equivalent (i.e., ((uintptr_t)x == (uintptr_t)y) implies that (x == y)) then the optimizer can't assume that, but the standard allows it to assume that 2022-04-20 13:50:14 (trying to find the rule in the C11 standard right now; found it for arrays, looking for it for scalars) 2022-04-20 13:50:47 and the difference is, you can put code at the top of main testing if int has those properties, and erroring out if not 2022-04-20 13:51:00 and the rest of the program is required to behave as if int has those properties 2022-04-20 13:51:08 (because that's un_specified_ behavior) 2022-04-20 13:51:32 a pointer is an address unless you are targetting something Bourughs 5000 or CHERI enhanced arch 2022-04-20 13:53:05 a pointer is not just an address in C semantics, because pointers store (at the level of the optimizer, the compiler isn't required to preserve this until runtime because there's no defined-behavior way to check it, and CHERI is the only case I'm aware of where a compiler does) provenance info as well, essentially stating what variable they can point to 2022-04-20 13:54:14 there you get descriptors and capabilities, if C never allowed casting ints into pointers then I see your latter example as errornous code that the checker of the compiler should rightfully reject 2022-04-20 13:56:18 but then pointer arithmetic must be specified and then it arises the question of if y could be aliased or not 2022-04-20 13:57:05 right, see e.g. paragraph 8 of 6.5.6 of the C11 standard 2022-04-20 13:57:28 it does define the rules you get to assume about pointer arithmetic there 2022-04-20 14:00:12 afk, meeting, back in 30 2022-04-20 14:00:14 https://port70.net/~nsz/c/c11/n1570.html#6.5.6p8 2022-04-20 14:02:01 nothing about if the pointer becomes invalid if it goes past the array 2022-04-20 14:04:42 orrrrr sitting in a "waiting for zoom to start" zzz 2022-04-20 14:05:11 Zarutian_HTC: what are the semantics of int x[2]; printf("%d", x[5]); according to that 2022-04-20 14:05:44 lesse 2022-04-20 14:06:08 declare a two element array whose elements are ints 2022-04-20 14:06:41 call printf() with two arguments 2022-04-20 14:06:56 first argument is a literal string 2022-04-20 14:07:43 the second argument is a reference into that array, but it is three elements out of bounds of it 2022-04-20 14:08:14 right, so what does the pointer there point *to* according to that paragraph 2022-04-20 14:09:00 compiler should stop and error or barring that emit code when that array is accesed that checks at runtime if the array index is out of bounds 2022-04-20 14:09:40 from a practical standpoint, I 100% agree 2022-04-20 14:09:43 but that's not what's required by the spec 2022-04-20 14:10:05 or the pointer should carry with it that it is invalid 2022-04-20 14:11:20 the spec is incomplete there, it just says undefined behaviour like a tbd someone forgot about 2022-04-20 14:11:39 afk meeting 2022-04-20 14:14:06 Oh, I didn't k now C enforced array boundaries. 2022-04-20 14:14:36 that is the thing, it neither does and does not 2022-04-20 14:14:45 If I have float *p, can't I say p[i] if I want to? 2022-04-20 14:15:16 I thought pointers and array indexing were... closely related. 2022-04-20 14:16:03 sure, but then what are you programming against? the spec or the accidential correctness of the C compilers du jure? 2022-04-20 14:17:47 "compiler should stop and error..." <- ideally thatd be caught at comptime no 2022-04-20 14:17:51 This is interesting: 2022-04-20 14:17:53 https://people.cs.umass.edu/~liberato/courses/2017-spring-compsci365/lecture-notes/04-carving-strings-and-utf-8/ 2022-04-20 14:18:28 yeah utf8 is pretty niftily designed 2022-04-20 14:18:31 Me? I'd almost be certainly programming against the system I had in front of me and anything I could figure out about it. :-) 2022-04-20 14:18:53 Don't come to me for squeakily standard compliant code that will port all over town. 2022-04-20 14:19:18 I've done too much embedded, in which I controlled the hardware and the software (including the tool chain). 2022-04-20 14:19:37 KipIngram: which is why I often program in macro assembler, having its docu and the docu of the target handy 2022-04-20 14:20:19 or I do stuff in Tcl, Lua, Scheme or ecmascript 2022-04-20 14:22:20 one reason I like Forth is how bootstrapable it is and how I long to implement runtimes of aforesaid higher languages in it 2022-04-20 14:26:27 Yeah, I like how good it is for stuff like that too. 2022-04-20 15:17:50 So, I'm playing with UTF-8. 2022-04-20 15:18:32 I find that if I pack the bytes of a character into a buffer and TYPE them, everything works. But if I EMIT the bytes one after another, I get error characters. 2022-04-20 15:19:04 I don't immediately see why that shouldn't work too. Does Linux just forbid UTF-8 chars from being split across system calls? 2022-04-20 15:19:44 KipIngram: I don't think so. You can test though by running your data through "pv" utility at very slow speed 2022-04-20 15:20:44 Well, I think EMIT is actually testing it - it sends a single-character string through the write syscall. 2022-04-20 15:20:53 And I know nothing is going in between. 2022-04-20 15:21:17 KipIngram: is this a forth running on your host, or connected over serial? 2022-04-20 15:21:32 It's local. 2022-04-20 15:21:52 ahh, hmm, interesting 2022-04-20 15:22:18 KipIngram: you could, of course, still test independently of your program 2022-04-20 15:22:21 Yes - it is. It feels like that's something that should work, but... apparently not. 2022-04-20 15:22:32 using just the data in a file, piped through "pv" 2022-04-20 15:22:35 yes, true. Lemme see about that. 2022-04-20 15:23:15 you might perhaps need to set terminal settings to raw mode, if buffering effects might invalidate the experiment 2022-04-20 15:23:34 Here's what Python does: 2022-04-20 15:23:36 >>> print(chr(194)) ; print (chr(163)) 2022-04-20 15:23:38  2022-04-20 15:23:40 £ 2022-04-20 15:23:54 That "pound sign" is the right character, but that A with the hat shouldn't be there. 2022-04-20 15:24:16 what does "chr" procedure do? 2022-04-20 15:24:28 That's weird. 2022-04-20 15:24:38 >>> print(chr(194)+chr(163)) 2022-04-20 15:24:40 £ 2022-04-20 15:24:52 When I TYPE those two bytes in Forth I get the pound sign only. 2022-04-20 15:25:15 Oh - Gforth gets it right. 2022-04-20 15:25:20 I must have a bug in my program. 2022-04-20 15:25:25 Lemme look around. 2022-04-20 15:25:34 194 emit 163 emit £ ok 2022-04-20 15:26:09 I don't really know if chr() in Python does what I assumed. 2022-04-20 15:26:13 It very well may not. 2022-04-20 15:26:25 But gforth got it right, so it's not a split across syscall thing. 2022-04-20 15:26:32 I've got something broken. 2022-04-20 15:26:35 Looking now. 2022-04-20 15:26:57 I would say find the python function that just outputs the raw byte to stdout 2022-04-20 15:27:29 There's not much to go wrong in my system. 2022-04-20 15:27:43 : emit scratch c! scratch 1 type ; 2022-04-20 15:27:53 type is a primitive - I'm looking at it now. 2022-04-20 15:28:08 But if I TYPE both bytes at once, length 2, it works fine. 2022-04-20 15:30:17 That is doing precisely a "TOS value" byte write to stdout. 2022-04-20 15:30:25 That's really weird. 2022-04-20 15:31:35 KipIngram: when emitting them separately, can you capture the output to a file and look at a hexdump? 2022-04-20 15:32:06 Of course, I don't know exactly how gforth is doing it, except I know the first emit doesn't know the second one is coming. 2022-04-20 15:33:01 gforth even works with KEY in between the emits and me waiting a while. The 194 alone produces no output, just as you'd think it shouldn't. 2022-04-20 15:33:21 Um, maybe. Good idea. 2022-04-20 15:33:23 Hang on. 2022-04-20 15:34:47 Oh oh oh - I know what's going on, I think. One moment. 2022-04-20 15:35:22 : back-to-back 194 emit 163 emit ; ok 2022-04-20 15:35:24 back-to-back £ ok 2022-04-20 15:35:27 Compiled, it works. 2022-04-20 15:35:33 It has to do with stuff the interpreter is up to. 2022-04-20 15:35:50 That actually makes sense. I still want to pin it down precisely - maybe I don't want that. 2022-04-20 15:36:19 I expect the interpreter to be messing around with the console while EXPECT is running, but it's long since done when the words actually run. 2022-04-20 15:37:09 Yeah, compiled it works with key in between as well. 2022-04-20 15:38:06 Hmmm. The interpreter shouldn't be touching stdout except in type. That's the only place I output anything. 2022-04-20 15:38:13 But - there's got to be something. 2022-04-20 15:41:48 KipIngram: were you able to capture that output? 2022-04-20 15:42:09 see if there are any extra bytes inserted by interpreter 2022-04-20 15:42:16 Yeah - that's what clued me in to this. There's a shit ton of ansi sequences in there in between. 2022-04-20 15:42:28 But I haven't figured out yet where I'm doing it. 2022-04-20 15:42:32 flow control...? 2022-04-20 15:42:40 software flow control...? 2022-04-20 15:43:06 So far I'm only seeing output where you'd expect it - during EXPECT, for the prompt, and so on. But it shouldn't get back to any of that until it's done with the entire line. 2022-04-20 15:43:19 I'm not doing any flow control. 2022-04-20 15:43:30 oh, ansi sequences, like adjusting cursor position and such? 2022-04-20 15:43:37 But thank you - your idea showed it to me. 2022-04-20 15:43:46 Yes, I do a lot of that in EXPECT. 2022-04-20 15:44:12 And I emit a couple of spaces at the end of the command line - one after the command line itself etc. 2022-04-20 15:44:22 But during interpretation of the command string there shouldn't be any. 2022-04-20 15:45:03 hmmm... maybe some buffer needs to be flushed? 2022-04-20 15:45:58 here's part of it: 2022-04-20 15:46:09 194 emit 163 emi ^[[u^[[?25ht^[[?25l^[[s^[[D^[[D^[[D^[[D^[[D^[[D^[[D^[[D^[[D^[[D^[[D^[[D^[[D^[[D^[[D^[[D^[[D194 emit 163 emit ^[[u^[ 2022-04-20 15:46:40 Hmmm. do I have a hex editor? 2022-04-20 15:46:53 hexdump? 2022-04-20 15:47:04 I'm installing something now. 2022-04-20 15:48:10 So is flow control something that could be going on behind my back? 2022-04-20 15:48:32 I.e., something that I'm not doing "explicitly"? 2022-04-20 15:48:33 umm, I wouldn't think so on a local program 2022-04-20 15:48:43 Yeah - that's what I'd think. 2022-04-20 15:48:44 maybe over a serial port 2022-04-20 15:48:53 Oh - I've got something to try. 2022-04-20 15:50:11 Oh, no I don't. I'm not actually running inside screen. I rebooted yesterday and didn't start my usual screen session (which I just use to get to have multiple windows I can switch to). 2022-04-20 15:52:31 When I compile it it's fine no matter how long I make a KEY in between wait. 2022-04-20 15:52:51 So I'd say it's something I'm *doing* that's causing it. 2022-04-20 15:53:37 sounds like it. something I'm wondering about is when your interpreter flushes streams 2022-04-20 15:54:00 I wonder also if it might be interesting to see what happens if you set your terminal to raw mode 2022-04-20 15:54:02 using sterm 2022-04-20 15:54:12 I am in raw mode. Or at least damn near to it. 2022-04-20 15:54:23 I did that to get the input line to behave the way I wanted it to. 2022-04-20 15:54:35 I'd have to study the code a bit to recall exactly what I set up. 2022-04-20 15:54:46 But I'm betting that there's something a bit off in my termios settings. 2022-04-20 15:54:53 Some flag. 2022-04-20 15:55:08 But that doesn't get touched except at startup and bye. 2022-04-20 15:55:55 sounds plausible 2022-04-20 15:55:58 I know how to track it down. I can put the two emits at different places in the interpreter code, and zero in on the trouble spot. 2022-04-20 15:59:50 Oh - I know what's doing it. Heh heh. Forehead slap... 2022-04-20 16:00:17 pray tell 2022-04-20 16:00:44 I use color in my output. Input typing is white, errors are red, system output (ok promt and so on) is green and executed word output is blue. 2022-04-20 16:00:53 Is the color change before and after each execute. 2022-04-20 16:00:55 Duh. 2022-04-20 16:01:03 ah ha! 2022-04-20 16:01:37 Yep. Now I feel silly. 2022-04-20 16:01:51 now, just call it a feature and be sure to advertise it on the box later 2022-04-20 16:01:55 But, as usual, "it makes perfect sense." 2022-04-20 16:02:02 It usually does, once you see it. 2022-04-20 16:02:23 Exactly. I've played with it enough since then to know that I rather like the color coding. 2022-04-20 16:02:31 Makes the output screen look fancy dancy. 2022-04-20 16:02:57 Errors in red and "success" prompts in green particularly please me. 2022-04-20 16:03:42 it seems a strange idea though to make any changes to executed word output 2022-04-20 16:03:56 ;;; : interpret find tasks 0=me blue exec normal me [ 2022-04-20 16:03:58 def "interpret", interpret 2022-04-20 16:04:00 run find, tasks, zeme, 16+do, blue, exec, normal, me, 36+do 2022-04-20 16:04:08 There it is right there - blue exec normal 2022-04-20 16:04:38 Yes, I thought about that. But if the word needs to do color control itself, it can. 2022-04-20 16:04:49 It won't be interfered with inside the word. 2022-04-20 16:05:27 My editor for example - I plan to support color coded source, but that will all be running inside exec so it won't be disturbed. 2022-04-20 16:06:16 If I decide there's a problem with it I can quickly yank it out. 2022-04-20 16:07:04 It was going to bother me a lot if I had some unexplained "mystery output" going to the console. 2022-04-20 16:07:36 Now I wonder why Python was giving me that A-hat character. 2022-04-20 16:07:57 First thing to understand there would be exactly what chr() does. 2022-04-20 16:08:18 Oh, I see. Look at this: 2022-04-20 16:08:31 >>> chr(65) 2022-04-20 16:08:33 'A' 2022-04-20 16:08:40 It'll be something to do with the ' marks. 2022-04-20 16:10:06 a quick internet search: https://www.geeksforgeeks.org/working-with-binary-data-in-python/ 2022-04-20 16:10:34 Aha - thank you. I was using different search terms - that looks better. 2022-04-20 16:19:52 >>> print(b'\xC2\xA3'.decode('utf-8')) 2022-04-20 16:19:54 £ 2022-04-20 16:22:54 I can change how I do this color stuff. I can wrap the blue around the whole of interpret, rather than just around execute. 2022-04-20 16:23:12 ERR handles its own color, and the ok prompt does too. 2022-04-20 16:25:41 i might recommend also providing some variable that allows interpreter color to be turned off entirely 2022-04-20 16:26:30 Yeah, I thought about that when you questioned the wisdom of this earlier. I probably should make it switchable. 2022-04-20 16:26:32 But: 2022-04-20 16:26:34 194 emit 163 emit £ ok 2022-04-20 16:26:54 Too bad the color doesn't copy and paste over. 2022-04-20 16:35:21 What I'd really like to be able to do is save the color settings and restore them after I do a "color coded thing." 2022-04-20 16:35:39 I'm not sure if there's a way to do that, though. Need to noodle the ansi codes some more. 2022-04-20 19:49:40 You know, it occurred to me that if I want to do this "arrival time" discrimination between "just escape" and "escape sequences," then I'm going to need to guarantee that the keyboard never goes unattended for long enough to miss an arrival too significantly. 2022-04-20 19:50:06 I think that likely means I need that "downcounter with periodic detour" in my NEXT even for the foreground task. 2022-04-20 19:51:02 If I do that it eliminates the need to second new register to "alternative NEXT." NEXT will just always have that functionality. 2022-04-20 19:52:07 It would also mean that KEY wouldn't have to actually poll the keyboard - the periodic background task would do that, and KEY would just check the local keyboard buffer. 2022-04-20 19:54:00 It's a little crazy how "variant" the sequences returned by various multi-byte keystrokes coughs up. It can be as short as two, but I've seen as many as seven, on "shifted function keys." 2022-04-20 19:54:41 I'm very tempted to impose some sanity on that via that keyboard handler. The handler will recognize what it needs to recognize, but pass something more uniform to the application level. 2022-04-20 19:56:08 I was thinking a "first byte" that's not used by either ASCII or UTF-8, followed by a second byte that uniquely determines the key. It also seems useful to me to have bits in the two bytes sent to the app that directly reflect the state of the modifier keys. 2022-04-20 23:27:09 Well, I bit the bullet and installed a "tick counter." A down counter in NEXT, and a side branch that currently does nothing but reloads it and jumps back. 2022-04-20 23:27:26 Turned out the only place in my code I was using rbx at all was in BLOCK. 2022-04-20 23:27:45 And I was not using rdx there, but was in numerous other places (but no need to preserve it's value). 2022-04-20 23:28:12 So I switched block to rdx instead of rbx, and promoted rbx to "rrTICK" (a nasm alias). 2022-04-20 23:28:41 I haven't made any measurements - obviously there's no "casually noticeable" difference. 2022-04-20 23:30:09 I chose a counter value that should put me in the general neighborhood of 1 ms (considerable margin for error there - I'll have to tune it). 2022-04-20 23:30:35 I'm going to try to make this enough - I'd rather not take another register as a dedicated NEXT pointer. 2022-04-20 23:30:51 This hook should let me do anything I need to do. 2022-04-20 23:31:46 rbx is used in the init code, but nowhere once the vm is running. 2022-04-20 23:57:27 So it looks like parsing "dup" out of the input stream and executing it requires 9870 passes through NEXT.