[SCM] Lisaac compiler branch, master, updated. lisaac-0.12-613-g9ac6f7b

Mildred Ki'Lya silkensedai at online.fr
Mon Mar 8 00:07:51 UTC 2010


The following commit has been merged in the master branch:
commit 9ac6f7b8283969681ece6642df9090d0c3d9aaff
Author: Mildred Ki'Lya <silkensedai at online.fr>
Date:   Mon Mar 8 01:05:20 2010 +0100

    More Documentation

diff --git a/src/HACKING b/src/HACKING
index bdaceaa..b68a30f 100644
--- a/src/HACKING
+++ b/src/HACKING
@@ -3,7 +3,7 @@ A Guide to Hacking in the Compiler Source
 
 You can generate the type hierarchy using the script `src/hierarchy.sh`
 
-Questions to Benoit
+Questions to Benoît
 ===================
 
 - Why `&` and `|` are duplicated in `EXPR_AND_LOGIC`, `EXPR_AND`,
@@ -34,20 +34,27 @@ Found in `ANY`.
   last element of `seq_list` as when a `PROFIL` is executed, the `list_current`
   is reset to `NULL`.
 
+- `modify_count:INTEGER`: How many times a new pass was requested during the
+  current pass.
+
 
 Passes
 ======
 
-Passes can be found in `PROTOTYPE.depend`
+Passes can be found in `PROTOTYPE.depend`. The passes continues until
+`modify_count` hasn't increased in the pass.
 
 Depending Pass
 --------------
 
-Main code in `NODE.extend_pass`.
-
 This is where all the parsing happens and all the abstract syntax tree (AST) is
 generated.
 
+Main code in `NODE.extend_pass`. This will walk through all the `NODE_TYPE`s
+and `update` them. A `NODE_TYPE` is a possible polymorphic call that need
+resolution. If the `update` return `TRUE`, it means that the node no longer need
+to be updated and can be skipped from the depending pass next time.
+
 Executing Pass
 --------------
 
@@ -86,11 +93,8 @@ Generate the `main()` source code: `LIST.genere_extern`
 
 Generate functions: `PROFIL_LIST.genere`
 
-Particular Types
-================
-
-AST Objects (items)
--------------------
+Abstract Syntax Tree
+====================
 
 The objects descending from `ITM_CODE` and `ITM_ARGUMENT` and `ITM_TYPE` and
 more generally, all items in the `item` directory form the abstract syntax tree.
@@ -156,10 +160,75 @@ as an instruction is an instruction (`EXPR` inherit from `INSTR`).
                 - `ITM_TYPE_GENERIC` (`item`)
 
 
+Dynamic Binding
+===============
 
+Dynamic binding is chen a slot is called and the receiver is of a polymorphic
+type. We have to generate a `switch` C statement to choose which implementation
+to use.
 
-Code Life Types
----------------
+When a call to a slot is converted from the AST to code life in
+`ITM_READ.to_run_expr`, it creates a `NODE_TYPE` instruction using
+`NODE.new_read`. At this stage, the node is not yet ready for the execution
+pass and need updates from the depending passes. Updating is divided in
+`update_case` and `update_depth`.
+
+`update_case`, beside handling special case for booleans and `Expanded`, will
+ask the dispatching `expr`ession for the list of possible runtime types using
+`EXPR.get_type`. Then for each type, it will ask the `data` (`DTA`) to produce
+a list for a special dynamic type. Then the list is inserted in the `switch`.
+As a special case, if the list of dynamic types is empty, don't generate a
+switch. If it contains only one type, only store the list generated by the
+`data` and don't bother with a `switch`.
+
+The list generated by the `data` might contains other nodes for further
+dispatching. For instance, it can contain a `NODE_STYLE` to dispatch between
+different versions of the same code slot (in case the slot has been written
+to). `update_depth` role is to call `data.update_branch` on each of the lists
+generated by the `data`. The `data` will then take care of updating further
+nodes it created. The `type_self` given is either the `type_self` already given
+or if `NULL`, the dynamic type.
+
+`TYPE_NODE`, requires a non `NULL` `self_type` when updated (`update_link`).
+This type always corresponds to the dynamic type and us used to generate the
+`CALL_SLOT` instruction, dispatching on the differents possible slot
+implementations.
+
+# `NODE` #
+
+- NODE (dispatcher)
+    - NODE_TYPE (dispatcher)
+    - NODE_STYLE (dispatcher)
+
+A `NODE` is a slot call site that need dispatching.
+
+`NODE_TYPE` dispatches polymorphic calls according to an `expr`ession dynamic
+type. The `data` is used to create the code `LIST` for each possible dynamic
+type, and further dispatch the call using `NODE_STYLE`.
+
+`NODE_STYLE` dispatches the slot call according to the different possible
+implementations of the slot. If the slot has only one implementation, this is
+just fine. In any case, it creates a `CALL_SLOT` instruction using the
+arguments supplied by the `data`.
+
+The `count` value represents the number of possibilities for dispatching
+computed until now.
+
+It has the following different states:
+
+- `switch = NULL` and `first_code = NULL`: No code at all, dispatching on an
+  empty set.
+- `switch = NULL` and `first_code != NULL`: The dispatching `expr`ession has
+  only one possibility. Don't bother generating a `switch`.
+- `switch != NULL`: the `expr`ession has more than one dispatching possibility,
+  the switch contains a `list` of `CASE` containing the code `LIST`s.
+
+
+Code Life
+=========
+
+Code Life is a special representation of the source code that is losely related
+to the syntax and is the best form to perform optimizations.
 
 # `INSTR` #
 
