3 Go for fully dynamic: A special dispatch provides for lazy loading of member protos. A ProtoBuilder greedily reads the source(s), then builds the proto (now that it knows the number of ivars), then compiles the methods. That means the methods are grabbed as text, and the parser can know at the time of parse-primary whether it needs to auto-declare.
5 Trylon objects get a special vtable that also checks (and knows) the enclosing context.
7 Just use "arg"/"args" for lambdas:
18 Equals-block should make a new object, not a dict literal:
27 new-cell = Cell new: value
40 But that should still serve the dict-literal purpose (and even better: 'dict entry' vs. 'dict at: "entry"').
47 All fields supporting the use of protos as packages (subproto names, ".parent-context", etc.) should be shared fields.
60 Standard Object must be loaded first, and can't join Standard until later. Use a (namespace ...) function instead of sends to access parent namespaces, and don't specify Main in its arguments -- (namespace Standard), (namespace Standard Implementation). It will dynamically check to see if the namespace is loaded and load it from the .k file if not. Or call it (load-trylid-proto), or just (trylid-proto). So something like this:
62 (define trylid-root-object (read-trylid-proto-file "Standard Object.k"))
64 (read-trylid-proto-file "Main.k")
65 ;; Should result in everything else getting loaded.
67 Standard Object is a subclass whose access gives "trylid-root-object" -- that allows its own .k file to work before Main is set up.
69 I still kinda want to make Main special...
71 "true" and "false" may present problems, but I should probably wait to see if they do before trying to fix them. If they do, perhaps fake values can be used temporarily until Standard Bool is loaded.
73 In trylid.k, this is all put together in (load-trylid).
78 Jolt's "break" Is Broken
81 It's the "break" statement that's breaking things right now ("cannot reduce 34675(#nil Block ---) to VOID") (in jolt-burg, anyway).
89 A single "PrimitiveWord" type can handle all operations, and be specially handled by the compiler.
93 int-obj int-at: byte-at: long-at: obj-at:
105 Always thru trylid-proto: 1:45.
106 "Quicker" (byte-ptr): 1:47. (!)
107 "Quicker" (trylid-int): 1.24.
108 "Quicker" (trylid-char): 0:58.
109 "Quicker" (trylid-string): 1.00.
111 At this point, the Trylid compiler loads itself (mostly; it did so completely recently, but not at the moment) but doesn't do codegen. It became obvious that the generated Jolt code is much slower than Trylon's generated C, by about an order of magnitude. My first theory was that (trylid-proto) might be the cause. And it turned out that it was called surprisingly often: 7,636,346 times. An attempt to eliminate its use for proto access failed due to dependency issues (I forget the details), so I tried just optimizing the primitives, as seen above.
113 I'm thinking this can be fixed in the general case by having a proto set up auto-loading stubs for its subprotos early in its loading process. The stub would replace itself with the real proto-returner (via (add-shared-field-to)).
122 "self" instead of BytePtr/Char: 1:16.
123 Same, with Int added: 1:15.
124 "new"s rewritten: 0:19.
126 The rewritten "new"s (BytePtr/Char/Int) are rewritten so they reference Implementation as a Jolt variable (StandardImplementation) instead of thru (trylid-proto).
128 New proto-loading scheme:
138 Currently, the compiler running in Jolt is about 4x slower than the one Trylon makes. I'm thinking (trylid-int) and (trylid-char) may be to blame. Here are the stats on what gets consed during a run:
145 (I don't get why it takes so much longer to grep through the results than to generate them. If there are no hits, it only takes a few seconds.)
147 (Well, there are 8.5 million lines... I'm not sure I'll ever know the breakdown 'cause grep is so slow.)
149 I was thinking of changing (trylid-char) et al. to macros, but realized that was difficult because would I need to keep sets of boxed objects. And it should be much easier to switch to tagged ints, with chars being ints.
151 An there are even easier improvements: (byte-ptr) becomes a macro for [StandardBytePtr new_: value]. Strings don't cons their BytePtrs, although then it's not a fair comparison with Trylon.
153 Well, it isn't that hard to use macros after all:
156 trylid-char-literal 9.0, 8.6
157 +trylid-int-literal 7.7, 8.0, 8.5
158 +trylid-string-literal 7.8, 8.0
160 It's odd that trylid-string-literal didn't seem to help, as that would seem to be the "heaviest". ...Now that I've got the stats filled in, I see why: there just aren't so many of them. Why so many byte-ptrs, then? From non-literal strings, undoubtedly.
165 Cola Lightbulb Goes On
168 All my Statements and Expressions are supposed to respond to "translate: compiler". (I think like this:)
171 jolt-expression translate: compiler
179 Rename "Main" to "Trylid".
187 Rename ".parent-proto" to "..". This is compatible with filesystem use because the meaning is "parent namespace". (Still need ".proto", though, unless it's unused. Hmm, it seems it's only used by 'is-a:' currently, and we already have a good (?) version of that on Pepsi Object. Might as well leave it since it's already there, though.)
189 Need to add ThisSetter, perhaps to Trylon too. Then maybe rewrite create:'s as new:'s, or just add new:'s explicitly:
192 return this raw-new create: name
194 Once exceptions are working, install a new doesNotUnderstand: in Pepsi Object that throws an exception. Once the new parsers are in, make my own command line. I want the command line to handle blocks!
196 Precompile only Standard, Posix, and the compiler itself... which is everything we're precompiling now. But then have it compile out of the filesystem. In other words, the current compiler ("Compiler run:") isn't the default action, and must be turned on via build-settings. Otherwise, run a command line, and allow compiling directly from Trylid in the filesystem to machine code.
199 # Default: try using the hidden '.iterator'.
200 if this responds-to: '.iterator'
201 return this .iterator
203 return this doesNotUnderstand: 'iterator'
205 Weird behavior while testing exceptions: "[(trylid-proto Posix) jmp_buf]" crashes, but if I once do "[Posix jmp_buf]", the first one won't crash after that. And I have verified that "(trylid-proto Posix)" and "Posix" are the same.
207 ".source" should specify a proto's source in the filesystem. As a FilesystemObject (new name for FileDirectoryEntry), or as a path?
215 ".parent-proto" actually means "superclass" currently, not "enclosing context". So ".." would be an entirely new addition.
223 "Object detach": Give the object its own vtable. (Can verify that ".proto == this" if it wants.)
231 While self-compiling:
233 Cache hits: 170017841.
234 Cache misses: 9271514.
239 Field Access Optimization
246 The tradeoff is that the generated Coke code is less readable; at this point I don't think the speedup is worth it.
255 Loading directories from the command line.
256 [Done, but can't re-load.]
257 Unify String (maybe).
259 Field access optimization:
260 Setter translate-call:.
261 Explicit calls on "this" (as in constructors).