Rune - Further Object abstraction work
[rune.git] / docs / overview.html
1 <HTML>
2 <HEAD>
3 <TITLE>Rune Language Overview</TITLE>
4 </HEAD>
5 <BODY>
6 <CENTER><H2><B>Rune Language Overview</B></H2></CENTER>
7 <CENTER><H3><B>(c)Copyright 1996-2018, Matthew Dillon</B></H3></CENTER>
8 <P>
9 <H2><B>(I) History</B></H2>
10 <UL>
11     <P>
12     Well, the story of Rune is long.  My desire to write a language began in
13     the late 1980's after I had learned C and started looking for something
14     better.  Many years later people will note that I am still a hard-core
15     C programmer, working mainly on the DragonFly kernel code base.  You
16     might think (if you didn't know me) that I'd be able to find *something*
17     out there that would satisfy me language-wise, other than C.  But I
18     haven't.
19     <P>
20     For various reasons I have very little love for most of the programming
21     languages out in the world today.  I hate the design-by-committee mess
22     people call C++, I hate the kitchen-sink-control-the-programmer approach
23     taken by Eiffel, the cacophony that is perl, the limited Objective-C,
24     the ever-changing typeless lets-break-everyone-again TCL (though I will
25     admit that, of late, it seems to have settled down.  Still, TCL isn't
26     for me!).  I'm not interested in the politics associated with Java
27     that has destroyed it as a viable programming language, or the wordy
28     semantics and constructs (Java is a toy that should never have seen
29     the light of day IMHO).  I don't mind some of the newer mostly interpreted
30     languages but for one reason or another they aren't really my cup of tea.
31     I hate leaving performance on the table or having core language constructs
32     such as expandable arrays fall down on the job of managing memory well.
33     Languages like Scheme, Python, and Ruby are better, but have a number
34     of show-stopper quirks (like the crazy indenting mechanics of python,
35     for example), and nobody seems to be able to handle locking or threading
36     properly.  As a kernel programmer I want something which can handle
37     threading and locking in as non-invasive and natural manner as possible.
38     And when I say threading, I don't mean a few dozen threads.... I want a
39     language that can handle a million light-weight threads.
40     <P>
41     I'm a great believer in the concept of a class hierarchy and in
42     object-centric design, and yet as you can see I have done little but
43     write in C in my life which is kinda like the wild west when it comes
44     to object-centric programming.
45     <P>
46     Of course, another reason I have not switched to a more object-oriented
47     language is simply because every time I try I find myself constantly
48     comparing it to my internalized ideal.
49     <P>
50     Rune is culmination of almost everything I want in a language.  It
51     has gone down many paths, retreated, gone down again, retreated.
52     Pointers began as very fat objects which I then tried to collapse by
53     internalizing type and lock data, which failed.  So they became fat
54     again and now in this iteration I am attempting to reduce them to
55     something inbetween...  two machine fields rather than five.
56     <P>
57     Throughout this period, I began thinking of my dream language
58     as "D" in my head, but I was ambivalent about trying to name it that
59     as a public release.  I finally came up with a great name, "Rune", after
60     running through literally a thousand different possibilities.  I don't
61     care if it's already being used for other things... so is virtually
62     every other interesting word in the dictionary.  "Rune" is the name of
63     the language, now.
64     <P>
65     So why has it taken so long to write Rune?   Well, there are many
66     reasons.  Some of you might remember the 'DICE' system I wrote for
67     the Amiga and sold as shareware in the early 90's.  DICE was a full
68     ANSI-C compiler (circa that period), preprocessor, assembler, and
69     linker, and included a full set of standard C libraries.
70     I wrote it all, for the 68000.
71     <P>
72     Unfortunately this points to a severe character flaw of mine when it
73     comes to me and writing code... I am a bit of a perfectionist when it
74     comes to my own personal work, and other people's work rarely achieves
75     a level of robustness that I am comfortable with.  I was able to build
76     DICE quickly because the C language standard already existed, as well
77     as standards for all the other necessary pieces, so I just had to
78     start coding it up.  But Rune is a different matter.  With Rune I am 
79     designing the language as well as implementing it, and that amplifies
80     the character flaw.  I want to give people as good a base as possible.
81     <P>
82     Over these many years my language has evolved.  I have added many
83     features and removed many more.  I have written over two dozen drafts
84     of the grammer but it has only been the last five or so years that
85     it's settled down into something I consider to be reasonable.  Another
86     time factor is what I call the 'Dillon' factor.  When I set out to
87     design something I expect to be able to grasp and hold the entirety
88     of the project in my head without external references.  Rune is complex
89     enough that it has taken quite a while to achieve this state of mind.
90     I want to be able to scale simple concepts into extremely sophisticated
91     capabilities.
92     <P>
93     I've been especially hard-nosed on this project, but I believe quite
94     strongly that getting the core right can have a thousand-fold payback
95     down the line.  I will say, right off the bat, that Rune is not for
96     everyone.  It is not meant to be a kitchen-sink language.  For example,
97     it is more systems-oriented and less abstract.
98     <P>
99     So that's the history in a nutshell.  I've left out what few discussions
100     I have had with friends and my many attempts to kick the process (multiple
101     times, over the years).  In the end it's only the final draft that matters,
102     and this is it (at least as of this moment :-)).  This is the end of the
103     beginning and the beginning of something new.
104 </UL>
105 <H2><B>(II) Language Features and 'why I did it that way'</B></H2>
106 <UL>
107     <P>
108     I absolutely can't stand languages that try to implement <I>everything</I>.
109     Kitchen sink languages tend to be so complex that they wind up being
110     unusable or unreadable or unlearnable or unmaintainable.  When a
111     programmer is able to implement some concept ten thousand different ways,
112     you will wind up with ten thousand different implementations and you can
113     huck any efficient, collaborative development right out the window.
114     I have thought long and hard in regards to which concepts I should
115     include.  Should I have inheritance, multiple-inheritance, subclassing,
116     organization of class hierarchies, and so forth?  I've thrown out a lot
117     of concepts as simply not meshing well with the rest of Rune.
118     <P>
119     For example, you will not find multiple-inheritance in Rune.  Why?
120     Because multiple inheritance almost always results in unreadable code.
121     Well-designed programs just don't need it.  Abstraction is good to a
122     point.  Take it too far and code might as well be gobbly-gook to anyone
123     who wasn't the original author.
124     <P>
125     Similarly I have considered many exception-handling schemes but as yet
126     I have not come across anything I really like.  I consider contracts
127     to really just be assertions, and I am in the school of thought where
128     a failed assertion is a bug and should abort the program.  Actual bugs
129     should assert, period.  The last thing you want to do is to try to catch
130     a bug and unwind code with yet more potentially buggy, untested exception
131     handlers.  Code paths which rarely run are also rarely bug-free.
132     <P>
133     Nominal errors... something which can happen under normal operating
134     conditions that you want to process... those are the real problem.
135     I would *like* to have language constructs to facilitate error handling,
136     but I don't want something which makes the code too much more complex
137     than the nominal case we might see in a simple C call such as read().
138     Plus there are many situations where an error simply should not be
139     handled by the deepest caller receiving it, and which may or may not
140     effect operation of the call stack leading up to it.
141     <P>
142     The biggest problem with most error handling is that implementations
143     return too many possible errors when they should be asserting and
144     panicing on most of them instead.  You don't coddle software bugs,
145     you stamp them out and nothing stamps out bugs faster than an
146     assertion and core dump.
147     <P>
148     Lets take a simple example.  Lets say you have a routine to load a
149     font by name which returns a 'Font *' to the caller.  An error occurs
150     if the font does not exist.  The question is then how to handle it and
151     who should handle it?  I would argue that the best way to handle it is
152     to have an error code embedded in the Font structure itself, and instead
153     of the font loader returning NULL the font loader instead sets an error
154     in the font structure and never returns NULL.  For arguments sake,
155     the caller could even allocate the structure:
156     <P>
157     <UL><LI>
158 Font *font;
159
160 font.new();
161 font->loadFont("fubar");
162     </LI></UL>
163     <P>
164     The advantage of this mechanic is that the caller might not necessarily
165     be in a position to handle the error, but some higher-level routine in
166     the call stack, or even some other part of the program might.  The caller
167     has the option of simply proceeding as if nothing bad happened and leaving
168     the error for someone more suited to handle it (say, the GUI user
169     requestor that the user originally typed the font name into!).  This
170     is the type of flexibility I want to see in any language-supported
171     exception-handling.  As you should be able to see already, there's no
172     single error code or single error path.  Errors could, in fact, bifurcate
173     on the way back up the call stack simply by registering them within the
174     object.
175     Not all errors can be handled this way of course, but there is a whole
176     class of errors that can.  Possibly not the best example I could come up
177     with.
178     <P>
179     And this is why Rune does not have anything yet, because I haven't come
180     across a mechanism that I really like.  You'll find many drafts and
181     attempts in the spec history, but nothing implemented in this first
182     release.
183     <P>
184     You will not find a formal single-root class hierarchy.  Been there, done
185     that, stupid idea.  Nor will you find complex overloading features.  Rune
186     is designed in a manner that avoids most potential namespace conflicts
187     without over-burdening the programmer with long dotted identifier
188     sequences or complex specifications.  Since most conflicts are naturally
189     avoided in the first place, Rune doesn't need sophisticated overloading or 
190     conflict handling features.  What will you find in Rune?  Read on!
191     <P>
192     * Import mechanism.  Rune uses an import mechanism to collect project
193       files and libraries together into a program.  There is NO include
194       mechanism, and there is currently no pre-processor mechanic (though
195       I am considering it).
196       If you import a directory then Rune will locate "$directory/main.d"
197       and import that.  "main.d" then typically imports whatever libraries are
198       required as well as the other project files and provides a <B>main()</B>
199       to start execution of the program.  Library-library dependancies are 
200       typically resolved simply by having the library itself import whatever
201       other libraries it needs (and as a welcome side effect this makes 
202       libraries self contained).  Duplicate imports of self-contained entities
203       are allowed, will be shared, and do not result in any significant extra
204       overhead.
205     <P>
206     * Semantic search is not class-hierarchical.  Rune locates an identifier
207       through a semantic search based on how you stack and name imports.
208       Within a procedure the semantic search begins in a manner similar to C,
209       where the search checks local declarations within the procedure
210       and then within the current file.  If the identifier cannot be found
211       the semantic search progresses upward through the import hierarchy
212       until it hits the root (of the import hierarchy) -- the original file
213       that kicked the whole thing off in the first place.  There is no object
214       root.  Identifiers are searched level-by-level and can be forward 
215       referenced (Rune makes no distinction between backward and forward
216       references except in one parse-time convenience case).
217       <P>
218       You can push down into an import, type, or class, by using a dotted
219       sequence of identifiers.  For example, if <B>main.d</B> imports
220       "File" (file support library) and "a.d", "b.d", and "c.d", then code
221       sitting in "c.d" can access the file support library simply with a 
222       construct like <B>File.FILE *fi = ....;</B>.  Rune also includes
223       a mechanism which allows semantic searches to automatically push into
224       an import without specifying the import's id, by using double quotes
225       in the import name instead of angle-brackets.
226       Secondly, an <B>alias</B> mechanic allows you to pull up oft-used
227       identifiers without pulling up the entire namespace.
228       <P>
229       The <B>limport</B> mechanism is typically used only to collect tightly
230       integrated source files together... for example, source files in a
231       subdirectory.  The main system library is typically imported by a
232       project this way, but externaal library imports in general are almost
233       universally named entities (imported using angle-brackets) and not
234       imported using double-quotes, in order to avoid namespace conflicts.
235     <P>
236     * Context-sensitive semantic search.  Complex classes often have many
237       constants associated with them.  Under certain circumstances Rune
238       provides direct visibility into any global fields defined for a class
239       in the context of a method call made to that class.  An example of
240       this would be something like <B>fd.open("fubar", O_RDONLY)</B>,
241       where the O_RDONLY constant is directly accessible when used as
242       an argument to the <B>open</B> method call (and otherwise would be
243       accessible via a dotted <B>fd</B> or <B>Fd</B> expression).
244     <P>
245     * Typedefs.  Rune supports typedefs.  Typedefs are used to 'alias' 
246       classes, with or without modification, making them available as simple
247       identifiers or via mulitple semantic paths.  A typedef can be placed
248       anywhere a declaration can be placed:  At the top level, in a
249       <B>class</B> definition, in a procedure... even inside a compound
250       type if you want (though I might call you crazy).  Typedefs are
251       extremely convenient constructs which allow you to short-cut complex
252       types to avoid having to specify class paths with lots of dots.  For
253       example, if your project uses <B>File.FILE</B> a lot, you could
254       simply <B>typedef File.FILE FILE;</B> in your project's "main.d"
255       source file and just use <B>FILE</B> in all the project source
256       files it imports.
257       <P>
258       Typedefs can also be used to change default assignments.  For
259       example, <B>typedef myint int a = 4;</B> creates a new type
260       <B>myint</B>.  When you instantiate <B>myint</B> the object content
261       will default to a value of 4 unless you specifically give it another
262       default.
263     <P>
264     * Classes.  Rune supports a class mechanism.  All types except compound
265       types are based on a class somewhere.  This includes core Rune types
266       such as <B>int</B>.  What you know as an <B>int</B> in C serves the
267       same function in Rune with the same physical size, but <B>int</B> is
268       in fact a full-blown class in Rune.
269       Classes contain declarations: typedefs, storage declarations,
270       operators, procedures, and constants.  <B>It is important to note
271       that Rune uses a C-like pass-by-value model.  Rune also supports bounded
272       pointers and so can pass objects by reference, and also supports passing
273       and returning an object by <I>lvalue</I>.  An <I>lvalue</I> is
274       effectively an object which appears to be passed by value but is
275       actually passed by reference, allowing the procedure to modify it.
276       <I>lvalue</I> is necessary to implement operators like "++" and "+=".
277       Rune makes no distinction between core classes and user-defined
278       classes.</B>
279     <P>
280     * Subclasses.  Rune supports a subclassing mechanism.  A subclass is 
281       basically a merge of its superclass plus additional declarations
282       and/or refinements to declarations inherited from the superclass.
283       Namespace overloading is explicit.. if you declare something using
284       an identifier that conflicts with a declaration in the superclass
285       and you do not explicitly say that you are refining the superclass
286       declaration, then your declaration will be used by anything you
287       define in your subclass but the 'hidden' declaration in the superclass
288       will be used by anything defined by the superclass.  Rune allows you
289       to refine methods, typedefs, and storage (changing the size of 
290       preexisting storage elements in an object).  However, because I have
291       no wish to force the entire language to be dynamically typed at run
292       time only subclasses which refine procedures, extend existing storage,
293       and adjust default assignments are compatible with dynamically bound
294       reference pointers (see later).  The base fields of subclass which
295       match the superclass must be compatible with an accessor running
296       through the superclass.
297     <P>
298     * Refinement.  When you subclass a class you can refine declarations
299       made in the superclass.  You can only refine declarations by making
300       them more specific.  For example, if the declaration in the
301       superclass is <B>Integer x = 4;</B> then you could refine it to
302       be <B>int8 x;</B> but you could not refine it to be <B>float x;</B>.
303       You can refine types and default values and you can partially
304       resolve procedure arguments (and/or refine argument and return types).
305       <B>Refinement is an extremely powerful mechanism.  The core library
306       uses refinement to declare all of Numeric's operators in the Numeric
307       superclass using a typedef'd type called 'T'.  The core library then
308       simply refines the typedef T in various subclasses in order to
309       automatically re-form the supeclass operators and procedures into
310       more specific operators -- without having to redeclare the operators
311       or procedures at all.</B>  This means, in effect, that you can write
312       generic procedures in the superclass that operate on declarations
313       defined by the superclass in the context of the subclass.
314       <FONT COLOR="darkgreen">Subclass refinement is one of the most 
315       sophisticated and important features of the Rune language</FONT>.
316       <P>
317       Refinement also works well with <B>method</B> procedures.  These are
318       procedures which execute with an object context called <B>this</B>.
319       If you create a subclass which refines a superclass declaration,
320       and then call an unrefined superclass method, the superclass method
321       will use your refined declaration(s).  Superclass procedures which
322       are overriden by subclass refinement are not automatically called.
323       Instead your refined procedure must use the
324       <B>super-><I>funcname(...)</I></B> mechanism to chain the
325       superclass method.
326     <P>
327     * Pass-by-value and embedded objects.  Rune uses the C pass-by-value
328       and embedded-type model.  In C you can embed one structure inside
329       another.  You can do the same with classes in Rune.  Rune also has what
330       we call an <I>lvalue</I> extension which allows a procedure to
331       enforce a pass-by-reference and/or return-by-reference for an object
332       that is passed to it literally, which Rune operators use to implement
333       variable-modifying behavior (such as <B>++x</B>) and which you will
334       be able to use to for the same purpose.
335     <P>
336     * Forward referenced identifiers.  Rune does not impose any requirements
337       on the ordering of declarations within a file or between files and
338       libraries.  The only thing you cannot do is directly embed classes
339       in a way that forms a loop (class A into class B and class B into
340       class A).  You can, of course, embed mutual pointers.
341     <P>
342     * Bounded pointers.  Rune's interpreter uses bounded pointers.  For
343       example, a pointer into an array can be manipulated with addition
344       and subtraction, just like C.  But Rune will not allow the pointer
345       to be accessed if it goes out of bounds.  Rune also does not allow you
346       to arbitrarily cast pointers from types containing pointers to other
347       types or vise-versa.  Casts are allowed only between types whos contents
348       do not contain pointers.
349       <P>
350       This does mean that Rune pointers can be relatively expensive if misused,
351       but the multiple features of a Rune pointer are not to be triffled with
352       and this will ultimately be something that can be optimized heavily by
353       the language implementation.
354     <P>
355     * Dynamically bound pointers (known as reference types).  In Rune something
356       like 'Frame *x;' represents a pointer to a frame.  A dynamically bound
357       reference is something like 'Frame @x;'.  This creates a pointer object
358       that can be bound to the specified class or any compatible subclass of
359       the specified class at run-time.  You can only access the fields whos
360       API is defined by the superclass (Frame in this case) through a
361       reference type, but that's why we have refinement.  Your method calls
362       will call into the version of the procedures refined by the associated
363       subclass, for example.  Subclasses can do other cool things like
364       change default values, and the access via the superclass will of
365       course see the different default.
366     <P>
367     * Constant optimizations.  Both the interpreter and the code generator
368       do VERY serious constant optimizations.  The interpreter will shortcut
369       constant expressions on the fly after evaluation so the next use
370       can simply return the constant.  The code generator will use hints
371       from the resolver to determine that an expression should return a
372       constant and execute the interpreter at code-generation time to
373       obtain the constant.  Constant optimizations are far more than just
374       being able to evaluate simple operators, they also include making calls
375       to 'pure' functions with constant arguments with any level of
376       sophistication.  This means that you can have something like sin()
377       (take the sine of a floating point value) and if you pass it a
378       constant the result will be evaluated at compile-time by the
379       code generator rather than at run-time, and will be evaluated just
380       once by the interpreter and then replaced by a constant.
381     <P>
382     * Constant evaluation for global default initialization.  When
383       generating code, the interpreter is invoked to resolve default
384       assignments.  In Rune you can initialize a global using expressions
385       which would not normally be considered constant expressions in a
386       language like C.  However, there are limits to the complexity allowed.
387       Any address assignments must resolve to an assembly symbol and offset,
388       and any circular assignments, such as the one shown below, will
389       give indeterminant results which may change depending on whether
390       the program is compiled or interpreted.  This Rune specification does
391       not allow circular default assignments, but might not error-out
392       if you choose to use them.  In addition, global pointer variables
393       are not available at compile-time.
394     <UL><LI>
395 global int a = b + 1;
396 global int b = a + 1;
397     </LI></UL>
398     <P>
399     * A global variable assignment's initialization is resolved at
400       compile-time.  A global variable initialized via a global
401       constructor is resolved at run-time.
402     <P>
403     * Automatic zeroing.  Stack declarations are automatically initialized
404       to zero if not otherwise assigned (pointers are initialized to a
405       typed-NULL).  Allocations are always zerod unless explicitly told not
406       to.  Only allocations of structures which do not contain pointers,
407       lvalues, or references can request an uninitialized allocation.
408       Pointers are always initialized and cannot be optionally told not
409       to be.
410     <P>
411     * There is no union.  Believe me, this is a feature.  The subclassing
412       mechanism should be plenty good enough to handle nominal union-like
413       situations and Rune allows content casting as long as the content
414       contains no lvalues, pointers, or references.
415     <P>
416     * User-defined operators.  All operators in Rune are physically declared.
417       Even Rune's core operators on integers and other types are declared
418       in the core Rune "sys" library.  You can define your own unary and binary
419       operators and you can use almost any sequence of operatic characters
420       to do it.  Rune imposes one bit of sanity, however.  You cannot specify 
421       the precedence.  The precedence of an operator is fixed based on 
422       the characters making up the operator.  All C-like operators wind
423       up with C-like precedences.  Your own operators will wind up with
424       C-like precedences too, using simple rules defined in the Rune grammer.
425       <P>
426       <FONT COLOR="red">
427       User-defined operators can be emplaced in any class belonging to the
428       arguments you supply to the operator when you use it, and may also be
429       emplaced in your main semantic search path.  So, for example, you
430       cannot add a new operator to the core <B>Integer</B> class but you
431       can certainly add a new operator that operates on various kinds of
432       ints semantically, such as in your <B>main.d</B> module. </FONT>
433     <P>
434     * Pure functions - A 'pure' function with constant arguments will
435       be interpreted at compile-time and replaced with its result.  For
436       example, most math operators and trig functions are defined as being
437       pure.  So if you have a bit of code that, say, runs cos(1.5), the
438       run-time overhead will be the same as for a constant.
439     <P>
440     * LValue operators and procedures (deserves separate mention).  An
441       LValue operator is capable of assigning the
442       left hand side as well as returning a result.  The left hand
443       side must be an lvalue.  For example, the C "+=" and "++" operators
444       are LValue operators, while "+" is a normal RValue operator which
445       returns a temporary result.  LValue operators allow Rune to implement
446       almost the full complement of C operators and additionally allows you to
447       build your own user operators with similar characteristics.
448     <P>
449     * User-defined casts.  All casts in Rune are physically declared, including
450       core castings such as int8->int16.  The Rune class library implements
451       the more common casts but does not implement all casts.  The language
452       also builds-in certain casts for conveniences.  For example, a pointer
453       will auto-cast to a bool in order to allow <B>if (ptr) ...</B>.
454       <P>
455       Rune is a bit more strict when it comes to auto-casting integral and
456       floating point constants and variables to other integral or floating
457       point types.  Rune generally only auto-casts when the target type is
458       well known, such as the argument type in a procedure call.  Rune
459       generally will not auto-cast intermediate results to match operators.
460       This tends to be non-deterministic (in C the rules are just too flexible
461       and allow for very sloppy coding).  Rune will usually complain if you
462       mix integral and floating types together in an expression.
463     <P>
464     * Method calls.  A method call is something like <B>fp->setmode(10)</B>.
465       That is, making a call through an object.  In Rune a method declarations
466       or call is similar to a procedure call passing the object as an lvalue
467       as the first argument to the procedure and, in fact, the Rune resolver
468       converts method declarations and calls to exactly that.  You can also
469       create <I>global</I> method calls.  These can be called through the 
470       object or through the object's type, but rather then passing an object
471       as the first argument the type is passed instead.  Something like
472       <B>FILE *fi = FILE.fopen(...)</B> is an example of a global method
473       call.
474       <P>
475       Rune normally constructs the first argument for a method call silently
476       and automatically.  The argument is named <B>this</B> and will represent
477       the object itself (not a pointer), so nominal accesses are via '.'.
478       Normal method calls require a valid non-NULL object which has the
479       side effect of allowing the method procedure to access the contents of
480       the object without further bounds-checking.
481       <P>
482       However, there are cases where you might want to declare the <B>this</B>
483       argument yourself.  Specifically there are cases where you may wish to
484       pass an lvalue pointer to an object rather then the lvalue object in
485       order to be able to allocate or otherwise replace the pointer.
486       To do this, you must declare an lvalue pointer to the object as the
487       first argument and name it "this".  An example of this would be the
488       <B>Frame.createFrame()</B> method in "classes/gfx/window.d".
489     <P>
490     * Rune does not implement multiple-inheritance, on purpose.  The main
491       reason is that implementations of multiple inheritance abstract what
492       is actually going on so much that they often make code unreadable
493       and unmaintainable.  In Runeland we would prefer that code be relatively
494       easy to understand and maintain.  The subclass mechanism is not perfect,
495       but it is sufficient.
496     <P>
497     * Declaration/Class merging.  You do not have to build all the declarations
498       making up a class in the <B>class</B> definition itself.  You can place
499       the declarations outside the class definition and even place them in
500       other source files as long as <B>library</B> scope is adhered to and
501       the declarations do not forward-reference the class (this is because
502       the merge occurs at parse time rather then resolve-time).  This allows
503       very large classes to be built without ruining the readability of the
504       source code.  You cannot merge a declaration into a class outside
505       of the library defining the class, but you can of course create a
506       subclass and add elements to the subclass (remember the part where I
507       said being able to do something a thousand different ways is not a good
508       idea?  Well, this is one of those).
509     <P>
510     * Very little magical type promotion.  Rune does not automatically
511       promote integer types for standard operators.  If you add two
512       <B>int8</B>'s together the result is going to be another <B>int8</B>.
513       Rune will not allow you to compare an <B>int8</B> against an
514       <B>int32</B> without a cast unless you create a specific operator
515       to do it.  You must decide or cast (casting is preferred).  My intent
516       here is to remove the single largest problem C has when porting
517       between architectures (including tiny 8-bit architectures), which is
518       that C redefines its core types to suit the architecture in order to
519       reduce auto casts that would otherwise not be optimal for that
520       architecture, resulting in less portable code.
521       <P>
522       This allows Rune to be used across the entire range of platforms,
523       from 8 bit cpu's to 128 bit cpu's, without having to make incompatible
524       changes to the core language specification.
525       <P>
526       Automatic type promotion is not the convience you might think it is.
527       I have occassionally tried to compare or assign integers with characters 
528       while programming in Rune but fixing the cases have not been a burden.
529       In fact I believe requiring the specificity has resulted in a higher
530       level of clarity for Rune code in general without creating an undue
531       burden on the programmer.
532       <P>
533       <FONT color="red">
534       I do intend to make an exception for constants.  This has not been
535       entirely coded yet so Rune will complain about mismatches against
536       constants of the wrong type in some cases (mostly for operators) and
537       not in others at the moment.  As long as the constant is compatible
538       I think it is perfectly reasonable to auto-promote or auto-demote it.
539       If you hit these problems give your constants the correct suffix for
540       the expression.</FONT>
541     <P>
542     * Inherent casts.  If Rune knows the type an expression needs to be,
543       for example an argument to a procedure, it will attempt to
544       cast your expression to that type. Rune can only cast based on 
545       cast operators in the class hierarchy, so Rune can automatically cast,
546       say, an <B>int8</B> to an <B>int32</B> but cannot automatically
547       cast an <B>int8</B> to a <B>uint32</B> without a little help from
548       the programmer.  <B>Keep in mind the such casting occurs after
549       the expression has been evaluated.  If you add two int8's together,
550       you will get an int8 result and that result might then be cast to
551       something larger.  The cast will not change the fact that the 
552       "+" operator in this case still returns an int8 result.</B>
553     <P>
554     * Object-oriented.  Everything is an object and eventually bases at
555       some class or compound type.  Oh wait, I said that.  Ok, I'll say
556       it again.  Even the lowly <B>int</B> is a class.  All of the operators
557       for base classes are defined in the classes/* subdirectory and have
558       internal tie-ins.  There is no way around having internal tie-ins,
559       otherwise the interpreter and generator wouldn't know what to do!
560       <P>
561       <FONT color="red">Internal tie-ins are only allowed in the
562       rune-distributed classes directory, programmers should never use
563       them in their own code and Rune will eventually (even soon) generate
564       a resolve-time error if you try.  But it doesn't yet.</FONT>
565     <P>
566     <FONT color="red">
567     * Partial procedure argument resolution.  This allows you to make a
568       more complex procedure compatible with a less complex call interface
569       by pre-evaluating and pre-supplying missing arguments.  For example,
570       a library that takes a procedure callback does not need to know about
571       additional information you supply with the procedure, such as
572       application-specific structures and pointers.  Partial resolution
573       looks like a procedure call in C but you take the address of the call.
574       For example, if you have a function that takes two arguments you can
575       turn it into a function taking one argument by partially resolving
576       the other, like '<B>&func(a:23)</B>'.  <B>alias</B> can also be used 
577       to partially resolve a procedure.
578       </FONT>
579     <P>
580     * Memory and code efficiency.  I stick to a model that does not require 
581       bloating instantiated object structures.  Rune transplants as few of
582       the resolve-time structures into the binary and run-time as possible
583       (basically Type, Declaration, and SemGroup structures).  Rune threads
584       are N:M and have minimal overhead.
585     <P>
586     * Built-in Interpreter.  My intention with Rune is to be able to
587       interpret it, compile it, and even do an on-the-fly hybrid of the
588       two.  The compilation process itself may have to interpret pieces of
589       code anyway to collapse constants, so it is only natural.  I also
590       intend to eventually allow dynamic compilation...  loading and
591       unloading source modules on the fly.  For now we have just the
592       interpreter and the x86 compiler backend.
593     <P>
594     * No #includes.  No preprocessor, but a few very simple preprocessor
595       directives to block-out debugging and testing code, or non-operational
596       musings.  This is a feature, but it still needs work.  The C preprocessor
597       is ridiculously useful in many situations, but also ridiculously
598       invasive.  The language implements an import mechanism for glueing
599       together source modules.  You pull everything.
600       <P>
601       There is no export mechanism but there are three levels of semantic
602       scope: <B>private</B>, <B>library</B>, and <B>public</B>.
603       <FONT color="red">My intention is to give the lexer a simple 
604       preprocessing capability, similar to what you might find in
605       <B>make</B>, but I have no intention of having a full
606       fledged C-like preprocessor (even though I could just borrow
607       the one from DICE) because I believe that preprocessing, and most
608       especially #include files, take what could be a nice modular
609       object-oriented application and library set and turns it into a
610       nightmare of semantic collisions.  I might lose the argument on this
611       front, though.</FONT>.
612     <P>
613     <FONT color="red">
614     * Compartmentalized lexer, parser, interpreter, compiler, and library
615       manager.  At each stage the intention is to be able to save an image
616       to the file that can be mmap()'d and accessed directly in a later
617       stage, eventually allowing whole projects to be partially pre-parsed,
618       pre-compiled, etc.  The features will also be necessary when we
619       allow code modification on the fly.
620       </FONT>
621     <P>
622     * Threads.  Very cool threads.  The traditional problem one has with
623       threading is that one must explicitly declare all sorts of
624       infrastructure to create and manage multiple threads and related
625       data structures.  Rune simplifies this greatly by introducing
626       the concept of a threaded procedure call.  If thread A calls the 
627       threaded procedure X, thread A will be suspended until the threaded
628       procedure X issues a <B>result(exp);</B> statement.  The value is
629       returned to A and A's thread resumes execution.  The threaded procedure
630       also continues to run.  <B>For example, a threaded procedure could
631       allocate and return an object representing the thread to the caller, then
632       continue running as the new thread.</B>
633       <P>
634       Rune threads are synchronous by default, meaning they share the same
635       machine context of their caller and are thus very low-overhead and very
636       fast-switching.  A Rune thread may be qualified <B>async</B> to
637       generate an actual new machine thread (similar to a posix thread).
638       A good example of the use of synchronous threads is for, say, a GUI
639       gadget library where each gadget is implemented as a Rune thread.
640       Since only one gadget is typically being manipulated at any given
641       moment it is a serious waste of resources to give each gadget a full
642       machine thread.  Instead you would run all the gadgets as synchronous
643       threads within a single async gadget-handling thread.
644     <P>
645     * Compound types and expressions.  Rune implements compound types and
646       expressions via a clever use of parenthesis and commas.  <B>There is
647       no C-like comma-operator in Rune.  Also, note that the arguments
648       to a procedure are, in fact, interpreted as one big compound type.</B>
649       Instead, there is the concept of the compound expression.  A compound
650       expression is something like this: <B>(1, 2, 3)</B>.  Additionally,
651       the elements of a compound type can be named in a manner similar
652       to the declaration of a procedure's arguments.  For example,
653       you can do this:
654       <UL><B>
655         <P>(int a = 2, int b, int c) x = (b:23, c:44);
656         <BR>x.c = x.a + x.b;
657       </B></UL>
658       <P>
659       Now is that cool or what?  As with any declaration you can specify
660       default values.  When you make a call to a procedure which
661       returns a compound type you can either store the result into
662       a compatible compound type (throwing away elements you don't
663       request), or you can store the result into a normal type
664       in which case only the first element of the returned compound
665       type is retained.  When building a compound type any elements
666       which have defaults are optional, and since a procedure's 
667       argument set is a compound type you can extend a procedure in a
668       backwards compatible fashion by adding a new argument to it and
669       giving it a default.  'Older' users of the procedure who don't 
670       supply the argument are still ok.
671       <P>
672       you can also set defaults for procedure arguments in the procedure
673       declaration, and the default expressions can access other procedure
674       arguments by name.  If you are declaring a method procedure this means
675       that default expressions can access the object via <B>this</B>.
676     <P>
677     * Multi-valued returns.  If you haven't guessed yet, a multi-valued
678       return is simply a compound type.  I've flip-flopped a number of
679       times on whether to implement critical error handling via a multi-valued
680       return mechanism or via exception handling, but ultimately came to the
681       conclusion that trying to implement it via the multi-valued return
682       mechanism would lead to code that was just too messy.
683     <P>
684     <FONT color="red">
685     * Exception-handling.  Rune does not currently implement exception
686       handling.  I have a
687       <B>raise</B>/<B>catch</B> mechanism documented in red, but I probably
688       won't implement it.  This mechanism would distinguis between
689       nominal status returns such as a file EOF or non-blocking status
690       and more serious error conditions or aborts that warrant an exception.
691       The exception-handling mechanism gives subsystems a relatively painless
692       semi in-band way to back-out of situations without having to process
693       error codes from every single procedure call made.  The mechanism is
694       similar to what TCL uses in some respects.  Currently not implemented
695       (and might never be)</FONT>
696     <P>
697     * Constructors and Destructors.  Classes may have any number of
698       constructors and destructors.  A constructor or destructor is a method
699       procedure that takes no arguments.
700       <P>
701       Constructors are automatically called when an object is instantiated,
702       after any type and declarative defaults are set.  Destructors are called
703       when the last reference to an object goes away.  The constructors
704       and destructors associated with the superclass will be called
705       before the constructors and destructors associated with a subclass.
706       Constructors and destructors are called in order, first to last.
707       <P>
708       Destructors are called when the last ref on an object's storage goes
709       away, prior to type-based deinitialization.  The runtime will
710       REF+LOCK the storage (giving it 1 ref) and call its destructors,
711       then proceed with type-based deinitialization.  Resurrection of the
712       object during its destruction is possible but frowned upon and
713       does not cause an early-return of the destruction sequence.
714       <P>
715       Type-based deinitialization consists of releasing all pointers contained
716       in the object (if any) and may trigger the destruction of additional
717       objects.
718       <P>
719       A destructor can resurrect an object by assigning a pointer to it (such
720       as a global or as part of some other data structure).  In this situation
721       the REFs on the storage will be > 1 and the runtime will not free or
722       unmap the object.  You will likely wind up with a dead object which
723       then needs to be reinitialized.
724       <P>
725       Note that constructors must be cognizant of the partially-initialized
726       nature of the object and destructors must be cognizant of the same,
727       plus potential redestruction races by other threads (usually by doing
728       a final check before returning).  Additional issues may arise when
729       multiple constructors and destructors are present.  In particular, note
730       that ALL destructors are called on an object even if one resurrects it,
731       so these may need to make additional checks in more complex coding
732       situations.
733       <P>
734       Rune will not recurse releases (which can easily lead to stack
735       overflows).  Instead the related RefStors will be moved to a list and
736       acted upon by the current thread when the destruction of the current
737       RefStor completes.
738     <P>
739     * Heap storage via pointers.  You may call <B>ptr.new()</B> on any
740       pointer to call the runtime to allocate and assign an object to that
741       pointer.  You can also declare objects directly using <B>heap</B>
742       scope which is similar.  The object is freed when the last reference
743       to it goes away.
744       <P>
745       Rune also has <B>persist</B> scope which mmap()s the object from a
746       persistent file, allowing it to survive program invocations.
747       <FONT COLOR="red">The RefStor is not memory-mapped, but 256 bytes is
748       set-aside in the file for a future shared RefStor implementation.
749       The programmer must be cognizant that discrete copies of the program
750       sharing the same persistent store will not be able to lock against
751       each other.</FONT>
752       <P>
753       <B>Note that Rune does not detect unreachable cycles. 
754       I consider creating an unreachable cycle to be sloppy programming.
755       Also note that Rune does not (currently) garbage collect and will
756       act on last-drops immediately.  I am loath to give this up.  Last-drop
757       handling can be a very powerful programming mechanic, it is not
758       something to be discarded lightly.  Garbage collection has always been
759       extremely messy and non-deterministic and generally not a desirable
760       abstraction.
761       </B>
762     <P>
763     * Scripting.  Rune supplies a nifty little #! scripting mechanism which
764       makes writing a program in Rune and executing it via the interpreter
765       trivial.  Rune's interpreter is not JIT but it is heavily optimized
766       and snappy.  Be sure to put a -x in your #! script to prevent Rune
767       from misinterpreting user command line arguments as rune options
768       (presumably you want those to be passed through to the Rune program).
769     <P>
770     * No version control.  Rune does not attempt to integrate version control
771       mechanisms into the language.  Folks, the plain fact of the matter is
772       that even the most robust Eiffel-like version control mechanism does not
773       make up for actually testing a project with the latest set of so-and-so
774       library.  In fact, I strongly believe that integrating such features into
775       a language create more problems then they solve because, like
776       exceptions, it results in code paths which are virtually untestable
777       and as likely to blow up as to work the first time they occur in real
778       life.  In balancing one evil against the other I would much prefer 
779       documentation over enforced language-level compatibility.  Rune provides
780       mechanisms, such as argument defaulting, that allow you to create
781       backwards compatible enhancements but Rune does not require that you
782       use them.  There is also nothing preventing you from including a major
783       version number in the names of the libraries you import, nor is there
784       anything preventing you from importing different versions of the same
785       library (though the usability of doing so is suspect).  Rune is
786       designed to facilitiate, but not enforce, backwards compatibility.
787     <P>
788     * Automatic object locking and ref-counting in Rune has gone through an
789       enormous amount of work and rework.  Generally speaking I want Rune
790       to do much of the object locking necessary to create a safe
791       multi-threaded environment automatically.  At the very least it
792       is important to guarantee field stability for pointer safety.
793       Idealy we also want to provide ordering determinism for objects.
794       <P>
795       There are two primary types of locks available: <B>hard</B> and
796       <B>soft</B>.  A hard-lock works traditionally, enforces
797       determinism, but is vulnerable to deadlock situations.  A soft-lock
798       is a type of lock which can be 'lost' when a thread voluntarily blocks
799       and will be reacquired upon resumption.  Soft locks avoid the deadlock
800       problem but also lose ordering and reentrancy determinism between
801       threads.
802       <P>
803       Rune does not implement the locking type in the lock structure but
804       instead implements it in the threading model.  By default, most locking
805       is <B>soft</B> (thus guaranteeing only field stability).  Only method
806       object locks during method calls are <B>hard</B> by default.
807       Any pointer declared on the thread stack acquires a soft-lock for
808       the object it is pointing to by default.  Reassigning the pointer
809       releases any prior lock and acquires the new lock.
810       Indirections through structures which produce temporary
811       pointers (for example, <B>a->b->c</B> where <B>b</B> is a pointer)
812       will temporarily lock and release the underlying object as needed.
813       The act of acquiring new locks may block and thus temporarily release
814       and then reacquire any soft-locks already held.
815       <P>
816       The programmer may implement a <B>hard</B> code section for any
817       bit of code which requires more determinism.  A <B>hard</B> code
818       section causes all existing or acquired locks to operate as if
819       they were hard until the end of the section, after which they revert
820       to their previous state.  This feature simply bumps an all-hard counter
821       in the thread structure.  This feature can be dangerous and what you
822       do inside a hard-code section must be very carefully thought out.
823       <P>
824       The locking mode is stacked on a per-procedure basis.  If hard-locked
825       code calls a soft-locked procedure any new locks acquired within the
826       soft-locked procedure will be soft-locked instead of hard-locked, while
827       all locks already held 'hard' by the caller remain hard.
828       <P>
829       The trade-offs with these choices are as follows: First, locks
830       have to be 'soft' by default to avoid deadlock potential in 'most'
831       of the code written by the programmer.  Second, the act of locking an
832       object can block, so any existing soft-held locks can be temporarily
833       lost in the normal flow of code in ways that are unexpected.  This
834       creates a serialization problem if the programmer isn't careful.
835       Third, the code generation cost of constantly lock+ref/unlock+dropping
836       objects is enormous, much higher than it would be using a garbage
837       collection scheme.  However, there are actually very few use-cases where
838       where the locking overhead impacts performance in a meaningful way.
839       Finally, the lock+ref state of local variables vs stored fields created
840       significant compatibility problems for double-indirected pointers and
841       confusion with arrays.
842       <P>
843       The language has added various scope keywords to allow the programmer
844       to optimize locking operations, controlling how fields are accessed.
845       These keywords are primarily meant only for those bits of code which
846       must be highly performant.
847       <P>
848       The lock structure itself is associated with the object's storage,
849       not embedded in the object, so the sizeof() an object is always as
850       expected.
851       <P>
852       Races due to unsafe program behavior are far more common than most
853       programmers believe.  Rune tries to bridge the gap by making
854       multi-threading a natural, even highly desireable part of the language,
855       but leaves the door open for programmer-directed optimizations.
856     <P>
857     * Rune Pointers.  All pointers in rune consist of two raw fields
858       The first is a pointer to the actual object, the second
859       is a pointer to a PointerInfo structure.
860       <P>
861       The PointerInfo structure is a fat structure which contains numerous
862       bits of information needed to operate on a Rune pointer.  This includes
863       array bounds, type, and refstor, all of which are raw low-level pointers.
864       The PointerInfo is typically dynamically allocated.  In situations where
865       the type and pointer bonafides are entirely known and the RefStor is
866       known by other means, the code generator will omit the PointerInfo
867       when possible.
868       <P>
869       The RefStor structure is a fat structure which contains meta-data
870       associated with the supervising structure's allocation and disposal,
871       lock, and ref-count.  It is not specific to the type the pointer points
872       to.  For example, a procedure's stack is represented by a single RefStor.
873       <P>
874       The RefStor structure contains the lock and information on how the
875       object was allocated.  It may encompass whole environments.  For
876       example, the RefStor for a procedure's stack context.
877 </UL>
878
879 <P>
880 <H2><B>(III) Native types and operators</B></H2>
881 <UL>
882     <P>
883     Please refer to the Rune core class module,
884     <A HREF="../classes/sys/class.d">../classes/sys/class.d</A>.
885     <P>
886     Generally speaking core types are as you might expect coming from
887     a C environment, with some significant exceptions as shown below.
888     Non-pointer types in Rune are deterministic and not adjusted to fit
889     the architecture.  Instead, the code generator is expected to produce
890     the correct code for the type specified.
891     <UL>
892         <P>
893         * There is no 'char' type in Rune.  Instead you must specify
894           'uchar' or 'schar', or use 'uint8_t' or 'int8_t'.  This is
895           to avoid common confusion with C.  In Rune, strings are always
896           arrays of unsigned chars (aka uchar *) and encodings are always
897           UTF-8.  However, basic functions like strlen() still count 8-bit
898           octets and can be used with memcpy, bcopy, etc, not 'characters'
899           in the international coding sense.  This is because such code
900           almost universally needs to know the physical string length in
901           bytes, not the number of international characters.  The distinct
902           UTF library may be used for international parsing, length, and so
903           forth.
904         <P>
905         * int is always a signed 32-bit quantity regardless of the
906           architecture.  The Rune programmer can always assume that an
907           'int' is 32-bits.
908         <P>
909         * long is always a signed 64-bit quantity regardless of the
910           architecture.  The Rune programmer can always assume that a
911           'long' is 64-bits.
912         <P>
913         * bool is a subclass of Numeric, NOT a subclass of Integer.
914           bool can be cast to or from an integer so conditionals (which
915           require bools) work pretty much as they would in C.  This is done
916           on purpose as it allows booleans to be special-cased by the
917           code generator and makes certain optimizations easier to
918           propagate.  Otherwise, though, boolean storage is either going to be
919           an 8-bit object or stored in a (potentially not 8-bit) machine
920           register or as a condition code.  Bitfields are not implemented in
921           Rune's language (on purpose) <FONT color="red">but adjacent
922           booleans will overload onto 8, 16, 32, or 64 bit fields
923           in-structure as possible</FONT>.
924         <P>
925         * size_t is a signed 32-bit or signed 64-bit quantity of the same
926           width as a machine pointer and will be architecture-specific.
927           Rune programmers can depend on it being signed.  This required
928           some thought but honestly any C programmer has hit up against
929           (many times) issues when wanting to use out-of-band values for
930           indexes such as -1 to mean special things, or to represent
931           error conditions, or there are system calls which can return -1,
932           or you want to have a signed range when doing arithmatic on size
933           and length fields, or pointer arithmatic, or in order to perform
934           certain conditionals.  It just makes more sense for size_t to
935           be signed.
936           <P>
937           size_t is the same width as a machine pointer by definition.
938           <P>
939           Because size_t is signed, all allocations and structures must be
940           sized less than 1/2 the size of the machine address space.  Use
941           usize_t if you need an unsigned value.
942         <P>
943         * off_t is always a signed 64-bit quantity regardless of the
944           architecture, even if the architecture only supports 32-bit file
945           offsets.  The Rune programmer can always assume that off_t is
946           64-bits regardless of the architecture.
947           <P>
948           Rune does not support 128-bit file offsets.  This starts to get
949           into silly-land where a focus on the abstraction exceeds the value
950           of the abstraction.
951     </UL>
952     <P>
953 </UL>
954 <P>
955 <H2><B>(IV) Operational Stages</B></H2>
956 <UL>
957     <P>
958     * Lexer
959     <UL>
960         <P>
961         The Rune lexer converts a Rune source file into a stream of tokens.
962         The lexer is responsible for detecting and skipping comments and
963         whitespace, and for separting tokens out.
964         <P>
965         The Rune lexer is writen directly in C, uses mmap(), and is designed
966         to not have to deal with 0-terminated strings.  Thise makes it
967         ridiculously fast. 
968         Tokens are tracked through a token_t structure which is typically
969         manipulated by reference, and an integer identifier is returned 
970         along with the new token.  The parser switches on this identifier
971         almost universally.  The lexer has a look-ahead capability which
972         the parser uses on occassion.
973     </UL>
974     <P>
975     * Parser
976     <UL>
977         <P>
978         The Rune parser takes a stream of tokens from the lexer and (well
979         Duhhh!) parses the language.  The Rune parser will also recursively
980         open and parse lexical streams related to <B>import</B> statements.
981         <P>
982         The Rune parser is recursive-descent, written directly in C.  Parser
983         elements are simply procedures.  However, the language is LALR(1)
984         (or LALR(2) depending on how you look at it) and the parser never
985         has to back up.  This makes the parser extremely fast.
986         <P>
987         The Rune parser constructs a hierarchy of statements, expressions, and
988         declarations on the fly.  The primary hierarchical component that
989         glues everything together is the statement.  For example,
990         the statement representing an import will have a reference to
991         the imported entity.
992         <P>
993         However, declarations are used as the cornerstone of the semantic
994         identifier search and management subsystem.  Any identifier that
995         can be looked up will have an associated declaration somewhere.
996         Declarations also earmark storage offsets within structures,
997         compound objects, procedures, and procedure arguments.
998         <P>
999         <B>The Rune parser does not attempt resolve identifiers at parse-time.
1000         This is one reason why Rune can have forward-referenced identifiers.
1001         Identifiers representing definitions are hashed at parse time,
1002         however.  The parser holds identifiers in domains and collapses
1003         them when possible, but it is really up to the resolver pass to
1004         truly collapse identifiers.</B>
1005     </UL>
1006     <P>
1007     * Resolver
1008     <UL>
1009         <P>
1010         The resolver is responsible for taking a parse set and turning it
1011         into something that can be interpreted or compiled.  The Resolver
1012         is extremely sophisticated and must take at least three passes on
1013         the parse-set:
1014         <P>
1015         <B>* Pass 1 -</B> Resolve subclass hierarchy.  The resolver 
1016         must first integrate declarations from the superclass into the
1017         subclass.  Refinement issues are handled at this time.  Note
1018         that the statement, expression, and declaration subhierarchies
1019         are duplicated for each subclass in order to allow Rune to optimize
1020         the refined procedures on a subclass-by-subclass basis.  This
1021         greatly simplifies the job of the interpreter and compiler.  
1022         <P>
1023         Resolving the subclass hierarchy is a recursive affair.  For
1024         example, the declarations in <B>Numeric</B> must be integrated
1025         with the declarations in <B>Integer</B> and from there integrated
1026         with the declarations in, say, <B>int8_t</B>.
1027         <P>
1028         <B>* Pass 2 -</B> Resolve types, expressions, and declarations.
1029         This pass is responsible for assigning an intermediate type to
1030         each expression, resolving the types (figuring out actual
1031         storage and alignment requirements for a type), and resolving
1032         non-procedural declarations (figuring out the actual storage
1033         requirements for a declaration).  This includes completely
1034         resolving compound types, the top-level, and classes, all of
1035         which are really just a list of declarations.
1036         <P>
1037         This pass is responsible for looking up and resolving operators,
1038         procedures, and for enforcing casts.  All of these operations
1039         involve manipulation of the expression hierarchy.
1040         <P>
1041         <B>* Pass 3 -</B> Resolve temporary storage requirements.  The
1042         interpreter and compiler needs to know about temporary
1043         storage requirements for expressions and aggregate
1044         storage requirements for procedures.  For example, if you
1045         do something like <B>int a = (b + c) * d;</B> then we need
1046         to store the intermediate result from (b + c) somewhere.
1047         This pass figures out what those requirements are so the
1048         interpreter can allocate the necessary space.
1049         <P>
1050         This pass allows the interpreter or compiler to know how much
1051         space a procedure requires to operate inclusive of variable 
1052         declarations and temporary space.  The Rune intepreter will
1053         reserve the space for the entire procedure up-front, on the
1054         stack, when the procedure is called.  The resolver is also able
1055         to figure out legal overlappings for storage so when you
1056         have multiple executable blocks in a procedure, like this:
1057         <B>{ int a; ... } { int b; ... }</B>, Rune will only
1058         need to allocate 4 bytes of actual stack space to represent
1059         both <B>a</B> and <B>b</B>.  The same goes for temporary
1060         space used by an expression.  The resolver is aware of the
1061         difference between lvalue and non-lvalue intermediate storage
1062         and only needs to allocate actual space for non-lvalue storage.
1063     </UL>
1064     <P>
1065     * Interpreter (selected resolver backend)
1066     <UL>
1067         <P>
1068         The interpreter will execute a Rune program.  It provides internal
1069         tie-ins to core classes, operators, and system calls, which are
1070         implemented by the interpreter itself rather then in Rune code.
1071         For example, adding two integers together ("+" on two ints)
1072         requires tie-ins to a native in-interpreter implementation of the
1073         operator.
1074         <P>
1075         The Rune interpreter will do on-the-fly optimization of the statement
1076         and expression hierarchy.  For example, if you have a
1077         constant-producing procedure and you call it, the
1078         interpreter will interpret the procedure, recognize the
1079         constant result, and then shortcut the expression hierarchy so
1080         the constant can simply be supplied directly the next time that
1081         particular call is made.  Another example is our internal
1082         bindings.  When the interpreter sees an operator bound
1083         to an internal function it will resolve the binding and from then
1084         on simply call the function directly.
1085         <P>
1086         Other common optimizations are things like <B>variable + constant</B>
1087         operations, which Rune will do for certain selected types.  In most
1088         cases the interpreter simply changes the ex_Func function
1089         vector in the expression or st_Func function vector in the statement
1090         to achieve the optimization.
1091         <P>
1092         Currently the Rune interpreter runs all Rune threads in a single
1093         pthread (N:1), owing to on-the-fly optimization model.  Eventually
1094         it should be able to do SMP.
1095     </UL>
1096     <P>
1097     * Code generator (selected resolver backend)
1098     <UL>
1099         <P>
1100         The compiler will do partial interpretation to resolve constants
1101         and then generate pseudo-assembly output.  This output is then
1102         run through a translator and finally the native assembler and linker,
1103         and linked against the Rune runtime library.
1104         <P>
1105         The compiler generates RAS (Rune assembly) output.  I am also
1106         attempting to generate LLVM output but I am having trouble with
1107         the LLVM backend taking enormous amounts of time to compile it
1108         (sometimes 10+ minutes for a simple program).
1109         <P>
1110         Rune assembly output is pseudo-assembly designed to be easily
1111         translated into instructions for the target machine.  It supports
1112         implied, 1-op, 2-op, and 3-op forms (1-op and 2-op for unary
1113         instructions, 2-op and 3-op for binary instructions).  It also
1114         supports cache tagging to allow the target translator to registerize
1115         variables.  Being pseudo-assembly it is weakly-typed... basically
1116         just 8, 16, 32, 64, and 128-bit operands (128 bits for floating point
1117         only, they aren't currently implemented for integers).
1118         <P>
1119         The pseudo-instruction set and EA forms are orthogonal... it is the
1120         translator's job to convert the forms.
1121     </UL>
1122     <P>
1123     * RAS Assembler (selected resolver backend)
1124     <UL>
1125         <P>
1126         RAS converts pseudo-assembly into machine target assembly, currently
1127         just 64-bit x86-64.  RAS is responsible for variable-life calculations,
1128         registerization, and certain instruction optimizations such as doing
1129         conditional reversals and inversions.
1130     </UL>
1131     <P>
1132     * Linker (selected resolver backend)
1133     <UL>
1134         <P>
1135         We use the system's native assembler and linker in the final stage
1136         of compilation to produce a native Rune binary.  The native rune
1137         binary links against the Rune runtime library which provides basic
1138         threading, locking, ref-counting, heap, and system-call support.
1139     </UL>
1140 </UL>
1141 </BODY>
1142 </HTML>