colorful rat Ratfactor.com > Dave's Repos

meow5

A stack-based pure inlining concatenative programming language written in NASM assembly
git clone http://ratfactor.com/repos/meow5/meow5.git

meow5/design-notes.txt

Download raw file: design-notes.txt

1 *********************************************************** 2 * Meow5 Design Notes * 3 *********************************************************** 4 5 All this stuff is pretty much done - but I'm leaving 6 this file for posterity. 7 8 =========================================================== 9 DONE: write header AFTER the word (to make it dirt-simple 10 to calc length of machine instructions and write it there) 11 12 DONE: use linked list like i learned how to implement in 13 jonesforth 14 15 =========================================================== 16 DONE: Add a regression test suite to test all 17 functionality as I add it (probably best added after I make 18 this take input from STDIN!) 19 20 (I have a very small test.sh - works great) 21 22 =========================================================== 23 Display free memory and bytes compiled so far - on start up 24 and/or on demand. 25 26 =========================================================== 27 DONE: get as quickly as possible to 28 29 : meow5 meow meow meow meow meow ; 30 31 first compound word after meow5 could be: 32 33 : exit0 0 exit ; 34 35 =========================================================== 36 Idea: Add description/usage instructions strings to word 37 'tails' so they can be read (maybe even searched?) while in 38 the interpreter. A totally easy feature that wouldn't have 39 made sense on the old memory-started machines of the late 40 1960s. I'm thinking that some stack annotations could be 41 semi-automated, too. Well, there is a ton of low-hanging 42 usability fruit once you go down this avenue. Gotta stick 43 with the minimum viable PoC for now...would be so easy to 44 get wrapped up in shaving those yaks and choosing juuuuuust 45 the right colors for that bike shed... 46 47 Also consider automatically generating the "stack effect" 48 comments that explain the input and output params on the 49 stack. 50 (*Also* consider (optionally) enforcing them!) 51 52 =========================================================== 53 DONE/YES: A rule: COMPILE mode words can _only_ be 54 defined via 'colon' OR composed entirely of machine code 55 with no CALLWORD macros? 56 57 =========================================================== 58 DONE: Challenge: how to have dictionary words that can be 59 called in meow5 itself to form the basis of the language 60 (specifically, 'find', 'inline', etc.)? The "tails" that 61 make them words make them not function as good assembly 62 citizens. 63 64 Right now, I've got a temporary variable in BSS that 65 functions as a single return address for these words. 66 67 What I think I might need to do is make a macro that detects 68 that a return is requested and then does it. 69 70 DONE: Yup, went with this idea: OR have two labels at the 71 end of those words - one that is the end when you 72 inline/compile it as a word and the 'tail' label. The length 73 of the word would be considered the instructions before the 74 "return" jump mechanism. So when inlined, it wouldn't even 75 check for a jump, it would just flow on through to the next 76 word. 77 78 DONE: And I think i'll probably need to have a mini-stack 79 for return addresses in this tiny subset of 80 words-that-can-be-called-like-functions. Just a handful of 81 nested calls (i'm not going to use recursion or anything 82 like that): 83 84 return_stack: resb 32 85 return_stack_pointer: resb 4 86 87 Something like that. 88 89 NOTE: Turns out, an "inline all the things!" language can't 90 have nested calls anyway (kinda obvious in retrospect) so 91 I'm removing the return stack and replacing it with my 92 original single return address. This is only used in 93 immediate mode to return from a single word's immidate 94 exection. 95 96 =========================================================== 97 Display machine code (at least) and all 'tail' meta-info 98 about a word (or all words), maybe even with some nice 99 ansi color coding. I wanna make this look pretty so much, 100 but I know I've gotta hold off on the curtains and carpet 101 and get the walls and floors built first.. 102 103 =========================================================== 104 DONE: have explicit interpret-time vs comp-time context 105 words. 106 107 Regular interpret-time: 108 : foo 1 2 add ; 109 Compile-time: 110 :comp if ... ; 111 And when searching, we can skip any words that don't 112 match: 113 * name length 114 * name 115 * context (compile or interpret) 116 Which ALSO means that we can define two different words 117 with the same name for compile/run (or interp/comp) time 118 119 =========================================================== 120 DONE: Use stack for all word param passing - don't 121 get fancy with trying to keep track of registers 122 with this proof of concept!!! 123 124 =========================================================== 125 DONE!!!! How hard is it to write an elf executable? it would 126 be super cool to be able to write any compiled word 127 straight to disk as a tiny, self-contained executable! 128 Especially when done right from the interpreter REPL. 129 I bet not many languages have *that* feature! (I don't 130 know of any). 131 132 =========================================================== 133 DONE!!!!! And holy cow, that was rough. 134 Done? As long as we have free space for them, strings have a 135 place in memory now... 136 Challenge: Programs are built up by concatenating words 137 togeher, so by definition, everything a top-level word needs 138 is guaranteed to be contained in that word (if we wanted to 139 write it out as a stand-alone executable.) But how do we 140 reference data like strings? And variables/constants? 141 142 How do other compiling Forths handle that, for that matter? 143 Do they write out every word in the dictionary? And is the 144 outer interpreter always included??? 145 146 =========================================================== 147 Register Usage 148 149 Typical usage notes (JF = JONESFORTH) 150 151 EAX: The accumulator/return val 152 EBX: often for pointers 153 ECX: often for counters 154 EDX: whatever 155 ESI: The source index for string operations. 156 JF used ESI for NEXT word address pointer 157 EDI: The destination index for string operations. 158 EBP: pointer to current fn stack frame base 159 JF used EBP as Return stack pointer ("RSP") 160 ESP: pointer to current fn stack frame top 161 JF used the stack as THE parameter stack 162 EIP: instruction pointer! 163 164 =========================================================== 165 DONE: Hmmm... as much as possible, I'll use the stack and 166 other in-memory pointers to avoid having to think about 167 explicit registers as much as possible. Certainly some 168 of the ones needed for a traditional "threaded interpreted" 169 Forth won't be needed for Meow5!