DataMuseum.dk

Presents historical artifacts from the history of:

DANOSI

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DANOSI

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦5fbcc7821⟧ TextFile

    Length: 61806 (0xf16e)
    Types: TextFile
    Names: »P5INIT.PAS«

Derivation

└─⟦b6837b237⟧ Bits:30010500 SW2103 REL 1.11 Sourcer DVBS1.SW2103.rel.1.11-1 MASTER 31-1-192
    └─⟦this⟧ »P5INIT.PAS« 

TextFile

const\r
filrec_max = 256;\r
\r
default_lambda_version = 5;  (* determines micro-program version *)\r
version_date= '90.03.01';\r
\r
(*   const.   global for pass5:       *)\r
compiler_test = true; (*used for testing rc3502c changes*)\r
\r
ownpassno = 5;  (* pass number of this pass *)\r
versionpass4 = 600;\r
versionpass5 = 200; (* version * 100 + subversion *) (* 860908 *)\r
\r
const_niv_0 = 0;\r
size_of_return_point = 8; (* room for  activation record *)\r
(* max hw stack size *)\r
max_hw_stack = 16 ; (*bytes*)\r
\r
\r
ext_descr_size= 24; (* size of one element in the external description table in half words *)\r
\r
ext_max_routine = 150; (* max no of words (of 2 chars each) pr inline routine *)\r
ext_max_charbuf = 5000; (* number of words in charbuf *)\r
descr_max_param= 30; (* max number of parameters of a module *)\r
\r
c_size_identifier= 12;\r
\r
type\r
filrec = array[1..filrec_max] of integer;\r
\r
identifier= packed array [ 1..c_size_identifier ] of char;\r
(*    type definitions from modules:     *)\r
\r
usemodes = (sys_use, general_use);\r
ext_states = (ext_unused, ext_declared, ext_open, ext_closed);\r
\r
param_ptr= ^ param_descr;\r
\r
param_descr = record\r
next_param: param_ptr;\r
kind,\r
size : integer;\r
end;\r
\r
\r
ext_descr = record\r
state : ext_states;\r
mode  : usemodes;\r
id    : identifier;\r
\r
(* parameter description *)\r
no_of_param : integer;\r
paramptr    : param_ptr;  (* chain of parameters *)\r
\r
(* special variables for open routines *)\r
appetite  : integer;\r
wordcount : integer;  (* no of words (of 2 chars each) in open routine *)\r
firstword : integer;  (* < 0: file position, > 0: index in char buf *)\r
\r
(* special variables for closed routines *)\r
no_of_uses : integer;\r
\r
(* link through ext_declared entries *)\r
decl_link : integer;\r
end; (* ext descr *)\r
\r
\r
(* case table descriptor *)\r
case_table_ptr= ^ case_table_entry;\r
case_table_entry= record\r
next_entry,\r
former_entry: case_table_ptr; (* couble chained list of case table entry descriptors *)\r
first,  (* lower range value *)\r
last,   (* upper range value *)\r
x_index: integer; (* label sequence number *)\r
end;\r
\r
universal_ptr= ^integer;\r
var\r
incode_filptr : ^ filrec;\r
incode_fileix : integer;\r
extcode_filptr: ^ filrec;\r
extcode_fileix: integer;\r
\r
pass5_ok :  boolean;\r
in_pass5 : file of filrec;\r
out_pass5 : text;\r
ext_pass5 : file of filrec;\r
\r
lambda_version : integer;\r
\r
ext_tab_max: integer;\r
\r
case_tab_freelist: case_table_ptr;\r
\r
\r
procedure alloc_ext_tab_and_call_pass5;\r
\r
const\r
max_ext_names = 65521 div sizeof(ext_descr);\r
type\r
t_ext_tab= array [1..max_ext_names] of ext_descr;\r
var\r
needed_size : word;\r
p_ext_tab : ^ t_ext_tab;\r
\r
procedure  pass5( var ext_tab: t_ext_tab; var pass5_ok : boolean );\r
\r
label\r
\r
   1 ;                   (*  exit on fatal error  *)\r
\r
const\r
\r
(*  repr. of standard values in Real-Time Pascal :  *)\r
const_nil_var = 1; (*nilvalue for reference, pointer and shadowvariables.*)\r
(*                   passive  value for semaphorevariables too .*)\r
jump_across_first = 4; (* used for jumping across the first instruction of a *)\r
(*                        routine i. e. reaad rlinetab because of conventions*)\r
value_false = 0;\r
value_true = 1;\r
(* nil field in reference and shadow variables *)\r
c_ref_field_nil = 3855 ;  (* the field [15 .. 15], i.e.  256 X 15 +  15  *)\r
c_shadow_field_nil = 1799; (* 7*256 + 7 *)\r
descr_free_words = 4; (*number of unused words in descr*)\r
\r
(* definition of pass6-tokens *)\r
zbegin =   'b';\r
zendlist = '.'; (* end of declaration-list *)\r
zconst =   'c';\r
zend   =   'e';\r
zline  =   'l';\r
zoption=   'o';\r
zname  =   'z';\r
dollar_a = '1'; (* => $a *)\r
dollar_b = '2'; (* => $b *)\r
dollar_i = '3'; (* => $i *)\r
\r
(* definition of identifiers for pass6 *)\r
c_name =   'c';  (* long constants, dope vectors *)\r
e_name =   'e';  (* external routines *)\r
l_name =   'l';  (* labels *)\r
r_name =   'r';  (* internal routine entries *)\r
x_name =   'x';  (* case labels *)\r
c12_name=  'c           ';\r
e12_name=  'e           ';\r
r12_name=  'r           ';\r
l12_name=  'l           ';\r
x12_name=  'x           ';\r
\r
(* definition of used identifiers *)\r
id_entry =            'entry       ';\r
id_exit  =            'exit        ';\r
id_exception =        'exception   ';\r
id_param =            'param       ';\r
id_procinf =          'procinf     ';\r
id_name  =            'name        ';\r
id_except=            'exception   ';\r
id_appeval =          'appeval     ';\r
id_appstat =          'appstat     ';\r
id_default_appetite = 'defapp      ';\r
id_work    =          'work        ';\r
id_linetab =          'linetab     ';\r
id_continue=          'continue    ';\r
id_rep    =           'rep         ';\r
id_endrep   =         'endrep      ';\r
id_blockexit=         'blkexit     '; (* destination of exit statement *)\r
(* stdcall *)\r
id_sucpred =          'sucpred     ';\r
(* while *)\r
id_whrep =            'whrep       ';\r
id_whexit=            'whexit      ';\r
(* lock *)\r
id_size_ok=           'size_ok     ';\r
id_cont  =            'cont        ';\r
id_exc   =            'exc         ';\r
(* jump across initialization of pointers in a heap object,         *)\r
(* if NEW returns nil *)\r
id_nil_element =      'nilelem     ';\r
id_end_nil_test=      'endnil      ';\r
(* the following m-names are declared in outermost code environment *)\r
id_mstart=            'mstart      '; (* offset into reference variable *)\r
id_mfirst=            'mfirst      ';(* offset into buffer, first-attribute *)\r
(* if *)\r
id_ifelse =           'ifelse      ';\r
id_ifexit =           'ifexit      ';\r
(* repeat *)\r
id_rprep =            'rprep       ';\r
id_rpcont=            'rpcont      ';\r
id_rpexit=            'rpexit      ';\r
(* loop *)\r
id_loop=              'loop        ';\r
id_loopexit=          'loopexit    ';\r
(* for *)\r
id_forrep   =         'forrep      ';\r
id_forstore =         'forstore    ';\r
id_forcont=           'forcont     ';\r
id_forexit  =         'forexit     ';\r
(* case *)\r
id_casetab =          'casetab     ';\r
id_otherwise=         'otherwise   ';\r
id_caseexit=          'caseexit    ';\r
(* array-init *)\r
id_arrayrep =         'arrayrep    ';\r
id_rep_exit=          'repexit     ';\r
id_index_store =      'ixstore     ';\r
(* name for initialization of dope vector of dynamic array *)\r
id_elems_ready =      'elemsready  ';\r
(* names from lambda-environment *)\r
id_alfalength =       'alfalength  ';\r
id_level       =      'level       ';\r
id_excode      =      'excode      ';\r
id_expoint     =      'expoint     ';\r
id_exopcode    =      'exopcode    ';\r
id_exic        =      'exic        ';\r
id_semchain    =      'semchain    ';\r
id_refchain    =      'refchain    ';\r
id_shadowchain =      'shadowchain ';\r
id_processchain =     'processchain';\r
id_osem        =      'osem        ';\r
id_oref        =      'oref        ';\r
id_oshadow     =      'oshadow     ';\r
id_cpexcfirst  =      'cpexcfirst  ';\r
id_exappetite  =      'exappetite  ';\r
id_exitappetite=      'exitappetite';\r
id_maxstack    =      'maxstack    ';\r
id_bonappetite =      'bonappetite ';\r
id_plinetab    =      'plinetab    ';\r
(* offsets in the processdescriptor *)\r
id_opd_count   =      'opdcount    ';\r
id_opd_param   =      'opdparam    ';\r
id_opd_linked  =      'opdlinked   ';\r
id_opd_procinf =      'opdprinf    ';\r
id_opd_name    =      'opdname     ';\r
id_opd_process =      'opdprocess  ';\r
(* misc *)\r
id_hardset     =      'hardset     ';\r
\r
\r
c_size_opcode = 6;\r
c_size_identifier = 12;\r
c_size_option_list = 10;\r
\r
\r
(*  exception no.  , relative to the symbol  cpexcfirst ( see: lambdaenv ) :  *)\r
c_exc_case = 0; (* label not found and no otherwise *)\r
c_exc_succ = 1; (* succ exceeds upper value *)\r
c_exc_pred = 2; (* pred exceeds lower value *)\r
c_exc_with = 3; (* size error, new type greater than original type *)\r
c_exc_lock = 4; (* size error, new type greater than actual buffer(first..top) *)\r
c_exc_ref = 5; (* reference variable not nil at routine exit *)\r
c_exc_shadow = 6; (* shadow variable not nil at routine exit *)\r
c_exc_new= 7; (* not enough memory to satisfiy the request *)\r
\r
c_exc_max = 47;\r
\r
(* constants in pass 4 code *)\r
\r
(* value of type_v in pass 4 code  *)\r
\r
byte_typ = 1;   field_typ = 5;\r
word_typ = 2;   addr_typ  = 6;\r
point_typ= 3;   set_typ  = 7;\r
double_typ = 4;  dyn_typ  = 8;\r
\r
(* values of type_o in pass 4 code  *)\r
\r
bool_typ = 1;      int_typ = 2;     real_typ = 3;     setof_typ = 4;\r
pointer_typ = 5;   sem_typ = 6;     ref_typ = 7;      shadow_typ = 8;\r
scalar_typ = 9;\r
\r
(* compare function number in pass 4 code   *)\r
\r
   xeq = 2;        xne = 3;         xlt = 4; \r
   xgt = 5;        xle = 6;         xge = 7;\r
   xeq_set = 8;    xne_set = 9;     xle_set = 10;\r
   xge_set = 11;   xin = 12;        xeq_struc = 13;\r
   xne_struc = 14; \r
