elt.sa
Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
---------------------------> Sather 1.1 source file <--------------------------
-- Copyright (C) International Computer Science Institute, 1994. COPYRIGHT --
-- NOTICE: This code is provided "AS IS" WITHOUT ANY WARRANTY and is subject --
-- to the terms of the SATHER LIBRARY GENERAL PUBLIC LICENSE contained in --
-- the file "Doc/License" of the Sather distribution. The license is also --
-- available from ICSI, 1947 Center St., Suite 600, Berkeley CA 94704, USA. --
--------> Please email comments to sather-bugs@icsi.berkeley.edu. <----------
-- elt.sa: Class elements.
-- ELT: An element of a class in the Sather compiler.
-- ELT_TBL: A table of class elements retrievable by name.
class ELT
class ELT is
-- An element of a class in the Sather compiler. We avoid copying
-- any source trees and computing much for code which isn't used.
attr sig:SIG; -- The signature of the element.
attr srcsig:SIG; -- The signature of this routine or iter
-- in the class it originally came from. Used to detect built-in ops.
attr as:$AS_CLASS_ELT; -- The source tree for this element.
-- This may be a routine or iter definition or an attribute
-- definition. Whether this refers to the reader or the writer
-- is determined from the signature. The element may have a
-- different name or "private" status from the source because
-- of renaming.
attr con:TP_CONTEXT; -- The context within which the types in
-- this element should be resolved. The same context can be shared
-- between elements. An element finds its prog here, too.
attr is_private:BOOL; -- True if private. Explicit because of
-- "private" and "readonly" includes.
attr is_external:BOOL; -- True if this is in an external
-- class (with or without a body).
create(sig:SIG, srcsig:SIG, as:$AS_CLASS_ELT, con:TP_CONTEXT,
is_private:BOOL):SAME
-- A new element with the specified attributes. If any of the
-- attributes is void then prints an error message and returns
-- void.
pre ~void(sig) and ~void(srcsig) and ~void(as) and ~void(con) is-- BOOL::not BOOL::not BOOL::not BOOL::not
r::=new; r.sig:=sig; r.srcsig:=srcsig; r.as:=as;-- ELT::sig ELT::srcsig ELT::as
r.con:=con; r.is_private:=is_private; return r end;-- ELT::con ELT::is_private
prog:PROG
-- The program that this element belongs to.
pre ~void(self) is -- BOOL::not
return con.prog end;-- ELT::con TP_CONTEXT::prog
name:IDENT
-- The name of the feature represented by this element.
pre ~void(self) is-- BOOL::not
return sig.name end;-- ELT::sig SIG::name
ret:$TP
-- The return type, if any.
pre ~void(self) is -- BOOL::not
return sig.ret end;-- ELT::sig SIG::ret
tp:$TP
-- The type this element comes from.
pre ~void(self) and ~void(sig) is -- BOOL::not ELT::sig BOOL::not
return sig.tp end;-- ELT::sig SIG::tp
impl:IMPL
-- The implementation object for this element.
pre ~void(self) is-- BOOL::not
r::=tp.impl;-- ELT::tp
if void(r) then
#OUT + "Compiler error, ELT::impl with sig: " + sig.str +-- OUT::create OUT::plus ELT::sig SIG::str
"returns void."; return void end; -- OUT::plus
return r end;
is_iter:BOOL
-- True if self is an iter.
pre ~void(self) is
return sig.is_iter end;
is_shared_writer:BOOL is
-- True if self is the writer routine for a shared attribute.
if ~sig.is_shared_writer_sig then return false end;-- ELT::sig SIG::is_shared_writer_sig BOOL::not
las::=as;-- ELT::as
typecase las
when AS_SHARED_DEF then return true
else return false end end;
is_attr_writer:BOOL is
-- True if self is the writer routine for an object attribute.
if ~sig.is_attr_writer_sig then return false end;-- ELT::sig SIG::is_attr_writer_sig BOOL::not
las::=as;-- ELT::as
typecase las
when AS_ATTR_DEF then return true
else return false end end;
is_attr_reader:BOOL is
-- True if self is the reader routine for an object attribute.
if ~sig.is_reader_sig then return false end;-- ELT::sig SIG::is_reader_sig BOOL::not
las::=as;-- ELT::as
typecase las
when AS_ATTR_DEF then return true
else return false end end;
is_const_reader:BOOL is
-- True if self is the reader routine for a constant attribute.
if ~sig.is_reader_sig then return false end;-- ELT::sig SIG::is_reader_sig BOOL::not
las::=as;-- ELT::as
typecase las
when AS_CONST_DEF then return true
else return false end end;
is_shared_reader:BOOL is
-- True if self is the reader routine for a shared attribute.
if ~sig.is_reader_sig then return false end;-- ELT::sig SIG::is_reader_sig BOOL::not
las::=as;-- ELT::as
typecase las
when AS_SHARED_DEF then return true
else return false end end;
is_abstract:BOOL is
-- True if this element is a routine or iter without a body.
las::=as;-- ELT::as
typecase las
when AS_ROUT_DEF then return las.is_abstract -- AS_ROUT_DEF::is_abstract
else return false end end;
is_attr_access:BOOL is
-- True if this element is a reader or a writer for a
-- constant, shared, or object attribute.
las::=as; -- ELT::as
typecase las
when AS_SHARED_DEF then return true
when AS_CONST_DEF then return true
when AS_ATTR_DEF then return true
else return false end end;
is_invariant:BOOL is
-- True if this element describes a routine of the form
-- `invariant:BOOL'.
return sig.is_invariant end;-- ELT::sig SIG::is_invariant
conflicts_with(e:SAME):BOOL is
-- True if the signature of self conflicts with the signature of
-- `e'. This is a symmetric relationship.
return sig.conflicts_with(e.sig) end;-- ELT::sig SIG::conflicts_with ELT::sig
as_tp:AS_TYPE_SPEC is
clelt ::= as; -- CLASS_ELT-- ELT::as
res : AS_TYPE_SPEC;
typecase clelt
when AS_CONST_DEF then
if ~void(clelt.tp) then -- AS_CONST_DEF::tp BOOL::not
res := clelt.tp-- AS_CONST_DEF::tp
else
res := #AS_TYPE_SPEC;-- AS_TYPE_SPEC::create
res.name := #IDENT("INT");-- AS_TYPE_SPEC::name IDENT::create
end;
when AS_SHARED_DEF then res := clelt.tp;-- AS_SHARED_DEF::tp
when AS_ATTR_DEF then res := clelt.tp;-- AS_ATTR_DEF::tp
else
end;
return res;
end;
end; -- class ELT
class ELT_TBL < $STR
class ELT_TBL < $STR is
-- A table of class elements retrievable by name.
--
-- `get_query!(i:IDENT):ELT' yields each element named by `i'.
-- `test(e:ELT):BOOL' tests for the given element.
-- `insert(e:ELT):SAME' inserts an element.
-- `delete(e:ELT):SAME' deletes an element.
-- `elt!:ELT' yields each element.
include FQSET{IDENT,ELT};
-- the following attrs are used as cache by the optimizer.
attr aref_asize:INT;
attr aref_set:INT;
attr aref_get:INT;
str:STR is
tp:$TP;
a:ARRAY{STR}:=#(size);-- ARRAY{1}::create ELT_TBL::size
i::=0;
loop
sg::=elt!.sig;-- ELT_TBL::elt! ELT::sig
st::=sg.str;-- SIG::str
tp:=sg.tp;-- SIG::tp
if ~void(sg.srcsig) then-- SIG::srcsig BOOL::not
st:=st+" ["+sg.srcsig.str+"]";-- STR::plus STR::plus SIG::srcsig SIG::str STR::plus
end;
a.set!(st);-- ARRAY{1}::set!
end;
s:STR:="interface of class "+tp.str+" is\n";-- STR::plus STR::plus
a.sort;-- ARRAY{1}::sort
loop
s:=s+" "+a.elt!+"\n";-- STR::plus STR::plus ARRAY{1}::elt! STR::plus
end;
s:=s+"end;\n";-- STR::plus
return s;
end;
query_test(name:IDENT, e:ELT):BOOL is
-- True if `e' is an element with the name `name'.
if void(e) then return false end;
return e.sig.name=name end;-- ELT::sig SIG::name IDENT::is_eq
query_hash(i:IDENT):INT is
-- A hash value computed from the name `i'.
return i.hash end;-- IDENT::hash
elt_hash(e:ELT):INT is
-- A hash value computed from the name of an element.
return e.sig.name.hash end;-- ELT::sig SIG::name IDENT::hash
elt_conflicting_with(e:ELT):ELT
-- Returns an element of self that conflicts with `e' if one
-- exists, otherwise returns void.
pre ~void(e) is-- BOOL::not
loop r::=get_query!(e.name);-- ELT_TBL::get_query! ELT::name
if r.conflicts_with(e) then return r end end;-- ELT::conflicts_with
return void end;
elt_same_name_as(e:ELT):ELT
-- Returns an element of self that has the same name as `e' if one
-- exists, otherwise returns void.
pre ~void(e) is-- BOOL::not
loop return get_query!(e.name) end;-- ELT_TBL::get_query! ELT::name
return void end;
ifc:IFC is
-- The interface of this set of elements.
if void(self) or hsize=0 then return void end;
st:SIG_TBL; sig:SIG;
loop sig:=elt!.sig; st:=st.insert(sig) end;
return #(st,sig.tp) end;
public_ifc:IFC is
-- The public interface of this set of elements.
st:SIG_TBL; if void(self) or hsize=0 then return void end;-- ELT_TBL::hsize INT::is_eq
e:ELT;
loop e:=elt!;-- ELT_TBL::elt!
if ~e.is_private then st:=st.insert(e.sig) end end;-- ELT::is_private BOOL::not SIG_TBL::insert ELT::sig
return #(st,e.sig.tp) end;-- IFC::create ELT::sig SIG::tp
elt_with_sig(s:SIG):ELT
-- Return an element from this table with the signature `s'
-- if present, void if not.
pre ~void(s) is-- BOOL::not
loop r::=get_query!(s.name);-- ELT_TBL::get_query! SIG::name
if s.is_eq(r.sig) then return r end end;-- SIG::is_eq ELT::sig
return void end;
end; -- class ELT_TBL