[SCM] Lisaac compiler branch, master, updated. lisaac-0.12-646-gbca8253
Mildred Ki'Lya
silkensedai at online.fr
Sat Aug 21 09:29:15 UTC 2010
The following commit has been merged in the master branch:
commit bca8253d4330b9aae5e5218b259a610ebb1c0beb
Author: Mildred Ki'Lya <silkensedai at online.fr>
Date: Sat Aug 21 11:26:30 2010 +0200
Documentation
diff --git a/src/HACKING b/src/HACKING
index bb468d0..860aee6 100644
--- a/src/HACKING
+++ b/src/HACKING
@@ -163,7 +163,7 @@ as an instruction is an instruction (`EXPR` inherit from `INSTR`).
Dynamic Binding
===============
-Dynamic binding is chen a slot is called and the receiver is of a polymorphic
+Dynamic binding is when 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.
@@ -171,9 +171,9 @@ 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` and `update_depth`. Note: `update` is deferred in `NODE`.
-`update_case`, beside handling special case for booleans and `Expanded`, will
+* `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`.
@@ -181,7 +181,7 @@ 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
+* 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
@@ -189,11 +189,32 @@ 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`).
+`NODE_TYPE`, requires a non `NULL` `type_self` 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.
+Call hierarchy example:
+
+ NODE_TYPE.update // update depending pass
+ update_case type_self=NULL
+ EXPR.get_type // get dynamic type list
+ // foreach dynamic type:
+ l := DTA.product with self (type_self=NULL)
+ lookup with in // parent lookup algorithm
+ update_depth type_self=NULL
+ // foreach branch in case:
+ // type_self is set to the dynamic type of the branch (if NULL)
+ DTA.update_branch l:LIST self type_self=t
+ l:LIST.first
+ NODE_?.update_link type_self=t
+ l:LIST.second
+ NODE_TYPE.update_link type_self=t
+ update_case type_self=t
+ ...
+ update_branch type_self=t
+ ...
+
# `NODE` #
- `NODE` (`dispatcher`)
@@ -202,7 +223,7 @@ implementations.
A `NODE` is a slot call site that need dispatching.
-`NODE_TYPE` dispatches polymorphic calls according to an `expr`ession dynamic
+`NODE_TYPE` dispatches polymorphic calls according to an `expr`ession's dynamic
type. The `data` is used to create the code `LIST` for each possible dynamic
type, and further dispatch the call using `NODE_STYLE`.
diff --git a/src/dispatcher/dta.li b/src/dispatcher/dta.li
index 80af012..4cd14aa 100644
--- a/src/dispatcher/dta.li
+++ b/src/dispatcher/dta.li
@@ -131,6 +131,7 @@ Section Private
name := slot.name;
s := typ.get_local_slot name;
+ // Is the slot in the current prototype ? Yes: call ; No: lookup parent
(s = NULL).if {
// Lookup parent.
// First, evaluate the parent slot in the EXPR r
diff --git a/src/dispatcher/node.li b/src/dispatcher/node.li
index 780b9b9..81c911f 100644
--- a/src/dispatcher/node.li
+++ b/src/dispatcher/node.li
@@ -65,6 +65,17 @@ Section Public
//
// Extern Creation read.
//
+ // When the following expression is used:
+ // (receiver.slot (args, ...))
+ // Arguments:
+ // p:POSITION Source code position
+ // s:SLOT The corresponding slot from the static (PROTO?)TYPE
+ // rec:EXPR receiver, dispatching EXPR
+ // my_self:EXPR receiver, first argument (in case the receiver is an
+ // EXPR_MULTIPLE)
+ // larg:ARRAY(EXPR) Arguments. The first is the same as my_self
+ // is_intern:BOOL if the call is with the implicit Self reeiver
+ //
- new_read p:POSITION slot s:SLOT receiver rec:EXPR
self my_self:EXPR intern is_intern:BOOLEAN :NODE <-
@@ -214,20 +225,20 @@ Section Public
Section Public
- - position:POSITION <-
- (
- data.position
- );
+ - position:POSITION <- data.position;
+ data:DTA;
+ // The DTA used to generate each branch
+ expr:EXPR;
+ // Dispatching expression: from it we infer the different possible branches
- + first_code:LIST;
- + first_type:TYPE;
- + switch:SWITCH;
+ + first_code:LIST; // first branch
+ + first_type:TYPE; // first dispatching type
+ + switch:SWITCH; // switch dispatching the different branches
- count:INTEGER <-
+ // Count how many dispatching branch there is
( + result:INTEGER;
(switch != NULL).if {
diff --git a/src/item/itm_read.li b/src/item/itm_read.li
index e90a087..67f21d1 100644
--- a/src/item/itm_read.li
+++ b/src/item/itm_read.li
@@ -103,11 +103,17 @@ Section Public
Section ITM_READ, SLOT_DATA
- to_run_with first_itm:ITM_CODE args larg:FAST_ARRAY(ITM_CODE) :EXPR <-
- ( + rec:EXPR;
- //
+ // Generic slot to run a READ given:
+ // first_item a receiver
+ // larg an argument list (stripped trom the receiver)
+ //
+ // Does the preprocessing job before calling `to_run_with_self`
+ (
+ + rec:EXPR; // Receiver EXPR
+ + is_resend:BOOLEAN; // If we resend the call to the parent slot
+ + implicit_self:BOOLEAN; // Implicit call (Self receiver omitted)
+ itm_list:ITM_LIST;
+ itm_read:ITM_READ;
- + is_resend,implicit_self:BOOLEAN;
//
// Compute `rec'.
@@ -119,26 +125,38 @@ Section ITM_READ, SLOT_DATA
implicit_self := TRUE;
} else {
rec := first_itm.to_run_expr;
+ //
// Resend detect.
+ //
+ // If we detect that the receiver is an ITM_READ and it has the name of
+ // a parent in the Section Inherit, then we consider this a resend.
itm_list ?= first_itm;
(itm_list != NULL).if {
- itm_read ?= itm_list.code.first;
+ itm_read ?= itm_list.code.first;
} else {
- itm_read ?= first_itm;
+ itm_read ?= first_itm;
};
is_resend := (
- (itm_read != NULL) &&
- {position.prototype.search_parent (itm_read.name)}
+ (itm_read != NULL) &&
+ {position.prototype.search_parent (itm_read.name)}
);
};
to_run_with_self (rec,implicit_self,is_resend) args larg
);
- to_run_with_self (r:EXPR,implicit_self,is_resend:BOOLEAN)
- args larg:FAST_ARRAY(ITM_CODE) :EXPR <-
- ( + args:FAST_ARRAY(EXPR);
- + rec_type:TYPE;
- + rec:EXPR;
+ args larg:FAST_ARRAY(ITM_CODE) :EXPR <-
+ // Continues the job of `to_run_with args`
+ // r receiver EXPR
+ // implicit_self if the Self receiver was omitted
+ // is_resend if the READ is a call resent to an inherited parent
+ // larg ITM_CODE of the arguments (except the receiver)
+ (
+ + args:FAST_ARRAY(EXPR); // Contains all arguments converted to EXPR,
+ // including the receiver
+ + rec_type:TYPE; // Receiver type
+ + rec:EXPR; // If the receiver is an EXPR_MULTIPLE, then we only
+ // take the first value as dispatching receiver
+ em:EXPR_MULTIPLE;
+ pos_null:POSITION;
//
--
Lisaac compiler
More information about the Lisaac-commits
mailing list