\r
(* std function number in pass 4 code       *)\r
\r
 xord= 1; xsucc= 2; xpred= 3; xchr= 4; xnil= 5; xnilref (* only used in rev c *)= 6;\r
 xnew = 7;\r
\r
(* mode for for statement   *)\r
\r
   xup = 1;     xdown = 2;\r
\r
(* export name type                          *)\r
\r
offset_type = 1;    value_type = 2;\r
\r
(* end pass 4 code constants *)\r
\r
\r
\r
\r
\r
(*   const. local to modules:       *)\r
\r
byte_length = 1;\r
word_length = 2; (* length of integer and word = 2 bytes *)\r
pointer_length = 3; (*length of pointer = 3 bytes *)\r
trapenter = 1; (*parameter for mtrh instruction*)\r
trapreturn = 2;(*parameter for mtrh instruction*)\r
\r
(* offsets in anonymous object created in conjunction with lockmes statement *)\r
(* offsets are pointer_length+0, 2, and 4 *)\r
lockmes_first_offset= 3; (* the object is a record with the buffer pointer as first field *)\r
lockmes_last_offset= 5; (* followed by first and last+1, the values from the attribute part of the buffer *)\r
lockmes_top_offset= 7; (* and the computed top value (first + size of new type) *)\r
\r
\r
\r
(*   type definitions global for pass5:     *)\r
\r
type\r
\r
option_list = record\r
  no_of_options : integer;\r
options : array [ 1 .. c_size_option_list ] of\r
record\r
pno, p1, p2 : integer;\r
end;\r
              end;\r
\r
opcode = (op_aaaaa ,op_abs   ,op_add   ,op_and   ,\r
          op_cexch ,op_cgreg ,op_compl ,op_coutwq,\r
          op_crget ,op_crput ,op_csell ,op_div   ,\r
          op_eq    ,op_ge    ,op_gt    ,op_index ,\r
          op_indh0 ,op_indh01,op_indh02,op_indh1 ,\r
          op_indh11,op_indh12,op_inpdv ,op_inth0 ,\r
          op_intpa ,op_intrs ,op_iocda ,op_iorsc ,\r
          op_jmcht ,op_jmpga ,op_jmprw ,op_jmzeq ,\r
          op_jmzge ,op_jmzgt ,op_jmzle ,op_jmzlt ,\r
          op_jmzne ,op_le    ,op_llock ,op_lrele ,\r
          op_lrese ,op_lt    ,op_madd  ,op_mod   ,\r
          op_moveb ,op_movebs,op_moveg ,op_msub  ,\r
          op_mtrh  ,op_mtrs  ,op_mul   ,op_ne    ,\r
          op_neg   ,op_not   ,op_or    ,op_pcals ,\r
          op_pcals0,op_pcals1,op_pexit ,op_reaad ,\r
          op_readb ,op_readw ,op_reagd ,op_reaid ,\r
          op_reaisd,op_reald ,op_reard ,op_reasd ,\r
          op_reaxd ,op_rechd ,op_rechw ,op_renhb ,\r
          op_renpb ,op_restc ,op_revga ,op_revgb ,\r
          op_revgd ,op_revgw ,op_revla ,op_revlb ,\r
          op_revld ,op_revlw ,op_revpd ,op_revpw ,\r
          op_revsa ,op_revsb ,op_revsd ,op_revsf ,\r
          op_revsm ,op_revsw ,op_setad ,op_setatm,\r
          op_setcr ,op_setdi ,op_seteq ,op_setin ,\r
          op_setre ,op_setsb ,op_setsp ,op_setst ,\r
          op_settm ,op_setun ,op_shc   ,op_stcea ,op_stnhb ,\r
          op_ststc ,op_stvga ,op_stvgb ,op_stvgd ,\r
          op_stvgw ,op_stvla ,op_stvlb ,op_stvld ,\r
          op_stvlw ,op_stvsa ,op_stvsb ,op_stvsd ,\r
          op_stvsf ,op_stvsw ,op_sub   ,op_teqad ,\r
          op_tnill ,op_uadd  ,op_uadhw ,op_udiv  ,\r
          op_ult   ,op_umod  ,op_umul  ,op_usub  ,\r
          op_xor   ,op_xxxxx);\r
opcode_range = op_aaaaa .. op_xxxxx;\r
\r
\r
exc_code = 0 .. c_exc_max;\r
\r
\r
context = record\r
niv : integer;\r
stack_size : integer;\r
max_stack_size : integer;\r
end;\r
\r
frame_kind = (g_frame, l_frame, i_frame, s_frame);\r
\r
addr_kind_type = ( addr, stack_addr, packed_arr );\r
\r
varvalue_descr = record\r
kind : integer;\r
size : integer;\r
val  : integer;\r
end;\r
\r
varaddr_descr = record\r
kind : addr_kind_type;\r
access : frame_kind;\r
niv : integer;\r
offset : integer;\r
size : integer\r
end;\r
\r
instruction_type =(normal,\r
                   empty_stack, (*emties the stack after execution*)\r
                   open_instr , (*requires 2 extra stack elements not  allowed in pass5 *)\r
                   hw_instr   , (* hw instruction not allowed in pass5 *)\r
                   set_instr  ,  (* only simple operands on stack *)\r
                   set_only_sw, (*only swstack shall be manipulated*)\r
                   set_hw_word  ); (* only simple operands on stack.Move one word on stack after instruction *)\r
\r
\r
opcode_def = record\r
opname :  array [ 1 .. c_size_opcode ] of char;\r
opappetite,    (*  stack movement *)\r
min_hw_stack:  (* required elements on stack before execution *) integer;\r
op_type     : instruction_type;\r
end;\r
\r
pass4codes =\r
( xfirstcode,\r
\r
 xmodule,  xeom,\r
 xoption,  xnewline,\r
\r
 xprocess,  xextprocess,\r
 xblock,  xlength,  xendblock,\r
\r
 xbegincode,  xcodeline,  xendcode,\r
\r
 xsubdef,\r
 xarray1template,  xarray2template,  xarray3template,\r
 xrecordtemplate,  xfieldsize,  xdynfieldsize, xincfield,\r
 xendtemplate,\r
 xenddecl,\r
\r
 xallocdynvar,\r
\r
 xinitialize,  xstrucinit,  xsimpleinit,  xsetinit,\r
 xexception,  xextexception,\r
 xsysinit,  xsysdyninit,\r
 xsysnewinit,\r
 xfieldinit,  xdynfieldinit,\r
 xendinitfields,\r
 xarrayinit,  xarraydyninit,\r
 xpoolinit,\r
 xvarinit,\r
\r
 xexport,\r
\r
 xproc,  xextproc,\r
 xfunc,  xextfunc,\r
 xparamtype,\r
\r
 xdeflix,\r
\r
 xproccall,  xendpcall,\r
 xextproccall, xstdproccall,\r
 xprocessparam,  xendprocessparam,\r
 xstdfunccall,  xfcall,  xendfunccall,\r
 xfunccall,  xextfunccall,\r
 xendnewcall,\r
\r
 xvarpointer,  xtempointer,  xarglistsize,\r
\r
 xvarparam,  xvalueparam, xreturnparam,\r
\r
 xassignstat,  xleft,  xassign,\r
\r
 xcasestat,  xcase,  xendcaselist,  xendcasestat,  xendcase,\r
 xcaserange,  xcaselabel,  xotherwise,\r
\r
 xforstat,  xleftfor,  xforstore,  xdo,  xendfor,\r
\r
 xgoto,\r
\r
 xifstat,  xifexpr,  xelse,  xif,\r
\r
 xrepeat,  xuntil,  xendrepeat,\r
\r
 xloopstat, xendloopstat, xcontloopstat, xexitloopstat,\r
 xexitstat,\r
\r
 xwhile,  xwhileexpr,  xendwhile,\r
\r
 xwithstat, xwithvar, xwithdynvar,  xendwith,  xnoretype, xretype, xdynretype,\r
\r
 xlockstat,  xlockvar,  xlockdynvar,  xendlock,\r
\r
 xlockmesstat, xexitlock,\r
\r
 xchannel,  xchanvar,  xendchannel,\r
\r
 xexchstat,  xexchange,\r
\r
 xnot,  xneg,  xcompare,  xcompstruc,  xcompdynstruc,  xdiv,\r
 xmul,  xshift,  xrotate, xmod,  xor_,  xxor,\r
 xadd,  xsub,  xand,  xrangetest,\r
 xdynrangetest,\r
\r
 xconst,  xlconst,  xsetconst,\r
 xset,  xinclude,  xsetexpr,  xincludeint,  xendset,\r
\r
 xinitconst,\r
\r
 xindvar,  \r
\r
 xaddr,  xcaddr,  xindaddr, \r
 xpackedarr,\r
\r
 xfield,  xdynfield,\r
\r
 xindexexpr,  xcindex,  xindex,\r
\r
 xerror, xerrorno, xerrortext,\r
 xrangemax, xhindex,\r
 xlastcode\r
\r
);\r
pass4codeindex = 0..160;\r
\r
\f

