Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_SRC_1_19910112
-
6-1-exec/execpd.b36
There are 2 other files named execpd.b36 in the archive. Click here to see a list.
!<5.1.EXEC>EXECPD.B36.2, 14-Nov-82 04:36:22, Edit by PA0B
!Add DISPLAY opcodes for integers, Add OUTRANGE keyword
!<4.EXEC>EXECPD.B36.82, 24-Jun-81 11:22:58, Edit by DK32
!Fewer operations and more line numbers
!<4.EXEC>EXECPD.B36.81, 7-Mar-81 18:00:49, Edit by DK32
!Add Parsing-in-progress bit
!<4.EXEC>EXECPD.B36.80, 25-Feb-81 21:52:20, Edit by DK32
!Subcommands, Fields for Bliss 2.1, PassOutput
!<4.EXEC>EXECPD.B36.79, 7-Jan-81 17:52:45, Edit by DK32
!Separate controlled forks from invoked forks
!<4.EXEC>EXECPD.B36.78, 23-Dec-80 17:05:38, Edit by DK32
!Universal Exec linkage, Parse Invisible and Deleted
!<4.EXEC>EXECPD.B36.77, 11-Dec-80 23:17:28, Edit by DK32
!Preserved contexts
!<4.EXEC>EXECPD.B36.76, 9-Dec-80 00:16:15, Edit by DK32
!Exit Save and ToProgram
!<4.EXEC>EXECPD.B36.75, 4-Dec-80 15:06:46, Edit by DK32
!Command names in ECB
!<4.EXEC>EXECPD.B36.74, 25-Nov-80 20:36:35, Edit by DK32
!Preserved and superceded symbols
!<4.EXEC>EXECPD.B36.73, 30-Oct-80 15:56:38, Edit by DK32
!Runtime channel list
!<4.EXEC>EXECPD.B36.72, 25-Oct-80 23:01:11, Edit by DK32
!One invoked fork per context
!<4.EXEC>EXECPD.B36.71, 20-Oct-80 17:24:50, Edit by DK32
!Remove procdefs from GST
!<4.EXEC>EXECPD.B36.70, 18-Oct-80 15:53:26, Edit by DK32
!Parse FileList, Default_Gen, Wild
!<4.EXEC>EXECPD.B36.69, 9-Oct-80 20:36:15, Edit by DK32
!Parse List, Synonym and NoOriginal declarations
!<4.EXEC>EXECPD.B36.68, 2-Oct-80 15:59:39, Edit by DK32
!Parse NoIndirect and NoHelp
!<4.EXEC>EXECPD.B36.67, 25-Sep-80 18:15:12, Edit by DK32
!I/O fields in ECB
!<DK32.CG>EXECPD.B36.66, 6-Aug-80 20:58:09, Edit by DK32
!Keep PTY/PCT details in ECB
!<DK32.CG>EXECPD.B36.65, 29-Jul-80 15:08:03, Edit by DK32
!GETTYPOUT/CLEARTYPEOUT are GETTYPEOUT/CLEARTYPEOUT, Larger
!GST _COD, CNS, SML
!<DK32.CG>EXECPD.B36.64, 19-Jul-80 19:22:35, Edit by DK32
!Additional comment on GST _NMA, Add 4th parameter register to EXEC linkage
!<DK32.CG>EXECPD.B36.63, 10-Jul-80 13:53:26, Edit by DK32
!Add DCB to ECB
!<DK32.CG>EXECPD.B36.62, 3-Jul-80 14:31:38, Edit by DK32
!Add * option to SBS
!
! General definitions for Programmable Command Language 1
!
! Copyright (C) 1980, Carnegie-Mellon University
!
! Primitive things
LITERAL
TRUE=-1,
FALSE=0,
MAXLBL=20, ! Implementation limit of labels
MAXPRM=8, ! Implementation limit of procedure parameters
MAXVRC=128; ! Implementation limit of variables
! Some otherwise unused bits in the CM%FFL field of the FLDDB, used
! for various purposes.
LITERAL
CM_NIN = %O'000400000000', ! NoIndirect requested
CM_SHR = %O'000200000000', ! StdHelp requested (used only within compiler)
CM_WLD = %O'000100000000'; ! Wild requested
! Some unused values of CM%FNC
LITERAL
$CMFLS = %O'27'; ! FileList
!
! Substitute for CH$PTR when I desire only a pointer just before a word
! of 7-bit bytes. This is necessary only because BLISS will never
! knowingly generate a byte pointer with 440700 in the left half; it will
! instead take an extra instruction to point to the previous word and then
! put 010700 in the left half.
!
MACRO
BYTPTR(ADR) = ( LOCAL HLF: HLF_WRD; ! Byte pointer
HLF = ADR;
HLF[HLF_LFT] = %O'440700';
.HLF )%;
!
! Alternate linkage type use for all routines. It is basically
! the standard BLISS36C linkage, except that CX is a temporary
! since the Exec uses it that way, and Z is never to be used by
! Bliss code. Also, all arguments are passed through registers.
!
LINKAGE EXEC = PUSHJ( REGISTER=1, REGISTER=2, REGISTER=3, REGISTER=4):
LINKAGE_REGS(15,13,1)
GLOBAL(Z=0)
NOPRESERVE(2,3,4,5,14)
PRESERVE(6,7,8,9,10,11,12);
!
! Many things are represented as halfword fields in fullwords.
! They generally should be described as true fields, but that
! is not always possible: They are often subfields of existing
! fields.
!
FIELD HLF_FLD =
SET
HLF_LFT = [0,18,18,0], ! Left half
HLF_RGT = [0,0,18,0] ! Right half
TES;
!
! Scanner codes
! The compiler converts the source into these 36-bit codes for parsing.
!
MACRO MAKSCN(NAM) = LITERAL %NAME('SCN_',NAM) = %NUMBER(MAKSCN_CNT);
%ASSIGN(MAKSCN_CNT,MAKSCN_CNT+1) %;
COMPILETIME MAKSCN_CNT = 1;
MAKSCN(IDENT); ! Identifier; name is in atom buffer
MAKSCN(NUMB); ! Number; binary is in atom buffer
MAKSCN(QSTRING); ! Quoted string; text is in atom buffer
MAKSCN(PLUS); ! +
MAKSCN(MINUS); ! -
MAKSCN(TIMES); ! *
MAKSCN(DIV); ! /
LITERAL SCN_1RL = %NUMBER(MAKSCN_CNT); ! Tag so I can identify the relationals
MAKSCN(LSS); ! LSS or <
MAKSCN(LEQ);
MAKSCN(NEQ);
MAKSCN(EQL); ! EQL or =
MAKSCN(GTR); ! GTR or >
LITERAL SCN_LRL = %NUMBER(MAKSCN_CNT); ! Tag the last relational
MAKSCN(GEQ);
MAKSCN(LPAREN); ! (
MAKSCN(RPAREN); ! )
MAKSCN(SEMI); ! ;
MAKSCN(COMMA); ! ,
MAKSCN(COLON); ! :
MAKSCN(LBRKT); ! [
MAKSCN(RBRKT) ! ]
MAKSCN(PROCEDURE);
MAKSCN(COMMAND);
MAKSCN(SYNONYM);
MAKSCN(NOORIGINAL);
MAKSCN(BEGIN);
MAKSCN(END);
MAKSCN(EXTERNAL);
MAKSCN(INTEGER);
MAKSCN(STRING);
MAKSCN(LET);
MAKSCN(IF);
MAKSCN(THEN);
MAKSCN(ELSE);
MAKSCN(GOTO);
MAKSCN(RETURN);
MAKSCN(CASE);
MAKSCN(FROM);
MAKSCN(TO);
MAKSCN(OF);
MAKSCN(INRANGE);
MAKSCN(OUTRANGE);
MAKSCN(DO); ! THESE THREE MUST BE
MAKSCN(WHILE); ! CONTIGUOUS AND IN THIS
MAKSCN(UNTIL); ! ORDER TO BE COMPILED
MAKSCN(SELECT);
MAKSCN(DOCOMMAND);
MAKSCN(ORIGINAL);
MAKSCN(GUIDE);
MAKSCN(PARSE);
MAKSCN(OTHERWISE);
MAKSCN(NOINDIRECT);
MAKSCN(DEFAULT);
MAKSCN(HELP);
MAKSCN(NOHELP);
MAKSCN(WORDS);
MAKSCN(RADIX);
MAKSCN(PARSEONLY);
MAKSCN(STDHELP);
MAKSCN(TIME);
MAKSCN(DATE);
MAKSCN(DEFAULT_DEV); ! These 4 must be contiguous and in this order
MAKSCN(DEFAULT_DIR);
MAKSCN(DEFAULT_NAM);
MAKSCN(DEFAULT_EXT);
MAKSCN(DEFAULT_GEN); ! This is separate
MAKSCN(INPUT);
MAKSCN(OUTPUT);
MAKSCN(WILD);
MAKSCN(INVISIBLE);
MAKSCN(DELETED);
MAKSCN(ERROR);
MAKSCN(PROMPT);
MAKSCN(NOECHO);
MAKSCN(SYSNAME); ! System name; system name index in atom buffer
MAKSCN(INVOKE);
MAKSCN(PASSOUTPUT);
MAKSCN(TYPEIN);
MAKSCN(NORETURN);
MAKSCN(GETTYPEOUT);
MAKSCN(CLEARTYPEOUT);
MAKSCN(KILLPROGRAM);
MAKSCN(DISPLAY);
MAKSCN(BINARY);
MAKSCN(EXIT);
MAKSCN(SAVE);
MAKSCN(TOPROGRAM);
MAKSCN(ABORT);
MAKSCN(NOP);
MAKSCN(CALL);
MAKSCN(EOFILE); ! End of source
!
! The output of the compiler: Executer codes
!
!
! Description of instructions in Code portions of routine texts
!
FIELD COD_FLD =
SET
COD_VLD = [0,33,3,0], ! Validity code
COD_LNO = [0,24,9,0], ! Line number
COD_OPR = [0,18,6,0], ! Operation code
COD_OPA = [0,0,18,0], ! Operand descriptor A
COD_OPB = [1,18,18,0], ! Operand descriptor B
COD_OPC = [1,0,18,0], ! Operand descriptor C
COD_CNS = [0,0,36,0] ! Instruction word regarded simply as a word
TES;
LITERAL COD_VLD_NUM=5; ! The validity code
!
! The operation codes
!
! Macro to help keep operation list consistent
MACRO MAKOPR(NAM) = LITERAL %NAME('OPR_',NAM)=%NUMBER(MAKOPR_CNT);
%ASSIGN(MAKOPR_CNT,MAKOPR_CNT+1) %;
COMPILETIME MAKOPR_CNT = 0;
! Three operand operators: A = B <operator> C
MAKOPR(ADD); MAKOPR(SUB); MAKOPR(MUL); MAKOPR(DIV); ! Integer ops
MAKOPR(CNS); ! Concatenate strings
! Two operand operators: A = <operator> C
MAKOPR(STO); ! Copy integer
MAKOPR(STS); ! Copy string
! Two operand branches: Jump to code index A if B <test> C satisfied
MAKOPR(BLE); MAKOPR(BLT); MAKOPR(BEQ); ! Arithmetic comparison
MAKOPR(BNE); MAKOPR(BGE); MAKOPR(BGT);
MAKOPR(CLE); MAKOPR(CLT); MAKOPR(CEQ); ! String comparison
MAKOPR(CNE); MAKOPR(CGE); MAKOPR(CGT);
! Assorted two word operators
MAKOPR(CAL); ! Call procedure A, parameter list at
! constant index B (-1 if no actuals)
! (length in first word), store result
! in C if typed procedure
MAKOPR(CAS); ! Case: Based on integer A, jump to A'th
! location in table B (length in C(B)), biased
! by constant C
MAKOPR(PRS); ! Parse command operands using FDB at A,
! if all fail jump to C (give standard
! error if C=-1)
MAKOPR(SBS); ! Extract substring: Store in A substring of
! string C, starting at Const[B] with length
! Const[B+1] (or full length if Const[B+1]=-1)
MAKOPR(DCM); ! Do Exec command in string A, original
! if B=0, storing output to C
! One word operators
LITERAL OPR_11W=MAKOPR_CNT; ! First one word operator
MAKOPR(JMP); ! Jump to code index A
MAKOPR(RET); ! Return from command or procedure; value in A
MAKOPR(IVP); ! Invoke program given in string A
MAKOPR(TIN); ! Type string A into program fork
MAKOPR(TIX); ! Same as TIN but without free CRLF
MAKOPR(GTO); ! Get output from program fork into string A
MAKOPR(KIL); ! Kill program fork
MAKOPR(DPY); ! Type string A to real terminal
MAKOPR(DPB); ! Type string A in binary mode
MAKOPR(DPN); ! Type string A without carriage return
MAKOPR(XIT); ! Exit command, options in A field: low bit=
! Save, next bit=To Program
MAKOPR(ABT); ! Issue fatal error with string A
MAKOPR(NOP); ! No operation
MAKOPR(PSH); ! Push copy of operand A
MAKOPR(POP); ! Pop operand A
MAKOPR(PMT); ! Prompt with string A
MAKOPR(PMN); ! Prompt with string A and no echo
MAKOPR(IVO); ! Invoke program given in string A, PassOutput
MAKOPR(DIY); ! Type integer A to real terminal
MAKOPR(DIB); ! Type string A in binary mode (well, why not?)
MAKOPR(DIN); ! Type integer A without carriage return
LITERAL OPR_LST=%NUMBER(MAKOPR_CNT)-1;
!
! System procedure/variable name table format
!
FIELD SYN_FLD =
SET
SYN_RTV = [0,35,1,0], ! Variable implemented as routine
SYN_WRT = [0,34,1,0], ! Variable can be written to
SYN_TYP = [0,21,3,0], ! Type
SYN_CLS = [0,18,3,0], ! Class
SYN_NML = [0,0,18,0], ! Length of name
SYN_NAM = [1,18,18,0], ! Address of ASCII name
SYN_ADR = [1,0,18,0] ! Address of datum or routine entry
TES;
LITERAL
! The types must be the same as the STE types
SYN_TYP_INT = 0, ! Integer
SYN_TYP_STR = 1, ! String
SYN_CLS_PRC = 0, ! Ordinary procedure
SYN_CLS_FCN = 1, ! Typed procedure
SYN_CLS_VAR = 2; ! Variable
!
! Operand descriptor format
!
FIELD OPN_FLD =
SET
OPN_CLS = [0,16,2,0], ! Class of operand reference
OPN_STR = [0,15,1,0], ! If constant or temporary, indicates string
OPN_ADR = [0,0,15,0], ! Symbol index or constant index of operand
OPN_WRD = [0,0,36,0] ! Entire operand word
TES;
LITERAL
OPN_CLS_VAR = 0, ! User variable (widely assumed to be zero)
OPN_CLS_SYN = 1, ! System procedure or variable
OPN_CLS_CNS = 2, ! Constant
OPN_CLS_TMP = 3, ! Temporary
OPN_TMP_INT = %O'600000', ! Another representation of temporary integer
OPN_TMP_STR = %O'700000'; ! Another representation of temporary string
!
! String value; used everywhere to refer to any string
!
FIELD STV_FLD =
SET
STV_LEN = [0,18,18,0], ! Character length of string
STV_ADR = [0,0,18,0] ! Address of string
! (real or relative depends on context)
TES;
!
! String block; used only to store accumulated text from a PCT
!
FIELD STB_FLD =
SET
STB_CNT = [0,18,18,0], ! Count of characters in block
STB_LEN = [0,0,18,0], ! Length of block
STB_BUF = [1,0,36,0] ! Buffer
TES;
!
! Local symbol table entry
!
FIELD STE_FLD =
SET
STE_WRD = [0,0,36,0], ! First word, to help in addressing the entry
STE_VLD = [0,33,3,0], ! Validity field
STE_CLS = [0,30,3,0], ! Class of symbol
STE_TYP = [0,29,1,0], ! Variable type
STE_LOC = [0,0,18,1], ! Stack frame displacement of variable datum
STE_NAM = [1,0,36,0], ! Stringvalue of symbol name
STE_NML = [1,18,18,0], ! length
STE_NMA = [1,0,18,0] ! constant table index
TES;
LITERAL STE_LEN = 2, ! Length of symbol table entry
STE_VLD_NUM=2, ! Validity code number
STE_CLS_VAR=0, ! Local variable
STE_CLS_GBL=1, ! Global variable
STE_CLS_FML=2, ! Procedure argument
STE_CLS_PRC=3, ! Procedure
STE_CLS_FCN=4, ! Function
STE_TYP_INT=0, ! Integer
STE_TYP_STR=1; ! String
!
! Global symbol table entry
!
FIELD GST_FLD =
SET
GST_VLD = [0,0,36,0], ! Validity word; entry unused if zero
GST_PSV = [0,35,1,0], ! Preserved object
GST_SPR = [0,34,1,0], ! Superceded object if preserved
GST_DPL = [0,34,1,0], ! Duplicate of preserved if not preserved
GST_CLS = [0,31,3,0], ! Class of object
GST_TYP = [0,30,1,0], ! FV Type
GST_PCT = [0,26,4,0], ! PF Number of arguments
GST_CMA = [0,26,4,1], ! C Argument list, -2 = Parses, -1 = default
GST_SLN = [0,18,8,0], ! CPF Stack to reserve
GST_TXT = [0,0,18,0], ! CPFS Real address of text
GST_COD = [1,0,12,0], ! CPF Length of code
GST_CNS = [1,12,12,0], ! CPF Length of constant table
GST_SML = [1,24,12,0], ! CPF Length of symbol table
GST_VAL = [1,0,36,0], ! V Value
GST_PLN = [1,0,9,0], ! S Bytes in text, including terminator
GST_NAM = [2,0,36,0], ! Stringvalue of name of global object
GST_NML = [2,18,18,0], ! length
GST_NMA = [2,0,18,0] ! address
! For synonym entries, there is an extra word
! before the name block, in case it need be
! an abbreviation; the word is not counted in
! GST_NML
TES;
LITERAL GST_LEN = 3, ! Length of global symbol table entry
GST_CLS_CMD = 0, ! Command
GST_CLS_PRC = 1, ! Procedure
GST_CLS_VAR = 2, ! Variable
GST_CLS_FCN = 3, ! Function
GST_CLS_SYN = 4, ! Synonym
! Certain routines require that GST types have the same
! representations as STE types
GST_TYP_INT = 0, ! Integer
GST_TYP_STR = 1; ! String
!
! Appearance of runtime stack frame
!
FIELD FRM_FLD =
SET
FRM_RET = [0,0,18,0], ! Relative address in caller to return to
FRM_PRV = [0,18,18,0], ! Caller's stack frame
FRM_STK = [1,18,18,0], ! Caller's stack pointer
FRM_PRC = [1,0,18,0], ! Caller's GST entry
FRM_WRD = [0,0,36,0] ! A variable or argument word
TES;
LITERAL FRM_LOC = 2; ! First local variable
!
! Execution Context Block
!
FIELD ECB_FLD =
SET
ECB_NXT = [0,0,18,0], ! Link to next (older) context block
ECB_PRC = [0,18,18,0], ! Current routine's GST address or 0 if Procdef
ECB_POS = [1,0,36,0], ! Terminal file position
ECB_PC = [2,0,18,0], ! PC
ECB_FP = [2,18,18,0], ! FP
ECB_SP = [3,0,18,0], ! SP
ECB_STK = [3,18,18,0], ! Relative address of bottom of stack
ECB_CTN = [4,0,18,0], ! Number of fork-controlling PTY/ITY
ECB_CTJ = [4,18,18,0], ! JFN on that PTY/PCT
ECB_DTN = [5,0,18,0], ! Number of DoCommand-output PTY/ITY
ECB_DTJ = [5,18,18,0], ! JFN on that PTY/PCT
ECB_DTO = [6,18,18,0], ! Operand designator for DoCommand output
ECB_DCB = [6,0,18,0], ! Address of DoCommand string block
ECB_RCL = [7,18,18,0], ! Runtime channel list
ECB_GSC = [7,0,18,0], ! Address of global symbol for command
ECB_PFL = [8,0,18,0], ! Address of list of parsed JFN's
ECB_CFK = [8,18,18,0], ! Handle of controlled fork
ECB_CNM = [9,0,36,0], ! Command name in SIXBIT
ECB_PSV = [10,35,1,0], ! Preserved context
ECB_FNI = [10,34,1,0], ! Controlled fork was not Invoked
ECB_SCM = [10,33,1,0], ! Parsing a subcommand
ECB_ECO = [10,32,1,0], ! Echo off in subcommand parse
ECB_PAS = [10,31,1,0], ! Program running in PassOutput mode
ECB_PAR = [10,30,1,0], ! Command in the midst of Parsing
ECB_OPM = [11,0,36,0], ! Original prompt pointer
ECB_ORA = [12,0,18,0], ! Original reparse address
ECB_CSB = [13,0,36,0], ! First word of command state block
ECB_CJB = [23,0,36,0], ! First word of GTJFN block
ECB_CFB = [43,0,36,0] ! First word of command buffer
TES;
!
! General free space list
!
FIELD FRE_FLD =
SET
FRE_CNT = [0,18,18,0], ! Size of block including header
FRE_PTR = [0,0,18,0] ! Link to next free block
TES;
!
! Entry in JFN list
!
FIELD JLS_FLD =
SET
JLS_LNK = [0,0,18,0], ! Link to next entry in list
JLS_WLD = [0,35,1,0], ! Set if wildcards should be preserved
JLS_JFN = [1,0,36,0] ! JFN
TES;
!
! Entry in runtime channel list
!
FIELD RCL_FLD =
SET
RCL_CHN = [0,0,18,0], ! Channel number
RCL_NXT = [0,18,18,0], ! Link to next entry on list
RCL_JFN = [1,0,18,0], ! JFN
RCL_OUT = [1,18,1,0] ! Open for output
TES;
!
! Macros to make use of structures and fields more convenient
!
MACRO COD_BLK = BLOCKVECTOR[0,1] FIELD(COD_FLD)%,
OPRAND = BLOCK[0] FIELD(OPN_FLD)%,
STR_VAL = BLOCK[1] FIELD(STV_FLD)%,
SYMENT = BLOCKVECTOR[0,STE_LEN] FIELD(STE_FLD)%,
STE_BLK = BLOCK[STE_LEN] FIELD(STE_FLD)%,
GST_TBL = BLOCKVECTOR[0,GST_LEN] FIELD(GST_FLD)%,
GST_BLK = BLOCK[GST_LEN] FIELD(GST_FLD)%,
STKFRM = BLOCKVECTOR[0,1] FIELD(FRM_FLD)%,
ECB_BLK = BLOCK[0] FIELD(ECB_FLD)%,
FRE_LST = BLOCK[0] FIELD(FRE_FLD)%,
STB_BLK = BLOCK[0] FIELD(STB_FLD)%,
HLF_WRD = BLOCK[1] FIELD(HLF_FLD)%,
SYN_TBL = BLOCKVECTOR[0,2] FIELD(SYN_FLD)%,
JLS_WRD = BLOCK[2] FIELD(JLS_FLD)%,
RCL_WRD = BLOCK[2] FIELD(RCL_FLD)%;