"AL HARTMANN INFORMATION SCIENCE CALIFORNIA INSTITUTE OF TECHNOLOGY PASADENA, CALIFORNIA 91109 PDP 11/45 CONCURRENT PASCAL COMPILER PASS 3: SCOPE ANALYSIS SEPTEMBER 1974" (NUMBER) "########### # PREFIX # ###########" CONST EOL = '(:10:)'; FF = '(:12:)'; EOM = '(:25:)'; PRINTLIMIT = 18; MAXDIGIT = 6; WORDLENGTH = 2 "BYTES"; REALLENGTH = 8 "BYTES"; SETLENGTH = 16 "BYTES"; LISTOPTION = 0; SUMMARYOPTION = 1; TESTOPTION = 2; CHECKOPTION = 3; CODEOPTION = 4; NUMBEROPTION = 5; TYPE FILE = 1..2; CONST IDLENGTH = 12; TYPE IDENTIFIER = ARRAY (.1..IDLENGTH.) OF CHAR; TYPE POINTER = @ INTEGER; OPTION = LISTOPTION..NUMBEROPTION; PASSPTR = @PASSLINK; PASSLINK = RECORD OPTIONS: SET OF OPTION; LABELS, BLOCKS, CONSTANTS, RESETPOINT: INTEGER; TABLES: POINTER END; TYPE ARGTAG = (NILTYPE, BOOLTYPE, INTTYPE, IDTYPE, PTRTYPE); TYPE ARGTYPE = RECORD CASE TAG: ARGTAG OF NILTYPE, BOOLTYPE: (BOOL: BOOLEAN); INTTYPE: (INT: INTEGER); IDTYPE: (ID: IDENTIFIER); PTRTYPE: (PTR: PASSPTR) END; CONST MAXARG = 10; TYPE ARGLIST = ARRAY (.1..MAXARG.) OF ARGTYPE; CONST PAGELENGTH = 256; TYPE PAGE = ARRAY (.1..PAGELENGTH.) OF INTEGER; PROCEDURE READ(VAR C: CHAR); PROCEDURE WRITE(C: CHAR); PROCEDURE NOTUSED1; PROCEDURE NOTUSED2; PROCEDURE GET(F: FILE; P: INTEGER; VAR BLOCK: UNIV PAGE); PROCEDURE PUT(F: FILE; P: INTEGER; BLOCK: UNIV PAGE); FUNCTION FILE_LENGTH(F:FILE): INTEGER; PROCEDURE MARK(VAR TOP: INTEGER); PROCEDURE RELEASE(TOP: INTEGER); PROGRAM MAIN(VAR PARAM: ARGLIST); "############################################# # PASS(VAR OK: BOOLEAN; VAR LINK: POINTER) # #############################################" CONST "INPUT OPERATORS" EOM1=1; CONST_ID1=2; CONST_DEF1=3; TYPE_ID1=4; TYPE_DEF1=5; VAR_ID1=6; VAR_LIST1=7; EVAR_LIST1=8; INITS_DEF1=9; INITS_END1=10; PROC_ID1=11; PROC_DEF1=12; PROCE_DEF1=13; PROC_END1=14; PROCE_END1=15; FUNC_ID1=16; FUNC_DEF1=17; FUNCE_DEF1=18; FUNC_END1=19; FUNCE_END1=20; PROG_ID1=21; PROG_DEF1=22; INTF_ID1=23; TYPE1=24; ENUM1=25; ENUM_ID1=26; ENUM_DEF1=27; SUBR_DEF1=28; SET_DEF1=29; ARRAY_DEF1=30; REC1=31; FIELD_ID1=32; FIELDLIST1=33; REC_DEF1=34; CLASS1=35; MONITOR1=36; PROCESS1=37; STACK1=38; PSTART1=39; PARM_ID1=40; PARM_TYPE1=41; UNIV_TYPE1=42; CPARMLIST1=43; VPARMLIST1=44; BODY1=45; BODY_END1=46; ANAME1=47; STORE1=48; CALL_NAME1=49; CALL1=50; ARG_LIST1=51; ARG1=52; FALSEJUMP1=53; DEF_LABEL1=54; JUMP_DEF1=55; INTF1=56; DEF_CASE1=57; CASE1=58; JUMP1=59; END_CASE1=60; ADDRESS1=61; FOR_STORE1=62; FOR_LIM1=63; FOR_UP1=64; FOR_DOWN1=65; WITH_VAR1=66; WITH_TEMP1=67; WITH1=68; INIT_NAME1=69; INIT1=70; VALUE1=71; LT1=72; EQ1=73; GT1=74; LE1=75; NE1=76; GE1=77; IN1=78; UPLUS1=79; UMINUS1=80; PLUS1=81; MINUS1=82; OR1=83; STAR1=84; SLASH1=85; DIV1=86; MOD1=87; AND1=88; FNAME1=89; NOT1=90; EMPTY_SET1=91; INCLUDE1=92; FUNCTION1=93; CALL_FUNC1=94; NAME1=95; COMP1=96; SUB1=97; ARROW1=98; CONSTANT1=99; REAL1=100; FREAL1=101; INTEGER1=102; FINTEGER1=103; CHAR1=104; FCHAR1=105; STRING1=106; FSTRING1=107; NEW_LINE1=108; LCONST1=109; MESSAGE1=110; PROCE_ID1=111; FUNCE_ID1=112; PEND1=113; CASE_JUMP1=114; "OUTPUT OPERATORS" EOM2=1; TYPE_DEF2=2; NEW_NOUN2=3; VAR_LIST2=4; EVAR_LIST2=5; INITS_DEF2=6; PROC_DEF2=7; PROCE_DEF2=8; FUNC_DEF2=9; FUNCE_DEF2=10; PROG_DEF2=11; TYPE2=12; ENUM_DEF2=13; SUBR_DEF2=14; SET_DEF2=15; INTF2=16; ARRAY_DEF2=17; REC2=18; FIELDLIST2=19; REC_DEF2=20; CLASS2=21; MONITOR2=22; PROCESS2=23; STACK2=24; PSTART2=25; PARM_TYPE2=26; UNIV_TYPE2=27; CPARMLIST2=28; VPARMLIST2=29; BODY2=30; BODY_END2=31; ADDRESS2=32; RESULT2=33; STORE2=34; CALL_PROC2=35; CALL_PROG2=36; INTF_ID2=37; PARM2=38; FALSEJUMP2=39; DEF_LABEL2=40; JUMP_DEF2=41; FUNCF_DEF2=42; JUMP2=43; CASE_LIST2=44; FOR_STORE2=45; FOR_LIM2=46; FOR_UP2=47; FOR_DOWN2=48; WITH_VAR2=49; WITH_TEMP2=50; WITH2=51; INIT2=52; VALUE2=53; LT2=54; EQ2=55; GT2=56; LE2=57; NE2=58; GE2=59; IN2=60; UPLUS2=61; UMINUS2=62; PLUS2=63; MINUS2=64; OR2=65; STAR2=66; SLASH2=67; DIV2=68; MOD2=69; AND2=70; NOT2=71; EMPTY_SET2=72; INCLUDE2=73; FUNCTION2=74; CALL_FUNC2=75; ROUTINE2=76; VAR2=77; ARROW2=78; VCOMP2=79; RCOMP2=80; SUB2=81; INDEX2=82; REAL2=83; STRING2=84; LCONST2=85; MESSAGE2=86; NEW_LINE2=87; FWD_DEF2=88; CHK_TYPE2=89; PROCF_DEF2=90; UNDEF2=91; PEND2=92; CASE_JUMP2=93; "OTHER CONSTANTS" NOUN_MAX=700; MIN_CASE=0; MAX_CASE=127; THIS_PASS=3; SPELLING_MAX=700; OPERAND_MAX=150; UPDATE_MAX=100; UPDATE_MAX1=101; MAX_LEVEL=15; "MODES" CLASS_MODE=1; MONITOR_MODE=2; PROCESS_MODE=3; PROC_MODE=4; PROCE_MODE=5; FUNC_MODE=6; FUNCE_MODE=7; PROGRAM_MODE=8; "STANDARD SPELLING/NOUN INDICES" XUNDEF=0; XFALSE=1; XTRUE=2; XINTEGER=3; XBOOLEAN=4; XCHAR=5; XQUEUE=6; XABS=7; XATTRIBUTE=8; XCHR=9 ; XCONTINUE=10; XCONV=11; XDELAY=12; XEMPTY=13; XIO=14; XORD=15; XPRED=16; XSTOP=17; XREALTIME=18; XSETHEAP=19; XSUCC=20; XTRUNC=21; XSTART=22; XWAIT=23; XREAL=24; "STANDARD NOUN INDICES" ZARITHMETIC=25; ZINDEX=26; ZPASSIVE=27; ZVPARM=28; ZCPARM=29; ZSPARM=30; ZWITH=31; "ERRORS" UNRES_ERROR=1; AMBIGUITY_ERROR=2; ABORT_ERROR=3; CONSTID_ERROR=4; SUBR_ERROR=5; FEW_ARGS_ERROR=6; ARG_LIST_ERROR=7; MANY_ARGS_ERROR=8; CASERANGE_ERROR=9; CASETYPE_ERROR=10; AMBICASE_ERROR=11; WITH_ERROR=12; INIT_ERROR=13; PROC_USE_ERROR=14; NAME_ERROR=15; COMP_ERROR=16; SUB_ERROR=17; INTERFACE_ERROR=18; CALL_NAME_ERROR=19; "MISCELANEOUS" NOT_POSSIBLY_FORWARD=FALSE; POSSIBLY_FORWARD=TRUE; OUTPUT=TRUE; RETAIN=FALSE; PROC_TYPE= 1; STD_LEVEL=0; GLOBAL_LEVEL=1; TEXT_LENGTH = 18; INFILE = 1; OUTFILE = 2; TYPE ENTRY_KIND=(INDEX_CONST,REAL_CONST,STRING_CONST,VARIABLE, PARAMETER,FIELD,SCALAR_KIND,SYSCOMP_KIND,ROUTINE_KIND,SET_KIND, PROGRAM_KIND,POINTER_KIND,ARRAY_KIND,RECORD_KIND,WITH_KIND,UNDEF_KIND); OPERAND_CLASS=(VAR_CLASS,ROUTINE_CLASS,ICONST_CLASS,RCONST_CLASS,SCONST_CLASS, DEF_CLASS,UNDEF_CLASS,FCONST_CLASS,PROGRAM_CLASS,CASE_LABEL, FUNCVALUE_CLASS); ERROR_NOTE=(YES,NO,SUPPRESS); SPELLING_INDEX=0..SPELLING_MAX; NOUN_INDEX = 0..NOUN_MAX; STACK_INDEX=0..OPERAND_MAX; UNIV_SET = ARRAY (.1..8.) OF INTEGER; UPDATE_INDEX=0..UPDATE_MAX; NAME_PTR=@NAME_REC; VARIANT_PTR=@VARIANT_REC; ENTRY_PTR=@ENTRY_REC; ENTRY_REC= RECORD NOUN:NOUN_INDEX; CASE KIND:ENTRY_KIND OF INDEX_CONST:(CONST_TYPE:NOUN_INDEX; CONST_VAL:INTEGER); REAL_CONST:(REAL_DISP:INTEGER); STRING_CONST:(STRING_LENGTH,STRING_DISP:INTEGER); VARIABLE:(VAR_TYPE:ENTRY_PTR); PARAMETER:(PARM_TYPE,NEXT_PARM:ENTRY_PTR); FIELD:(FIELD_TYPE:ENTRY_PTR; VARIANT:VARIANT_PTR); SCALAR_KIND:(RANGE_TYPE:NOUN_INDEX); SYSCOMP_KIND:(INIT_STAT:ENTRY_PTR; ENTRY_NAME:NAME_PTR); ROUTINE_KIND:(ROUT_PARM:ENTRY_PTR; ROUT_TYPE:NOUN_INDEX); PROGRAM_KIND:(PROG_PARM:ENTRY_PTR; INTERFACE:NAME_PTR); POINTER_KIND:(OBJECT_TYPE:ENTRY_PTR); ARRAY_KIND:(INDEX_TYPE:NOUN_INDEX; EL_TYPE:ENTRY_PTR); WITH_KIND:(WITH_TYPE:NOUN_INDEX); RECORD_KIND:(FIELD_NAME:NAME_PTR) END; OPERAND= RECORD CASE CLASS:OPERAND_CLASS OF VAR_CLASS:(VTYPE:ENTRY_PTR); PROGRAM_CLASS:(PROG,PPARM:ENTRY_PTR); ROUTINE_CLASS:(ROUT,PARM:ENTRY_PTR); FUNCVALUE_CLASS:(FUNC_TYPE:NOUN_INDEX); ICONST_CLASS:(ICONST_TYPE:NOUN_INDEX; ICONST_VAL:INTEGER); RCONST_CLASS:(RCONST_DISP:INTEGER); SCONST_CLASS:(SCONST_LENGTH,SCONST_DISP:INTEGER); CASE_LABEL:(LABEL,INDEX:INTEGER); DEF_CLASS:(DEF_ENTRY:ENTRY_PTR; DEF_SPIX:SPELLING_INDEX) END; NAME_ACCESS=(GENERAL,EXTERNAL,INTERNAL,INCOMPLETE, UNRESOLVED,QUALIFIED,FUNCTIONAL,UNDEFINED); LEVEL_INDEX=0..MAX_LEVEL; SPELLING_ENTRY= RECORD ENTRY:ENTRY_PTR; LEVEL:LEVEL_INDEX; ACCESS:NAME_ACCESS END; DISPLAY_REC= RECORD BASE:0..UPDATE_MAX1; LEVEL_ENTRY:ENTRY_PTR; PREV_SYSCOMP:LEVEL_INDEX; PREV_LIST: NAME_PTR END; UPDATE_REC= RECORD UPDATE_SPIX:SPELLING_INDEX; OLD_ENTRY:SPELLING_ENTRY END; PACKED_SET=INTEGER; VARIANT_REC= RECORD TAG_DISP:INTEGER; LABEL_SET:PACKED_SET; NEXT_VARIANT:VARIANT_PTR END; NAME_REC= RECORD NAME_SPIX:SPELLING_INDEX; NAME_ENTRY:ENTRY_PTR; NEXT_NAME:NAME_PTR END; TEXT_TYPE = ARRAY (.1..TEXT_LENGTH.) OF CHAR; VAR INTER_PASS_PTR: PASSPTR; PARAMETERIZED,CONSTANTS: SET OF OPERAND_CLASS; QUALIFIABLE,TYPES,CONST_KINDS: SET OF ENTRY_KIND; NAME_LIST, OLD_NAMES: NAME_PTR; HALT,TEST,RESOLUTION: BOOLEAN; OPS:ARRAY (.STACK_INDEX.) OF OPERAND; UENTRY,FIRST_PARM,THIS_PARM: ENTRY_PTR; COMP_MODES,ENTRY_MODES: SET OF CLASS_MODE..PROGRAM_MODE; INACCESSIBLE,ENTRY_ACCESS,OP_ACCESS: SET OF NAME_ACCESS; LABELS: ARRAY (.MIN_CASE..MAX_CASE.) OF INTEGER; THIS_UPDATE: UPDATE_INDEX; T:STACK_INDEX; ENUM_VAL,THIS_LABEL,SY,CONST_DISP, UNRES_COUNT: INTEGER; ENUM_TYPE,THIS_NOUN: NOUN_INDEX; UPDATES:ARRAY (.UPDATE_INDEX.) OF UPDATE_REC; DISPLAY:ARRAY (.LEVEL_INDEX.) OF DISPLAY_REC; SYSCOMP_LEVEL,THIS_LEVEL,BODY_LEVEL: LEVEL_INDEX; SPELLING_TABLE:ARRAY (.SPELLING_INDEX.) OF SPELLING_ENTRY; "############################" "COMMON TEST OUTPUT MECHANISM" "############################" PRINTED: INTEGER; OK: BOOLEAN; "PASS1 TO 6: OK = NOT DISK OVERFLOW PASS7: OK = NOT DISK OVERFLOW & PROGRAM CORRECT" PAGE_IN: PAGE; PAGES_IN, WORDS_IN: INTEGER; PAGE_OUT: PAGE; PAGES_OUT, WORDS_OUT: INTEGER; PROCEDURE PRINT_TEXT (TEXT: TEXT_TYPE); VAR I: INTEGER; BEGIN WRITE(EOL); FOR I:= 1 TO TEXT_LENGTH DO WRITE(TEXT(.I.)); WRITE(EOL) END; PROCEDURE FILE_LIMIT; BEGIN PRINT_TEXT('PASS 3: FILE_LIMIT'); OK:= FALSE END; PROCEDURE INIT_PASS (VAR LINK: PASSPTR); BEGIN LINK:= PARAM(.2.).PTR; OK:= TRUE; PAGES_IN:= 1; WORDS_IN:= PAGELENGTH; PAGES_OUT:= 1; WORDS_OUT:= 0 END; PROCEDURE NEXT_PASS (LINK: PASSPTR); BEGIN IF WORDS_OUT > 0 THEN IF PAGES_OUT > FILE_LENGTH(OUTFILE) THEN FILE_LIMIT ELSE PUT(OUTFILE, PAGES_OUT, PAGE_OUT); WITH PARAM(.1.) DO BEGIN TAG:= BOOLTYPE; BOOL:=OK END; WITH PARAM(.2.) DO BEGIN TAG:= PTRTYPE; PTR:= LINK END; WITH PARAM(.4.) DO BEGIN TAG:= INTTYPE; INT:= PAGES_OUT END; END; PROCEDURE READ_IFL (VAR I: INTEGER); BEGIN IF WORDS_IN = PAGELENGTH THEN BEGIN IF PAGES_IN > FILE_LENGTH(INFILE) THEN FILE_LIMIT ELSE BEGIN GET(INFILE, PAGES_IN, PAGE_IN); PAGES_IN:= SUCC(PAGES_IN) END; WORDS_IN:= 0 END; WORDS_IN:= SUCC(WORDS_IN); I:= PAGE_IN(.WORDS_IN.) END; PROCEDURE WRITE_IFL (I: INTEGER); BEGIN WORDS_OUT:= SUCC(WORDS_OUT); PAGE_OUT(.WORDS_OUT.):= I; IF WORDS_OUT = PAGELENGTH THEN BEGIN IF PAGES_OUT > FILE_LENGTH(OUTFILE) THEN FILE_LIMIT ELSE BEGIN PUT(OUTFILE, PAGES_OUT, PAGE_OUT); PAGES_OUT:= SUCC(PAGES_OUT) END; WORDS_OUT:= 0 END END; PROCEDURE PRINTABS(ARG: INTEGER); VAR T: ARRAY (.1..MAXDIGIT.) OF CHAR; REM, DIGIT, I: INTEGER; BEGIN REM:= ARG; DIGIT:= 0; REPEAT DIGIT:= DIGIT + 1; T(.DIGIT.):= CHR(ABS(REM MOD 10) + ORD('0')); REM:= REM DIV 10; UNTIL REM = 0; FOR I:= DIGIT DOWNTO 1 DO WRITE(T(.I.)); FOR I:= DIGIT + 1 TO MAXDIGIT DO WRITE(' '); END; PROCEDURE PRINTEOL; BEGIN WRITE(EOL); PRINTED:= 0 END; PROCEDURE PRINTFF; VAR I:INTEGER; BEGIN PRINTEOL; FOR I:=1 TO 130 DO WRITE('3'); PRINTEOL END; PROCEDURE PRINTOP(OP: INTEGER); BEGIN IF PRINTED = PRINTLIMIT THEN PRINTEOL; WRITE('C'); PRINTABS(OP); PRINTED:= PRINTED + 1; END; PROCEDURE PRINTARG(ARG: INTEGER); BEGIN IF PRINTED = PRINTLIMIT THEN PRINTEOL; IF ARG < 0 THEN WRITE('-') ELSE WRITE(' '); PRINTABS(ARG); PRINTED:= PRINTED + 1; END; "NOTE: A PASS RUNNING WITH TEST OUTPUT SHOULD START BY CALLING PROCEDURE PRINTFF" "#############" "PASS ROUTINES" "#############" PROCEDURE PUT_ARG(ARG:INTEGER); BEGIN WRITE_IFL(ARG); IF TEST THEN PRINTARG(ARG) END; PROCEDURE PUT0(OP:INTEGER); BEGIN WRITE_IFL(OP); IF TEST THEN PRINTOP(OP) END; PROCEDURE PUT1(OP,ARG:INTEGER); BEGIN WRITE_IFL(OP); WRITE_IFL(ARG); IF TEST THEN BEGIN PRINTOP(OP); PRINTARG(ARG) END END; PROCEDURE PUT2(OP,ARG1,ARG2:INTEGER); BEGIN WRITE_IFL(OP); WRITE_IFL(ARG1); WRITE_IFL(ARG2); IF TEST THEN BEGIN PRINTOP(OP); PRINTARG(ARG1); PRINTARG(ARG2) END END; PROCEDURE PUT3(OP,ARG1,ARG2,ARG3:INTEGER); BEGIN PUT2(OP,ARG1,ARG2); PUT_ARG(ARG3) END; PROCEDURE PUT4(OP,ARG1,ARG2,ARG3,ARG4:INTEGER); BEGIN PUT3(OP,ARG1,ARG2,ARG3); PUT_ARG(ARG4) END; PROCEDURE IGNORE1(OP:INTEGER); VAR ARG:INTEGER; BEGIN READ_IFL(ARG); PUT1(OP,ARG) END; PROCEDURE IGNORE2(OP:INTEGER); VAR ARG1,ARG2:INTEGER; BEGIN READ_IFL(ARG1); READ_IFL(ARG2); PUT2(OP,ARG1,ARG2) END; PROCEDURE IGNORE3(OP:INTEGER); VAR ARG1,ARG2,ARG3:INTEGER; BEGIN READ_IFL(ARG1); READ_IFL(ARG2); READ_IFL(ARG3); PUT3(OP,ARG1,ARG2,ARG3) END; PROCEDURE LCONST; VAR LENGTH,I,ARG:INTEGER; BEGIN READ_IFL(LENGTH); PUT1(LCONST2,LENGTH); CONST_DISP:=CONST_DISP+LENGTH; FOR I:=1 TO LENGTH DIV 2 DO BEGIN READ_IFL(ARG); PUT_ARG(ARG) END END; PROCEDURE ERROR(NUMBER:INTEGER); BEGIN PUT2(MESSAGE2,THIS_PASS,NUMBER); END; PROCEDURE ABORT; BEGIN ERROR(ABORT_ERROR); HALT:=TRUE END; "##############" "INITIALIZATION" "##############" PROCEDURE STD_ID(VAR STD_ENTRY:ENTRY_PTR; INDEX:SPELLING_INDEX); BEGIN NEW(STD_ENTRY); STD_ENTRY@.NOUN:=INDEX; WITH SPELLING_TABLE(.INDEX.) DO BEGIN ENTRY:=STD_ENTRY; LEVEL:=STD_LEVEL; ACCESS:=GENERAL END END; PROCEDURE STD_CONST(CONST_INDEX,TYPE_INDEX:SPELLING_INDEX; CONST_VALUE:INTEGER); VAR CONST_ENTRY:ENTRY_PTR; BEGIN STD_ID(CONST_ENTRY,CONST_INDEX); WITH CONST_ENTRY@ DO BEGIN KIND:=INDEX_CONST; CONST_TYPE:=TYPE_INDEX; CONST_VAL:=CONST_VALUE END END; PROCEDURE STD_PARM(VAR PARM_ENTRY:ENTRY_PTR; PARMTYPE:ENTRY_PTR; PARM_INDEX:NOUN_INDEX); BEGIN NEW(PARM_ENTRY); WITH PARM_ENTRY@ DO BEGIN NOUN:=PARM_INDEX; KIND:=PARAMETER; PARM_TYPE:=PARMTYPE; NEXT_PARM:=NIL END END; PROCEDURE STD_ENTRY(VAR E:ENTRY_PTR; INDEX:NOUN_INDEX); BEGIN NEW(E); WITH E@ DO BEGIN NOUN:=INDEX; KIND:=UNDEF_KIND END END; PROCEDURE STD_ROUT(ROUT_INDEX,ROUTTYPE:NOUN_INDEX; FIRST_PARM:ENTRY_PTR); VAR ROUT_ENTRY:ENTRY_PTR; BEGIN STD_ID(ROUT_ENTRY,ROUT_INDEX); WITH ROUT_ENTRY@ DO BEGIN KIND:=ROUTINE_KIND; ROUT_PARM:=FIRST_PARM; ROUT_TYPE:=ROUTTYPE END END; PROCEDURE STD_SCALAR(VAR SCALAR_ENTRY:ENTRY_PTR; SCALAR_INDEX:SPELLING_INDEX); BEGIN STD_ID(SCALAR_ENTRY,SCALAR_INDEX); WITH SCALAR_ENTRY@ DO BEGIN KIND:=SCALAR_KIND; RANGE_TYPE:=SCALAR_INDEX END END; PROCEDURE INITIALIZE; VAR I:INTEGER; INT_TYPE,REAL_TYPE,BOOL_TYPE,CHAR_TYPE,QUEUE_TYPE, INDEX_TYPE,ARITH_TYPE,PASSIVE_TYPE,ARITH_SPARM,INT_CPARM,QUEUE_VPARM, PAS2_VPARM,PAS1_VPARM,CHAR_CPARM,INDEX_CPARM,INDEX1_CPARM,REAL_CPARM, INDEX_SPARM,QUEUE_CPARM: ENTRY_PTR; BEGIN INIT_PASS(INTER_PASS_PTR); WITH INTER_PASS_PTR@ DO BEGIN TEST:=TESTOPTION IN OPTIONS END; IF TEST THEN PRINTFF; THIS_NOUN:=ZWITH; CONST_DISP:=0; HALT:=FALSE; RESOLUTION:=FALSE; UNRES_COUNT:= 0; PARAMETERIZED:=(.ROUTINE_CLASS,PROGRAM_CLASS.); COMP_MODES:=(.CLASS_MODE,MONITOR_MODE,PROCESS_MODE.); ENTRY_MODES:=(.PROCE_MODE,FUNCE_MODE.); QUALIFIABLE:=(.SYSCOMP_KIND,RECORD_KIND.); CONSTANTS:=(.ICONST_CLASS,RCONST_CLASS,SCONST_CLASS.); TYPES:=(.SCALAR_KIND,SYSCOMP_KIND,ARRAY_KIND,RECORD_KIND,SET_KIND, UNDEF_KIND.); OP_ACCESS:=(.GENERAL,INTERNAL,QUALIFIED,FUNCTIONAL.); CONST_KINDS:=(.INDEX_CONST,REAL_CONST,STRING_CONST.); INACCESSIBLE:=(.UNDEFINED,INCOMPLETE.); ENTRY_ACCESS:=(.EXTERNAL,UNRESOLVED.); THIS_UPDATE:=-1; T:=-1; THIS_LEVEL:=STD_LEVEL; FOR I:=0 TO SPELLING_MAX DO SPELLING_TABLE(.I.).ACCESS:=UNDEFINED; "STANDARD ENTRYS" STD_CONST(XFALSE,XBOOLEAN,0); STD_CONST(XTRUE,XBOOLEAN,1); STD_ENTRY(UENTRY,XUNDEF); STD_ENTRY(INDEX_TYPE,ZINDEX); STD_ENTRY(ARITH_TYPE,ZARITHMETIC); STD_ENTRY(PASSIVE_TYPE,ZPASSIVE); STD_ID(QUEUE_TYPE,XQUEUE); QUEUE_TYPE@.KIND:=UNDEF_KIND; STD_SCALAR(INT_TYPE,XINTEGER); STD_SCALAR(REAL_TYPE,XREAL); STD_SCALAR(BOOL_TYPE,XBOOLEAN); STD_SCALAR(CHAR_TYPE,XCHAR); STD_PARM(ARITH_SPARM,ARITH_TYPE,ZSPARM); STD_PARM(INT_CPARM,INT_TYPE,ZCPARM); STD_PARM(QUEUE_CPARM,QUEUE_TYPE,ZCPARM); STD_PARM(QUEUE_VPARM,QUEUE_TYPE,ZVPARM); STD_PARM(CHAR_CPARM,CHAR_TYPE,ZCPARM); STD_PARM(INDEX_CPARM,INDEX_TYPE,ZCPARM); STD_PARM(INDEX_SPARM,INDEX_TYPE,ZSPARM); STD_PARM(PAS2_VPARM,PASSIVE_TYPE,ZVPARM); PAS2_VPARM@.NEXT_PARM:=INDEX_CPARM; STD_PARM(PAS1_VPARM,PASSIVE_TYPE,ZVPARM); PAS1_VPARM@.NEXT_PARM:=PAS2_VPARM; STD_PARM(INDEX1_CPARM,INDEX_TYPE,ZCPARM); INDEX1_CPARM@.NEXT_PARM:= INDEX_CPARM; STD_PARM(REAL_CPARM,REAL_TYPE,ZCPARM); STD_ROUT(XABS,ZARITHMETIC,ARITH_SPARM); STD_ROUT(XATTRIBUTE,XINTEGER,INDEX_CPARM); STD_ROUT(XCHR,XCHAR,INT_CPARM); STD_ROUT(XCONTINUE,PROC_TYPE,QUEUE_VPARM); STD_ROUT(XCONV,XREAL,INT_CPARM); STD_ROUT(XDELAY,PROC_TYPE,QUEUE_VPARM); STD_ROUT(XEMPTY,XBOOLEAN,QUEUE_CPARM); STD_ROUT(XIO,PROC_TYPE,PAS1_VPARM); STD_ROUT(XORD,XINTEGER,CHAR_CPARM); STD_ROUT(XPRED,ZINDEX,INDEX_SPARM); STD_ROUT(XSTOP,PROC_TYPE,INDEX1_CPARM); STD_ROUT(XREALTIME,XINTEGER,NIL); STD_ROUT(XSETHEAP,PROC_TYPE,INT_CPARM); STD_ROUT(XSUCC,ZINDEX,INDEX_SPARM); STD_ROUT(XTRUNC,XINTEGER,REAL_CPARM); STD_ROUT(XSTART,PROC_TYPE,NIL); STD_ROUT(XWAIT,PROC_TYPE,NIL); END; "#######" "NESTING" "#######" PROCEDURE PUSH_LEVEL(E:ENTRY_PTR); BEGIN IF THIS_LEVEL>=MAX_LEVEL THEN ABORT ELSE THIS_LEVEL:=THIS_LEVEL+1; WITH DISPLAY(.THIS_LEVEL.) DO BEGIN BASE:=THIS_UPDATE+1; LEVEL_ENTRY:=E; PREV_SYSCOMP:=SYSCOMP_LEVEL; PREV_LIST:=NAME_LIST; NAME_LIST:=NIL END END; PROCEDURE POP_LEVEL; VAR U:UPDATE_INDEX; BEGIN WITH DISPLAY (.THIS_LEVEL.) DO BEGIN SYSCOMP_LEVEL:=PREV_SYSCOMP; NAME_LIST:=PREV_LIST; FOR U:=THIS_UPDATE DOWNTO BASE DO WITH UPDATES(.U.) DO SPELLING_TABLE(.UPDATE_SPIX.):=OLD_ENTRY; THIS_UPDATE:=BASE-1 END; THIS_LEVEL:=THIS_LEVEL-1 END; "#############" "NAME HANDLING" "#############" PROCEDURE PUSH; BEGIN IF T>= OPERAND_MAX THEN ABORT ELSE T:=T+1 END; PROCEDURE NEW_ENTRY(VAR E:ENTRY_PTR); BEGIN IF THIS_NOUN>=NOUN_MAX THEN ABORT ELSE THIS_NOUN:=THIS_NOUN+1; NEW(E); WITH E@ DO BEGIN NOUN:=THIS_NOUN; KIND:=UNDEF_KIND END END; PROCEDURE PUSH_NEW_ENTRY(VAR E:ENTRY_PTR); BEGIN PUSH; NEW_ENTRY(E); WITH OPS(.T.) DO BEGIN CLASS:=DEF_CLASS; DEF_ENTRY:=E; DEF_SPIX:=XUNDEF END END; PROCEDURE UPDATE(SPIX:SPELLING_INDEX; E:ENTRY_PTR; A:NAME_ACCESS); BEGIN IF THIS_LEVEL<>GLOBAL_LEVEL THEN BEGIN "SAVE OLD ENTRY" IF THIS_UPDATE>=UPDATE_MAX THEN ABORT ELSE THIS_UPDATE:=THIS_UPDATE+1; WITH UPDATES(.THIS_UPDATE.) DO BEGIN UPDATE_SPIX:=SPIX; OLD_ENTRY:=SPELLING_TABLE(.SPIX.) END END; WITH SPELLING_TABLE(.SPIX.) DO BEGIN ENTRY:=E; LEVEL:=THIS_LEVEL; ACCESS:=A END END; PROCEDURE PUSH_NEW_NAME(RESOLVE,OUTPUT:BOOLEAN; A:NAME_ACCESS); VAR SPIX:SPELLING_INDEX; E:ENTRY_PTR; BEGIN READ_IFL(SPIX); IF SPIX<>XUNDEF THEN WITH SPELLING_TABLE(.SPIX.) DO IF (ACCESS<>UNDEFINED) AND (LEVEL=THIS_LEVEL) THEN IF RESOLVE AND (ACCESS=UNRESOLVED) THEN BEGIN E:=ENTRY; ACCESS:= A; RESOLUTION:= TRUE; UNRES_COUNT:= UNRES_COUNT - 1 END ELSE BEGIN ERROR(AMBIGUITY_ERROR); SPIX:=XUNDEF; END ELSE BEGIN NEW_ENTRY(E); UPDATE(SPIX,E,A) END; PUSH; WITH OPS(.T.) DO IF SPIX=XUNDEF THEN BEGIN CLASS:=UNDEF_CLASS; IF OUTPUT THEN PUT1(NEW_NOUN2,XUNDEF) END ELSE BEGIN CLASS:=DEF_CLASS; DEF_ENTRY:=E; DEF_SPIX:=SPIX; IF OUTPUT THEN PUT1(NEW_NOUN2,E@.NOUN) END END; PROCEDURE PUSH_OLD_NAME; VAR SPIX:SPELLING_INDEX; BEGIN PUSH; READ_IFL(SPIX); WITH OPS(.T.),SPELLING_TABLE(.SPIX.) DO IF ACCESS IN INACCESSIBLE THEN BEGIN ERROR(NAME_ERROR); CLASS:=UNDEF_CLASS END ELSE BEGIN CLASS:=DEF_CLASS; DEF_ENTRY:=ENTRY; DEF_SPIX:=SPIX END END; PROCEDURE FIND_NAME(LIST:NAME_PTR; SPIX:SPELLING_INDEX; VAR E:ENTRY_PTR); VAR NAME:NAME_PTR; BEGIN E:=NIL; NAME:=LIST; WHILE NAME<>NIL DO WITH NAME@ DO IF NAME_SPIX=SPIX THEN BEGIN E:=NAME_ENTRY; NAME:=NIL END ELSE NAME:=NEXT_NAME; IF E=NIL THEN BEGIN ERROR(NAME_ERROR); E:=UENTRY END END; PROCEDURE CHAIN_NAME(E:ENTRY_PTR; SPIX:SPELLING_INDEX); VAR N:NAME_PTR; BEGIN NEW(N); WITH N@ DO BEGIN NAME_SPIX:=SPIX; NAME_ENTRY:=E; NEXT_NAME:=NAME_LIST; NAME_LIST:=N END END; PROCEDURE SET_ACCESS(SPIX:SPELLING_INDEX; A:NAME_ACCESS); BEGIN SPELLING_TABLE(.SPIX.).ACCESS:=A; T:=T-1 END; PROCEDURE ENTER_NAMES(LIST:NAME_PTR); VAR THIS_NAME:NAME_PTR; BEGIN THIS_NAME:=LIST; WHILE THIS_NAME<>NIL DO WITH THIS_NAME@ DO BEGIN UPDATE(NAME_SPIX,NAME_ENTRY,QUALIFIED); THIS_NAME:=NEXT_NAME END END; FUNCTION DEFINED:BOOLEAN; BEGIN DEFINED:=OPS(.T.).CLASS<>UNDEF_CLASS END; FUNCTION TOP:ENTRY_PTR; BEGIN TOP:=OPS(.T.).DEF_ENTRY END; "#####################" "CONSTANT DECLARATIONS" "#####################" PROCEDURE CONST_ID; BEGIN PUSH_NEW_NAME(NOT_POSSIBLY_FORWARD,RETAIN,INCOMPLETE); IF DEFINED THEN THIS_NOUN:=THIS_NOUN-1 "CONST IDS DON'T POSSESS NOUNS" END; PROCEDURE CONST_DEF; BEGIN WITH OPS(.T-1.) DO IF CLASS=DEF_CLASS THEN BEGIN WITH DEF_ENTRY@, OPS(.T.) DO IF CLASS IN CONSTANTS THEN CASE CLASS OF ICONST_CLASS: BEGIN KIND:=INDEX_CONST; CONST_TYPE:=ICONST_TYPE; CONST_VAL:=ICONST_VAL END; RCONST_CLASS: BEGIN KIND:=REAL_CONST; REAL_DISP:=RCONST_DISP END; SCONST_CLASS: BEGIN KIND:=STRING_CONST; STRING_LENGTH:=SCONST_LENGTH; STRING_DISP:=SCONST_DISP END END ELSE ERROR(CONSTID_ERROR); T:=T-1; SET_ACCESS(DEF_SPIX,GENERAL) END ELSE T:=T-2 END; "#################" "TYPE DECLARATIONS" "#################" PROCEDURE TYPE_ID; VAR SPIX:SPELLING_INDEX; BEGIN READ_IFL(SPIX); WITH SPELLING_TABLE(.SPIX.) DO BEGIN IF (ACCESS<>UNDEFINED) AND (LEVEL=THIS_LEVEL) THEN BEGIN SPIX:=XUNDEF; ERROR(AMBIGUITY_ERROR) END ELSE UPDATE(SPIX,NIL,INCOMPLETE) END; PUSH; WITH OPS(.T.) DO IF SPIX=XUNDEF THEN CLASS:=UNDEF_CLASS ELSE BEGIN CLASS:=DEF_CLASS; DEF_SPIX:=SPIX END END; PROCEDURE TYPE_DEF; BEGIN WITH OPS(.T-1.) DO IF CLASS=DEF_CLASS THEN WITH SPELLING_TABLE(.DEF_SPIX.) DO BEGIN IF DEFINED THEN ENTRY:=TOP ELSE ENTRY:=UENTRY; ACCESS:=GENERAL END; T:=T-2; PUT0(TYPE_DEF2) END; PROCEDURE TYPE_(OUTPUT:BOOLEAN; OP:INTEGER); BEGIN PUSH_OLD_NAME; IF DEFINED THEN IF NOT(TOP@.KIND IN TYPES) THEN BEGIN ERROR(NAME_ERROR); OPS(.T.).CLASS:=UNDEF_CLASS END; IF OUTPUT THEN IF DEFINED THEN PUT1(OP,TOP@.NOUN) ELSE PUT1(OP,XUNDEF) END; PROCEDURE ENUM_ID; BEGIN PUSH_NEW_NAME(NOT_POSSIBLY_FORWARD,RETAIN,GENERAL); IF DEFINED THEN BEGIN THIS_NOUN:=THIS_NOUN-1; "CONST IDS DON'T HAVE NOUNS" WITH TOP@ DO BEGIN KIND:=INDEX_CONST; CONST_TYPE:=ENUM_TYPE; ENUM_VAL:=ENUM_VAL+1; CONST_VAL:=ENUM_VAL END END; T:=T-1 END; PROCEDURE ENUM; VAR E:ENTRY_PTR; BEGIN PUSH_NEW_ENTRY(E); ENUM_VAL:=-1; WITH E@ DO BEGIN KIND:=SCALAR_KIND; RANGE_TYPE:=NOUN; ENUM_TYPE:=NOUN END END; PROCEDURE SUBR_DEF; VAR MIN,MAX:INTEGER; TYPE1:NOUN_INDEX; E:ENTRY_PTR; BEGIN MIN:=0; MAX:=1; TYPE1:=XUNDEF; WITH OPS(.T.) DO IF CLASS=ICONST_CLASS THEN BEGIN MAX:=ICONST_VAL; TYPE1:=ICONST_TYPE END ELSE ERROR(SUBR_ERROR); WITH OPS(.T-1.) DO IF CLASS=ICONST_CLASS THEN BEGIN MIN:=ICONST_VAL; IF (MIN>MAX) OR (ICONST_TYPE<>TYPE1) THEN ERROR(SUBR_ERROR) END ELSE ERROR(SUBR_ERROR); T:=T-2; PUSH_NEW_ENTRY(E); WITH E@ DO BEGIN KIND:=SCALAR_KIND; RANGE_TYPE:=TYPE1; PUT4(SUBR_DEF2,NOUN,TYPE1,MIN,MAX) END END; PROCEDURE SET_DEF; VAR E:ENTRY_PTR; BEGIN T:=T-1; PUSH_NEW_ENTRY(E); E@.KIND:=SET_KIND; PUT1(SET_DEF2,E@.NOUN) END; PROCEDURE ARRAY_DEF; VAR INDEX:NOUN_INDEX; E,EL:ENTRY_PTR; BEGIN IF DEFINED THEN EL:=TOP ELSE EL:=UENTRY; T:=T-1; IF DEFINED THEN INDEX:=TOP@.NOUN ELSE INDEX:=XUNDEF; T:=T-1; PUSH_NEW_ENTRY(E); WITH E@ DO BEGIN KIND:=ARRAY_KIND; INDEX_TYPE:=INDEX; EL_TYPE:=EL; PUT1(ARRAY_DEF2,NOUN) END END; PROCEDURE REC; VAR E:ENTRY_PTR; BEGIN PUT0(REC2); PUSH_NEW_ENTRY(E); PUSH_LEVEL(E) END; PROCEDURE FIELD_LIST; VAR I,NUMBER:INTEGER; TYP:ENTRY_PTR; BEGIN READ_IFL(NUMBER); IF DEFINED THEN TYP:=TOP ELSE TYP:=UENTRY; T:=T-1; FOR I:=1 TO NUMBER DO WITH OPS(.T.) DO IF DEFINED THEN BEGIN WITH DEF_ENTRY@ DO BEGIN KIND:=FIELD; FIELD_TYPE:=TYP END; CHAIN_NAME(DEF_ENTRY,DEF_SPIX); SET_ACCESS(DEF_SPIX,INTERNAL) END ELSE T:=T-1; PUT1(FIELDLIST2,NUMBER) END; PROCEDURE REC_DEF; VAR E:ENTRY_PTR; BEGIN WITH TOP@ DO BEGIN KIND:=RECORD_KIND; FIELD_NAME:=NAME_LIST; PUT1(REC_DEF2,NOUN) END; POP_LEVEL END; PROCEDURE COMP_DEF(OP:INTEGER); VAR E:ENTRY_PTR; BEGIN SYSCOMP_LEVEL:=THIS_LEVEL; WITH TOP@ DO BEGIN KIND:=SYSCOMP_KIND; PUSH_NEW_ENTRY(E) "INITIAL STATEMENT"; INIT_STAT:=E; PUT2(OP,NOUN,E@.NOUN) END; WITH E@ DO BEGIN KIND:=ROUTINE_KIND; ROUT_PARM:=FIRST_PARM; ROUT_TYPE:=PROC_TYPE END; T:=T-1 END; PROCEDURE INITS_DEF; BEGIN PUT0(INITS_DEF2); TOP@.ENTRY_NAME:=NAME_LIST; END; "#####################" "VARIABLE DECLARATIONS" "#####################" PROCEDURE VAR_LIST(OP:INTEGER); VAR I,NUMBER:INTEGER; TYP:ENTRY_PTR; BEGIN READ_IFL(NUMBER); PUT1(OP,NUMBER); IF DEFINED THEN TYP:=TOP ELSE TYP:=UENTRY; T:=T-1; FOR I:=1 TO NUMBER DO WITH OPS(.T.) DO IF DEFINED THEN BEGIN WITH DEF_ENTRY@ DO BEGIN KIND:=VARIABLE; VAR_TYPE:=TYP END; IF OP=EVAR_LIST2 THEN CHAIN_NAME(DEF_ENTRY,DEF_SPIX); SET_ACCESS(DEF_SPIX,INTERNAL) END ELSE T:=T-1 END; "###################" "ROUTINE DECLARATIONS" "###################" PROCEDURE PROC_DEF(OP:INTEGER); BEGIN IF DEFINED THEN WITH TOP@ DO BEGIN KIND:=ROUTINE_KIND; ROUT_PARM:=FIRST_PARM; ROUT_TYPE:=PROC_TYPE; IF RESOLUTION THEN BEGIN RESOLUTION:=FALSE; PUT1(PROCF_DEF2,NOUN) END ELSE PUT1(OP,NOUN) END ELSE PUT1(OP,XUNDEF) END; PROCEDURE FUNC_DEF(OP:INTEGER); CONST NO_OUTPUT=FALSE; NOOP=0; VAR TYP:NOUN_INDEX; BEGIN TYPE_(NO_OUTPUT,NOOP); IF DEFINED THEN TYP:=TOP@.NOUN ELSE TYP:=XUNDEF; T:=T-1; IF DEFINED THEN WITH TOP@ DO BEGIN KIND:=ROUTINE_KIND; ROUT_PARM:=FIRST_PARM; ROUT_TYPE:=TYP; IF RESOLUTION THEN BEGIN RESOLUTION:=FALSE; PUT2(FUNCF_DEF2,TYP,NOUN) END ELSE PUT2(OP,TYP,NOUN) END ELSE PUT2(OP,XUNDEF,XUNDEF) END; PROCEDURE ROUT_END(A:NAME_ACCESS); BEGIN IF DEFINED THEN SET_ACCESS(OPS(.T.).DEF_SPIX,A) ELSE T:=T-1; POP_LEVEL; END; PROCEDURE PROG_DEF; BEGIN WITH OPS(.T.) DO BEGIN IF DEFINED THEN BEGIN WITH DEF_ENTRY@ DO BEGIN KIND:=PROGRAM_KIND; PROG_PARM:=FIRST_PARM; INTERFACE:=NAME_LIST; PUT1(PROG_DEF2,NOUN) END; SET_ACCESS(DEF_SPIX,INTERNAL) END ELSE BEGIN PUT1(PROG_DEF2,XUNDEF); T:=T-1 END; NAME_LIST:= OLD_NAMES END; END; PROCEDURE INTF_ID; VAR SPIX: SPELLING_INDEX; INTF_ENTRY: ENTRY_PTR; BEGIN READ_IFL(SPIX); IF SPIX<>XUNDEF THEN WITH SPELLING_TABLE(.SPIX.) DO IF (ACCESS<>UNDEFINED) AND (LEVEL=SYSCOMP_LEVEL) THEN IF ACCESS IN ENTRY_ACCESS THEN CHAIN_NAME(ENTRY,SPIX) ELSE ERROR(INTERFACE_ERROR) ELSE BEGIN "FORWARD REFERENCE" NEW_ENTRY(INTF_ENTRY); PUT1(FWD_DEF2, INTF_ENTRY@.NOUN); CHAIN_NAME(INTF_ENTRY, SPIX); UPDATE(SPIX, INTF_ENTRY, UNRESOLVED); UNRES_COUNT:= UNRES_COUNT + 1 END END; PROCEDURE PSTART; VAR M:INTEGER; E:ENTRY_PTR; BEGIN READ_IFL(M); PUT1(PSTART2,M); IF M IN COMP_MODES THEN PUSH_NEW_ENTRY(E) ELSE IF M IN ENTRY_MODES THEN IF DEFINED THEN WITH OPS(.T.) DO CHAIN_NAME(DEF_ENTRY,DEF_SPIX); IF DEFINED THEN E:=TOP ELSE E:=UENTRY; PUSH_LEVEL(E); FIRST_PARM:=NIL END; PROCEDURE PARMLIST(OP:INTEGER); VAR I,NUMBER:INTEGER; PTYPE:ENTRY_PTR; BEGIN IF DEFINED THEN PTYPE:=TOP ELSE PTYPE:=UENTRY; READ_IFL(NUMBER); PUT1(OP,NUMBER); FOR I:=NUMBER DOWNTO 1 DO WITH OPS(.T-I.) DO IF CLASS=DEF_CLASS THEN BEGIN WITH DEF_ENTRY@ DO BEGIN KIND:=PARAMETER; PARM_TYPE:=PTYPE; IF FIRST_PARM=NIL THEN FIRST_PARM:=DEF_ENTRY ELSE THIS_PARM@.NEXT_PARM:=DEF_ENTRY; THIS_PARM:=DEF_ENTRY; NEXT_PARM:=NIL END; SPELLING_TABLE(.DEF_SPIX.).ACCESS:=INTERNAL END; T:=T-NUMBER-1 END; "####" "BODY" "####" PROCEDURE BODY; BEGIN BODY_LEVEL:=THIS_LEVEL; PUT0(BODY2) END; PROCEDURE ANAME; BEGIN WITH OPS(.T.) DO IF CLASS=FUNCVALUE_CLASS THEN PUT1(RESULT2,FUNC_TYPE) ELSE PUT0(ADDRESS2) END; PROCEDURE CALL_NAME; VAR INTF:NAME_PTR; ERR:BOOLEAN; BEGIN ERR:=FALSE; WITH OPS(.T.) DO BEGIN IF CLASS=PROGRAM_CLASS THEN BEGIN PUT0(INTF2); INTF:=PROG@.INTERFACE; WHILE INTF<>NIL DO WITH INTF@ DO BEGIN PUT1(INTF_ID2,NAME_ENTRY@.NOUN); INTF:=NEXT_NAME END END ELSE IF CLASS=ROUTINE_CLASS THEN IF ROUT@.ROUT_TYPE<>PROC_TYPE THEN ERR:=TRUE ELSE "OK" ELSE ERR:=TRUE; IF ERR THEN BEGIN ERROR(CALL_NAME_ERROR); CLASS:=UNDEF_CLASS END END END; PROCEDURE CALL(OP:INTEGER); BEGIN WITH OPS(.T.) DO IF CLASS=ROUTINE_CLASS THEN BEGIN IF PARM<>NIL THEN ERROR(FEW_ARGS_ERROR); PUT0(OP) END ELSE IF CLASS=PROGRAM_CLASS THEN BEGIN IF PPARM<>NIL THEN ERROR(FEW_ARGS_ERROR); PUT0(CALL_PROG2) END ELSE PUT0(OP); IF OP<>CALL_FUNC2 THEN T:=T-1 END; PROCEDURE ARG_LIST; BEGIN WITH OPS(.T.) DO IF CLASS IN PARAMETERIZED THEN "OK" ELSE BEGIN ERROR(ARG_LIST_ERROR); CLASS:=UNDEF_CLASS END END; PROCEDURE ARG; VAR THIS_PARM:ENTRY_PTR; ERR:ERROR_NOTE; BEGIN T:=T-1 "POP ARGUMENT"; ERR:=NO; WITH OPS(.T.) DO IF CLASS=ROUTINE_CLASS THEN BEGIN THIS_PARM:=PARM; IF THIS_PARM=NIL THEN ERR:= YES ELSE PARM:=THIS_PARM@.NEXT_PARM END ELSE IF CLASS=PROGRAM_CLASS THEN BEGIN THIS_PARM:=PPARM; IF THIS_PARM=NIL THEN ERR:= YES ELSE PPARM:=THIS_PARM@.NEXT_PARM END ELSE ERR:=SUPPRESS; IF ERR<>NO THEN BEGIN IF ERR=YES THEN ERROR(MANY_ARGS_ERROR); PUT2(PARM2,XUNDEF,XUNDEF) END ELSE WITH THIS_PARM@ DO PUT2(PARM2,NOUN,PARM_TYPE@.NOUN); END; PROCEDURE DEF_CASE; BEGIN READ_IFL(THIS_LABEL); PUT1(DEF_LABEL2,THIS_LABEL) END; PROCEDURE CASE_; VAR VAL:INTEGER; BEGIN WITH OPS(.T.) DO IF CLASS=ICONST_CLASS THEN BEGIN PUT1(CHK_TYPE2,ICONST_TYPE); VAL:=ICONST_VAL; CLASS:=CASE_LABEL; LABEL:=THIS_LABEL; IF (VAL>=MIN_CASE) AND (VAL<=MAX_CASE) THEN INDEX:=VAL ELSE BEGIN ERROR(CASERANGE_ERROR); VAL:=0 END END ELSE BEGIN T:=T-1; ERROR(CASETYPE_ERROR) END END; PROCEDURE END_CASE; VAR L0,LN,MIN,MAX,I:INTEGER; BEGIN READ_IFL(L0); READ_IFL(LN); FOR I:=MIN_CASE TO MAX_CASE DO LABELS(.I.):=LN; IF OPS(.T.).CLASS=CASE_LABEL THEN BEGIN MIN:=OPS(.T.).INDEX; MAX:=MIN; END ELSE BEGIN MIN:=0; MAX:=0 END; WHILE OPS(.T.).CLASS=CASE_LABEL DO BEGIN WITH OPS(.T.) DO BEGIN IF LABELS(.INDEX.)=LN THEN LABELS(.INDEX.):=LABEL ELSE ERROR(AMBICASE_ERROR); IF INDEX>MAX THEN MAX:=INDEX ELSE IF INDEXNIL THEN ERROR(FEW_ARGS_ERROR); PUT0(CALL_FUNC2) END ELSE IF CLASS=FUNCVALUE_CLASS THEN ERROR(NAME_ERROR) END; PROCEDURE FUNCTION_ERROR(ERROR_NUM:INTEGER); BEGIN ERROR(ERROR_NUM); OPS(.T.).CLASS:=UNDEF_CLASS END; PROCEDURE FUNCTION_; VAR TYP: NOUN_INDEX; BEGIN TYP:= XUNDEF; WITH OPS(.T.) DO IF CLASS=ROUTINE_CLASS THEN WITH ROUT@ DO IF ROUT_TYPE = PROC_TYPE THEN FUNCTION_ERROR(PROC_USE_ERROR) ELSE TYP:= ROUT_TYPE ELSE FUNCTION_ERROR(NAME_ERROR); PUT1(FUNCTION2, TYP) END; PROCEDURE BINARY(OP:INTEGER); BEGIN PUT0(OP); T:=T-1 END; PROCEDURE POP2(OP:INTEGER); BEGIN PUT0(OP); T:=T-2 END; "########" "VARIABLE" "########" PROCEDURE PUSH_OPERAND(OP_ENTRY:ENTRY_PTR; COMP,RESULT:BOOLEAN); VAR OP:INTEGER; BEGIN IF NOT COMP THEN PUSH; WITH OPS(.T.) , OP_ENTRY@ DO CASE KIND OF INDEX_CONST: BEGIN CLASS:=FCONST_CLASS; PUT2(INDEX2,CONST_VAL,CONST_TYPE) END; REAL_CONST: BEGIN CLASS:=FCONST_CLASS; PUT1(REAL2,REAL_DISP) END; STRING_CONST: BEGIN CLASS:=FCONST_CLASS; PUT2(STRING2,STRING_LENGTH,STRING_DISP) END; VARIABLE,FIELD,PARAMETER: BEGIN CLASS:=VAR_CLASS; CASE KIND OF VARIABLE:VTYPE:=VAR_TYPE; FIELD: VTYPE:=FIELD_TYPE; PARAMETER: VTYPE:=PARM_TYPE END; IF COMP THEN OP:=VCOMP2 ELSE OP:=VAR2; PUT2(OP,NOUN,VTYPE@.NOUN) END; ROUTINE_KIND: BEGIN IF RESULT THEN BEGIN CLASS:=FUNCVALUE_CLASS; FUNC_TYPE:=OP_ENTRY@.ROUT_TYPE END ELSE BEGIN CLASS:=ROUTINE_CLASS; ROUT:=OP_ENTRY; PARM:=ROUT_PARM END; IF COMP THEN OP:=RCOMP2 ELSE OP:=ROUTINE2; PUT1(OP,NOUN) END; PROGRAM_KIND: BEGIN CLASS:=PROGRAM_CLASS; PROG:=OP_ENTRY; PPARM:=PROG_PARM; PUT1(ROUTINE2,NOUN) END; SCALAR_KIND,SYSCOMP_KIND,POINTER_KIND,ARRAY_KIND,RECORD_KIND, SET_KIND, UNDEF_KIND: BEGIN ERROR(NAME_ERROR); CLASS:=UNDEF_CLASS; IF NOT COMP THEN PUT0(UNDEF2) END END END; PROCEDURE NAME; VAR SPIX:SPELLING_INDEX; COMP,ERR,RESULT:BOOLEAN; NAME_ENTRY:ENTRY_PTR; BEGIN READ_IFL(SPIX); ERR:=FALSE; COMP:=FALSE; RESULT:=FALSE; WITH SPELLING_TABLE(.SPIX.) DO IF ACCESS IN OP_ACCESS THEN BEGIN NAME_ENTRY:=ENTRY; CASE ACCESS OF GENERAL: ; FUNCTIONAL: RESULT:=TRUE; INTERNAL: IF LEVEL 0 THEN ERROR(UNRES_ERROR); PUT0(EOM2); WITH INTER_PASS_PTR@ DO BEGIN RELEASE(RESETPOINT); CONSTANTS:=CONST_DISP END; NEXT_PASS(INTER_PASS_PTR) END. RY_PTR;