\r
\r
(* end pass 4 codes *)\r
\r
\r
\r
\r
pass5errors = (\r
ext_table_size,      (* ext_tab_max too small *)\r
ext_param_number,    (* error in user program *)\r
param_number,        (* error in user program *)\r
v_stack_size,        (* max_v_stack too small *)\r
case_label_error,    (* error in user program *)\r
compiler_error,      (* error in this pass *)\r
overflow,            (* hw stack overflow*)\r
wrong_version,       (* wrong pass4-pass5 combination *)\r
inconsistent_use,    (* error in user program *)\r
param_error,         (* inconsistent params in open routine *)\r
param_table_full,    (* max_param_table too small *)\r
pass4code_error,     (* error in input data from pass4 *)\r
moveg_warning        (* WARNING about use of open procedure 'moveg' *)\r
);\r
hw_errors  =   (open_routine,       (*hwstack inconsistence in code for open routine*)\r
                set_instruction,    (*hwstack inconsistence before set instruction*)\r
                simple_open_function,(* as open_routine*)\r
                array_init,         (*inconsistence at jump to label in code_array_init*)\r
shadow_removal,      (*inconsistence at jump to label in code_shadow_remove*)\r
                ref_removal         (*inconsistence at jump to label in code_ref_remove*)\r
);\r
\r
\r
\r
callmodes = (int_call, ext_call, open_call, std_call);\r
\r
\r
  stat_acc_rec =\r
record\r
\r
assign :\r
record\r
\r
kind_type : array [ addr_kind_type, 0 .. 6 ] of integer;\r
size : array [ 0 .. 15 ] of integer\r
\r
end;\r
\r
end;\r
\r
trap_table_type = record\r
trap_entry : array [ 0 .. 255 ] of integer\r
end;\r
(*index types for op_stv, and op_rev tables*)\r
\r
frames = (g, (*global*)\r
          l, (*local*)\r
          s);(*stack*)\r
\r
types =  (b, (*byte*)\r
          w, (*word*)\r
          a, (*pointer i.e. address*)\r
          d);(*double*)\r
\r
base_types = byte_typ..double_typ;\r
\r
\r
\r
(*   var. declarations global for pass5:      *)\r
\r
\r
var\r
heapfree: longint;\r
\r
preserve_option,\r
prolog_yes, epilog_yes, compress_yes, callpass6_yes, statacc_yes, summary_yes,\r
measurement_yes, trap_code,\r
dyn_eval_stack,\r
heap_init, (* true during sys init call in conjunction with new-call *)\r
openroutine_yes: boolean;\r
\r
hw_stack_size :  integer; (* hw stack pointer to top *)\r
old_hw : integer; (*used for storing hw_stack_size before entrance to open routines*)\r
\r
\r
trap_nr_table : ^ trap_table_type;\r
current_trap_nr,\r
no_of_measure_recs : integer;\r
\r
\r
\r
descr : record\r
\r
(* in this variable the Descriptor Segment, part 1 is accumulated. *)\r
\r
kind :  integer;\r
name :  identifier;\r
(*process inf*)\r
\r
entry_point,\r
exception_point :  identifier;\r
\r
default_appetite : integer;\r
\r
last_param_offset: integer;\r
free_words : array [1..descr_free_words] of integer;\r
\r
no_of_params  :  integer;\r
param  :  array [ 1 .. descr_max_param ] of param_descr;\r
\r
end   (*  descr  *);\r
\r
enforced_create_size : integer;\r
(* if defined (option 10) then suppress computed default appetite *)\r
enforced_exception_app : integer;\r
\r
\r
\r
exc_hard : set of exc_code;\r
\r
exc_descr : record\r
\r
state : integer;\r
internal : boolean;\r
key : integer;\r
niv,\r
lix : integer\r
\r
end;\r
\r
c : context;\r
in_kind  :     (setatm,settm); (*used to choose right instruction*)\r
\r
operand_situation: ( before_opands, after_short_const, after_opands );\r
\r
\r
\r
\r
\r
\r
(*    var. declarations from the modules:      *)\r
\r
in_item_count, in_line_no : integer;\r
in_options : option_list;\r
token: pass4codes;\r
convert_in_code : array [ pass4codeindex ] of pass4codes;\r
\r
\r
mess_summ_state : integer;\r
\r
out_state, out_pos : integer;\r
\r
out_line_state : boolean;\r
out_special : boolean;\r
\r
not_resolved : integer;  (* links through all ext_declared *)\r
\r
file_position: integer; (* < 0: before reset, else position in library file *)\r
\r
ext_open_codes:\r
record\r
cur_word_ptr : integer; (* points at first free word in charbuf *)\r
charbuf : array [ 1 .. ext_max_charbuf ] of integer;\r
end;\r
\r
\r
stat_acc :  stat_acc_rec;\r
\r
\r
type\r
t_op_table = array[opcode_range] of opcode_def;\r
const\r
op_table : t_op_table = (\r
  (opname:'aaaaa '; opappetite:  0; min_hw_stack:  0; op_type: normal ),\r
  (opname:'abs   '; opappetite:  0; min_hw_stack:  2; op_type: normal ),\r
  (opname:'add   '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'and   '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'cexch '; opappetite: -8; min_hw_stack:  8; op_type: normal ),\r
  (opname:'cgreg '; opappetite:  2; min_hw_stack:  0; op_type: normal ),\r
  (opname:'compl '; opappetite:  0; min_hw_stack:  2; op_type: normal ),\r
  (opname:'coutwq'; opappetite:  4; min_hw_stack:  0; op_type: normal ),\r
  (opname:'crget '; opappetite:  0; min_hw_stack:  2; op_type: normal ),\r
  (opname:'crput '; opappetite: -4; min_hw_stack:  4; op_type: normal ),\r
  (opname:'csell '; opappetite: -2; min_hw_stack:  2; op_type: normal ),\r
  (opname:'div   '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'eq    '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'ge    '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'gt    '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'index '; opappetite: -6; min_hw_stack: 10; op_type: normal ),\r
  (opname:'indh0 '; opappetite: -2; min_hw_stack:  6; op_type: normal ),\r
  (opname:'indh01'; opappetite: -2; min_hw_stack:  6; op_type: normal ),\r
  (opname:'indh02'; opappetite: -2; min_hw_stack:  6; op_type: normal ),\r
  (opname:'indh1 '; opappetite: -2; min_hw_stack:  6; op_type: normal ),\r
  (opname:'indh11'; opappetite: -2; min_hw_stack:  6; op_type: normal ),\r
  (opname:'indh12'; opappetite: -2; min_hw_stack:  6; op_type: normal ),\r
  (opname:'inpdv '; opappetite: -2; min_hw_stack:  8; op_type: normal ),\r
  (opname:'inth0 '; opappetite:  0; min_hw_stack:  2; op_type: normal ),\r
  (opname:'intpa '; opappetite: -2; min_hw_stack: 10; op_type: normal ),\r
  (opname:'intrs '; opappetite: -4; min_hw_stack:  6; op_type: normal ),\r
  (opname:'iocda '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'iorsc '; opappetite: -4; min_hw_stack:  6; op_type: normal ),\r
  (opname:'jmcht '; opappetite: -2; min_hw_stack:  2; op_type: normal ),\r
  (opname:'jmpga '; opappetite:  0; min_hw_stack:  0; op_type: normal ),\r
  (opname:'jmprw '; opappetite:  0; min_hw_stack:  0; op_type: normal ),\r
  (opname:'jmzeq '; opappetite: -2; min_hw_stack:  2; op_type: normal ),\r
  (opname:'jmzge '; opappetite: -2; min_hw_stack:  2; op_type: normal ),\r
  (opname:'jmzgt '; opappetite: -2; min_hw_stack:  2; op_type: normal ),\r
  (opname:'jmzle '; opappetite: -2; min_hw_stack:  2; op_type: normal ),\r
  (opname:'jmzlt '; opappetite: -2; min_hw_stack:  2; op_type: normal ),\r
  (opname:'jmzne '; opappetite: -2; min_hw_stack:  2; op_type: normal ),\r
  (opname:'le    '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'llock '; opappetite: -2; min_hw_stack:  6; op_type: normal ),\r
  (opname:'lrele '; opappetite: -4; min_hw_stack:  4; op_type: normal ),\r
  (opname:'lrese '; opappetite: -4; min_hw_stack:  4; op_type: normal ),\r
  (opname:'lt    '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'madd  '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'mod   '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'moveb '; opappetite:-10; min_hw_stack: 10; op_type: normal ),\r
  (opname:'movebs'; opappetite:-10; min_hw_stack: 10; op_type: normal ),\r
  (opname:'moveg '; opappetite:-10; min_hw_stack: 10; op_type: normal ),\r
  (opname:'msub  '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'mtrh  '; opappetite:  0; min_hw_stack:  0; op_type: normal ),\r
  (opname:'mtrs  '; opappetite: -2; min_hw_stack:  2; op_type: normal ),\r
  (opname:'mul   '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'ne    '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'neg   '; opappetite:  0; min_hw_stack:  2; op_type: normal ),\r
  (opname:'not   '; opappetite:  0; min_hw_stack:  2; op_type: normal ),\r
  (opname:'or    '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'pcals '; opappetite: -4; min_hw_stack:  4; op_type:empty_stack),\r
  (opname:'pcals0'; opappetite:  0; min_hw_stack:  0; op_type:empty_stack),\r
  (opname:'pcals1'; opappetite:  0; min_hw_stack:  0; op_type:empty_stack),\r
  (opname:'pexit '; opappetite:  0; min_hw_stack:  0; op_type: normal ),\r
  (opname:'reaad '; opappetite:  4; min_hw_stack:  0; op_type: normal ),\r
  (opname:'readb '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'readw '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'reagd '; opappetite:  4; min_hw_stack:  0; op_type: normal ),\r
  (opname:'reaid '; opappetite:  4; min_hw_stack:  0; op_type: normal ),\r
  (opname:'reaisd'; opappetite:  0; min_hw_stack:  4; op_type: normal ),\r
  (opname:'reald '; opappetite:  4; min_hw_stack:  0; op_type: normal ),\r
  (opname:'reard '; opappetite:  4; min_hw_stack:  0; op_type: normal ),\r
  (opname:'reasd '; opappetite:  0; min_hw_stack:  4; op_type: normal ),\r
  (opname:'reaxd '; opappetite:  4; min_hw_stack:  0; op_type:empty_stack),\r
  (opname:'rechd '; opappetite:  4; min_hw_stack:  0; op_type: normal ),\r
  (opname:'rechw '; opappetite:  2; min_hw_stack:  0; op_type: normal ),\r
  (opname:'renhb '; opappetite:  0; min_hw_stack:  0; op_type:empty_stack),\r
  (opname:'renpb '; opappetite: -2; min_hw_stack:  2; op_type:empty_stack),\r
  (opname:'restc '; opappetite:  0; min_hw_stack:  0; op_type:hw_instr),\r
  (opname:'revga '; opappetite:  4; min_hw_stack:  0; op_type: normal ),\r
  (opname:'revgb '; opappetite:  2; min_hw_stack:  0; op_type: normal ),\r
  (opname:'revgd '; opappetite:  4; min_hw_stack:  0; op_type: normal ),\r
  (opname:'revgw '; opappetite:  2; min_hw_stack:  0; op_type: normal ),\r
  (opname:'revla '; opappetite:  4; min_hw_stack:  0; op_type: normal ),\r
  (opname:'revlb '; opappetite:  2; min_hw_stack:  0; op_type: normal ),\r
  (opname:'revld '; opappetite:  4; min_hw_stack:  0; op_type: normal ),\r
  (opname:'revlw '; opappetite:  2; min_hw_stack:  0; op_type: normal ),\r
  (opname:'revpd '; opappetite:  4; min_hw_stack:  4; op_type: normal ),\r
  (opname:'revpw '; opappetite:  2; min_hw_stack:  2; op_type: normal ),\r
  (opname:'revsa '; opappetite:  0; min_hw_stack:  4; op_type: normal ),\r
  (opname:'revsb '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'revsd '; opappetite:  0; min_hw_stack:  4; op_type: normal ),\r
  (opname:'revsf '; opappetite: -4; min_hw_stack:  6; op_type: normal ),\r
  (opname:'revsm '; opappetite: -6; min_hw_stack:  6; op_type:empty_stack),\r
  (opname:'revsw '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'setad '; opappetite: -2; min_hw_stack:  2; op_type:set_instr),\r
  (opname:'setatm'; opappetite: -6; min_hw_stack:  8; op_type: normal ),\r
  (opname:'setcr '; opappetite: -4; min_hw_stack:  4; op_type:empty_stack),\r
  (opname:'setdi '; opappetite:  0; min_hw_stack:  0; op_type:set_instr),\r
  (opname:'seteq '; opappetite:  2; min_hw_stack:  0; op_type:set_instr),\r
  (opname:'setin '; opappetite:  0; min_hw_stack:  0; op_type:set_instr),\r
  (opname:'setre '; opappetite: -4; min_hw_stack:  6; op_type:empty_stack),\r
  (opname:'setsb '; opappetite:  2; min_hw_stack:  0; op_type:set_instr),\r
  (opname:'setsp '; opappetite:  2; min_hw_stack:  0; op_type:set_instr),\r
  (opname:'setst '; opappetite: -6; min_hw_stack:  0; op_type:set_only_sw),\r
  (opname:'settm '; opappetite:  0; min_hw_stack:  0; op_type:set_hw_word),\r
  (opname:'setun '; opappetite:  0; min_hw_stack:  0; op_type:set_instr),\r
  (opname:'shc   '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'stcea '; opappetite: -8; min_hw_stack: 10; op_type: normal ),\r
  (opname:'stnhb '; opappetite:  0; min_hw_stack:  0; op_type:empty_stack),\r
  (opname:'ststc '; opappetite:  0; min_hw_stack:  0; op_type:hw_instr),\r
  (opname:'stvga '; opappetite: -4; min_hw_stack:  4; op_type: normal ),\r
  (opname:'stvgb '; opappetite: -2; min_hw_stack:  2; op_type: normal ),\r
  (opname:'stvgd '; opappetite: -4; min_hw_stack:  4; op_type: normal ),\r
  (opname:'stvgw '; opappetite: -2; min_hw_stack:  2; op_type: normal ),\r
  (opname:'stvla '; opappetite: -4; min_hw_stack:  4; op_type: normal ),\r
  (opname:'stvlb '; opappetite: -2; min_hw_stack:  2; op_type: normal ),\r
  (opname:'stvld '; opappetite: -4; min_hw_stack:  4; op_type: normal ),\r
  (opname:'stvlw '; opappetite: -2; min_hw_stack:  2; op_type: normal ),\r
  (opname:'stvsa '; opappetite: -8; min_hw_stack:  8; op_type: normal ),\r
  (opname:'stvsb '; opappetite: -6; min_hw_stack:  6; op_type: normal ),\r
  (opname:'stvsd '; opappetite: -8; min_hw_stack:  8; op_type: normal ),\r
  (opname:'stvsf '; opappetite: -8; min_hw_stack:  8; op_type: normal ),\r
  (opname:'stvsw '; opappetite: -6; min_hw_stack:  6; op_type: normal ),\r
  (opname:'sub   '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'teqad '; opappetite: -6; min_hw_stack:  8; op_type: normal ),\r
  (opname:'tnill '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'uadd  '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'uadhw '; opappetite:  0; min_hw_stack:  2; op_type: normal ),\r
  (opname:'udiv  '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'ult   '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'umod  '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'umul  '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'usub  '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'xor   '; opappetite: -2; min_hw_stack:  4; op_type: normal ),\r
  (opname:'xxxxx '; opappetite:  0; min_hw_stack:  0; op_type: normal ) );\r
