calls.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, 1995. 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. <----------
-- $AM_CALL_EXPR: Supertype for calls.
-- AM_CALL_ARG: Argument to a call
-- AM_CALL_EXPR: Implementation to be included by $AM_CALL_EXPR nodes.
-- AM_ROUT_CALL_EXPR: Routine call expression.
-- AM_ITER_CALL_EXPR: Iter call expression.
-- AM_BND_ROUT_CALL_EXPR: Bound routine call expression.
-- AM_BND_ITER_CALL_EXPR: Bound iter call expression.
-- AM_EXT_CALL_EXPR: An external function call expression.
class AM_CALL_EXPR
class AM_CALL_EXPR is
-- Supertype for calls.
include AM_EXPR create->;
include ARRAY{AM_CALL_ARG} append->,merge_with_by->;
-- An array of argument expressions. These must be evaluated left
-- to right. This array includes `self'.
create(nargs:INT, source:SFILE_ID):SAME is
-- A new definition for a routine or iter with `nargs' arguments
-- (including self).
r::=new(nargs); r.source:=source; return r end; -- AM_BND_ROUT_CALL_EXPR::source
end;
class AM_CALL_ARG < $AM
class AM_CALL_ARG < $AM is
include AM source->;
attr expr: $AM_EXPR;
attr mode: $MODE;
source: SFILE_ID is
return expr.source;-- AM_CALL_ARG::expr
end;
source(set:SFILE_ID) is
expr.source := set;
end;
is_eq(ob: $OB): BOOL is
typecase ob
when AM_CALL_ARG then return is_eq(ob)
else return false; end;
end;
is_neq(ob: $OB): BOOL is return ~is_eq(ob) end;
is_eq(a: AM_CALL_ARG): BOOL is
return expr = a.expr and mode = a.mode;-- AM_CALL_ARG::expr AM_CALL_ARG::expr AM_CALL_ARG::mode AM_CALL_ARG::mode
end;
is_neq(a:AM_CALL_ARG): BOOL is
return ~is_eq(a);-- AM_CALL_ARG::is_eq BOOL::not
end;
-- Sets the mode to IN_MODE
create(e: $AM_EXPR): SAME is
res ::= new;
res.expr := e;-- AM_CALL_ARG::expr
res.mode := #IN_MODE;-- AM_CALL_ARG::mode IN_MODE::create
return res;
end;
create(e: $AM_EXPR, m: $MODE): SAME is
res ::= new;
res.expr := e;-- AM_CALL_ARG::expr
res.mode := m;-- AM_CALL_ARG::mode
return res;
end;
copy: SAME is
if void(self) then return void; end;
r ::= new;
r.expr := expr.copy;-- AM_CALL_ARG::expr AM_CALL_ARG::expr
r.mode := mode;-- AM_CALL_ARG::mode AM_CALL_ARG::mode
return r;
end;
end;
class AM_FORMAL_ARG < $AM
class AM_FORMAL_ARG < $AM is
include AM source->;
attr expr: AM_LOCAL_EXPR;
attr mode: $MODE;
tp: $TP is -- type of the argument expression
return expr.tp;-- AM_FORMAL_ARG::expr AM_LOCAL_EXPR::tp
end;
source: SFILE_ID is
return expr.source;-- AM_FORMAL_ARG::expr AM_LOCAL_EXPR::source
end;
source(set:SFILE_ID) is
expr.source := set;
end;
name: IDENT is
return expr.name;-- AM_FORMAL_ARG::expr AM_LOCAL_EXPR::name
end;
is_eq(ob: $OB): BOOL is
typecase ob
when AM_FORMAL_ARG then return is_eq(ob)
else return false; end;
end;
is_neq(ob: $OB): BOOL is return ~is_eq(ob) end;
is_eq(a: AM_FORMAL_ARG): BOOL is
return expr = a.expr and mode = a.mode;
end;
is_neq(a:AM_FORMAL_ARG): BOOL is
return ~is_eq(a);
end;
-- Sets the mode to IN_MODE
create(e: AM_LOCAL_EXPR): SAME is
res ::= new;
res.expr := e;-- AM_FORMAL_ARG::expr
res.mode := #IN_MODE;-- AM_FORMAL_ARG::mode IN_MODE::create
return res;
end;
create(e: AM_LOCAL_EXPR, m: $MODE): SAME is
res ::= new;
res.expr := e;-- AM_FORMAL_ARG::expr
res.mode := m;-- AM_FORMAL_ARG::mode
return res;
end;
copy: SAME is
if void(self) then return void; end;
r ::= new;
r.expr := expr;
r.mode := mode;
return r;
end;
end;
class AM_ROUT_CALL_EXPR < $AM_CALL_EXPR
class AM_ROUT_CALL_EXPR < $AM_CALL_EXPR is
-- Routine call expression.
include AM_CALL_EXPR;
attr fun:SIG; -- The signature to call.
tp:$TP is
-- The return type of this routine. Void if no return value.
return fun.ret end;-- AM_ROUT_CALL_EXPR::fun SIG::ret
needs_import : BOOL is
return fun.needs_import;-- AM_ROUT_CALL_EXPR::fun SIG::needs_import
end;
needs_export : BOOL is
return fun.needs_export;-- AM_ROUT_CALL_EXPR::fun SIG::needs_export
end;
attr as_type : AS_TYPE_SPEC;
copy:$AM_EXPR is
if void(self) then return void; end;
r::=#SAME(size,source);-- AM_ROUT_CALL_EXPR::create AM_ROUT_CALL_EXPR::size AM_ROUT_CALL_EXPR::source
r.fun:=fun;-- AM_ROUT_CALL_EXPR::fun AM_ROUT_CALL_EXPR::fun
r.as_type:=as_type;-- AM_ROUT_CALL_EXPR::as_type AM_ROUT_CALL_EXPR::as_type
loop
x::=elt!;-- AM_ROUT_CALL_EXPR::elt!
if ~void(x) then x:=x.copy; end;-- BOOL::not AM_CALL_ARG::copy
r.set!(x);-- AM_ROUT_CALL_EXPR::set!
end;
return r;
end;
-- two calls are equal if their sigs are equal, and all the args are equal
is_eq(a:$OB):BOOL is
typecase a
when AM_ROUT_CALL_EXPR then
if fun.is_neq(a.fun) then return false end;-- AM_ROUT_CALL_EXPR::fun SIG::is_neq AM_ROUT_CALL_EXPR::fun
if asize /= a.asize then return false end;-- AM_ROUT_CALL_EXPR::asize INT::is_eq AM_ROUT_CALL_EXPR::asize BOOL::not
-- if we have a call of the class OPT_DEBUG, we don't check
-- integer constant. Actually, we should do that ONLY of
-- -O_debug is used, but unfortunatly we don't have access
-- to this flag, so we do it anyway.
loop i::=asize.times!;-- AM_ROUT_CALL_EXPR::asize INT::times!
x:$AM_EXPR:=void;
if fun.tp.str="OPT_DEBUG" then -- AM_ROUT_CALL_EXPR::fun SIG::tp STR::is_eq
x:=[i].expr; -- AM_ROUT_CALL_EXPR::aget AM_CALL_ARG::expr
end;
typecase x when AM_INT_CONST then
y::=a[i].expr;-- AM_ROUT_CALL_EXPR::aget AM_CALL_ARG::expr
typecase y when AM_INT_CONST then
else return false; end;
else -- is executed if x is void (fun.tp.str/="OPT_DEBUG")
-- or x is no INT_CONST
if [i].is_neq(a[i]) then return false end;-- AM_ROUT_CALL_EXPR::aget AM_CALL_ARG::is_neq AM_ROUT_CALL_EXPR::aget
end;
end;
return true;
else return false;
end;
end;
hash:INT is
htemp ::= fun.hash;-- AM_ROUT_CALL_EXPR::fun SIG::hash
loop i::=asize.times!;-- AM_ROUT_CALL_EXPR::asize INT::times!
htemp := htemp.hash; -- add this in to mix things up a bit-- INT::hash
htemp := htemp.bxor([i].expr.hash);-- INT::bxor AM_ROUT_CALL_EXPR::aget AM_CALL_ARG::expr
end;
return htemp;
end;
-- a routine can be optimized if all it args can be optimized, and
-- the routine is not marked as 'unsafe'
--# can_invar_opt(prog:PROG):BOOL is
--# se_set::=fun.get_se_context(prog);
--# if void(se_set) then return false end;
--# if se_set.unsafe then return false end;
--# loop i::=asize.times!;
--# if ~[i].expr.can_invar_opt(prog) then return false end;
--# end;
--# return true;
--# end;
end;
class AM_ITER_CALL_EXPR < $AM_CALL_EXPR
class AM_ITER_CALL_EXPR < $AM_CALL_EXPR is
-- Iter call expression.
include AM_CALL_EXPR;
attr fun:SIG; -- The signature to call.
attr init:$AM_STMT; -- Code to execute the first time
-- through (ie. to compute self and the once args).
attr lp:AM_LOOP_STMT; -- The enclosing loop.
attr init_before_loop:BOOL; -- true if the initialization of the
-- iter can be executed before entering the
-- loop.
attr use_loop_index:BOOL; -- true if the iter call should use the enclosing
-- loop index variable.
attr uniq:STR; -- Uniq string used in builtin iter calls
attr arg_list:ARRAY{STR}; -- List of arguments as C-Code
tp:$TP is
-- The return type of this iter. Void if no return value.
return fun.ret end;-- AM_ITER_CALL_EXPR::fun SIG::ret
copy:$AM_EXPR is
#OUT+"It is not possible to copy iter expressions\n";-- OUT::create OUT::plus
assert(false);
return void; -- to keep the compiler happy
end;
end;
class AM_BND_ROUT_CALL_EXPR < $AM_CALL_EXPR
class AM_BND_ROUT_CALL_EXPR < $AM_CALL_EXPR is
-- Bound routine call expression.
include AM_CALL_EXPR;
attr br:$AM_EXPR; -- The bound routine to call.
attr br_tp:TP_ROUT; -- The type of the bound routine.
-- You can't just get this from br,
-- because it might be in a typecase.
tp:$TP is
-- The return type of the bound routine. Void if none.
return br_tp.ret;-- AM_BND_ROUT_CALL_EXPR::br_tp TP_ROUT::ret
end;
copy:$AM_EXPR is
if void(self) then return void; end;
r::=#SAME(size,source);-- AM_BND_ROUT_CALL_EXPR::create AM_BND_ROUT_CALL_EXPR::size AM_BND_ROUT_CALL_EXPR::source
if ~void(br) then r.br:=br.copy; end;-- AM_BND_ROUT_CALL_EXPR::br BOOL::not AM_BND_ROUT_CALL_EXPR::br AM_BND_ROUT_CALL_EXPR::br
r.br_tp:=br_tp;-- AM_BND_ROUT_CALL_EXPR::br_tp AM_BND_ROUT_CALL_EXPR::br_tp
loop
x::=elt!;-- AM_BND_ROUT_CALL_EXPR::elt!
if ~void(x) then x:=x.copy; end;-- BOOL::not AM_CALL_ARG::copy
r.set!(x);-- AM_BND_ROUT_CALL_EXPR::set!
end;
return r;
end;
end;
class AM_BND_ITER_CALL_EXPR < $AM_CALL_EXPR
class AM_BND_ITER_CALL_EXPR < $AM_CALL_EXPR is
-- Bound iter call expression.
include AM_CALL_EXPR;
attr bi:$AM_EXPR; -- The bound iter to call.
attr bi_tp : TP_ITER; -- The type of the bound iter
-- You can't just get this from bi,
-- because it might be in a typecase.
-- could be incorporated at a later point cf. am_iter_call_expr
-- attr init_before_loop:BOOL; true if the initialization of the
-- Only evaluated the first time through the loop.
attr init:$AM_STMT; -- Code to execute the first time
-- through (ie. to compute self and the once args).
attr lp:AM_LOOP_STMT; -- The enclosing loop.
tp:$TP is
-- The return type of the bound iter. Void if none.
return bi_tp.ret; -- AM_BND_ITER_CALL_EXPR::bi_tp TP_ITER::ret
end;
copy:$AM_EXPR is
#OUT+"It is not possible to copy bnd iter expressions\n";-- OUT::create OUT::plus
assert(false);
return void; -- to keep the compiler happy
end;
end;
class AM_EXT_CALL_EXPR < $AM_CALL_EXPR
class AM_EXT_CALL_EXPR < $AM_CALL_EXPR is
-- A call on a function defined in an external language. These
-- are the signatures in an external class with no body.
-- Does assignment of the result to a local. Target is void
-- for calls with no return value.
include AM_CALL_EXPR;
attr fun:SIG; -- The signature to call.
attr nm:IDENT; -- The name of the routine
create(nargs:INT, source:SFILE_ID, nm:IDENT):SAME is
r::=create(nargs,source);-- AM_EXT_CALL_EXPR::create
r.nm:=nm;-- AM_EXT_CALL_EXPR::nm
return r;
end;
ext_tp:$TP is
-- The class containing this routine.
return fun.tp end;-- AM_EXT_CALL_EXPR::fun SIG::tp
tp:$TP is
-- The return type of this routine. Void if no return value.
return fun.ret end;-- AM_EXT_CALL_EXPR::fun SIG::ret
copy:$AM_EXPR is
if void(self) then return void; end;
r::=#SAME(size,source);-- AM_EXT_CALL_EXPR::create AM_EXT_CALL_EXPR::size AM_EXT_CALL_EXPR::source
r.fun:=fun;-- AM_EXT_CALL_EXPR::fun AM_EXT_CALL_EXPR::fun
r.nm:=nm;-- AM_EXT_CALL_EXPR::nm AM_EXT_CALL_EXPR::nm
loop
x::=elt!;-- AM_EXT_CALL_EXPR::elt!
if ~void(x) then x:=x.copy; end;-- BOOL::not AM_CALL_ARG::copy
r.set!(x);-- AM_EXT_CALL_EXPR::set!
end;
return r;
end;
end;