@@ -233,7 +302,19 @@ This is an instruction and represents an expression. It does have a
 `static_type`. As for all instructions, it is subject to the excuting pass
 through the `execute` slot.
 
-TODO: What are `execute_link` and `execute_unlink`
+An instruction has two execution slots: `execute_link` and `execute_unlink`.
+When executed as an instruction (`execute` slot called) the expression unlinks
+itself for an instruction by itself do nothing useful.
+
+Expressions are linked together in a tree structure, and linking or unlinking
+expressions propagate to children expressions. When an expression is found to be
+useful in a computation, `execute_link` is called. But when an expression value
+is not needed, `execute_unlink` is called instead.
+
+When an expression is executed as an instruction, its value is not needed so it
+is unlinked. Still, if the expression has a side effect, it can choose to return
+an instruction as a result to `execute_unlink` or call
+`list_current.insert_before`.
 
 # `LIST` #
 
@@ -246,8 +327,6 @@ TODO: understand how the list return its expressions, given that they are
 expressions and not instructions, and that there can be more than one
 expression. Is it through `RESULT`?
 
-## Execution ##
-
 When executed, it puts itself as `list_current` for the time of its execution
 and restore the old value afterwards. Then, for all the instructions it
 contains, it excutes the instruction and replace the new instruction (returned
@@ -263,8 +342,9 @@ execution step except in the following optimizing cases:
 
 # `PROFIL` #
 
-A profil is a function signature in C. It represents a slot in Lisaac that might
-be customized with generic parameters or for optimization purposes.
+A profil inherit from `ANY` and is a function signature in C. It represents a
+slot in Lisaac that might be customized with generic parameters or for
+optimization purposes.
 
 A profil can be living or dead in the `PROFIL_LIST`. Just look at the
 documentation on the executing pass for more information about `PROFIL_LIST`.
@@ -277,3 +357,53 @@ a `LIST`
 `execute_recursive` is not called by `PROFIL_LIST` but by `PROFIL.set_life`
 only when in a recursive pass.
 
+
+Types
+-----
+
+There are many prototypes for types, they are expalined here:
+
+- `ITM_TYPE` hierarchy: represent a type plus all that surround the type
+  (`Strict`, `Expanded`, genericity, ...). This is only the name of the type in
+  the AST.
+
+- `ITM_PROTOTYPE`, `PROTOTYPE_CST`: is a constant reference value to the
+  prototype itself respectively in the AST and code life.
+
+- `PROTOTYPE`: The root of an AST, generated by `PARSER`.
+
+- `TYPE` hierarchy: the type information used for code life and execution
+  passes. This hierarchy represents a bare type without customization
+  (`Strict`, `Expanded`, ...)
+
+- `TYPE_FULL`: type with its customization.
+
+Tools
+-----
+
+# `ALIAS_STR` #
+
+`ALIAS_STR.get` serves to convert `STRING` to `STRING_CONSATNT`. The `STRING`s
+have to be compared using `==` while only `=` is necessary for
+`STRING_CONSTANT`s.
+
+# `ALIAS_ARRAY` #
+
+Storage pool for arrays, keep the memory from groing too much. This will give
+you an array with its capacity closest to what you need avoiding too much
+reallocation.
+
+# `POSITION` #
+
+Encodes in 32 bits any position in any file parsed now or ever. It contains a
+type id, a line number and a column number. 32 bits are a bit small but for the
+moment we hold it.
+
+# `PARSER` #
+
+The parser
+
+# `COMMON` #
+
+Common things for command lines. This is used by `LISAAC` and `SHORTER` to
+display help and compiler version.
diff --git a/src/dispatcher/dta.li b/src/dispatcher/dta.li
index 1a9792f..80af012 100644
--- a/src/dispatcher/dta.li
+++ b/src/dispatcher/dta.li
@@ -133,6 +133,8 @@ Section Private
     s := typ.get_local_slot name;
     (s = NULL).if {
       // Lookup parent.
+      // First, evaluate the parent slot in the EXPR r
+      // Then chain another NODE_TYPE to dispatch on r
       s := typ.get_path_slot name;
       r := s.result_type.get_expr_for typ;
       node_style := NODE_STYLE.create (expr.my_copy,s) with Self result r;

-- 
Lisaac compiler



More information about the Lisaac-commits mailing list