type\r
 fr_type = array[frame_kind] of frames;\r
const\r
conv_frame : fr_type = (\r
             g(*g_frame*),\r
             l(*l_frame*),\r
             s(*i_frame*), (*not used*)\r
             s(*s_frame*));\r
\r
type\r
 mc_type = array[base_types] of types;\r
const\r
conv_type  : mc_type = (\r
             b(*byte_typ*),\r
             w(*word_typ*),\r
             a(*point_typ*),\r
             d(*double_typ*));\r
\r
type\r
 stv_rev_type = array[g..s,b..d] of opcode;\r
 (*op_stv and op_rev contains the instructions rev.. and stv..*)\r
const\r
op_stv : stv_rev_type = (\r
          (op_stvgb,op_stvgw,op_stvga,op_stvgd),\r
          (op_stvlb,op_stvlw,op_stvla,op_stvld),\r
          (op_stvsb,op_stvsw,op_stvsa,op_stvsd) );\r
\r
op_rev : stv_rev_type = (\r
          (op_revgb,op_revgw,op_revga,op_revgd),\r
          (op_revlb,op_revlw,op_revla,op_revld),\r
          (op_revsb,op_revsw,op_revsa,op_revsd) );\r
\r
type\r
 op_comp_type = array[1..11] of opcode;\r
const\r
 op_comp  : op_comp_type = (\r
   op_ult, op_eq, op_ne, op_lt, op_gt, op_le, op_ge,\r
   op_seteq, op_seteq,\r
   op_setsb, op_setsp );\r
\r
type\r
 op_indh_type = array[0..1,0..2] of opcode;\r
const\r
op_indh : op_indh_type = (\r
             (op_indh0,op_indh01,op_indh02),\r
             (op_indh1,op_indh11,op_indh12) );\r
\r
\r
\r
(*    procedure declarations global for pass5:      *)\r
\r
\r
\r
procedure eom;\r
begin\r
writeln (out_pass5);\r
close (in_pass5);\r
if not preserve_option then\r
begin\r
erase(in_pass5);\r
assign(in_pass5, concat(path1_name, o_pass4_nixname));\r
erase(in_pass5);\r
end;\r
flush(out_pass5);\r
close (out_pass5);\r
(*$I-*)\r
close (ext_pass5);\r
(*$I+*)\r
if ioresult = 0 then;\r
end;\r
\r
\r
procedure printhead;\r
begin\r
write ('*** pass 5 line ', in_line_no:4, ',  ');\r
end;\r
\r
\r
procedure printstatus;\r
begin\r
writeln ('   token      =', ord(token));\r
writeln ('   no of items=', in_item_count);\r
writeln ('   stack      =', c.stack_size);\r
writeln('   hw stack size=',hw_stack_size);\r
end;\r
\r
\r
procedure error_this_pass (e: pass5errors);\r
begin\r
write('compiler error, error code = ', ord(e):1);\r
end;\r
\r
\r
procedure abort (e: pass5errors);\r
begin\r
write ('compilation terminated by ');\r
case e of\r
ext_table_size:         writeln ('external routine table overflow');\r
ext_param_number:       writeln ('too many params in declaration');\r
v_stack_size:           writeln ('operand stack overflow');\r
pass4code_error:        writeln ('pass 4 code error');\r
param_table_full:       writeln ('external routine param table full');\r
compiler_error:         writeln ('inconsistency in pass5');\r
overflow:               writeln('hardware stack overflow');\r
wrong_version:          writeln ('wrong pass4/pass5 combination');\r
else error_this_pass(e);\r
end;\r
printstatus;\r
eom; rtphalt(true);\r
end;\r
\r
\r
procedure error (e: pass5errors);\r
const stars= '*********************  ';\r
begin\r
printhead;\r
case e of\r
case_label_error:     writeln ('+decl caselabel');\r
param_number:         writeln ('too many formal parameters');\r
inconsistent_use:     writeln ('user is not allowed to call system-routines');\r
moveg_warning:        begin\r
       writeln('WARNING, Call of PROCEDURE moveg.');\r
