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!