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!