writeln(stars, 'You are breaking the RTP security.');\r
writeln(stars, 'Try to find another solution');\r
writeln(stars, 'inside the RTP language !!');\r
end;\r
else abort(e);\r
end;\r
pass5_ok := pass5_ok and (e=moveg_warning);\r
end;\r
\r
\r
procedure evalstack_error;\r
begin\r
printhead;\r
writeln ('evaluation stack error');\r
printstatus;\r
c.stack_size := 0;\r
hw_stack_size := 0;\r
end;\r
procedure table_error(op: opcode);\r
begin\r
with op_table[op] do\r
begin\r
writeln('error in opcodetable:',opname);\r
writeln('opappetite:',opappetite:2,' min_hw_stack:',min_hw_stack:2);\r
end;\r
end;\r
\r
procedure out_comment(str:string);\r
forward;\r
\r
procedure hw_stack_error(err:hw_errors);\r
begin\r
out_comment('****PASS5 HWSTACKERROR****');\r
writeln('error in hw stack evaluation.');\r
case err of\r
set_instruction: writeln('occured in out_opcode. hwstacksize too big for setinstruction');\r
open_routine: writeln('occoured in generating code for open routine.');\r
simple_open_function: writeln('occoured in generating code for simple open function.');\r
array_init: writeln('occurred when generating code for arrays with systemcomponents');\r
ref_removal: writeln('occurred when generating code for ref removal');\r
shadow_removal: writeln('occured when generating code for shadow removal');\r
end;\r
writeln('hw_stack_size is:',hw_stack_size:3);\r
end;\r
\r
\r
\r
procedure  context_eval(  change : integer );\r
\r
begin\r
\r
with c do\r
begin\r
\r
stack_size := stack_size + change;\r
if stack_size > max_stack_size then  max_stack_size := stack_size\r
\r
end\r
\r
end;\r
\r
\r
\r
\r
(*     procedure declarations from the modules:      *)\r
\r
\r
procedure extin(var n: integer);\r
begin\r
  extcode_fileix := extcode_fileix + 1;\r
  if extcode_fileix > filrec_max then\r
  begin\r
    read(ext_pass5, extcode_filptr^);\r
    extcode_fileix := 1;\r
  end;\r
(*$R-*)\r
  n := swap(extcode_filptr^[extcode_fileix]);\r
(*$R+*)\r
end;\r
\r
procedure passin(var n: integer);\r
begin\r
  incode_fileix := incode_fileix + 1;\r
  if incode_fileix > filrec_max then\r
  begin\r
    read(in_pass5, incode_filptr^);\r
    incode_fileix := 1;\r
  end;\r
  n := incode_filptr^[incode_fileix];\r
end;\r
\r
procedure get_token;\r
\r
var\r
found : boolean;\r
pass5_yes : boolean;\r
no1, no2, passno : integer;\r
\r
begin\r
\r
found := false;\r
\r
repeat\r
begin\r
\r
passin(no1);\r
token := convert_in_code [ no1 ];\r
(*$R-*)\r
in_item_count := in_item_count + 1;\r
(*$R+*)\r
\r
case token of\r
xoption:\r
begin\r
\r
passin(passno );\r
passin(no1 );\r
passin(no2 );\r
(*$R-*)\r
in_item_count := in_item_count + 3;\r
(*$R+*)\r
pass5_yes := no2 <> 0;\r
\r
if passno = 5 then\r
case no1 of\r
1: prolog_yes := pass5_yes;\r
2: epilog_yes := pass5_yes;\r
3: statacc_yes := pass5_yes;\r
4: compress_yes := pass5_yes;\r
5: callpass6_yes := pass5_yes;\r
6: summary_yes := pass5_yes;\r
7: enforced_exception_app := no2;\r
8: lambda_version := no2;\r
9: openroutine_yes := pass5_yes;\r
10: enforced_create_size := no2;\r
11: measurement_yes := pass5_yes;\r
12: preserve_option:= pass5_yes;\r
else ; (* blind *)\r
end\r
else\r
with in_options do\r
begin\r
\r
if passno = 0 then (* version identification *)\r
if no1 = 4 (* pass 4 *) then\r
if (no2 div 100 <> versionpass4 div 100) or\r
(no2 mod 100 < versionpass4 mod 100) then\r
error (wrong_version);\r
\r
if out_state = 1 (* after newline *) then\r
writeln (out_pass5, 'o.', passno:3, no1:7, no2:7, '.')\r
else\r
\r
if no_of_options < c_size_option_list then\r
begin\r
\r
out_special := true;\r
\r
no_of_options := no_of_options + 1;\r
with options [ no_of_options ] do\r
begin\r
pno := passno;\r
p1  := no1;\r
p2  := no2;\r
end;\r
\r
end\r
\r
end\r
end;\r
xnewline:\r
begin\r
\r
passin(in_line_no);\r
(*$R-*)\r
in_item_count := in_item_count + 1;\r
(*$R+*)\r
\r
out_special := true;\r
out_line_state := true;\r
end;\r
else found := true;\r
end;\r
\r
end\r
until  found;\r
\r
end; (* get_token *)\r
\r
\r
procedure skip_token (t: pass4codes);\r
begin\r
if token <> t then error (pass4code_error);\r
get_token;\r
end;\r
\r
\r
function  in_integer : integer;\r
\r
var   i : integer;\r
\r
begin\r
passin( i );\r
(*$R-*)\r
in_item_count := in_item_count + 1;\r
(*$R+*)\r
in_integer := i;\r
end;\r
\r
\r
procedure  in_identifier( var  ident : identifier );\r
\r
var\r
i, j, w : integer;\r
\r
begin\r
\r
i := 1;\r
\r
for j := 1 to 12 do\r
begin\r
\r
passin( w );\r
(*$R-*)\r
in_item_count := in_item_count + 1;\r
(*$R+*)\r
\r
if i <= c_size_identifier then\r
begin\r
\r
ident[ i ] := chr( w );\r
i := i + 1\r
\r
end;\r
\r
end;\r
\r
while i <= c_size_identifier do\r
begin\r
\r
ident[ i ] := ' ';\r
i := i + 1\r
\r
end;\r
\r
end (* in_identifier *);\r
\r
\r
procedure  in_init;\r
var token: pass4codes;\r
begin\r
\r
(* initialize conversion-table *)\r
for token := xfirstcode to xlastcode do\r
begin\r
in_item_count := ord(token);\r
convert_in_code [ in_item_count ] := token;\r
end;\r
\r
assign(in_pass5, concat(path1_name, o_pass4_codename));\r
(*$I-*)\r
reset(in_pass5);\r
if ioresult <> 0 then\r
begin\r
nofile(concat(path1_name, o_pass4_codename));\r
end;\r
(*$I+*)\r
incode_fileix := filrec_max;\r
in_item_count := 0;\r
in_line_no := 0;\r
in_options.no_of_options := 0;\r
\r
(* read first token *)\r
get_token;\r
\r
out_line_state := false;  (* suppress previous reading of linenumbers *)\r
end;\r
\r
\r
\r
\r
procedure  mess_summary_line( name : identifier;  head_line, begin_line, end_line : integer;\r
                              appetite : integer; dynamic_variables : boolean ; process_appetite : integer );\r
\r
var\r
dyn_mark : alfa;\r
\r
begin\r
\r
if summary_yes then\r
begin\r
\r
if mess_summ_state = 0 then\r
begin\r
\r
(*  print a header for the summary :  *)\r
writeln(output);\r
writeln(output, 'Information survey from REAL-TIME PASCAL, pass5, version ',\r
version_date);\r
\r
writeln;\r
writeln( '   name        headline beginline endline  appetite(words) default create-size');\r
writeln;\r
\r
mess_summ_state := 1\r
\r
end;\r
if dynamic_variables then\r
dyn_mark := '+ dynamic   '\r
else\r
dyn_mark := '            ';\r
\r
write( '   ', name );\r
if head_line = -1 (* external routine *) then\r
write( '   external, called ', appetite : 2, ' time(s) ')\r
else\r
write(  head_line : 6, begin_line : 10, end_line : 8, '  :  ', appetite div 2 : 6\r
, dyn_mark  );\r
if process_appetite <> 0 then\r
write( process_appetite : 12 );\r
writeln;\r
\r
end\r
\r
end;\r
\r
procedure out_nl;\r
var\r
i : integer;\r
\r
begin\r
   writeln( out_pass5 );\r
\r
   out_state := 1;   out_pos := 0;\r
\r
if out_special then\r
begin\r
\r
out_special := false;\r
\r
with in_options do\r
if no_of_options > 0 then\r
begin\r
for i := 1 to no_of_options do\r
with options [ i ] do\r
writeln (out_pass5, 'o.', pno:3, p1:7, p2:7, '.');\r
no_of_options := 0;\r
end;\r
\r
if out_line_state then\r
begin\r
writeln( out_pass5, 'l. ', in_line_no : 1);\r
out_line_state := false\r
end;\r
\r
end;\r
\r
end;\r
\r
\r
procedure  out_char( chr : char );\r
\r
begin\r
write( out_pass5, chr );\r
out_pos := out_pos + 1\r
end;\r
\r
procedure out_tab( pos : integer );\r
\r
begin\r
if out_pos < pos then\r
begin\r
write( out_pass5, ' ' : pos - out_pos);\r
out_pos := pos;\r
end\r
end;\r
\r
\r
procedure out_integer( i : integer );\r
\r
begin\r
if (i > 999) or (i < -99) then\r
begin\r
write (out_pass5, i : 6);  out_pos := out_pos + 6;\r
end\r
else\r
begin\r
write (out_pass5, i : 4);  out_pos := out_pos + 4;\r
end;\r
end;\r
\r
\r
procedure out_identifier( id : identifier );\r
\r
var\r
       i, n : integer;\r
\r
begin\r
\r
n := c_size_identifier;\r
while ( id[ n ] = ' ' ) and ( n > 1 ) do n := n - 1;\r
\r
write(out_pass5, ' ');\r
for i := 1 to n do write( out_pass5, id[i]);\r
out_pos := out_pos + n + 1;\r
\r
end;\r
\r
\r
procedure out_def( id : identifier );\r
\r
begin\r
   if out_state <> 1 then  out_nl;\r
