Code coverage for slot_data.li
///////////////////////////////////////////////////////////////////////////////
// Lisaac Compiler //
// //
// LSIIT - ULP - CNRS - INRIA - FRANCE //
// //
// This program is free software: you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation, either version 3 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
// //
// http://isaacproject.u-strasbg.fr/ //
///////////////////////////////////////////////////////////////////////////////
Section Header
+ name := SLOT_DATA;
- copyright := "2003-2007 Benoit Sonntag";
- author := "Sonntag Benoit (bsonntag@loria.fr)";
- comment := "Slot with data style";
Section Inherit
+ parent_variable:Expanded VARIABLE;
+ parent_slot:SLOT := SLOT;
Section Public
// BUG COMPILO 0.11
- id_section:SECTION_ <-
( + result:SECTION_;
(parent_slot != NULL).if {
result := parent_slot.id_section;
} else {
result := SECTION_.get_name (ALIAS_STR.section_private);
};
result
);
- receiver_type:TYPE <-
( + result:TYPE;
(parent_slot != NULL).if {
result := parent_slot.receiver_type;
} else {
result := type_block;
};
result
);
//
- common_slot:SLOT <- parent_slot;
//
// Sequence optimizer
//
+ last_write:WRITE;
+ last_seq_index:UINTEGER_32;
+ last_seq_or_and:UINTEGER_32;
+ last_seq_call_and_loop:UINTEGER_32;
+ last_seq_call_local_and_loop:UINTEGER_32;
+ last_list_current:LIST;
+ last_index:INTEGER;
- is_invariant rec:EXPR :BOOLEAN <-
(
((rec = NULL) || {rec.is_invariant}) &&
{last_write != NULL} &&
{loop_seq_call_and_loop = seq_call_and_loop} &&
{last_seq_index <= loop_seq_index}
);
- reset_last_write w:WRITE <-
(
(last_write = w).if {
last_write := NULL;
};
);
- set_read <-
(
last_index := -1;
);
- get_last_index:INTEGER <- last_index;
- set_write w:WRITE <-
(
/* A FAIRE
(
(! PROFIL.mode_recursive) &&
{style = '-'} &&
{last_write != NULL} &&
{last_index < list_current.index} &&
{last_sequence = sequence_global}
).if {
? {list_current.item last_index = last_write};
list_current.put (last_write.value) to last_index;
unwrite last_write;
new_execute_pass;
};
*/
last_write := w;
last_seq_index := seq_index;
last_seq_or_and := seq_or_and;
last_seq_call_and_loop := seq_call_and_loop;
last_seq_call_local_and_loop:= seq_call_local_and_loop;
//
last_list_current := list_current;
last_index := list_current.index;
);
- get_last_value rec:EXPR :EXPR <-
( + result:EXPR;
+ val:EXPR;
+ rd:READ;
+ rd_loc:READ_LOCAL;
+ wrt_slot:WRITE_SLOT;
+ l:LOCAL;
+ g:SLOT_DATA;
+ is_rec_ok:BOOLEAN;
+ my_require_count:INTEGER;
+ pb:PROFIL_BLOCK;
+ i:INSTR;
((! PROFIL.mode_recursive) && {loop_invariant = NULL} && {last_write != NULL}).if {
my_require_count := require_count;
(rec != NULL).if {
// Block exception.
pb ?= rec.static_type.raw;
((pb != NULL) && {require_list != NULL}).if {
rd_loc ?= rec;
l := rd_loc.local;
wrt_slot ?= require_first;
rd_loc ?= wrt_slot.receiver;
(rd_loc.local = l).if {
my_require_count := 1;
} else {
my_require_count := 0;
};
(require_list.lower).to (require_list.upper) do { j:INTEGER;
wrt_slot ?= require_list.item j;
rd_loc ?= wrt_slot.receiver;
(rd_loc.local = l).if {
my_require_count := my_require_count + 1;
};
};
};
};
(
(
(last_seq_call_and_loop = seq_call_and_loop) &&
{is_seq_list last_list_current}
) || {my_require_count = 1}
).if {
// Receiver test.
(rec = NULL).if {
is_rec_ok := TRUE;
}.elseif {rec.is_constant} then {
wrt_slot ?= last_write;
is_rec_ok := rec ~= wrt_slot.receiver;
} else {
rd ?= rec;
(rd != NULL).if {
l ?= rd.variable;
g ?= rd.variable;
wrt_slot ?= last_write;
rd ?= wrt_slot.receiver;
is_rec_ok := (rd != NULL) && {
(
{l = rd.variable} && {is_seq_list last_list_current} && {
(
(l.last_seq != NULL) && {l.last_seq.last_write != NULL} &&
{l.last_seq.last_seq_index < last_seq_index} &&
{last_seq_call_local_and_loop = seq_call_local_and_loop}
) || {l.require_count <= 1} || {l.style = ' '}
}
) ||
{
{g = rd.variable} && {g.style = '-'} && {
(
(g.last_write != NULL) && {g.last_seq_index < last_seq_index} &&
{last_seq_call_and_loop = seq_call_and_loop} &&
{is_seq_list (g.last_list_current)}
) || {g.require_count = 1}
}
}
};
};
};
(is_rec_ok).if {
val := last_write.value;
rd ?= val;
(rd = NULL).if {
l := NULL;
g := NULL;
} else {
l ?= rd.variable;
g ?= rd.variable;
};
(
( // Constant propagation.
val.is_constant
) ||
{ // Local propagation.
(l != NULL) && {is_seq_list last_list_current} && {
(
(l.last_seq != NULL) && {l.last_seq.last_write != NULL} &&
{l.last_seq.last_seq_index < last_seq_index} &&
{last_seq_call_local_and_loop = seq_call_local_and_loop}
) || {l.require_count <= 1} || {l.style = ' '}
}
} ||
{ // Global propagation.
(g != NULL) && {g.style = '-'} && {
(
(g.last_write != NULL) && {g.last_seq_index < last_seq_index} &&
{last_seq_call_and_loop = seq_call_and_loop} &&
{is_seq_list (g.last_list_current)}
) || {g.require_count = 1}
}
}
).if {
(rec != NULL).if {
rec.remove;
};
result := val.my_copy;
}.elseif {
// Propagation step by step.
(last_seq_or_and = seq_or_and) &&
{ensure_count = 1} &&
{list_current.index > list_current.lower} &&
{list_current.item (list_current.index - 1) = last_write}
} then {
(rec != NULL).if {
rec.remove;
wrt_slot ?= last_write;
wrt_slot.receiver.remove;
};
unwrite last_write;
list_current.put NOP to (list_current.index - 1);
result := val;
}.elseif {
(rec != NULL) && {is_seq_list last_list_current} &&
{my_require_count = 1} && {ensure_count = 1} &&
{last_index.in_range (last_list_current.lower) to (last_list_current.upper)} &&
{last_list_current.item last_index = last_write}
} then {
// Local conversion.
l := type.get_temporary position;
i := l.write (last_write.position) value val;
last_list_current.put i to last_index;
result := l.read (rec.position);
//
rec.remove;
wrt_slot ?= last_write;
wrt_slot.receiver.remove;
unwrite last_write;
};
};
};
};
result
);
//
// Constructeur.
//
- create b:SLOT type_full t:TYPE_FULL :SELF <-
(
create (b.position) name (b.name) style (b.style) base b type t
);
- create pos:POSITION name n:STRING_CONSTANT
style s:CHARACTER base b:SLOT type t:TYPE_FULL :SELF <-
// BSBS: N'est plus utilise' !!!
( + result:SELF;
result := clone;
result.make pos name n style s base b type t;
result
);
- make pos:POSITION name n:STRING_CONSTANT style s:CHARACTER base b:SLOT type t:TYPE_FULL <-
( + tmp:TYPES_TMP;
parent_slot := b;
//
position := pos;
name := n;
style := s;
intern_name := ALIAS_STR.get_intern name;
//
type := t;
(is_static).if {
tmp := TYPES_TMP.new;
tmp.add (type.raw);
type_set := tmp.to_types;
} else {
type_set := TYPES_TMP.types_empty;
};
((type.raw.is_block) && {name != ALIAS_STR.slot_id} && {name != ALIAS_STR.slot_self}).if {
list_variable_block.add_last Self;
};
? {type != NULL};
);
//
// Context
//
+ value_init:LIST;
- init <-
( + val,rec:EXPR;
+ wrt:WRITE;
+ old_list:LIST;
+ rd:ITM_READ_ARG1;
+ old_profil_current:PROFIL;
+ old_profil_slot:PROFIL_SLOT;
/*
string_tmp.copy "init : ";
string_tmp.append name;
warning_error (position,string_tmp);
*/
((value_init = NULL) && {(affect != '<') || {Self = slot_id}}).if {
// Context.
old_list := list_current;
old_profil_current := profil_current;
old_profil_slot := profil_slot;
profil_current := profil_slot := NULL;
value_init := list_current := LIST.create position;
(Self = slot_id).if {
val := PROTOTYPE_CST.create position type type;
} else {
// Code.
(value != NULL).if {
rd ?= value;
((rd != NULL) && {rd.arg = NULL}).if {
rec := PROTOTYPE_CST.create position type (receiver_type.default);
val := rd.to_run_with_self (rec,FALSE,FALSE) args NULL;
} else {
val := value.to_run_expr;
};
} else {
val := type.default_value position;
};
val := val.check_type type with position;
};
(style = '+').if {
rec := PROTOTYPE_CST.create position type (receiver_type.default);
} else {
rec := NULL;
};
(debug_level_option != 0).if {
list_current.add_last (
PUSH.create position context context_main first FALSE
);
};
wrt := write position with rec value val;
(is_zero val).if {
wrt.set_quiet_generation;
};
list_current.add_last wrt;
list_current.add_last (PROTOTYPE_CST.create position type (TYPE_VOID.default)); // BSBS:Alias
list_current := old_list;
profil_current := old_profil_current;
profil_slot := old_profil_slot;
};
);
//
// Execute.
//
- execute <-
( + lst:FAST_ARRAY(SLOT);
+ slot:SLOT_DATA;
+ s:SLOT;
+ val:LIST;
+ old_list_current:LIST;
//+ old_profil_current:PROFIL_SLOT;
+ insert_index:INTEGER;
(value_init != NULL).if {
val := value_init;
value_init := NULL;
insert_index := list_main.index;
list_main.add val to insert_index;
(type.is_expanded).if {
lst := type.slot_run;
(lst != NULL).if {
(lst.lower).to (lst.upper) do { j:INTEGER;
s := lst.item j;
(s.style = '+').if {
slot := s.slot_data_intern;
(slot != NULL).if {
slot.execute;
};
slot := s.slot_id;
(slot != NULL).if {
slot.execute;
};
};
};
};
};
old_list_current := list_current;
//old_profil_current := profil_current;
list_current := NULL;
//profil_current := NULL;
val.execute;
list_main.inc_index;
list_current := old_list_current;
//profil_current := old_profil_current;
};
);
//
// Genere
//
- genere buffer:STRING <-
(
type.genere_declaration buffer;
buffer.add_last ' ';
type.genere_star_declaration buffer;
buffer.append intern_name;
buffer.append ";\n";
);
//
// Display.
//
- display buffer:STRING <-
(
buffer.append intern_name;
buffer.add_last ' ';
buffer.add_last ':';
type.display buffer;
);
- display_all <-
(
string_tmp.clear;
display string_tmp;
string_tmp.print;
);
Section VARIABLE
- new_read p:POSITION with r:EXPR :READ <-
( + result:READ;
(style = '-').if {
? {r = NULL};
result := READ_GLOBAL.create p with Self;
} else {
? {r != NULL};
result := READ_SLOT.create p with (r,Self);
};
result
);
- new_write p:POSITION with r:EXPR value v:EXPR :WRITE <-
( + result:WRITE;
(style = '-').if {
? {r = NULL};
result := WRITE_GLOBAL.create p with v in Self;
} else {
? {r != NULL};
result := WRITE_SLOT.create p with v in (r,Self);
};
result
);
/*
- new_access r:EXPR :ACCESS <-
( + result:ACCESS;
(style = '-').if {
result := ACCESS_GLOBAL.create Self;
} else {
result := ACCESS_SLOT.create Self with r;
};
result
);
*/
- is_zero e:EXPR :BOOLEAN <-
( + pro:PROTOTYPE_CST;
+ int:INTEGER_CST;
(
pro ?= e;
(pro != NULL) && {
(pro.static_type.raw = TYPE_NULL) ||
{pro.static_type.raw = type_false}
}
) || {
int ?= e;
(int != NULL) && {int.value = 0}
}
);