\r
   out_identifier ( id );\r
write( out_pass5, '= ' );  out_pos := out_pos + 2;\r
\r
   out_state := 6\r
end;\r
\r
\r
procedure out_label( id : identifier );\r
\r
begin\r
   if out_state <> 1 then  out_nl;\r
\r
   out_identifier( id );\r
write( out_pass5, ': ' );  out_pos := out_pos + 2;\r
\r
   out_state := 2\r
end;\r
\r
\r
procedure out_lix (id_letter: char; index: integer);\r
begin\r
write (out_pass5, id_letter:2, '#', index:1);\r
out_pos := out_pos + 4;  (* assume normally two-digit indices... *)\r
end;\r
\r
\r
procedure out_lix_label (id_letter: char; index: integer);\r
begin\r
out_nl;\r
out_lix (id_letter, index);\r
out_label ('            ');\r
end;\r
\r
\r
procedure  out_comment( str : string );\r
var n: integer;\r
\r
begin\r
   if out_state <> 5 then\r
   begin\r
      if not compress_yes then  out_tab( 25 );\r
write( out_pass5, '; ' );  out_pos := out_pos + 2;\r
   end;\r
if not compress_yes then\r
begin\r
n := length(str);\r
while (str [ n ] = ' ') and (n > 1) do n := n-1;\r
write (out_pass5, str:n);\r
out_pos := out_pos + n;\r
end;\r
\r
   out_state := 5\r
end;\r
\r
\r
procedure out_start_param;\r
\r
begin\r
case out_state of\r
3: out_state := 4;\r
4: out_char(',');\r
else error (compiler_error);\r
end;\r
end;\r
\r
procedure out_resta(request:integer);\r
(*outputs a restore instruction i. e. the hardware stack will  contain\r
exactly request elements after the instruction *)\r
begin\r
if request > max_hw_stack then error(overflow);\r
if out_state<>1 then out_nl;\r
write (out_pass5,'resta');\r
write (out_pass5,request:4);\r
hw_stack_size := request;\r
out_state := 3;\r
end;\r
\r
procedure hw_stack_adjust(min_request,adjustment:integer);\r
(*checks if the hwstack has to be pushed or poped and does so if nessesary *)\r
begin\r
if hw_stack_size < min_request then\r
(*not enough elements i. e. push some elements to the stack *)\r
out_resta(min_request)\r
else\r
if (hw_stack_size + adjustment) > max_hw_stack then\r
(*overflow : leave 2 words on stack *)\r
out_resta(2*word_length);\r
\r
(*if none of the tests  were true then there is enough room on the stack  so do nothing *)\r
end;\r
\r
\r
procedure out_opcode( op : opcode );\r
\r
var\r
      i   : integer;\r
\r
begin\r
with op_table[op] do\r
begin\r
if compiler_test then\r
begin\r
if ((min_hw_stack + opappetite) > max_hw_stack) or\r
(op_type = open_instr) then table_error(op);\r
\r
end;\r
\r
if op_type <> hw_instr then\r
begin\r
\r
(* if not set instr then*)\r
if (op_type <> set_instr) and (op_type <> set_only_sw) and\r
   (op_type <> set_hw_word) then\r
\r
(*check and eventually adjust hw stack *)\r
hw_stack_adjust(min_hw_stack,opappetite)\r
\r
else\r
begin (*set instruction*)\r
(*only simple operands on stack*)\r
if hw_stack_size <> min_hw_stack then\r
out_resta(min_hw_stack);\r
(* NB! setcr is not marked as set instruction, the update of dyn eval stack is\r
done after the call of out_opcode(op_setcr) *)\r
if (op=op_setad) or (op=op_setre) then\r
dyn_eval_stack:= true;\r
end; (* set instruction *)\r
\r
(*output instruction*)\r
if (out_state <> 1) and (out_state <> 2) then out_nl;\r
if not compress_yes then out_tab(5);\r
write(out_pass5,opname);\r
\r
(*adjust stackpointers*)\r
context_eval(opappetite);\r
case op_type of\r
empty_stack:\r
\r
if opappetite > 0 then hw_stack_size := opappetite\r
else\r
hw_stack_size := 0;\r
\r
set_hw_word: hw_stack_size := word_length;\r
set_only_sw: ; (*setst*) (*only sw_stack manipulation*)\r
\r
else\r
hw_stack_size := hw_stack_size + opappetite;\r
end;\r
end\r
else\r
begin (*hw_instruction*)\r
(*normally not allowed in pass5, but nessesary for code execption *)\r
writeln(out_pass5);\r
write(out_pass5, opname);\r
hw_stack_size := 0;\r
end;\r
\r
end; (*with op_table *)\r
out_pos := out_pos + c_size_opcode;\r
   out_state := 3\r
end;\r
\r
\r
procedure out_p_id (id: identifier);\r
begin\r
out_start_param;\r
out_identifier (id);\r
end;\r
\r
\r
procedure out_p_int (i: integer);\r
begin\r
out_start_param;\r
out_integer (i);\r
end;\r
\r
\r
procedure out_expr (id: identifier; i: integer);\r
begin\r
out_start_param;\r
out_identifier (id);\r
if i >= 0 then out_char ('+');\r
out_integer (i);\r
end;\r
\r
\r
procedure out_op_id (op: opcode; id: identifier);\r
begin\r
out_opcode (op);\r
out_identifier (id);\r
out_state := 4;\r
end;\r
\r
\r
procedure out_op_int (op: opcode; i: integer);\r
begin\r
out_opcode (op);\r
out_integer (i);\r
out_state := 4;\r
end;\r
\r
procedure out_i_frame_addr(level : integer);\r
(*generates code for placing the address of the i_frame denoted by level\r
on top of stack*)\r
const\r
max_level = 4; (*max number of intermidiate references in one instruction*)\r
\r
var\r
step,stop: integer;\r
begin\r
if level = 0 then error(compiler_error)\r
else (*level > 0*)\r
if level <= max_level then\r
out_op_int(op_reaid,level)\r
else (*level > max_level*)\r
begin\r
stop := level div max_level;\r
if (level mod max_level = 0) then\r
begin\r
out_op_int(op_reaid,max_level);\r
stop := stop - 1;\r
end (*level = x * maxlevel*)\r
else\r
out_op_int(op_reaid, level mod max_level);\r
\r
for step := 1 to stop do\r
out_op_int(op_reaisd,max_level);\r
end; (*level > maxlevel *)\r
end; (*out_i_frame_addr*)\r
\r
procedure out_specopcode(op:opcode;movement:integer);\r
(* this procedure is used for instructions with extra stackchange than denoted\r
in the opcode table i. e.\r
pcals0 (-paramlength), pcals1 (-paramlength), pcals (-paramlength),\r
revsm (size)\r
renhb (param)\r
stnhb (-param)\r
setre (size)\r
setst (-size), settm (-size), setad (size + 2)   *)\r
begin\r
if op = op_stnhb then\r
out_op_int(op,-movement)\r
else\r
if op = op_renhb then\r
out_op_int(op,movement)\r
else\r
out_opcode(op);\r
context_eval(movement);\r
end;\r
\r
procedure out_op_rea(level,offset:integer);\r
(*pushes the address denoted by level, offset on top of the stack*)\r
begin\r
(*move address of i_frame on top of stack*)\r
out_i_frame_addr(level);\r
  \r
(*add offset*)\r
out_op_int(op_reasd,offset);\r
  \r
end; (*out_op_rea*)\r
\r
procedure out_op_rev__(access:frame_kind;type_v:base_types;level,offset:integer);\r
(*outputs a rev.. instruction dependent of which frame and type_v. In case of\r
i_frame the address is placed on top of stack and a revs. 0 is output*)\r
begin\r
\r
if access <> i_frame\r
then (*g_frame l_frame or s_frame*)\r
out_op_int(op_rev[conv_frame[access],conv_type[type_v]],offset)\r
else begin(*i_frame*)\r
out_op_rea(level,offset);\r
out_op_int(op_rev[s,conv_type[type_v]],0);\r
end;\r
end;\r
\r
\r
procedure out_token (t: char);\r
begin\r
case t of\r
dollar_a: begin out_char ('$'); out_char ('a'); end;\r
dollar_b: begin out_char ('$'); out_char ('b'); end;\r
dollar_i: begin out_char ('$'); out_char ('i'); end;\r
else\r
begin\r
if t <> zendlist then\r
out_char (t);\r
out_char ('.');\r
end;\r
end;\r
out_state := 3;\r
end;\r
\r
\r
procedure out_init;\r
\r
begin\r
assign( out_pass5, concat(path2_name, o_pass5_codename));\r
settextbuf(out_pass5, out_buf_ptr^);\r
rewrite( out_pass5 );\r
\r
out_state := 1;    out_pos := 0;\r
\r
out_special := false;\r
out_line_state := false;\r
writeln (out_pass5,\r
         'o.', 0 : 3 (* version id *), ownpassno:7, versionpass5:7, '.');\r
\r
out_nl;\r
\r
end;\r
\r
\r
procedure ext_init;\r
var\r
key : integer;\r
begin\r
not_resolved := -1;\r
ext_open_codes.cur_word_ptr := 1;\r
file_position := -1;  (* before reset *)\r
assign (ext_pass5, concat(rtp35_pathname, i_pass5_extname));\r
for key := 1 to ext_tab_max do\r
with ext_tab [ key ] do\r
state := ext_unused;\r
end;\r
\r
\r
procedure find_ext_routine;\r
var\r
key : integer;\r
cur_param: param_ptr;\r
begin\r
\r
key := in_integer;\r
if key > ext_tab_max then error (ext_table_size);\r
\r
with ext_tab [ key ] do\r
begin\r
in_identifier (id);\r
no_of_param := in_integer;\r
if no_of_param > 0 then\r
new(paramptr)\r
else\r
paramptr:= nil;\r
cur_param:= paramptr;\r
\r
no_of_uses := 0;\r
\r
get_token;\r
while token = xparamtype do\r
with cur_param^ do\r
begin\r
kind := in_integer;\r
size := in_integer;\r
get_token;\r
if token=xparamtype then\r
new(next_param)\r
else\r
next_param:= nil;\r
cur_param:= next_param;\r
end; (* with *)\r
\r
state := ext_declared;\r
while key<=not_resolved do\r
(* remove unused elements of parallel block from the chain of non reslved routines *)\r
not_resolved:= ext_tab[ not_resolved ].decl_link;\r
\r
decl_link := not_resolved;\r
not_resolved := key;\r
end;\r
end;  (* procedure find_ext_routine *)\r
\r
\r
procedure ext_copy_code (key : integer);\r
var\r
i, c, w : integer;\r
begin\r
with ext_tab [ key ] do\r
with ext_open_codes do\r
if wordcount > 0 then\r
begin\r
\r
(* put a warning if it is a call of 'moveg' *)\r
if id='moveg' then error(moveg_warning);\r
\r
if firstword < 0 then\r
begin (* text not in charbuf, position the library-file *)\r
if (file_position = -1) or (-firstword < file_position) then\r
begin\r
extcode_fileix := filrec_max;\r
(*$I-*)\r
reset(ext_pass5);\r
if ioresult <> 0 then\r
begin\r
nofile(concat(rtp35_pathname, i_pass5_extname));\r
end;\r
(*$I+*)\r
file_position := 0;\r
end;\r
for i := 1 to -(file_position + firstword) do extin ( w);\r
end;\r
\r
out_nl;\r
\r
for i := 1 to wordcount do\r
begin\r
if firstword > 0 then\r
w := charbuf [ i + firstword - 1 ]\r
else\r
extin ( w);\r
c := w shr 8;  if c = 10 then out_nl else out_char (chr(c));\r
c := w and 255;  if c = 10 then out_nl else out_char (chr(c));\r
end;\r
if firstword < 0 then (* update file position *)\r
file_position := -firstword + wordcount;\r
\r
end;\r
end; (* procedure ext_copy_code *)\r
\r
\r
procedure ext_scan;\r
const\r
size_of_codedescr = 8; (* no of words in descr, containing date etc *)\r
var\r
i, j, codewords, skipwords, codepos,\r
descr_length, no_of_pages, size_of_page, bytes_on_last_page, kind_of_obj,\r
app, pno, next_word,\r
curkey, prevkey : integer;\r
ident : identifier;\r
paramtab : array [ 1 .. descr_max_param ] of param_descr;\r
found : boolean;\r
param_p: param_ptr;\r
\r
begin\r
\r
extcode_fileix := filrec_max;\r
(*$I-*)\r
reset(ext_pass5);\r
if ioresult <> 0 then\r
begin\r
nofile(concat(rtp35_pathname, i_pass5_extname));\r
end;\r
(*$I+*)\r
extin(next_word);\r
file_position := 0;\r
\r
with ext_open_codes do\r
while not eof(ext_pass5) and (next_word > 0) and (not_resolved > 0) do\r
begin\r
descr_length := next_word;\r
extin(no_of_pages);\r
extin(size_of_page);\r
extin(bytes_on_last_page);\r
extin(kind_of_obj);\r
\r
(* read name *)\r
for i := 1 to 6 do\r
begin\r
extin (app);\r
ident [ i*2-1 ] := chr (app div 256);\r
ident [ i*2   ] := chr (app mod 256);\r
end;\r
for i := 13 to c_size_identifier do ident [ i ] := ' ';\r
\r
(* skip entry points etc *)\r
for i := 1 to 5 do extin (next_word);\r
(*read last param offset*)\r
extin (app);\r
\r
(*skip the free words*)\r
for i := 1 to descr_free_words do extin(next_word);\r
\r
(*read number of params *)\r
extin(pno);\r
if pno > descr_max_param then error (ext_param_number);\r
for i := 1 to pno do\r
with paramtab[ i ] do\r
begin\r
extin (kind);\r
extin (size);\r
end;\r
\r
file_position := descr_length div 2 + file_position;\r
codewords := ((no_of_pages - 1) * size_of_page + bytes_on_last_page + 1) div 2;\r
skipwords := codewords;\r
\r
if (kind_of_obj = 4) or (kind_of_obj = 5) then\r
begin (* open routine in library *)\r
\r
for i := 1 to size_of_codedescr do\r
begin\r
extin (next_word); (* skip date etc *)\r
skipwords := skipwords - 1;\r
codewords := codewords - 1;\r
end;\r
file_position := file_position + size_of_codedescr;\r
\r
\r
curkey := not_resolved;\r
prevkey := -1;\r
codepos := - file_position;\r
\r
repeat\r
with ext_tab [ curkey ] do\r
begin\r
(* total match is: same name and paramlist *)\r
if no_of_param = pno then\r
if id        = ident then\r
begin\r
found := true;  (* assume same param-descr *)\r
param_p:= paramptr;\r
for i := 1 to pno do\r
with paramtab[ i ] do\r
begin\r
if (param_p^.kind<>kind) or (param_p^.size<>size) then\r
found:= false;\r
param_p:= param_p^.next_param;\r
end;\r
if found then\r
begin\r
state := ext_open;\r
appetite := app;\r
wordcount := codewords;\r
\r
if prevkey = -1 then\r
not_resolved := decl_link\r
else\r
ext_tab [ prevkey ] . decl_link := decl_link;\r
curkey := prevkey;\r
\r
if skipwords > 0 then\r
if skipwords <= ext_max_routine then\r
(* routine is not too large *)\r
if cur_word_ptr + skipwords <= ext_max_charbuf then\r
begin (* there is room in charbuf *)\r
codepos := cur_word_ptr;\r
for i := 1 to skipwords do\r
extin (charbuf [ i + codepos - 1 ]);\r
cur_word_ptr := cur_word_ptr + skipwords;\r
skipwords := 0;\r
end;\r
\r
firstword := codepos;\r
end;\r
end;\r
prevkey := curkey;\r
curkey := decl_link;\r
end;\r
until curkey <= 0;\r
end;\r
\r
(* skip any remaining part of code-body *)\r
for i := 1 to skipwords do extin(next_word);\r
file_position := file_position + codewords;\r
(* skip external link part *)\r
extin (pno);\r
file_position := file_position + 1;\r
for i := 1 to pno do\r
begin\r
(* skip external name *)\r
for j := 1 to 6 do extin (next_word);\r
file_position := file_position + 6;\r
(* skip parameter list *)\r
extin (j); (* number of params *)\r
file_position := file_position + 2*j + 1;\r
for j := 2*j downto 1 do extin (next_word);\r
(* skip number of uses *)\r
extin (next_word);\r
file_position := file_position + 1;\r
end;\r
(* skip internal link part *)\r
extin (pno);\r
pno := pno * 4; (* four words per entry *)\r
for i := 1 to pno do extin (next_word);\r
file_position := file_position + pno + 1;\r
\r
(* now the libraryfile is positioned at start of next entry *)\r
extin(next_word);\r
end; (* scan of library file *)\r
\r
(* classify all remaining ext_declared as closed-routines *)\r
while not_resolved > 0 do\r
with ext_tab [ not_resolved ] do\r
begin\r
state := ext_closed;\r
not_resolved := decl_link;\r
end;\r
\r
end; (* procedure extscan *)\r
\r
\r
function getkind (key: integer) : callmodes;\r
begin\r
with ext_tab [ key ] do\r
begin\r
if state = ext_declared then ext_scan;\r
if state = ext_open then\r
getkind := open_call\r
else\r
getkind := ext_call;\r
end;\r
end; (* procedure getkind *)\r
\r
\r
function ext_lookup (var key: integer; look_id: identifier) : callmodes;\r
var\r
i : integer;\r
found : boolean;\r
begin\r
i := 1;\r
found := false;\r
repeat\r
with ext_tab [ i ] do\r
if state = ext_unused then\r
i := ext_tab_max + 1\r
else\r
if id = look_id then found := true\r
else\r
i := i + 1;\r
until found or (i > ext_tab_max);\r
if not found then error (compiler_error);\r
key := i;\r
ext_lookup := getkind (i);\r
end; (* procedure getkind *)\r
\r
\r
procedure  descr_end;\r
\r
var\r
i, j, no_of_entries : integer;\r
param_p: param_ptr;\r
\r
begin\r
\r
writeln (out_pass5, 'd.');\r
writeln (out_pass5, descr.name);\r
writeln (out_pass5, descr.kind);\r
writeln (out_pass5);\r
(* if it is a closed routine the entrypoint is the second instruction. This is *)\r
(*handelt by adding the length of the first instruction to the symbolic *)\r
(* value : entry_point *)\r
if (descr.kind = 1(*process*)) or\r
 (descr.kind =  2(*procedure*)) or (descr.kind = 3(*function*)) then\r
writeln(out_pass5,descr.entry_point, '+', jump_across_first)\r
else  (*open routine =  4 or 5*)\r
writeln(out_pass5,descr.entry_point);\r
writeln (out_pass5, descr.exception_point);\r
writeln (out_pass5);\r
if enforced_create_size <> 0 then\r
begin\r
writeln (out_pass5, enforced_create_size);\r
if descr.kind = 1 (* process *) then\r
enforced_create_size := 0;\r
end\r
else\r
\r
writeln (out_pass5, descr.default_appetite);\r
writeln (out_pass5, descr.last_param_offset);\r
writeln (out_pass5);\r
for i := 1 to descr_free_words do writeln(out_pass5,descr.free_words[i]);\r
writeln(out_pass5);\r
\r
writeln (out_pass5, descr.no_of_params);\r
for i := 1 to descr.no_of_params do\r
with descr.param [ i ] do\r
writeln (out_pass5, kind, ',', size);\r
writeln (out_pass5);\r
\r
no_of_entries := 0;\r
for i := 1 to ext_tab_max do\r
with ext_tab [ i ] do\r
if state = ext_closed (* closed routine *) then\r
begin\r
if no_of_uses > 0 then\r
no_of_entries := no_of_entries + 1\r
end;\r
\r
writeln( out_pass5, no_of_entries );\r
\r
for i := 1 to ext_tab_max do\r
with ext_tab [ i ] do\r
begin\r
if state = ext_closed (* closed routine *) then\r
begin\r
if no_of_uses > 0 then\r
begin\r
writeln (out_pass5);\r
writeln (out_pass5, id);\r
mess_summary_line( id, -1 (* external routine !! *), 0, 0, no_of_uses, false, 0 );\r
writeln (out_pass5, no_of_param);\r
param_p:= paramptr;\r
for j := 1 to no_of_param do\r
with param_p^ do\r
begin\r
writeln (out_pass5, kind, ',', size);\r
param_p:= next_param;\r
end; (* with *)\r
\r
writeln (out_pass5, no_of_uses);\r
writeln (out_pass5, e_name, '#', i:1);\r
end;\r
end;\r
no_of_uses := 0;\r
end;\r
end; (* descr_end *)\r
\r
\r
procedure init_trap_table;\r
var\r
step : integer;\r
begin\r
if trap_nr_table = nil then new(trap_nr_table);\r
with trap_nr_table ^ do\r
begin\r
for step := 2 to 255 do trap_entry [ step ] := 0; (* unused *)\r
trap_entry [ 0 ] := 1; (* reserved for main program *)\r
trap_entry [ 1 ] := 1; (* reserved for garbage and overload *)\r
end; (* with *)\r
no_of_measure_recs := 1 (* entry(0) for main *) + 1 (* entry(1) for overload *);\r
current_trap_nr := 0; (* main *)\r
end;\r
\r
\r
function new_trap_entry( ident : integer ) : integer;\r
(* if more free entries then find one, else use entry(1) *)\r
var\r
trap_nr : integer;\r
begin\r
trap_nr := 1;\r
if no_of_measure_recs < 256 then (* more free *)\r
with trap_nr_table ^ do\r
begin\r
no_of_measure_recs := no_of_measure_recs + 1;\r
trap_nr := abs( ident ) mod 256;\r
while trap_entry [ trap_nr ] <> 0 (* free *) do\r
trap_nr := (trap_nr + 1) mod 256;\r
trap_entry [ trap_nr ] := ident;\r
end; (* with *)\r
new_trap_entry := trap_nr;\r
end; (* new trap entry *)\r
\r
\r
function get_trap_nr( ident : integer ) : integer;\r
var\r
first_guess, trap_nr : integer;\r
begin\r
trap_nr := abs( ident ) mod 256;\r
first_guess := trap_nr;\r
get_trap_nr := 1; (* in case of miss entry(1) is used *)\r
with trap_nr_table ^ do\r
repeat\r
if trap_entry [ trap_nr ] <> ident then\r
trap_nr := (trap_nr + 1) mod 256\r
else\r
begin\r
first_guess := trap_nr; (* exit repeat *)\r
get_trap_nr := trap_nr;\r
end;\r
until trap_nr = first_guess;\r
end; (* get trap nr *)\r
\r
\r
\r
\r
\r
procedure code_call_proc\r
(use: usemodes; callkind: callmodes; key, niv, lix, paramlength,size_of_function_result: integer);\r
var\r
dummy,step,stop,level : integer;\r
\r
begin\r
\r
if callkind <> int_call then\r
with ext_tab [ key ] do\r
begin\r
no_of_uses := no_of_uses + 1;\r
if no_of_uses = 1 then\r
begin\r
mode := use;\r
if trap_code and ( callkind = ext_call ) then\r
dummy := new_trap_entry( -key ); (* externals are marked with negative identification *)\r
end;\r
if mode <> use then\r
error(inconsistent_use);\r
end;\r
\r
case callkind of\r
\r
open_call:\r
begin\r
with ext_tab[key] do\r
begin\r
(*check and adjust hw stack if nessesary *)\r
if paramlength <> hw_stack_size then\r
begin\r
if paramlength > max_hw_stack then (*not enough room for parameters empty stack*)\r
out_resta(0)\r
else\r
if size_of_function_result <> 0 then\r
begin (*simple function*)\r
if (appetite + paramlength) > max_hw_stack then\r
(*not room for both appetite and parameters . assure exactly parameters*)\r
out_resta(paramlength)\r
else\r
if (hw_stack_size + appetite) > max_hw_stack then\r
(*overflow make room for appetite*)\r
out_resta(max_hw_stack-appetite)\r
else\r
if paramlength > hw_stack_size then out_resta(paramlength);\r
end (*simple function*)\r
else (*procedure or non simple function*)\r
(*push exactly parameters to the stack*)\r
out_resta(paramlength)\r
end;\r
\r
(*copy the open routine *)\r
\r
ext_copy_code(key);\r
\r
(*adjust stack pointers*)\r
context_eval(appetite);\r
context_eval(-appetite-paramlength+size_of_function_result);\r
(*hw_stackpointer*)\r
if size_of_function_result <> 0 then\r
begin (*simple function *)\r
if hw_stack_size = 0 then hw_stack_size :=  size_of_function_result\r
else\r
hw_stack_size := hw_stack_size - paramlength + size_of_function_result;\r
\r
(*check consistence*)\r
if (hw_stack_size < 0) or (hw_stack_size > max_hw_stack) then\r
hw_stack_error(simple_open_function);\r
end\r
else\r
(*procedure or non simple function*)\r
hw_stack_size := 0;\r
end;\r
end;\r
\r
int_call,\r
ext_call:\r
begin\r
if trap_code then\r
begin\r
out_op_int(op_mtrh,trapenter);\r
out_start_param;\r
out_integer(current_trap_nr);\r
end;\r
level := c.niv - niv;\r
case level of\r
0: out_specopcode(op_pcals0,-paramlength);\r
1: out_specopcode(op_pcals1,-paramlength);\r
\r
else begin\r
(*level > 1*)\r
(*move addr of i frame on top of stack*)\r
out_i_frame_addr(level);\r
out_specopcode(op_pcals,-paramlength);\r
end;\r
end;\r
out_start_param;\r
if callkind = int_call then\r
begin\r
out_lix(r_name,lix);\r
out_char('+');\r
out_integer(jump_across_first);\r
end\r
else\r
begin\r
out_lix (e_name, key);\r
if trap_code then\r
begin\r
out_op_int(op_mtrh,trapreturn);\r
out_start_param;\r
out_integer(get_trap_nr(-key));\r
end;\r
end;\r
\r
end;\r
\r
end; (* case *)\r
\r
end; (* procedure code_call_proc *)\r
\r
\r
procedure  code_initvar( kind, offset, type_o : integer;\r
       var ref_count : integer; var shadow_count : integer);\r
forward;\r
\r
\r
procedure get_niv_offset ( var v : varaddr_descr );\r
\r
begin\r
with v do\r
begin\r
\r
kind := addr;\r
niv := in_integer; offset := in_integer;\r
size := 0;\r
if niv = c.niv then access := l_frame\r
else\r
if niv = const_niv_0 then access := g_frame\r
else\r
access := i_frame;\r
\r
end;\r
end; (* get niv, offset *)\r
\r
\r
\r
procedure  load_address( var  v : varaddr_descr; offset_zero : boolean);\r
\r
(* the execution of this procedure enforces  'v.kind' = 'addr'    *)\r
\r
begin\r
\r
case  v.kind  of\r
\r
addr:\r
  begin\r
case v.access of\r
g_frame: out_op_int(op_reagd,v.offset);\r
l_frame: out_op_int(op_reald,v.offset);\r
i_frame: out_op_rea(c.niv - v.niv, v.offset);\r
(*s_frame not possible here*)\r
end; (*case*)\r
\r
v.kind := stack_addr;   v.offset := 0;   v.access := s_frame;\r
end;\r
\r
stack_addr:\r
  if  ( offset_zero ) and ( v.offset <> 0 ) then\r
begin\r
out_opcode( op_reasd );\r
out_p_int( v.offset );\r
\r
v.offset := 0\r
end;\r
\r
packed_arr: error (compiler_error);\r
\r
end\r
\r
end;\r
\r
\r
\r
procedure  code_exc_trigger( exception_no : integer);\r
\r
begin\r
\r
out_opcode( op_rechw );\r
out_expr (id_cpexcfirst, exception_no);\r
\r
out_opcode( op_mtrs );\r
out_comment( '   trigger exception no. : ' ); out_integer( exception_no )\r
\r
\r
end;\r
\r
\r
procedure  code_allocpool( kind, offset, number, size : integer);\r
\r
var\r
w_offset,  key, refs : integer;\r
w_size : word;\r
begin\r
\r
(*  init. the semaphore of the pool to nil :  *)\r
\r
if (kind = 2) and (number > 0) then\r
begin\r
\r
out_opcode( op_revpd )\r
\r
end;\r
\r
code_initvar( kind, offset, 6, refs, refs);\r
\r
out_comment( '   start init. of pool. ' );\r
\r
\r
(*  prepare call of the routine: _initpool_rc  :  *)\r
if number > 0 then\r
begin\r
\r
(*  generate the actual parameters:  *)\r
\r
if kind = 1 then\r
begin\r
out_op_int (op_reald, offset);\r
\r
end\r
\r
else\r
if kind = 2 then\r
begin\r
if offset <> 0 then\r
out_op_int( op_reasd, offset );\r
\r
\r
end\r
\r
else\r
error(compiler_error);\r
\r
out_op_int (op_rechw, number);\r
(*$R-*)\r
w_size := size;\r
(*$R+*)\r
if odd( w_size ) then w_size := w_size + 1;\r
w_size := w_size div 2;\r
size := w_size;\r
\r
out_op_int (op_rechw, size);\r
\r
code_call_proc (sys_use, ext_lookup (key, '_initpool_rc'), key, const_niv_0, 0,\r
4 (* address *) + 2 (* number *) + 2 (* size *),0 );\r
end; (* if number > 0 *)\r
\r
end (* code_allocpool *);\r
\r
\r
«eof»