PASS1
Pass 1: parsing, symbol table and code generation. Each section's comment stands above it, each line's comments beside it; point at a name for its meaning; line numbers after GOTO, GOSUB and THEN are links.
Sections (102)
- 10 DECLARATIONS: INTEGER VARIABLES, ARRAYS AND THE COMMON BLOCK
- 200 PASS 1 OF THE COMPILER
- 690 START
- 770 STATEMENT LOOP: START A NEW LINE
- 780 NEXT STATEMENT ON THE LINE
- 1000 END
- 1100 FOR V=E1 TO E2 [STEP E3]
- 1400 NEXT [V[,V]...]
- 1500 DATA
- 1800 INPUT ["PROMPT";] V[,V]...
- 2100 DIM: SET THE DIMENSIONS OF EACH ARRAY (CONSTANTS ONLY); NO CODE
- 2200 READ A DIMENSION LIST INTO THE SYMBOL'S ENTRY; AN ARRAY MAY BE DIMENSIONED ONLY ONCE AND B
- 2500 READ V[,V]...
- 2600 PLOT X,Y / HLIN X1,X2 AT Y / VLIN Y1,Y2 AT X
- 2800 HPLOT [TO] X,Y [TO X,Y]...
- 3100 DRAW / XDRAW SHAPE [AT X,Y]
- 3300 ONERR GOTO LINE
- 3400 RESUME
- 3500 LET (ALSO A STATEMENT THAT BEGINS WITH A NAME)
- 3590 IF ... THEN LINE / GOTO LINE: BEQ OVER A JMP TO THE LINE
- 3650 GOTO LINE: JMP TO THE LINE (CHAINED UNTIL PASS 2 KNOWS ITS ADDRESS)
- 3700 RUN
- 3800 IF EXPRESSION THEN ...
- 4000 GOSUB LINE: JSR TO THE LINE
- 4040 IF ... THEN RETURN: BEQ OVER AN RTS
- 4100 RETURN: RTS
- 4120 AFTER AN UNCONDITIONAL TRANSFER: THE REST OF THE LINE IS NOT REACHED
- 4200 REM: REM! STARTS A COMPILER DIRECTIVE, ANY OTHER REMARK IS SKIPPED
- 4380 REM! CLEAR COMMON / REM! CLEAR CHAIN
- 4510 REM! USECOMMON / REM! DEFCOMMON LIST
- 4900 AFTER A NAME IN A DECLARATION LIST
- 5100 MATCH THE KEYWORD IN WL$ AGAINST THE SOURCE, LETTER BY LETTER (SPACES ALLOWED); A MISMATCH
- 5200 SKIP SPACES
- 5300 STOP / NEW: CALL THE LIBRARY; WHAT FOLLOWS ON THE LINE IS NOT REACHED
- 5400 ON EXPRESSION GOTO / GOSUB LINE[,LINE]...
- 5600 WAIT ADDRESS,MASK[,MASK]
- 5800 DEF FN NAME(PARAMETER)=EXPRESSION
- 6100 POKE ADDRESS,VALUE
- 6200 PRINT
- 6400 GET V
- 6500 EXPECT A COMMA, ELSE THE STATEMENT IS FINISHED
- 6600 CALL / HIMEM: (ONE ARGUMENT, REAL ENTRY)
- 6700 STATEMENTS WITH ONE ARGUMENT
- 6800 POP / CLEAR / STATEMENTS WITHOUT ARGUMENTS
- 6830 END OF THE STATEMENT
- 6870 END OF THE PROGRAM
- 6950 WARNING
- 7100 SKIP TO THE NEXT COLON OUTSIDE QUOTES OR THE END OF THE LINE
- 7200 EXPECT = / ( / ) / , / THE CHARACTER IN XF; ELSE A SYNTAX ERROR
- 7530 FATAL ERRORS: NAME THE KIND IN WL$
- 7720 REPORT A FATAL ERROR, SHOW THE LINE WITH !ERR!, PAUSE IF ASKED; NO MORE CODE IS WRITTEN
- 7990 CONVERT THE DIGITS IN WL$ TO A NUMBER (A BAD NUMBER SETS N5)
- 8100 LIST THE LINE IN THE LISTING BUFFER
- 8200 NEXT TOKEN
- 8220 START A LINE
- 8490 READ ONE BYTE OF THE SOURCE FILE INTO IV
- 8600 LINE NUMBER REFERENCE: FIND OR ENTER THE LINE'S SYMBOL
- 8800 SCAN A NUMBER INTO WL$
- 9000 NAME WITH ITS TYPE AND SUBSCRIPTS: AN OPERAND
- 9200 NAME WITH ITS TYPE SUFFIX: K4 = -1 FOR %, -2 FOR $, ELSE -3
- 9500 SCAN A NAME
- 9600 ARRAY ELEMENT
- 10100 FUNCTION ARGUMENTS, AS DESCRIBED IN F()
- 10500 STRING LITERAL
- 10900 EXPRESSIONS
- 11310 PARSER
- 12210 NUMERIC CONSTANT
- 12440 NUMERIC FUNCTION CALL (SGN TO LEN, VAL, ASC)
- 12540 FN NAME(ARGUMENT)
- 13200 TWO-CHARACTER RELATIONS
- 13500 REDUCE WHILE THE OPERATOR ON THE STACK HAS A HIGHER PRIORITY THAN THE ONE ARRIVING (OE())
- 14000 PARSE STACK: PUSH AN OPERATOR, POP, PUSH AND POP AN OPERAND
- 14400 STORE A TRIPLE IN TP()
- 14800 VARIABLE SYMBOL
- 14900 FN SYMBOL: FIND OR ENTER THE FUNCTION'S NAME IN CHAINS 1-4
- 15100 ALLOCATE ML WORDS OF THE SYMBOL TABLE
- 15300 EMIT A VARIABLE OR CONSTANT ROUTINE CALL
- 15400 EMIT AN OPCODE AND A CHAINED REFERENCE (LINE OR FN)
- 15450 EMIT A WORD
- 15600 EMIT A BYTE
- 15700 WRITE TO THE LINE NUMBER FILE / PATCH A WORD IN THE OBJECT FILE
- 16000 FILE HELPERS
- 16300 RESUME/DEBUG
- 16400 EMIT A JSR TO CALL TABLE ENTRY CI; THE ENTRY 3 BYTES LOWER SERVES THE OTHER ARGUMENT TYPE
- 16700 EMIT A JMP TO CALL TABLE ENTRY CI
- 16800 TEMPORARIES
- 16900 FREE A TEMPORARY
- 17000 END OF DEF FN: THE FUNCTION'S TEMPORARIES ARE NOT USED AGAIN
- 17100 GENERATE THE CODE OF AN ASSIGNMENT'S VALUE
- 17200 CODE GENERATOR
- 17550 BY OPERATION
- 17590 + * : APPLY THE OPERAND IN MEMORY TO THE ACCUMULATOR
- 18100 AND / OR
- 18400 COMPARISONS
- 18900 ARRAY ELEMENT: PUSH ALL SUBSCRIPTS BUT THE FIRST, LAST TO FIRST
- 19060 STRING COMPARISONS, LIKEWISE
- 19810 WHERE DOES THE RESULT GO: THE NEXT TRIPLE THAT USES IT, OR A TEMPORARY
- 19960 A STRING RESULT IS KEPT IF THE NEXT STRING OPERATION USES IT, ELSE SAVED IN A STRING TEMPO
- 20300 STORE THE RESULT OF AN EXPRESSION IN THE TARGET
- 20500 LOAD OR APPLY AN OPERAND
- 20800 SET THE FLAGS FOR IF
- 20900 COMPILATION TERMINATED: DELETE THE OBJECT FILE AND RESTORE DOS
10DECLARATIONS: INTEGER VARIABLES, ARRAYS AND THE COMMON BLOCK
INTEGER VARIABLES
EL IS LIBRARY ROUTINE ($0947) THAT RESETS THE STACK, DROPPING EVERY PENDING GOSUB AND FOR, AND RESETS THE DATA POINTER; CALLED AFTER AN ERROR
MN IS DRIVE MOTOR-OFF SWITCH FOR THE BOOT SLOT
SC IS 1 IF THE SOURCE AND OBJECT FILES ARE ON THE BOOT DRIVE (MOTOR KEPT ON), ELSE 0
SC() IS SYMBOL TABLE: CHAIN HEADS, THEN ENTRIES LINKED THROUGH THEIR FIRST WORD
INTEGER VARIABLES
N1 IS RESUME/DEBUG CODE OPTION (1 = YES)
O4 IS COMPILATION LISTING OPTION (1 = YES)
OO IS PAUSE ON ERRORS OPTION (1 = YES)
P8 IS INTEGER ARITHMETIC OPTION (1 = YES)
INTEGER VARIABLES
C3 IS COMMON KIND: -1 NONE, 0 DEFINE, 255 USE
FC IS 1 ONCE A FATAL ERROR HAS BEEN REPORTED (NO MORE CODE IS WRITTEN)
KV IS ADDRESS OF THE FIVE PACKED BYTES LEFT BY THE USR ROUTINE ($0371)
QB IS ADDRESS OF THE ROUTINE THAT READS ONE BYTE FROM THE OPEN FILE INTO IX ($037E)
WS IS ADDRESS OF THE ROUTINE THAT WRITES THE BYTE IN IX TO THE OPEN FILE ($0387)
INTEGER VARIABLES
CD IS START OF THE COMMON BLOCK (THE PROGRAM START BEFORE COMMON MOVED IT)
CI IS INDEX OF THE ROUTINE IN THE CALL TABLE CC()
LB IS LIBRARY ADDRESS, STORED AS ADDRESS-32767
SU IS NEXT FREE PLACE FOR AN OPERATOR ON THE PARSE STACK (GROWS UP)
VC IS VARIABLES ADDRESS ASKED FOR, AS ADDRESS-32767, OR -32767 FOR END OF PROGRAM
INTEGER VARIABLES
EO IS 1 WHEN THE EXPRESSION IS COMPLETE
J IS INNER LOOP INDEX; 1 IF AN ARRAY WAS DIMENSIONED BEFORE
K4 IS TYPE CODE (-3 REAL, -2 STRING, -1 INTEGER, +22 FOR AN ARRAY), OR AN OPERATION NUMBER
OW IS BYTE TO WRITE TO THE OBJECT FILE
TZ IS SIZE OF THE SYMBOL TABLE (5350 WORDS)
VB IS VALUE PASSED TO AND FROM THE STACK AND SYMBOL ROUTINES (USUALLY A SYMBOL)
INTEGER VARIABLES
D IS ENTRY ADJUSTMENT: 0, OR -3 FOR THE OTHER TYPE'S ENTRY
FZ IS WHICH FLAG TEST IF NEEDS: 0 INTEGER (LDA $A0/ORA $A1), 1 REAL (LDA $9D)
K8 IS LOOP INDEX
KD IS KIND OF THAT OPERAND (ITS TP(X,0) ENTRY)
LH IS NUMBER OF SOURCE LINES READ
NB IS OPERAND BEING LOADED OR APPLIED
NQ IS OPERATION CODE OF THE TRIPLE
RN IS 1 IF THE OPERANDS ARE USED AS REALS
SK IS SAVED OPERATION NUMBER
SS IS SAVED OPERATION NUMBER
UZ IS SIZE OF THE TRIPLE TABLE (100)
INTEGER VARIABLES
BF IS START OF THE LISTING BUFFER ($0280)
DW IS DOS STATE BYTE AT $AA52: POKED BEFORE EACH DIRECT FILE READ OR WRITE
F IS WHICH FILE DOS IS SET UP FOR: 1 SOURCE (READ), 2 OBJECT (WRITE), 3 LINE NUMBER FILE
F() IS ARGUMENT DESCRIPTION OF A FUNCTION: F(0) NUMBER, F(1..3) TYPES, F(4) ARGUMENT BEING READ
FQ IS 1 TO WRITE TO THE LINE NUMBER FILE EVEN AFTER A FATAL ERROR
P3 IS BYTE WAITING TO BE COPIED INTO THE LISTING BUFFER
PE IS LOW BYTE OF THE NEXT LINE LINK (A ZERO LINK ENDS THE PROGRAM)
RC IS 1 FOR THE STATEMENT RIGHT AFTER THEN (NO RESUME/DEBUG CALL)
SJ IS CODE ADDRESS OF THAT STORE
TG IS 1 WHEN THE EXPRESSION IS THE VALUE OF AN ASSIGNMENT
INTEGER VARIABLES
EP IS TYPE OF THE EXPRESSION: 1 INTEGER, 2 STRING, 3 REAL
HW IS LAST CHAIN HEAD IN SC(); ENTRIES ARE ALLOCATED ABOVE IT
LQ IS ADDRESS OF THE ROUTINE THAT LISTS THE TOKENIZED LINE IN THE INPUT BUFFER ($038D)
MX IS DRIVE MOTOR-ON SWITCH FOR THE BOOT SLOT ($C089+SLOT*16), TOUCHED TO KEEP THE DRIVE SPINNING
N5 IS 1 IF THE LAST SCAN FOUND NO NAME OR NO NUMBER
NG IS NUMBER OF CONSTANT HASH CHAINS (32)
NK IS NUMBER OF LINE NUMBER HASH CHAINS (32)
NU IS NUMBER OF VARIABLE HASH CHAINS IN THE SYMBOL TABLE (32)
O2 IS OPERATION CODE USED TO SELECT THE GENERATOR, OR A SUBSCRIPT COUNT
OH IS INTEGER CONSTANTS OPTION (1 = YES)
S8 IS SIZE OF THE PARSE STACK (100)
SF IS TRIPLE BEING EXAMINED WHEN DECIDING WHERE A RESULT GOES
T9 IS SCRATCH: A SYMBOL OR SIZE BEING WORKED ON
UV IS ADDRESS OF THE USR ROUTINE THAT PACKS A NUMBER INTO FIVE BYTES ($0377)
V3 IS NEXT FREE PLACE FOR AN OPERAND ON THE PARSE STACK (GROWS DOWN)
INTEGER VARIABLES
D3 IS 1 AFTER AN UNCONDITIONAL TRANSFER: FURTHER STATEMENTS ON THE LINE ARE NOT REACHED
IZ IS 2 WHILE NAMES ARE BEING DECLARED INTEGER (ALSO AFTER INTEGER *), ELSE 0
K0 IS NEXT FREE WORD IN THE SYMBOL TABLE SC()
LM IS LENGTH OF THE RUNTIME LIBRARY IN BYTES (4013)
MJ IS NEXT BYTE OF THE SOURCE LINE (ONE BYTE LOOKAHEAD); -1 AT END OF PROGRAM
RI IS SAVED ID DURING AN INTEGER DECLARATION LIST
U IS OPERATION NUMBER FOR A MEMORY OPERAND, OR THE OPERAND SAVED FOR LATER
VO IS FIRST VARIABLE CHAIN HEAD IN SC() (9; 1-4 HOLD FN AND LINE SYMBOLS, 5-8 TEMPORARIES)
INTEGER VARIABLES
BO IS START OF THE TEXT OF A STRING LITERAL OR DATA ITEM IN THE LISTING BUFFER
ED IS OBJECT FILE BASE: FILE POSITION = PC - ED (THE FILE STARTS WITH THE BSAVE HEADER)
GZ IS INSIDE DEF FN: NAME HASH OF THE PARAMETER, ELSE 0
IX IS ADDRESS OF THE ONE-BYTE TRANSFER CELL FOR QB AND WS ($0376)
N4 IS NUMBER OF DIMENSIONS IN A DIM OR DECLARATION
PC IS ADDRESS OF THE NEXT OBJECT CODE BYTE, AS ADDRESS-32767
S3 IS SAVED SYMBOL (FOR LOOP VARIABLE), OR THE NUMBER OF LINES IN AN ON LIST
T5 IS INSIDE DEF FN: THE PARAMETER'S SYMBOL
U7 IS TOKEN NUMBER OF THE STATEMENT (TOKEN-128), THEN THE CALL TABLE INDEX IT SELECTS
XF IS TOKEN OR CHARACTER EXPECTED NEXT (SYNTAX CHECK)
INTEGER VARIABLES
CC IS ADDRESS OF THE LINK WORD OF THE LAST DATA BLOCK (DATA BLOCKS ARE CHAINED)
CC() IS CALL TABLE: ADDRESSES OF THE LIBRARY AND ROM ROUTINES, BY INDEX
FD IS 1 IF THE FLAGS ALREADY REFLECT THE RESULT (IF NEEDS NO TEST)
LK IS OPERATION OF THE LAST TRIPLE (TELLS THE STORE WHAT IS IN THE ACCUMULATOR)
LZ IS LEFT OPERAND OF THE TRIPLE
RV IS 1 IF THE RESULT IS REAL
SE IS 1 WHEN THE EXPRESSION'S VALUE MUST BE REAL (A REAL TARGET OR A FUNCTION BODY)
INTEGER VARIABLES
BM IS NEXT FREE BYTE IN THE LISTING BUFFER
BX IS 1 IF THE OPERATOR BEING REDUCED TAKES TWO OPERANDS
D2 IS DECLARATION STATE: 2 BEFORE ANY STATEMENT, 1 AFTER COMMON, 0 AFTER A STATEMENT
IV IS BYTE JUST READ FROM THE SOURCE FILE
T0 IS CURRENT TOKEN OR CHARACTER OF THE SOURCE LINE
TP IS OPERATOR ON TOP OF THE PARSE STACK
TP() IS TRIPLE TABLE: TP(I,0) OPERATION OR OPERAND KIND, TP(I,1) LEFT, TP(I,2) RIGHT
WN IS TYPE THE CALL TABLE ENTRY IS FOR: 1 INTEGER, 3 REAL
INTEGER VARIABLES
BK IS END OF THE LISTING BUFFER; A LINE THAT REACHES IT IS TOO LONG
DP() IS DOS PATCH TABLE: DP(I,0) ADDRESS (AS A SIGNED WORD, ADDRESS-65536), DP(I,1) ORIGINAL BYTE
FG IS 1 IF THE FOR LOOP VARIABLE IS REAL, 0 IF IT IS AN INTEGER
HY IS NAME HASH (99*FIRST CHARACTER+SECOND), OR LINE NUMBER-32767
J3 IS LAST VARIABLE STORED BY THE CODE (A LOAD RIGHT AFTER IT IS LEFT OUT)
KX IS FIRST CONSTANT CHAIN HEAD IN SC()
L IS FIRST LINE NUMBER CHAIN HEAD IN SC()
ML IS SCRATCH
PN IS ADDRESS TO PATCH WITH THE CURRENT CODE ADDRESS
RH IS RIGHT OPERAND OF THE TRIPLE
TB IS TRIPLE BEING GENERATED
TU IS SYMBOL OF THE EXPRESSION'S RESULT
U2 IS NUMBER OF TRIPLES IN TP() PLUS ONE
UR IS PROGRAM START, STORED AS ADDRESS-32767; MOVED UP BY COMMON DECLARATIONS
XK IS CALL TABLE INDEX FOR THE OPERANDS IN THE OTHER ORDER (SWAPPED COMPARISON)
INTEGER VARIABLES
OE() IS OPERATOR TABLE: OE(I,0) TOKEN, OE(I,1) PRIORITY ON THE STACK, OE(I,2) PRIORITY ARRIVING
SZ() IS PARSE STACK: OPERATORS FROM THE BOTTOM, OPERANDS FROM THE TOP
COMMON BLOCK, IN THE ORDER IT IS LAID OUT: NUMBERS FIRST, THEN STRINGS. THE PASSES SHARE IT, SO EVERY PASS DECLARES IT THE SAME WAY
BP$ IS TWO BELLS, SOUNDED BEFORE EACH ERROR MESSAGE
CO$ IS DOS CLOSE COMMAND
DI$ IS CONTROL-D, THE DOS COMMAND PREFIX
DN$ IS SLOT AND DRIVE OF THE BOOT DRIVE (",S6,D1")
LN$ IS NAME OF THE LINE NUMBER FILE ("CLINENUM")
OD$ IS OBJECT FILE NAME
OO$ IS SLOT AND DRIVE OF THE OBJECT FILE
OP$ IS DOS OPEN COMMAND
RV$ IS DOS READ COMMAND
SB$ IS SLOT AND DRIVE OF THE SOURCE FILE
SI$ IS SOURCE FILE NAME
WO$ IS DOS WRITE COMMAND
200PASS 1 OF THE COMPILER: READS THE TOKENIZED SOURCE PROGRAM A BYTE AT A TIME, CHECKS ITS SYNTAX, BUILDS THE SYMBOL TABLE IN SC() AND WRITES THE OBJECT CODE. REFERENCES THAT ARE NOT YET KNOWN (LINES, VARIABLE ROUTINES) ARE WRITTEN AS BACKWARD CHAINS FOR PASS 2. SET UP THE BUFFERS AND TABLES
THE COPYRIGHT NOTICE; WL$ IS THEN THE WORK STRING
WL$ IS WORK STRING: KEYWORD BEING MATCHED, DIGITS OF A NUMBER, NAME OF AN ERROR
THE LISTING BUFFER IS THE INPUT BUFFER $0280-$036F
THE LISTING BUFFER ENDS AT $036F; A LINE THAT FILLS IT IS TOO LONG
THE SYMBOL TABLE SC() HAS 5350 WORDS
SYMBOL TABLE ENTRIES ARE ALLOCATED FROM THE WORD AFTER THE LAST CHAIN HEAD
AT MOST 100 TRIPLES PER EXPRESSION
THE TRIPLE TABLE IS EMPTY; TRIPLES ARE NUMBERED FROM 1
THE OPERATOR SIDE OF THE PARSE STACK IS EMPTY
THE PARSE STACK HAS 100 PLACES; THE OPERAND SIDE STARTS AT THE TOP AND GROWS DOWN
NOT INSIDE DEF FN
(THE TRIPLE TABLE IS EMPTIED AGAIN)
NO DATA STATEMENT YET: THE DATA CHAIN IS EMPTY
COPY THE CALL TABLE OUT OF THE COMMON SYMBOL TABLE AREA WHERE PASS 0 LEFT IT
ENTRY K8 OF THE CALL TABLE, FROM SC(150) TO SC(285)
COPY THE OPERATOR TABLE LIKEWISE
THREE VALUES FOR EACH OF THE 17 OPERATORS
FROM SC(300) TO SC(350): TOKEN, STACK PRIORITY, ARRIVING PRIORITY
FN LT(X): TRUE IF X IS A LETTER
FN DG(X): TRUE IF X IS A DIGIT
FN OS(X): TRUE IF X IS AN OPERATOR TOKEN (+ - * / ^ AND OR > = < NOT, OR A TWO-CHARACTER RELATION)
FN OE(X): TRUE IF X IS AN OPERATOR, A PARENTHESIS OR THE END OF THE LINE
FN NU(X): TRUE IF X IS A NUMERIC FUNCTION TOKEN (SGN TO LEN, VAL, ASC)
FN SF(X): TRUE IF X IS A STRING FUNCTION TOKEN (STR$, CHR$, LEFT$, RIGHT$, MID$)
FN ES(X): TRUE IF X ENDS A STATEMENT (COLON OR END OF LINE)
FN UB(X): X STORED AS A WORD (X+32767)
FN IV(X): TRUE IF TRIPLE X GIVES AN INTEGER (INTEGER TEMPORARY, INTEGER VARIABLE OR RESULT)
FN LO(X): TRUE IF OPERATION X TAKES ITS LEFT OPERAND FROM THE ACCUMULATOR
FN RT(X): TRUE IF OPERATION X TAKES ITS RIGHT OPERAND FROM THE ACCUMULATOR
FN IA(X): TRUE IF TRIPLE X IS IN THE ACCUMULATOR
OPEN THE SOURCE FILE ON ITS DRIVE
OPEN THE OBJECT FILE ON ITS DRIVE
OPEN THE LINE NUMBER FILE ON THE BOOT DRIVE
NO FILE IS SET UP FOR READING OR WRITING YET
LINE NUMBER FILE RECORDS ARE WRITTEN ONLY WHILE FQ IS SET
NO FATAL ERROR YET
NO SOURCE LINES READ YET
DECLARATIONS (REM! LINES) ARE ALLOWED UNTIL THE FIRST STATEMENT
THE COMMON BLOCK BEGINS AT THE PROGRAM START; EACH COMMON DECLARATION MOVES UR UP PAST IT
NO COMMON DECLARATION YET
NO STORE THROUGH AN ARRAY ELEMENT ADDRESS IS PENDING
NOT COMPILING AN ASSIGNMENT
THE OBJECT FILE BEGINS WITH THE 4-BYTE ADDRESS AND LENGTH OF A BINARY FILE, SO THE PROGRAM'S FIRST BYTE IS AT FILE POSITION 4
COUNT FROM ADDRESS 0 WHILE THE FIRST BYTES OF THE FILE ARE RESERVED
24 ZERO BYTES RESERVE THE FILE'S ADDRESS AND LENGTH AND THE PROGRAM'S FIRST 20 BYTES (THE CALL TO THE LIBRARY AND THE HEADER), WHICH ARE WRITTEN AT THE END OF THE COMPILATION
K8 COUNTS THE 24 BYTES
WRITE ONE ZERO BYTE
690START: THE CODE BEGINS 20 BYTES INTO THE PROGRAM (AFTER THE CALL TO THE LIBRARY AND THE HEADER); READ THE FIRST LINE'S LINK AND NUMBER
THE TWO LENGTH BYTES AT THE START OF THE PROGRAM FILE ARE READ AND NOT USED
THE SECOND LENGTH BYTE
THE LOW BYTE OF THE FIRST LINE'S LINK
THE HIGH BYTE OF THE LINK (A ZERO LINK MEANS NO LINES) AND THE LOW BYTE OF THE LINE NUMBER
NO LINES: REPORT IT AND STOP THE COMPILATION
THERE IS NO PREVIOUS TOKEN TO COPY INTO THE LISTING BUFFER
THE LISTING BUFFER IS EMPTY
770STATEMENT LOOP: START A NEW LINE
READ THE LINE NUMBER AND THE FIRST TOKEN
780NEXT STATEMENT ON THE LINE
THIS STATEMENT IS NOT THE ONE RIGHT AFTER THEN
COLON OR END OF LINE: AN EMPTY STATEMENT
ANY STATEMENT BUT REM ENDS THE DECLARATIONS
NOT A KEYWORD: AN ASSIGNMENT
NOT REACHED: SKIP IT WITH A WARNING (DATA AND REM ARE STILL COMPILED)
CI AND U7 = TOKEN-128: FOR MOST STATEMENTS THE CALL TABLE ENTRY WITH THIS INDEX IS THE STATEMENT'S LIBRARY OR ROM ROUTINE (FOR EXAMPLE 10 = PR#, 23 = HOME, 61 = CLEAR)
ML = 1 FOR END (128) UP TO 64 FOR NEW (191)
READ THE TOKEN AFTER THE KEYWORD
DISPATCH ON THE KEYWORD
THE NEXT 21 KEYWORDS: XDRAW (149) TO SPEED= (169)
(THE SECOND LIST)
THE LAST 22: LET (170) TO NEW (191); DEL, SHLOAD, TRACE, NOTRACE, LOMEM:, RECALL, STORE, &, LOAD, SAVE, CONT AND LIST ARE NOT SUPPORTED (6950)
(THE THIRD LIST)
A LETTER STARTS AN ASSIGNMENT WITHOUT LET
ANYTHING ELSE CANNOT START A STATEMENT
1000END: JMP TO THE LIBRARY'S END ROUTINE; WHAT FOLLOWS ON THE LINE IS NOT REACHED
JMP TO CALL TABLE ENTRY 0, THE LIBRARY'S END ROUTINE ($1363)
THE REST OF THE LINE IS NOT REACHED
1100FOR V=E1 TO E2 [STEP E3]: INITIAL VALUE (WITH THE LOOP VARIABLE'S ADDRESS), LIMIT, STEP; INTEGER LOOPS USE THE INTEGER ENTRIES
RESUME/DEBUG CALL BEFORE THE STATEMENT
THE LOOP VARIABLE (A SIMPLE NUMERIC VARIABLE); VB = ITS SYMBOL, K4 = ITS TYPE
SAVE THE LOOP VARIABLE'S SYMBOL WHILE THE EXPRESSION IS COMPILED
FG = 1 FOR A REAL LOOP VARIABLE, 0 FOR AN INTEGER ONE
EXPECT =
THE INITIAL VALUE
THE OPERATION NUMBER OF THE CALL THAT STARTS THE LOOP: 21 INTEGER VARIABLE AND INTEGER VALUE, 22 REAL VARIABLE AND INTEGER VALUE, 23 INTEGER VARIABLE AND REAL VALUE, 24 BOTH REAL
THE LOOP VARIABLE AGAIN
OPERATION K4 ON THE LOOP VARIABLE: PASS 2 MAKES IT A JSR TO THE LIBRARY'S LOOP START ENTRY FOR THAT OPERATION
TWO MORE BYTES, FILLED BY PASS 2 WITH THE LOOP VARIABLE'S ADDRESS
EXPECT TO
THE LIMIT
REAL LOOP: CALL TABLE ENTRY 5, THE LIMIT FOR A REAL LOOP (REAL ENTRY, OR 3 LOWER FOR AN INTEGER LIMIT)
INTEGER LOOP: CALL TABLE ENTRY 125, THE LIMIT FOR AN INTEGER LOOP
(INTEGER ENTRY, OR 3 LOWER FOR A REAL LIMIT)
NO STEP: ENTRY 129 (INTEGER LOOP) OR 130 (REAL LOOP), A STEP OF 1
SKIP STEP
THE STEP
REAL LOOP: ENTRY 3, THE STEP FOR A REAL LOOP
INTEGER LOOP: ENTRY 126, THE STEP FOR AN INTEGER LOOP
1400NEXT [V[,V]...]: ONE CALL PER VARIABLE, EACH FOLLOWED BY THE VARIABLE'S ADDRESS (0 FOR A BARE NEXT)
RESUME/DEBUG CALL BEFORE THE STATEMENT
NEXT WITHOUT A VARIABLE: JSR TO CALL TABLE ENTRY 2 (THE LIBRARY'S NEXT, $0A31), THEN A ZERO WORD
THE NEXT VARIABLE IN THE LIST
OPERATION 25 ON THE VARIABLE: PASS 2 MAKES IT A JSR TO THE LIBRARY'S NEXT
[OPERATION 25][LINK TO THE PREVIOUS REFERENCE]
A WORD, THE VARIABLE'S ADDRESS (PASS 2 FILLS IT IN), OR 0 FOR A BARE NEXT
WF IS WORD TO WRITE TO THE OBJECT FILE (A LINK OR ADDRESS)
(THE WORD)
A COMMA CONTINUES THE LIST; ANYTHING ELSE ENDS THE STATEMENT
1500DATA: JUMP OVER THE ITEMS, EACH STORED AS LENGTH AND TEXT, ENDED BY 255 AND A LINK TO THE NEXT DATA BLOCK
A JMP OVER THE ITEMS
ITS ADDRESS WORD IS CHAINED TO THE PREVIOUS DATA LINK THROUGH CC; PASS 2 RESOLVES THE CHAIN
CC = THE ADDRESS OF THIS WORD, THE LATEST LINK IN THE CHAIN
WRITE THE WORD
SKIP SPACES BEFORE THE NEXT ITEM
ML = 1 FOR A QUOTED ITEM
A QUOTE OPENS A QUOTED ITEM
THE ITEM'S TEXT STARTS HERE IN THE LISTING BUFFER
AN ITEM ENDS AT THE END OF THE LINE, AT ITS CLOSING QUOTE, OR (UNQUOTED) AT A COMMA OR COLON
ANOTHER CHARACTER OF THE ITEM
WRITE THE ITEM AS ITS LENGTH AND TEXT (QUOTES LEFT OUT)
SPACES MAY FOLLOW THE ITEM
255 ENDS THE BLOCK
WRITE THE 255
THE LINK TO THE NEXT DATA BLOCK, CHAINED THROUGH CC LIKE THE JMP
THIS WORD IS NOW THE LATEST LINK
1800INPUT ["PROMPT";] V[,V]...
RESUME/DEBUG CALL BEFORE THE STATEMENT
JSR TO CALL TABLE ENTRY CI (4, THE LIBRARY'S INPUT START, WHICH SAVES THE STATEMENT'S ADDRESS FOR A REENTER)
CALL TABLE ENTRY 39 READS THE FIRST NUMBER, 40 THE FIRST STRING
NO PROMPT
AFTER A PROMPT: ENTRIES 42 (NUMBER) AND 43 (STRING)
THE PROMPT, A STRING LITERAL; VB = ITS ADDRESS
JSR TO ENTRY 28, THE LIBRARY ROUTINE THAT PRINTS THE PROMPT, FOLLOWED BY THE LITERAL'S ADDRESS
(JSR TO ENTRY 28)
THE LITERAL'S ADDRESS ...
... AS A WORD
EXPECT ;
THE VARIABLE TO READ INTO
ITS TYPE IN EP, AND THE CODE FOR AN ARRAY ELEMENT'S ADDRESS
THE READ ROUTINE FOR A NUMBER ...
... OR A STRING (THE NEXT ENTRY)
JSR TO THE READ ROUTINE
STORE THE VALUE IN THE VARIABLE
END OF THE LIST: ENTRY 48, THE LIBRARY ROUTINE THAT ENDS INPUT (?EXTRA IGNORED)
SKIP THE COMMA
FURTHER ITEMS: ENTRIES 44 (NUMBER) AND 45 (STRING)
2100DIM: SET THE DIMENSIONS OF EACH ARRAY (CONSTANTS ONLY); NO CODE
THE ARRAY'S NAME AND TYPE
EXPECT (
ITS DIMENSIONS
A COMMA CONTINUES THE LIST
2200READ A DIMENSION LIST INTO THE SYMBOL'S ENTRY; AN ARRAY MAY BE DIMENSIONED ONLY ONCE AND BEFORE IT IS USED WITH A DIFFERENT NUMBER OF SUBSCRIPTS
N4 COUNTS THE DIMENSIONS
THE ARRAY TYPE CODE (TYPE+22)
THE DIGITS OF THE NEXT DIMENSION
NOT A NUMBER: THE DIMENSION MUST BE A CONSTANT
COUNT THE DIMENSION
CONVERT IT (RETURNING TO 2300)
A DIMENSION FROM 0 TO 32767
AT MOST 88 DIMENSIONS
KEEP THE DIMENSION ON THE PARSE STACK
(PUSH IT)
FIND OR ENTER THE ARRAY'S SYMBOL
J = 0: NOT DIMENSIONED BEFORE
A NEW SYMBOL (THE LAST ENTRY ALLOCATED): STORE THE NUMBER OF DIMENSIONS AND MAKE ROOM FOR THEM
AN OLD SYMBOL MUST HAVE THE SAME NUMBER OF SUBSCRIPTS
ITS FIRST DIMENSION IS SET (NOT -1): IT WAS DIMENSIONED BEFORE
T9 = THE SYMBOL
THE DIMENSIONS COME OFF THE STACK LAST FIRST
THE NEXT DIMENSION FROM THE STACK
DIMENSIONED BEFORE WITH OTHER DIMENSIONS: REDEFINED
STORE THE DIMENSION IN THE SYMBOL'S ENTRY
EXPECT )
RETURN THE SYMBOL IN VB
2500READ V[,V]...
RESUME/DEBUG CALL BEFORE THE STATEMENT
THE VARIABLE TO READ INTO
ITS TYPE IN EP, AND THE CODE FOR AN ARRAY ELEMENT'S ADDRESS
CALL TABLE ENTRY 7 READS A STRING ...
... ENTRY 6 A NUMBER
JSR TO THE READ ROUTINE
STORE THE VALUE IN THE VARIABLE
A COMMA CONTINUES THE LIST
2600PLOT X,Y / HLIN X1,X2 AT Y / VLIN Y1,Y2 AT X
RESUME/DEBUG CALL BEFORE THE STATEMENT
THE FIRST VALUE (X, OR X1 / Y1)
CALL TABLE ENTRY 60 SAVES IT
EXPECT ,
PLOT: THE SECOND VALUE AND THEN ENTRY 13, PLOT
HLIN / VLIN: THE SECOND VALUE
ENTRY 120 SAVES IT
EXPECT AT
THE THIRD VALUE AND THEN ENTRY 14 (HLIN) OR 15 (VLIN)
2800HPLOT [TO] X,Y [TO X,Y]...
RESUME/DEBUG CALL BEFORE THE STATEMENT
HPLOT TO: NO FIRST POINT
THE FIRST POINT
CALL TABLE ENTRY 19 PLOTS IT
EACH TO ...
EXPECT TO, ELSE THE STATEMENT IS FINISHED
... X,Y
ENTRY 59 DRAWS THE LINE TO IT
A POINT X,Y: X, THEN ENTRY 122 SAVES IT, THEN Y
CALL TABLE ENTRY 122 SAVES X
THEN Y, LEFT IN THE ACCUMULATOR FOR THE CALLER'S ROUTINE
3100DRAW / XDRAW SHAPE [AT X,Y]
RESUME/DEBUG CALL BEFORE THE STATEMENT
THE SHAPE NUMBER
NO AT: CALL TABLE ENTRY 20 (DRAW) OR 21 (XDRAW)
ENTRY 86 SAVES THE SHAPE NUMBER
SKIP AT
X, THEN ENTRY 122 SAVES IT
ENTRY 122 SAVES X
EXPECT ,
Y, THEN ENTRY 26 (DRAW AT) OR 27 (XDRAW AT)
3300ONERR GOTO LINE: CALL WITH THE HANDLER'S ADDRESS; WHAT FOLLOWS ON THE LINE IS NOT REACHED
EXPECT GOTO (ONERR GETS NO RESUME/DEBUG CALL)
JSR TO CALL TABLE ENTRY 37, THE LIBRARY'S ONERR ROUTINE
THE HANDLER'S LINE NUMBER
ITS ADDRESS WORD, CHAINED TO THE LINE'S SYMBOL
3400RESUME: A JUMP TO THE LIBRARY ONLY WITH THE RESUME/DEBUG OPTION, OTHERWISE IGNORED WITH A WARNING
WITHOUT THE OPTION RESUME IS IGNORED WITH A WARNING
3500LET (ALSO A STATEMENT THAT BEGINS WITH A NAME): COMPILE THE TARGET, THEN THE EXPRESSION OF ITS TYPE, THEN THE STORE
RESUME/DEBUG CALL BEFORE THE STATEMENT
THE TARGET VARIABLE OR ARRAY ELEMENT
EXPECT =
ITS TYPE IN EP, AND THE CODE FOR AN ARRAY ELEMENT'S ADDRESS
THE VALUE BY THE TARGET'S TYPE: 1 INTEGER, A NUMERIC EXPRESSION (LEFT AS AN INTEGER IF IT IS ONE); 2 STRING; 3 REAL, A NUMERIC EXPRESSION MADE REAL
MARK THE STORE AS AN ASSIGNMENT
STORE THE VALUE IN THE TARGET
THE STORE IS DONE
3590IF ... THEN LINE / GOTO LINE: BEQ OVER A JMP TO THE LINE
SKIP THE GOTO AFTER THEN
BEQ *+5: OVER THE JMP WHEN THE CONDITION IS FALSE
*+5: THE BRANCH SKIPS THE THREE BYTES OF THE JMP
3650GOTO LINE: JMP TO THE LINE (CHAINED UNTIL PASS 2 KNOWS ITS ADDRESS)
THE LINE NUMBER
JMP, ITS ADDRESS CHAINED TO THE LINE'S SYMBOL
3700RUN: JMP $03F5 (THE & VECTOR, WHICH THE LIBRARY POINTS AT THE PROGRAM); RUN LINE: CLEAR, THEN GOTO
RESUME/DEBUG CALL BEFORE THE STATEMENT
RUN LINE: JSR TO CALL TABLE ENTRY 61, CLEAR, THEN A JMP TO THE LINE
3800IF EXPRESSION THEN ...: SET THE FLAGS FROM THE RESULT, THEN DECIDE THE FORM
RESUME/DEBUG CALL BEFORE THE STATEMENT
THE CONDITION
IF ITS CODE DID NOT LEAVE THE FLAGS SET, TEST THE ACCUMULATOR (FZ = 1: LDA $9D, 0: LDA $A0 / ORA $A1)
IF ... GOTO LINE
EXPECT THEN
IF ... THEN GOTO LINE
IF ... THEN LINE
IF ... THEN RETURN
IF ... THEN STATEMENTS: BNE OVER A JMP TO THE NEXT LINE
BNE *+5
*+5: SKIP THE JMP
A JMP TO THE NEXT LINE
ITS ADDRESS WORD WAITS ON THE PARSE STACK UNTIL THE NEXT LINE STARTS, WHEN IT IS PATCHED WITH THAT LINE'S ADDRESS
TWO BYTES FOR THE ADDRESS
THE STATEMENT AFTER THEN GETS NO RESUME/DEBUG CALL
COMPILE THE STATEMENTS AFTER THEN AS PART OF THE LINE
4000GOSUB LINE: JSR TO THE LINE
THE LINE NUMBER
JSR, ITS ADDRESS CHAINED TO THE LINE'S SYMBOL
JSR ... RETURNS HERE: THE LINE GOES ON
4040IF ... THEN RETURN: BEQ OVER AN RTS
SKIP THE RETURN AFTER THEN
BEQ *+3: OVER THE RTS WHEN THE CONDITION IS FALSE
*+3: SKIP THE RTS
4100RETURN: RTS
(THE RTS)
4120AFTER AN UNCONDITIONAL TRANSFER: THE REST OF THE LINE IS NOT REACHED
FURTHER KEYWORD STATEMENTS ON THE LINE ARE IGNORED WITH A WARNING
4200REM: REM! STARTS A COMPILER DIRECTIVE, ANY OTHER REMARK IS SKIPPED
SPACES MAY FOLLOW REM
AN ORDINARY REMARK: SKIP THE REST OF THE LINE
SKIP !
SPACES MAY FOLLOW !
NOT I: TRY CLEAR
INTEGER
ONLY BEFORE ANY OTHER STATEMENT
INTEGER *: EVERY REAL NAME FROM HERE ON IS AN INTEGER; NOTHING MAY FOLLOW
THE NEXT NAME
SAVE IZ
THE NAME IS DECLARED INTEGER
... AN ARRAY WITH ITS DIMENSIONS
THE DIMENSIONS GO INTO THE NAME'S SYMBOL
BACK TO THE STATE BEFORE THIS NAME (ALSO 2 AFTER INTEGER *)
A COMMA CONTINUES THE LIST; THE END OF THE LINE ENDS IT
THE NEXT NAME
4380REM! CLEAR COMMON / REM! CLEAR CHAIN: A CALL TO THE LIBRARY; MUST END THE LINE
NOT C: TRY USECOMMON
CLEAR
CLEAR MUST BE FOLLOWED BY COMMON OR CHAIN, ELSE THE LINE IS A REMARK
CHAIN
CALL TABLE ENTRY 128, THE LIBRARY'S CLEAR CHAIN ROUTINE
RESUME/DEBUG CALL BEFORE THE CALL
NO MORE DECLARATIONS
JSR TO THE ROUTINE
SPACES MAY FOLLOW
THE LINE MUST END HERE
4510REM! USECOMMON / REM! DEFCOMMON LIST: ALLOCATE THE COMMON BLOCK AT THE PROGRAM START IN DECLARATION ORDER AND MOVE THE PROGRAM START UP
NOT U: TRY DEFCOMMON
USE, THEN COMMON
ML = 255: THE PROGRAM USES A COMMON BLOCK DEFINED BY AN EARLIER PROGRAM
DEF, THEN COMMON
ML = 0: THE PROGRAM DEFINES THE COMMON BLOCK
MATCH COMMON
A DECLARATION ERROR IF USECOMMON AND DEFCOMMON ARE MIXED OR A STATEMENT CAME BEFORE
FROM HERE ON ONLY OTHER COMMON DECLARATIONS ARE ALLOWED
REMEMBER WHICH KIND OF COMMON THIS PROGRAM HAS
THE NEXT NAME
A SIMPLE VARIABLE: ONE ELEMENT
L1 IS NUMERIC VALUE OF A LINE NUMBER, DIMENSION OR CONSTANT
AN ARRAY: ITS DIMENSIONS
THE DIMENSIONS GO INTO THE NAME'S SYMBOL
L1 = THE NUMBER OF ELEMENTS, THE PRODUCT OF (DIMENSION+1)
THE DIMENSIONS ARE STORED AFTER THE COUNT IN THE ARRAY'S ENTRY
2 BYTES AN ELEMENT FOR AN INTEGER OR A STRING ...
... 5 FOR A REAL
L1 = THE SIZE IN BYTES
THE PROGRAM MAY NOT START ABOVE $BFFF
MOVE THE PROGRAM START UP PAST THE VARIABLE
THE CODE BEGINS 20 BYTES AFTER THE PROGRAM START
AND THE OBJECT FILE'S BASE MOVES WITH IT
APPEND THE SYMBOL TO THE LIST OF COMMON DECLARATIONS AT SC(0)
START AT THE HEAD OF THE LIST
AT THE END OF THE LIST: A TWO-WORD ENTRY (LINK, SYMBOL)
THE NEXT ENTRY; THE SAME SYMBOL DECLARED TWICE IS AN ERROR
4900AFTER A NAME IN A DECLARATION LIST: A COMMA CONTINUES IT, THE END OF THE LINE ENDS IT
SPACES MAY FOLLOW THE NAME
A COMMA: SKIP IT AND ANY SPACES AND RETURN FOR THE NEXT NAME
THE LIST HAS ENDED: DROP THE RETURN TO THE LIST
THE DECLARATION MUST END THE LINE
LIST A RECOGNIZED DIRECTIVE LINE ON THE SCREEN
AFTER THE WORD RECOGNIZED ...
... THE LINE ITSELF
GO ON WITH THE CONTROL-C CHECK AND THE NEXT LINE
5100MATCH THE KEYWORD IN WL$ AGAINST THE SOURCE, LETTER BY LETTER (SPACES ALLOWED); A MISMATCH IGNORES THE REST OF THE REMARK
ENTRY: MATCH THE WORD COMMON
EACH LETTER OF WL$ MUST BE THE CURRENT CHARACTER; SPACES BETWEEN LETTERS ARE SKIPPED
WHEN ALL LETTERS MATCH, RETURN
A MISMATCH: DROP THE RETURN TO THE CALLER
THE LINE IS AN ORDINARY REMARK: SKIP TO THE END OF THE LINE
AND GO ON WITH THE NEXT LINE
5200SKIP SPACES
5300STOP / NEW: CALL THE LIBRARY; WHAT FOLLOWS ON THE LINE IS NOT REACHED
JSR TO THE LIBRARY: CALL TABLE ENTRY 51 FOR STOP, 63 (END, $1363) FOR NEW
THE REST OF THE LINE IS NOT REACHED
5400ON EXPRESSION GOTO / GOSUB LINE[,LINE]...: CALL WITH THE COUNT AND THE LINE ADDRESSES
RESUME/DEBUG CALL BEFORE THE STATEMENT
THE INDEX EXPRESSION
CALL TABLE ENTRY 52 IS ON ... GOSUB ...
EXPECT GOSUB
JSR TO THE ROUTINE (INTEGER ENTRY, OR 3 LOWER FOR A REAL INDEX)
THE COUNT BYTE, PATCHED WHEN THE LIST IS COMPLETE
(A PLACE FOR THE COUNT)
S3 COUNTS THE LINES
EACH LINE NUMBER ...
... BECOMES A WORD CHAINED TO THE LINE'S SYMBOL
COUNT IT
PATCH THE COUNT BYTE
THE COUNT IS PATCHED INTO THE BYTE AFTER THE JSR
5600WAIT ADDRESS,MASK[,MASK]
RESUME/DEBUG CALL BEFORE THE STATEMENT
THE ADDRESS
CALL TABLE ENTRY 49 SAVES THE ADDRESS (REAL ENTRY, OR 3 LOWER FOR AN INTEGER)
EXPECT ,
THE MASK
NO SECOND MASK: ENTRY 53, WAIT
ENTRY 119 SAVES THE MASK
SKIP THE COMMA
THE SECOND MASK, THEN ENTRY 54, WAIT WITH TWO MASKS
5800DEF FN NAME(PARAMETER)=EXPRESSION: JUMP OVER THE BODY; THE BODY STORES THE ARGUMENT IN THE PARAMETER, COMPUTES THE EXPRESSION AND RETURNS
EXPECT FN (DEF GETS NO RESUME/DEBUG CALL)
THE FUNCTION'S NAME
NOT A NAME
FIND OR ENTER THE FUNCTION'S SYMBOL
ITS ADDRESS IS ALREADY SET: A FUNCTION IS DEFINED ONLY ONCE
A JMP OVER THE BODY
ITS ADDRESS WORD IS PATCHED AT THE END OF THE BODY
(TWO BYTES FOR THE ADDRESS)
THE BODY STARTS HERE: THE FUNCTION'S ADDRESS
EXPECT (
THE PARAMETER'S NAME
WHILE THE BODY IS COMPILED THIS NAME MEANS THE PARAMETER
THE PARAMETER IS A REAL TEMPORARY OF ITS OWN (FROM CHAIN 8)
A REAL TEMPORARY FROM THE FUNCTION'S OWN CHAIN
T5 = THE PARAMETER'S SYMBOL
THE BODY STARTS BY STORING THE ARGUMENT (IN THE FLOATING POINT ACCUMULATOR) IN THE PARAMETER: OPERATION 1
A LOAD OF THE PARAMETER RIGHT AFTER THIS STORE IS LEFT OUT
(THE ADDRESS OF THE STORE)
EMIT THE STORE
EXPECT )
EXPECT =
THE BODY'S EXPRESSION, A REAL VALUE LEFT IN THE ACCUMULATOR
RTS
(THE RTS)
PATCH THE JMP WITH THE ADDRESS AFTER THE BODY
THE PARAMETER'S NAME IS AN ORDINARY NAME AGAIN
THE FUNCTION'S TEMPORARIES ARE KEPT FOR IT ALONE
6100POKE ADDRESS,VALUE
RESUME/DEBUG CALL BEFORE THE STATEMENT
THE ADDRESS
CALL TABLE ENTRY 49 SAVES THE ADDRESS (REAL ENTRY, OR 3 LOWER FOR AN INTEGER)
EXPECT ,
THE VALUE, THEN ENTRY 57, POKE
6200PRINT: EACH ITEM BY TYPE; ; NOTHING, , A TAB TO THE NEXT FIELD, TAB( AND SPC( CALLS; A CARRIAGE RETURN UNLESS THE STATEMENT ENDS WITH ; , TAB( OR SPC(
RESUME/DEBUG CALL BEFORE THE STATEMENT
AFTER AN ITEM (OR FOR PRINT ALONE) AT THE END OF THE STATEMENT: JSR TO CALL TABLE ENTRY 58, THE ROM'S CARRIAGE RETURN (CRDO, $DAFB)
AFTER ; , TAB( OR SPC( AT THE END OF THE STATEMENT: NO CARRIAGE RETURN
, JSR TO ENTRY 56, THE TAB TO THE NEXT PRINT FIELD
TAB(: ENTRY 121
NOT SPC(: AN EXPRESSION
SPC(: ENTRY 84
SKIP TAB( OR SPC(
THE ARGUMENT
EXPECT )
JSR TO THE ENTRY (INTEGER ENTRY, OR 3 LOWER FOR A REAL ARGUMENT)
AN EXPRESSION OF EITHER TYPE
A NUMBER: ENTRY 82 (REAL ENTRY, OR 3 LOWER FOR AN INTEGER)
6400GET V
RESUME/DEBUG CALL BEFORE THE STATEMENT
THE VARIABLE
ITS TYPE IN EP, AND THE CODE FOR AN ARRAY ELEMENT'S ADDRESS
CALL TABLE ENTRY 62 GETS A NUMBER (A KEY'S DIGIT VALUE) ...
... ENTRY 64 A ONE-CHARACTER STRING
STORE THE VALUE IN THE VARIABLE
A COMMA CONTINUES THE LIST
6500EXPECT A COMMA, ELSE THE STATEMENT IS FINISHED
SKIP THE EXPECTED CHARACTER AND RETURN
NOT THERE: DROP THE RETURN TO THE STATEMENT ...
... WHICH IS FINISHED
6600CALL / HIMEM: (ONE ARGUMENT, REAL ENTRY)
RESUME/DEBUG CALL BEFORE THE STATEMENT
THE ARGUMENT
THE ROUTINE IS CALL TABLE ENTRY TOKEN-128: 12 CALL, 35 HIMEM:
JSR, REAL ENTRY OR 3 LOWER FOR AN INTEGER ARGUMENT
6700STATEMENTS WITH ONE ARGUMENT: VTAB HTAB COLOR= HCOLOR= SPEED= ROT= SCALE= IN# PR#
RESUME/DEBUG CALL BEFORE THE STATEMENT
THE ARGUMENT
THE ROUTINE IS CALL TABLE ENTRY TOKEN-128 (ALSO THE LAST CALL OF PLOT, HLIN, VLIN, DRAW, WAIT, POKE)
JSR, INTEGER ENTRY OR 3 LOWER FOR A REAL ARGUMENT
6800POP / CLEAR / STATEMENTS WITHOUT ARGUMENTS
RESUME/DEBUG CALL BEFORE THE STATEMENT (POP, CLEAR)
JSR TO CALL TABLE ENTRY TOKEN-128; GR, TEXT, HGR, HGR2, HOME, NORMAL, INVERSE, FLASH AND RESTORE COME HERE DIRECTLY, WITHOUT A RESUME/DEBUG CALL
6830END OF THE STATEMENT: LIST THE LINE IF ASKED, CHECK FOR CONTROL-C, GO ON WITH THE NEXT STATEMENT OR LINE
THE STATEMENT MUST END HERE
LIST THE LINE WHEN IT IS COMPLETE
CONTROL-C TERMINATES THE COMPILATION
6870END OF THE PROGRAM: PATCH THE REFERENCES STILL WAITING ON THE STACK, CLOSE THE FILES AND RUN PASS 2
THE IF STATEMENTS OF THE LAST LINE STILL WAIT FOR THE ADDRESS OF THE NEXT LINE: PATCH THEM WITH THE END OF THE PROGRAM
THE PROGRAM ENDS WITH A JMP TO CALL TABLE ENTRY 0, THE LIBRARY'S END ROUTINE
(THE JMP)
SET DOS'S OUTPUT STATE TO THE START OF A WRITE LINE, SO THE NEXT CONTROL-D STARTS A COMMAND
CLOSE ALL FILES
STRING STORAGE IS SET UP SO THAT THE COMMON STRINGS SURVIVE THE CHAIN TO PASS 2
RUN PASS 2
6950WARNING: LINE NUMBER N IGNORED (AN UNSUPPORTED KEYWORD, OR A STATEMENT AFTER AN UNCONDITIONAL TRANSFER); SKIP TO THE NEXT COLON OUTSIDE QUOTES
END THE DIRECT FILE OUTPUT
TWO BELLS
THE NUMBER OF THE LINE BEING COMPILED
SKIP THE STATEMENT
CHECK FOR CONTROL-C, THEN GO ON
7100SKIP TO THE NEXT COLON OUTSIDE QUOTES OR THE END OF THE LINE
K8 = 1 OUTSIDE QUOTES, 0 INSIDE
A QUOTE SWITCHES
A COLON OUTSIDE QUOTES ENDS THE STATEMENT
LIST THE LINE SO FAR
7200EXPECT = / ( / ) / , / THE CHARACTER IN XF; ELSE A SYNTAX ERROR
EXPECT = (TOKEN 208)
EXPECT (
EXPECT )
EXPECT A COMMA
THE EXPECTED CHARACTER: SKIP IT AND RETURN; ANYTHING ELSE IS A SYNTAX ERROR
7530FATAL ERRORS: NAME THE KIND IN WL$
A STATEMENT THAT DOES NOT FOLLOW THE RULES
A DECLARATION OUT OF PLACE, MIXED OR REPEATED
A BAD DIMENSION OR NUMBER OF SUBSCRIPTS
THE PARSE STACK OR THE TRIPLE TABLE IS FULL
A SOURCE LINE TOO LONG FOR THE LISTING BUFFER, OR A PROGRAM THAT WOULD PASS $BFFF
NO ROOM LEFT IN SC()
AN EXPRESSION THAT ENDS TOO SOON
A NUMBER THAT CANNOT BE CONVERTED, OR SOMETHING THAT IS NOT AN OPERAND
AN ARRAY DIMENSIONED AGAIN OR A FUNCTION DEFINED AGAIN
A STRING WHERE A NUMBER IS NEEDED, OR THE REVERSE
7720REPORT A FATAL ERROR, SHOW THE LINE WITH !ERR!, PAUSE IF ASKED; NO MORE CODE IS WRITTEN
END THE DIRECT FILE OUTPUT
FROM NOW ON NO CODE IS WRITTEN; PARSING GOES ON TO FIND MORE ERRORS
TWO BELLS
WHICH ERROR, FROM WL$
THE LINE UP TO THE ERROR ...
... THE MARK ...
... AND THE REST OF THE STATEMENT
WITHOUT THE PAUSE OPTION, GO ON AT ONCE
STOP THE DRIVE MOTOR WHILE WAITING
CLEAR THE KEYBOARD STROBE
THE PROMPT
WAIT FOR A KEY
CLEAR THE KEYBOARD STROBE
CONTROL-C ENDS THE COMPILATION
THE ERROR MAY HAVE COME FROM DEEP INSIDE SUBROUTINES: RESET THE STACK
AND EMPTY THE PARSE STACK, THE TRIPLE TABLE AND THE DEF FN STATE
GO ON WITH THE NEXT STATEMENT OR LINE
7990CONVERT THE DIGITS IN WL$ TO A NUMBER (A BAD NUMBER SETS N5)
A NUMBER TOO LARGE FOR VAL GIVES AN ERROR, CAUGHT HERE
VAL CONVERTS THE DIGITS (THE INTERPRETER'S OWN NUMBER CONVERSION)
TURN ONERR OFF AGAIN (ERRFLG, $D8)
A GOOD NUMBER
RETURN TO THE CALLER: K8 = 1 A DIMENSION (2300), 2 A LINE NUMBER (8700), 3 A CONSTANT (12200)
AN ERROR IN VAL: TURN ONERR OFF ...
... AND RESET THE STACK
A BAD NUMBER
8100LIST THE LINE IN THE LISTING BUFFER
NOTHING TO LIST
END THE DIRECT FILE OUTPUT
A ZERO ENDS THE TOKENIZED LINE
THE BUFFER IS EMPTY AGAIN
THE ROUTINE AT $038D LISTS THE LINE, EXPANDING THE TOKENS INTO KEYWORDS
8200NEXT TOKEN: T0 = NEXT BYTE OF THE LINE, MJ = THE ONE AFTER IT, COPYING EACH INTO THE LISTING BUFFER
THE PREVIOUS TOKEN WAS NOT THE END OF THE LINE
8220START A LINE: READ ITS NUMBER, DEFINE ITS LINE SYMBOL AT THE CURRENT CODE ADDRESS, RECORD IT IN THE LINE NUMBER FILE
ENTRY AT THE START OF A LINE: NO STORE TO REMEMBER ...
... AND THE NEW LINE IS REACHED
THE LINE NUMBER, LOW BYTE ...
JS IS CURRENT SOURCE LINE NUMBER
THE HIGH BYTE OF THE LINE NUMBER
... AND HIGH BYTE
THE FIRST BYTE OF THE LINE'S TEXT
WITH THE LISTING OPTION, PRINT THE LINE NUMBER
THE LINE NUMBER FILE TAKES A RECORD FOR EACH LINE: ITS NUMBER AND THE ADDRESS OF ITS CODE
WRITE THE RECORD EVEN AFTER A FATAL ERROR
THE LINE NUMBER, AS A WORD
(THE NUMBER, LOW BYTE FIRST)
THE ADDRESS WHERE THE LINE'S CODE BEGINS
(THE ADDRESS, LOW BYTE FIRST)
NORMAL OBJECT OUTPUT AGAIN
COUNT THE LINE
THE FIRST TOKEN OF THE LINE BECOMES THE LOOKAHEAD
AND THE BYTE AFTER IT IS READ
THE IF STATEMENTS OF THE PREVIOUS LINE ARE WAITING FOR THIS LINE'S ADDRESS: PATCH THEIR JMP ADDRESSES
THE LISTING BUFFER IS FULL: THE LINE IS TOO LONG
COPY THE PREVIOUS TOKEN INTO THE LISTING BUFFER
THE LOOKAHEAD BECOMES THE CURRENT TOKEN
NOT THE END OF THE LINE: THE BYTE JUST READ BECOMES THE LOOKAHEAD, AND THE NEXT BYTE IS READ
THE END OF THE LINE: THE NEXT TWO BYTES ARE THE NEXT LINE'S LINK
THE HIGH BYTE OF THE LINK
A ZERO LINK ENDS THE PROGRAM; THEN READ THE LOW BYTE OF THE NEXT LINE NUMBER
8490READ ONE BYTE OF THE SOURCE FILE INTO IV
THE SOURCE FILE MUST BE SET UP FOR READING
THE ROUTINE AT $037E READS ONE BYTE OF THE FILE INTO $0376
KEEP THE DRIVE RUNNING
IV = THE BYTE READ
8600LINE NUMBER REFERENCE: FIND OR ENTER THE LINE'S SYMBOL
THE DIGITS OF THE LINE NUMBER
NOT A NUMBER
CONVERT IT (RETURNING TO 8700)
A LINE NUMBER FROM 0 TO 65534
LINE SYMBOLS HOLD THE NUMBER-32767
ITS CHAIN: L + NUMBER MOD NK
THE END OF THE CHAIN: A NEW THREE-WORD ENTRY (LINK, REFERENCE CHAIN, NUMBER); VB POINTS AT ITS REFERENCE CHAIN
THE NEXT ENTRY; THE SAME NUMBER IS THE LINE'S SYMBOL
NOT THIS ONE: GO ON ALONG THE CHAIN
8800SCAN A NUMBER INTO WL$
WL$ COLLECTS THE DIGITS
NO DIGIT: NO NUMBER
ADD THE DIGIT AND READ ON
WHILE THERE ARE DIGITS
ADD THE CHARACTER TO WL$ AND GO TO THE NEXT TOKEN
9000NAME WITH ITS TYPE AND SUBSCRIPTS: AN OPERAND
THE NAME AND ITS TYPE
A SIMPLE VARIABLE OR AN ARRAY ELEMENT
RETURN ITS TRIPLE IN VB
AN OPERAND TRIPLE: KIND K4, LEFT = THE SYMBOL VB; IT GOES ON THE PARSE STACK
THE TRIPLE'S KIND IS THE OPERAND'S TYPE CODE
9200NAME WITH ITS TYPE SUFFIX: K4 = -1 FOR %, -2 FOR $, ELSE -3
THE NAME
% : AN INTEGER
$ : A STRING
A NAME, REAL UNLESS A SUFFIX FOLLOWS
NO NAME
K4 = -3: REAL
A SIMPLE REAL NAME AND ITS SYMBOL (FOR AND NEXT VARIABLES); AN INTEGER-DECLARED NAME IS FOUND AS AN INTEGER
9500SCAN A NAME: HY = 99*FIRST CHARACTER+SECOND; LATER LETTERS AND DIGITS ARE SKIPPED
A NAME STARTS WITH A LETTER
99 TIMES THE FIRST CHARACTER ...
READ THE SECOND CHARACTER
... PLUS THE SECOND, A LETTER OR DIGIT
9600ARRAY ELEMENT: SUBSCRIPTS AS EXPRESSIONS, CHECKED AGAINST THE ARRAY'S DIMENSIONS
KEEP THE NAME HASH AND THE ARRAY TYPE CODE ON THE STACK
(PUSH THE HASH)
THE ARRAY TYPE CODE: 19 REAL, 20 STRING, 21 INTEGER
SKIP (
ONE SUBSCRIPT SO FAR
A SUBSCRIPT: A NUMERIC EXPRESSION, LEFT ON THE STACK AS A TRIPLE
A COMMA: ANOTHER SUBSCRIPT
SKIP THE COMMA, AND COUNT THE SUBSCRIPT UNDER THE ONES BEFORE IT ON THE STACK
THE COUNT, UNDER THE SUBSCRIPT JUST PARSED
AT MOST 88 SUBSCRIPTS
THE NEXT SUBSCRIPT
THE LAST SUBSCRIPT
EXPECT )
O2 = THE NUMBER OF SUBSCRIPTS
THE COUNT
T9 = THE ARRAY'S OWN TRIPLE
THE ARRAY'S TRIPLE TAKES THE LAST SUBSCRIPT AS ITS RIGHT OPERAND; THE OTHERS GO, LAST TO FIRST, TWO TO A TRIPLE WITH OPERATION 22 (A MISSING SECOND ONE IS 0)
AFTER EACH RIGHT OPERAND BUT THE LAST: A NEW TRIPLE WITH OPERATION 22
THE NEXT SUBSCRIPT FROM THE STACK
THE ARRAY TYPE CODE
AN EVEN COUNT LEAVES THE LAST PAIR'S RIGHT OPERAND EMPTY
THE NEXT FREE TRIPLE
THE NAME HASH
FIND OR ENTER THE ARRAY'S SYMBOL
A NEW ARRAY: STORE ITS NUMBER OF SUBSCRIPTS AND MARK IT NOT DIMENSIONED (-1); IT GETS 10 PER SUBSCRIPT
AN OLD ONE MUST HAVE THE SAME NUMBER OF SUBSCRIPTS
THE ARRAY'S TRIPLE: KIND = THE ARRAY TYPE (19 REAL, 20 STRING, 21 INTEGER), LEFT = THE SYMBOL
(THE SYMBOL)
IT GOES ON THE STACK
10100FUNCTION ARGUMENTS, AS DESCRIBED IN F()
EXPECT (
KEEP THE FUNCTION'S OPERATION ON THE STACK
THE FIRST ARGUMENT
SAVE F() ON THE STACK (THE ARGUMENT MAY CALL ANOTHER FUNCTION)
ML = THE ARGUMENT'S TRIPLE
GET F() BACK
(EACH VALUE)
THE ARGUMENT'S TRIPLE REPLACES ITS TYPE
ALL ARGUMENTS READ
FEWER ARGUMENTS ARE ALLOWED ONLY FOR MID$ WITH TWO
THE FUNCTION'S TRIPLE: ITS OPERATION, THE FIRST ARGUMENT AS LEFT, THE SECOND AS RIGHT (0 IF NONE)
(THE FIRST ARGUMENT)
(THE SECOND ARGUMENT)
A THIRD ARGUMENT GOES INTO A FOLLOWING TRIPLE WITH OPERATION 17
THE FUNCTION'S TRIPLE GOES ON THE STACK
EXPECT )
10500STRING LITERAL: JUMP OVER ITS LENGTH AND TEXT; THE CODE REFERS TO IT BY ADDRESS
SKIP THE OPENING QUOTE
THE TEXT STARTS HERE IN THE LISTING BUFFER
THE TEXT ENDS AT THE CLOSING QUOTE OR THE END OF THE LINE
A JMP ...
... TO THE ADDRESS AFTER THE TEXT: 2 FOR THE ADDRESS, 1 FOR THE LENGTH, THEN THE TEXT
(THE ADDRESS AFTER THE TEXT)
VB = THE LITERAL'S ADDRESS (ITS LENGTH BYTE)
ENTRY: WRITE THE LENGTH AND THE TEXT, COPIED FROM THE LISTING BUFFER
THE TEXT, BYTE BY BYTE
SKIP THE CLOSING QUOTE
AN EXPRESSION OF EITHER TYPE, THEN ITS CODE
A NUMERIC EXPRESSION WHOSE VALUE IS WANTED AS A REAL (A REAL TARGET OR A FUNCTION BODY)
THE VALUE MUST BE REAL
10900EXPRESSIONS: PARSE INTO TRIPLES, THEN GENERATE THE CODE (EP GIVES THE TYPE)
A NUMERIC EXPRESSION AND ITS CODE
ITS CODE
AN INTEGER RESULT LEFT AS AN INTEGER: EP = 1
A STRING EXPRESSION AND ITS CODE
ITS CODE
PARSE AN EXPRESSION OF EITHER TYPE ...
... A NUMERIC ONE ...
... OR A STRING ONE
11310PARSER: BOTTOM UP WITH THE OPERATOR AND OPERAND STACK; OPERANDS AND REDUCED OPERATORS BECOME TRIPLES IN TP()
KEEP THE TYPE WANTED ON THE STACK
0 MARKS THE BOTTOM OF THIS EXPRESSION'S OPERATORS
(THE BOTTOM MARK)
... OR A NAME
NOT A NAME: A NUMERIC OPERAND (NUMBER, FUNCTION, SIGN OR NOT)
A NUMERIC VARIABLE
A NUMERIC EXPRESSION IS COMPLETE: ML = ITS RESULT
TAKE IT OFF THE STACK, WITH THE TYPE WANTED
THE TYPE WANTED, FROM UNDER THE RESULT
A STRING WAS WANTED
EP = 3: NUMERIC
VB = THE RESULT'S TRIPLE
AFTER A STRING OPERAND: A RELATION?
YES: A STRING COMPARISON, WHOSE RESULT IS NUMERIC
A STRING EXPRESSION IS COMPLETE
THE RESULT
IT MUST BE COMPLETE
THE TYPE WANTED
A NUMBER WAS WANTED
EP = 2: STRING
VB = THE RESULT'S TRIPLE
ENTRY AFTER AND / OR, WHERE A STRING COMPARISON MAY FOLLOW: A STRING LITERAL ...
... A NAME ...
... OR A NUMERIC OPERAND
A NUMERIC VARIABLE
A STRING VARIABLE
KEEP THE STRING OPERAND ON THE STACK
A STRING OPERAND HERE MUST BE COMPARED
NO RELATION: A STRING CANNOT STAND HERE
STRING RELATIONS ARE THE RELATION TOKEN+38 (245 >, 246 =, 247 <, 273 >=, 274 <=, 275 <>)
PUSH THE STRING RELATION
SKIP THE RELATION
THE RIGHT-HAND STRING EXPRESSION
KEEP ITS RESULT ON THE STACK
GO ON AS AFTER A NUMERIC OPERAND
A NUMERIC OPERAND: OPENING PARENTHESES ...
... A UNARY - BECOMES THE NEGATION OPERATOR 239 ...
... AND NOT (198) IS AN OPERATOR TOO
PUSH THE OPERATOR
A NAME?
A NUMERIC VARIABLE: REAL, OR INTEGER WITH %
% : AN INTEGER VARIABLE
SIMPLE OR ARRAY ELEMENT
THEN AN OPERATOR OR THE END
A NUMBER: ITS DIGITS ...
NO DIGITS AND NO POINT: A FUNCTION
... AND AN EXPONENT, E WITH AN OPTIONAL SIGN
THE E
- IS PUT IN AS THE CHARACTER -
THE EXPONENT'S DIGITS
CONVERT AND ENTER THE CONSTANT
ITS OPERAND TRIPLE
CONVERT WL$ (RETURNING TO 12200)
A NUMBER VAL CANNOT CONVERT
12210NUMERIC CONSTANT: AN INTEGER IF INTEGER CONSTANTS ARE ON AND THE VALUE IS A WHOLE NUMBER UP TO 32767, ELSE REAL, PACKED BY THE USR ROUTINE; ENTERED IN ITS CONSTANT CHAIN (VALUE OR EXPONENT MOD 32)
AN INTEGER CONSTANT, CHAINED BY ITS VALUE MOD 32
A REAL CONSTANT
THE USR ROUTINE PACKS THE VALUE INTO 5 BYTES AT $0371 (ROUNDED AS THE ROM STORES A NUMBER)
CHAINED BY ITS EXPONENT BYTE MOD 32
ITS CHAIN: KX + KEY MOD NG
NOT AT THE END OF THE CHAIN: COMPARE WITH THE NEXT ENTRY
A NEW REAL CONSTANT: AN EIGHT-WORD ENTRY (LINK, REFERENCE CHAIN, OPERATION MASK, THE 5 BYTES)
A NEW INTEGER CONSTANT: A FIVE-WORD ENTRY (LINK, REFERENCE CHAIN, OPERATION MASK, -10 TO MARK AN INTEGER, THE VALUE)
(THE ENTRY)
NO OPERATIONS USED YET
-10 MARKS AN INTEGER CONSTANT
THE VALUE
THE NEXT ENTRY
A REAL CONSTANT IS COMPARED BYTE BY BYTE
AN INTEGER CONSTANT MATCHES AN INTEGER ENTRY WITH THE SAME VALUE
THE SAME 5 BYTES?
A DIFFERENT BYTE: GO ON ALONG THE CHAIN
FOUND: VB POINTS AT ITS REFERENCE CHAIN
12440NUMERIC FUNCTION CALL (SGN TO LEN, VAL, ASC)
NOT A NUMERIC FUNCTION: FN
THE FUNCTION'S OPERATION IS TOKEN-181 (SGN = 29 ... ASC = 49)
ONE ARGUMENT ...
... OF EITHER TYPE FOR FRE AND POS (IT IS NOT EVALUATED)
... NUMERIC FOR SGN TO PEEK ...
... A STRING FOR LEN, VAL AND ASC
SCRN( : TWO NUMERIC ARGUMENTS; THE ( IS PART OF THE TOKEN
SKIP THE FUNCTION'S TOKEN
THE ARGUMENT IN PARENTHESES
12540FN NAME(ARGUMENT)
FN
SKIP FN
THE FUNCTION'S NAME
NO NAME
EXPECT (
THE FUNCTION'S SYMBOL, KEPT ON THE STACK
(PUSH THE SYMBOL)
THE ARGUMENT, A NUMERIC EXPRESSION
IT IS THE TRIPLE'S RIGHT OPERAND
OPERATION 18 CALLS THE FUNCTION: LEFT = ITS SYMBOL
THE TRIPLE GOES ON THE STACK
EXPECT )
AFTER AN OPERAND: A RELATION?
REDUCE WHAT THE NEXT OPERATOR ALLOWS
NOT AN OPERATOR
PUSH THE OPERATOR
SKIP THE OPERATOR
AFTER AND / OR A STRING COMPARISON MAY FOLLOW
ANOTHER NUMERIC OPERAND
THE EXPRESSION IS COMPLETE: RETURN ITS RESULT
ANYTHING ELSE: THE EXPRESSION IS INCOMPLETE
A STRING OPERAND: OPENING PARENTHESES ...
... A LITERAL ...
ENTRY: A STRING LITERAL; ITS TRIPLE HAS KIND -4 AND THE LITERAL'S ADDRESS
KIND -4: A STRING LITERAL
... A STRING FUNCTION ...
ENTRY: A STRING FUNCTION; ITS OPERATION IS TOKEN-181 (STR$ = 47, CHR$ = 50, LEFT$ = 51, RIGHT$ = 52, MID$ = 53)
STR$ AND CHR$: ONE NUMERIC ARGUMENT
LEFT$ AND RIGHT$: A STRING AND A NUMBER
MID$: A STRING AND ONE OR TWO NUMBERS
SKIP THE FUNCTION'S TOKEN
THE ARGUMENTS IN PARENTHESES
THEN REDUCE
... OR A STRING VARIABLE
THE NAME MUST END WITH $
ENTRY AFTER A NAME AND $: A STRING VARIABLE
KIND -2: A STRING VARIABLE
SIMPLE OR ARRAY ELEMENT
AFTER A STRING OPERAND: REDUCE
+ JOINS STRINGS (CONCATENATION, 238)
THE EXPRESSION IS COMPLETE
A STRING OPERAND ALSO ENDS AT AN OPEN PARENTHESIS OR AFTER AND / OR (A COMPARISON FOLLOWS)
ANYTHING ELSE: INCOMPLETE
13200TWO-CHARACTER RELATIONS: >= OR => (235), <= OR =< (236), <> OR >< (237)
N5 = 0: A RELATION
>
>= : 235
>< : 237
<
<= : 236
<> : 237
NOT A RELATION
=> : 235
=< : 236
13500REDUCE WHILE THE OPERATOR ON THE STACK HAS A HIGHER PRIORITY THAN THE ONE ARRIVING (OE())
THE EXPRESSION IS NOT COMPLETE YET
NO OPERATOR LEFT: THE EXPRESSION IS COMPLETE
( IS ALWAYS PUSHED
AN OPERATOR OR ) ARRIVING: COMPARE PRIORITIES
THE END OF THE EXPRESSION: AN OPEN PARENTHESIS IS INCOMPLETE
OTHERWISE REDUCE
THE OPERATOR ON THE STACK
CONCATENATION AND THE STRING RELATIONS HAVE THE PRIORITIES OF + AND OF THE NUMERIC RELATIONS
THE OPERATOR ARRIVING
LOOK BOTH UP IN OE(): THE STACK PRIORITY OF THE ONE ON THE STACK, THE ARRIVING PRIORITY OF THE OTHER
(THE PRIORITY REPLACES THE TOKEN)
NOT HIGHER: STOP REDUCING (THE ARRIVING OPERATOR WILL BE PUSHED)
A ) ON THE STACK: REMOVE IT AND ITS (, KEEPING THE OPERAND BETWEEN THEM
A BINARY OPERATOR ...
... BUT NEGATION AND NOT TAKE ONE OPERAND
THE RIGHT OPERAND
THE OPERATOR, AS AN OPERATION NUMBER:
+ - * / ^ AND OR > = < BECOME 1 TO 10
>= <= <> BECOME 11 TO 13
NOT BECOMES 14
NEGATION BECOMES 15
CONCATENATION BECOMES 16
STRING > = < BECOME 23 TO 25
STRING >= <= <> BECOME 26 TO 28
THE OPERATION IN THE NEW TRIPLE
THE TRIPLE GOES ON THE STACK AS AN OPERAND
AND REDUCE FURTHER
ENTRY: PUSH THE TRIPLE BEING BUILT AND START THE NEXT
14000PARSE STACK: PUSH AN OPERATOR, POP, PUSH AND POP AN OPERAND
PUSH AN OPERATOR: IT IS THE NEW TOP OPERATOR
PUSH ON THE OPERATOR SIDE (OPERATORS AND OPERAND TRIPLES)
(ONE MORE)
THE TWO SIDES MET: TOO COMPLEX
POP FROM THE OPERATOR SIDE
AN OPERAND WAS POPPED, OR THE STACK IS EMPTY: THE TOP OPERATOR IS UNCHANGED
OTHERWISE FIND THE NEW TOP OPERATOR, ONE OR TWO PLACES DOWN
(THE OPERATOR IS UNDER AN OPERAND)
PUSH ON THE OPERAND SIDE (VALUES KEPT FOR LATER)
THE TWO SIDES MET: TOO COMPLEX
POP FROM THE OPERAND SIDE
14400STORE A TRIPLE IN TP()
THE TRIPLE'S OPERATION OR OPERAND KIND
ITS LEFT OPERAND
ITS RIGHT OPERAND
THE NEXT TRIPLE; AT MOST 100
14800VARIABLE SYMBOL: FIND OR ENTER THE NAME IN CHAIN (HASH+TYPE) MOD 32, AT THE END OF THE CHAIN; INSIDE DEF FN THE PARAMETER'S NAME MEANS THE PARAMETER
INSIDE DEF FN THE PARAMETER'S NAME MEANS THE PARAMETER
THE KEY: NAME HASH PLUS TYPE CODE
ITS CHAIN: VO + KEY MOD NU
THE END OF THE CHAIN: A NEW FIVE-WORD ENTRY (LINK, REFERENCE CHAIN, OPERATION MASK, NAME HASH, TYPE); WHILE DECLARING INTEGERS A REAL NAME IS ENTERED AS AN INTEGER (TYPE+2), STILL IN THE REAL NAME'S CHAIN
THE NEXT ENTRY: THE SAME NAME HASH?
THE SAME TYPE, OR A REAL NAME FOUND AS AN INTEGER-DECLARED ONE: K4 = THE TYPE FOUND, VB POINTS AT THE REFERENCE CHAIN
NOT THIS ONE: GO ON ALONG THE CHAIN
14900FN SYMBOL: FIND OR ENTER THE FUNCTION'S NAME IN CHAINS 1-4
ITS CHAIN: 1 + NAME HASH MOD 4
THE END OF THE CHAIN: A NEW FOUR-WORD ENTRY (LINK, REFERENCE CHAIN, NAME HASH, ADDRESS); -32767 = NOT DEFINED YET
THE NEXT ENTRY; THE SAME NAME IS THE FUNCTION'S SYMBOL
NOT THIS ONE: GO ON ALONG THE CHAIN
CALL OF A FUNCTION: JSR TO ITS BODY ...
... WHOSE ADDRESS IS KNOWN IF THE DEF FN CAME FIRST ...
... OTHERWISE THE ADDRESS IS CHAINED TO THE FUNCTION'S SYMBOL FOR PASS 2
15100ALLOCATE ML WORDS OF THE SYMBOL TABLE
LINK A NEW ENTRY TO THE END OF THE CHAIN AT VB
IT ENDS THE CHAIN
RESERVE ITS ML WORDS; VB POINTS AT ITS SECOND WORD
(RESERVE THE WORDS)
WHICH IS ITS REFERENCE CHAIN, EMPTY FOR NOW
SYMBOL TABLE FULL?
15300EMIT A VARIABLE OR CONSTANT ROUTINE CALL: MARK THE OPERATION USED, WRITE THE OPERATION NUMBER AND LINK THE REFERENCE INTO THE SYMBOL'S CHAIN
ENTRY: OPERATION K4 ON SYMBOL VB: PASS 2 WRITES A ROUTINE ENTRY ONLY FOR THE OPERATIONS MARKED IN THE SYMBOL'S MASK (BIT K4)
THE BIT IS SET IF SC(VB+1) MOD 2^(K4+1) >= 2^K4
SET THE BIT IF IT IS NOT SET YET
ENTRY WITHOUT THE MASK (STRING VARIABLES AND TEMPORARIES ALWAYS HAVE ALL THEIR ENTRIES): THE OPERATION NUMBER ...
... AND THE PREVIOUS REFERENCE TO THE SYMBOL; THIS REFERENCE BECOMES THE LATEST
THE SYMBOL'S CHAIN NOW STARTS AT THIS REFERENCE
WRITE THE OPERATION NUMBER
THEN THE LINK
15400EMIT AN OPCODE AND A CHAINED REFERENCE (LINE OR FN)
ENTRY: AN OPCODE (JMP OR JSR) ...
ENTRY: ... AND A WORD CHAINED TO THE SYMBOL: IT HOLDS THE PREVIOUS REFERENCE, AND THE SYMBOL NOW HOLDS THIS ONE
THE SYMBOL'S CHAIN NOW STARTS AT THIS WORD
15450EMIT A WORD
ENTRY: A WORD WF KEPT AS ADDRESS-32767, WRITTEN AS THE ADDRESS
ENTRY: THE SAME, WITHOUT ADVANCING PC
ENTRY: A WORD WRITTEN AS IT IS
ENTRY: THE SAME, WITHOUT ADVANCING PC: LOW BYTE ...
HE IS HIGH BYTE OF THAT WORD
... THEN HIGH BYTE
15600EMIT A BYTE
ENTRY: A JMP OPCODE
ENTRY: THE BYTE OW
ENTRY: WRITE OW WITHOUT ADVANCING PC; AFTER A FATAL ERROR ONLY LINE NUMBER FILE RECORDS ARE WRITTEN. DOS'S OUTPUT STATE 4 SENDS EVERY CHARACTER TO THE FILE; THE ROUTINE AT $0387 WRITES THE BYTE IN $0376
15700WRITE TO THE LINE NUMBER FILE / PATCH A WORD IN THE OBJECT FILE
ENTRY: PATCH THE WORD AT PN WITH THE CURRENT CODE ADDRESS
ENTRY: PATCH THE BYTE AT PN WITH OW
NOTHING IS WRITTEN AFTER A FATAL ERROR
DOS'S OUTPUT STATE 5: A CONTROL-D STARTS A COMMAND
POSITION THE OBJECT FILE AT THE BYTE TO PATCH
DOS WRITE WITH A BYTE POSITION, RELATIVE TO THE FILE'S START
THE OBJECT FILE IS SET UP FOR WRITING
... OR THE BYTE
AND POSITION THE FILE AT ITS END AGAIN
(THE FILE'S END)
16000FILE HELPERS
END THE DIRECT FILE INPUT OR OUTPUT: A CONTROL-D ALONE
CONTROL-D AND A RETURN END THE DIRECT INPUT OR OUTPUT
NO FILE IS SET UP NOW
KEEP THE DRIVE RUNNING IF ALL FILES ARE ON THE BOOT DRIVE
ENTRY: ADVANCE PC BY 2 FOR A WORD ...
ENTRY: ... OR BY 1 FOR A BYTE, SETTING UP THE OBJECT FILE FOR WRITING IF NEEDED
ONE MORE BYTE
THE CODE MAY NOT PASS $BFFF
16300RESUME/DEBUG: A CALL TO THE LIBRARY'S DEBUG ROUTINE BEFORE THE STATEMENT, EXCEPT RIGHT AFTER THEN
SAVE CI, EMIT THE CALL TO ENTRY 85 ($1423), RESTORE CI
16400EMIT A JSR TO CALL TABLE ENTRY CI; THE ENTRY 3 BYTES LOWER SERVES THE OTHER ARGUMENT TYPE
ENTRY: THE CALL TABLE HOLDS THE REAL ENTRY (WN = 3)
ENTRY: THE CALL TABLE HOLDS THE INTEGER ENTRY (WN = 1)
THE EXPRESSION'S TYPE IS THE OTHER ONE: USE THE ENTRY 3 BYTES LOWER
ENTRY: THE ENTRY AS IT IS
ENTRY: THE ENTRY 3 BYTES LOWER
JSR
16700EMIT A JMP TO CALL TABLE ENTRY CI
THE ENTRY AS IT IS
WRITE THE OPCODE
THEN THE ROUTINE'S ADDRESS
16800TEMPORARIES: TAKE THE FIRST FREE ONE OF THE TYPE FROM ITS CHAIN (5 INTEGER, 6 STRING, 7 REAL, 8 ALL TYPES INSIDE DEF FN), ELSE MAKE A NEW ONE
CHAIN 5 FOR AN INTEGER, 6 A STRING, 7 A REAL
INSIDE DEF FN ALL OF THE FUNCTION'S TEMPORARIES COME FROM CHAIN 8
THE END OF THE CHAIN: A NEW FOUR-WORD ENTRY (LINK, REFERENCE CHAIN, OPERATION MASK, TYPE); A TEMPORARY IN USE HAS ITS TYPE-3
THE NEXT ENTRY: A FREE TEMPORARY OF THIS TYPE IS TAKEN AND MARKED IN USE
16900FREE A TEMPORARY
THE TYPE GOES BACK FROM TYPE-3 TO TYPE
17000END OF DEF FN: THE FUNCTION'S TEMPORARIES ARE NOT USED AGAIN
EACH TEMPORARY IN CHAIN 8 ...
... THAT IS FREE ...
... IS MARKED IN USE FOR GOOD
17100GENERATE THE CODE OF AN ASSIGNMENT'S VALUE
EP = THE TARGET'S TYPE: 1 INTEGER, 2 STRING, 3 REAL (ARRAY TYPE CODES ARE 22 HIGHER)
THE TARGET'S TRIPLE IS LEFT FOR THE STORE (AN ARRAY ELEMENT GETS THE CODE OF ITS ADDRESS)
(THE TARGET'S CODE)
17200CODE GENERATOR: FOR EACH TRIPLE, DECIDE WHETHER ITS OPERANDS ARE INTEGER OR REAL, THEN GENERATE IT; A RESULT THAT IS NOT USED BY THE NEXT TRIPLE GOES TO A TEMPORARY
AFTER A FATAL ERROR NO CODE IS GENERATED
THE FIRST TRIPLE
A ZERO AFTER THE LAST ONE
ALL TRIPLES DONE
OPERATION 0 (LOAD) UNLESS SET BELOW
THE TRIPLE'S OPERATION AND LEFT OPERAND
OPERANDS AND RESULT REAL UNLESS DECIDED BELOW
FZ = 1 IF THE PREVIOUS TRIPLE LEFT THE FLAGS SET
THE FLAGS DO NOT REFLECT THIS TRIPLE YET
AN OPERAND TRIPLE GENERATES NO CODE BY ITSELF
THE CALL TABLE ENTRY FOR AN OPERATION IS ITS NUMBER+64 (2 - IS 66, FSUBT; 8 > IS 72; 29 SGN IS 93 ...)
THE RIGHT OPERAND
+ - * / ^ AND THE RELATIONS WITH TWO INTEGER OPERANDS:
WITH THE INTEGER ARITHMETIC OPTION + - * ARE INTEGER OPERATIONS
THE RELATIONS ALWAYS COMPARE INTEGERS AS INTEGERS
ARRAY ELEMENTS, AND, OR AND NOT USE THEIR OPERANDS AS THEY ARE; AN INTEGER ARRAY ELEMENT IS AN INTEGER
NEGATION OF AN INTEGER (WITH THE OPTION), PEEK, SCRN( AND PDL: INTEGER OPERANDS AND RESULT
CHR$, LEFT$, RIGHT$, MID$: INTEGER ARGUMENTS
LEN, ASC AND POS GIVE INTEGERS
OPERANDS USED AS REALS:
AN INTEGER RESULT LEFT IN THE INTEGER ACCUMULATOR BY THE PREVIOUS TRIPLE MUST BE MADE REAL FIRST
THE LEFT OPERAND, IF THE OPERATION TAKES IT FROM THE ACCUMULATOR AND IT IS AN INTEGER LEFT THERE (KIND -9)
OR THE RIGHT ONE LIKEWISE
IT IS NOW A REAL IN THE ACCUMULATOR
JSR TO CALL TABLE ENTRY 131, WHICH FLOATS THE INTEGER ACCUMULATOR
(THE ENTRY FOR THE OPERATION AGAIN)
17550BY OPERATION: 1 + 2 - 3 * 4 / 5 ^ 6 AND 7 OR 8-13 RELATIONS 14 NOT 15 NEGATION 16 CONCATENATION 18 FN 19-21 ARRAY ELEMENTS
23-28 STRING RELATIONS, 29-53 FUNCTIONS (17 AND 22 NEVER COME HERE)
17590+ * : APPLY THE OPERAND IN MEMORY TO THE ACCUMULATOR
+ IS OPERATION 2 OF A VARIABLE ROUTINE
* IS OPERATION 4
THE RIGHT OPERAND IS IN THE ACCUMULATOR: APPLY THE LEFT ONE
OTHERWISE LOAD THE LEFT OPERAND AND APPLY THE RIGHT ONE
- : OPERATION 3 SUBTRACTS THE ACCUMULATOR FROM THE OPERAND
/ : OPERATION 7 DIVIDES THE OPERAND BY THE ACCUMULATOR
THE LEFT OPERAND IS IN THE ACCUMULATOR: MOVE IT ASIDE
OTHERWISE KEEP THE OPERATION, LOAD THE RIGHT OPERAND ...
(OPERATION 0 FOR THE LOAD, K4 KEPT)
... AND APPLY THE LEFT ONE WITH THE OPERATION
^ : LOAD THE RIGHT OPERAND, LOAD THE LEFT ONE INTO THE SECOND ACCUMULATOR (OPERATION 6) AND CALL ENTRY 69, FPWRT
THE LEFT OPERAND IS IN THE ACCUMULATOR: MOVE IT TO THE SECOND ACCUMULATOR (ENTRY 83, MOVAF) ...
... OR, FOR INTEGERS, ENTRY 133, THE INTEGER MOVE, AND THEN ENTRY 134, THE INTEGER SUBTRACT
THEN LOAD THE RIGHT OPERAND AND CALL
18100AND / OR: TEST THE OPERAND IN MEMORY (LDA, AND ORA FOR AN INTEGER), THEN CALL
THE RESULT SETS THE FLAGS
THE LEFT OPERAND IS IN THE ACCUMULATOR: TEST THE RIGHT ONE IN MEMORY
OTHERWISE LOAD THE RIGHT ONE AND TEST THE LEFT ONE
FOR AN INTEGER IN THE ACCUMULATOR THE INTEGER ROUTINES, ENTRIES 123 AND 124
OPERATION 20: PASS 2 MAKES IT AN LDA OF THE VARIABLE (AND AN ORA OF ITS SECOND BYTE FOR AN INTEGER)
OPERATION 20: THE TEST
NOT: LOAD THE OPERAND
IF IT WAS ALREADY IN THE ACCUMULATOR WITHOUT THE FLAGS SET, SET THEM
THEN CALL ENTRY 78 (EQUAL TO ZERO)
NEGATION: ENTRY 79 (NEGOP), OR 132 FOR AN INTEGER
LOAD THE OPERAND AND CALL
18400COMPARISONS: IF THE RIGHT OPERAND IS IN THE ACCUMULATOR, COMPARE WITH THE LEFT ONE AND USE THE OPPOSITE RELATION
> : THE SWAPPED RELATION IS <
< : THE SWAPPED RELATION IS >
>= : THE SWAPPED RELATION IS <= (FOR CONCATENATION, THE ROUTINE THAT SWAPS ITS OPERANDS)
<= : THE SWAPPED RELATION IS >=
THE RESULT SETS THE FLAGS
STRING OPERATIONS
OPERATION 5 COMPARES THE OPERAND WITH THE ACCUMULATOR
THE RIGHT OPERAND IS IN THE ACCUMULATOR: COMPARE WITH THE LEFT ONE AND USE THE SWAPPED RELATION
OTHERWISE LOAD THE LEFT ONE, COMPARE WITH THE RIGHT ONE AND CALL
FN: LOAD THE ARGUMENT
JSR TO THE FUNCTION'S BODY
18900ARRAY ELEMENT: PUSH ALL SUBSCRIPTS BUT THE FIRST, LAST TO FIRST
U = THE ARRAY'S SYMBOL; CALL TABLE ENTRY 65 PUSHES A SUBSCRIPT
(ENTRY 65)
LOAD THE LAST SUBSCRIPT
MORE SUBSCRIPTS IN A FOLLOWING TRIPLE (OPERATION 22):
PUSH THE ONE LOADED
THE NEXT PAIR
THE PAIR'S FIRST AND SECOND SUBSCRIPTS
LOAD ITS FIRST SUBSCRIPT
THE FIRST SUBSCRIPT STAYS IN THE ACCUMULATOR; A REAL ONE IS MADE AN INTEGER BY ENTRY 1, AYINT
THE ARRAY'S ROUTINE
THE TARGET OF AN ASSIGNMENT: OPERATION 1, WHICH LEAVES THE ELEMENT'S ADDRESS FOR THE STORE; THE TRIPLES ARE DONE
A VALUE: OPERATION 0 LOADS THE ELEMENT
(THE CALL TO THE ARRAY'S ROUTINE)
19060STRING COMPARISONS, LIKEWISE
THE LEFT STRING IS THE RESULT JUST COMPUTED: LOAD THE RIGHT ONE AND CALL
THE RIGHT STRING IS THE RESULT JUST COMPUTED: LOAD THE LEFT ONE AND CALL THE ROUTINE FOR THE SWAPPED ORDER
NEITHER: LOAD THE LEFT STRING, PUSH IT WITH ENTRY 47, LOAD THE RIGHT ONE AND CALL
ENTRY 47 PUSHES THE LOADED STRING
SCRN( : LOAD X AND PUSH IT AS A BYTE (ENTRY 98), THEN LOAD Y AND CALL ENTRY 135
ENTRY 135: SCRN(
ONE-ARGUMENT FUNCTIONS: LOAD THE ARGUMENT AND CALL
LEFT$, RIGHT$, MID$: LOAD THE STRING, THEN THE NUMBER
MID$ WITH THREE ARGUMENTS: PUSH THE SECOND AS A BYTE (ENTRY 98), LOAD THE THIRD (FROM THE OPERATION 17 TRIPLE) AND CALL ENTRY 118 INSTEAD OF 117
JSR, INTEGER OR REAL ENTRY BY THE TYPE OF THE NUMBER
PEEK: LOAD THE ADDRESS; AN INTEGER ADDRESS USES THE ENTRY 3 BYTES LOWER
PDL, CHR$: LOAD THE ARGUMENT AND CALL, INTEGER OR REAL ENTRY
ENTRY: LOAD THE OPERAND, THEN ...
ENTRY: ... JSR, THE ENTRY AS IT IS FOR AN INTEGER OPERAND, 3 BYTES LOWER FOR A REAL ONE
ENTRY: APPLY THE RIGHT OPERAND
ENTRY: APPLY THE OPERAND IN NB WITH OPERATION K4
ENTRY: APPLY THE RIGHT OPERAND, THEN CALL
ENTRY: APPLY NB, THEN CALL
ENTRY: JSR TO CALL TABLE ENTRY CI (ALSO FRE AND POS, WHOSE ARGUMENT IS NOT LOADED)
19810WHERE DOES THE RESULT GO: THE NEXT TRIPLE THAT USES IT, OR A TEMPORARY
LOOK AT THE TRIPLES AFTER THIS ONE
CONCATENATION, STRING ARRAY ELEMENTS, STR$, CHR$, LEFT$, RIGHT$ AND MID$ GIVE STRINGS
THE LAST TRIPLE: THE RESULT STAYS IN THE ACCUMULATOR
THE NEXT OPERATION (OPERANDS AND CONCATENATIONS ARE PASSED OVER)
IT TAKES THIS RESULT FROM THE ACCUMULATOR AS ITS LEFT OPERAND ...
... OR AS ITS RIGHT ONE: KEEP IT THERE
OTHERWISE STORE IT IN A TEMPORARY: AN INTEGER ONE (KIND -8) ...
(KIND -8)
... OR A REAL ONE (KIND -6)
THE TRIPLE NOW STANDS FOR THE TEMPORARY
TAKE A FREE TEMPORARY OF THE TYPE
(ITS SYMBOL)
OPERATION 1 STORES THE RESULT IN IT
(THE STORE)
19960A STRING RESULT IS KEPT IF THE NEXT STRING OPERATION USES IT, ELSE SAVED IN A STRING TEMPORARY
A STRING RESULT: THE LAST TRIPLE KEEPS IT
THE NEXT TRIPLE THAT WORKS ON STRINGS
A CONCATENATION OR STRING RELATION THAT USES IT KEEPS IT
SO DOES A STRING FUNCTION THAT TAKES IT AS ITS STRING
OTHERWISE IT GOES TO A STRING TEMPORARY (KIND -7)
(KIND -7)
TAKE A FREE STRING TEMPORARY
OPERATION 1 STORES IT
(THE STORE, NO MASK NEEDED)
THE RESULT STAYS IN THE ACCUMULATOR: KIND -9 FOR AN INTEGER ...
... -5 FOR A REAL OR A STRING
THE TRIPLE'S NEW KIND
THE NEXT TRIPLE
THE NEXT TRIPLE
ALL TRIPLES DONE: NB = THE LAST ONE
THE TRIPLE TABLE IS EMPTY AGAIN
ITS KIND OR OPERATION
THE TARGET OF AN ASSIGNMENT: KEEP ITS SYMBOL AND KIND FOR THE STORE
AN OPERATION: ITS RESULT IS IN THE ACCUMULATOR
A SINGLE OPERAND: LOADING IT SETS THE FLAGS
A SINGLE INTEGER OPERAND STAYS AN INTEGER UNLESS A REAL IS WANTED
LOAD IT
AN INTEGER RESULT WHERE A REAL IS WANTED: FLOAT IT (ENTRY 131)
20300STORE THE RESULT OF AN EXPRESSION IN THE TARGET
THE TARGET IS A SIMPLE VARIABLE
AN ARRAY ELEMENT: A VALUE FOR AN INTEGER ARRAY THAT IS NOT ALREADY AN INTEGER (FROM INPUT, READ, GET OR A REAL EXPRESSION) IS MADE AN INTEGER (ENTRY 1, AYINT)
THEN ENTRY 67 STORES IT AT THE ELEMENT'S ADDRESS
(THE CALL)
OPERATION 1 STORES THE ACCUMULATOR ...
... OPERATION 7 STORES THE FLOATING POINT ACCUMULATOR IN AN INTEGER VARIABLE
THE TARGET'S SYMBOL
REMEMBER A PLAIN STORE: A LOAD OF THE SAME VARIABLE RIGHT AFTER IT IS LEFT OUT
A STRING VARIABLE NEEDS NO MASK
(EMIT THE STORE)
20500LOAD OR APPLY AN OPERAND
ENTRY: LOAD THE RIGHT OPERAND ...
ENTRY: ... OR NB, UNLESS IT IS ALREADY IN THE ACCUMULATOR (OPERATION 0, KEEPING K4)
ENTRY: APPLY NB WITH OPERATION K4: ITS SYMBOL ...
... AND KIND
A TEMPORARY IS FREE AGAIN ONCE IT IS USED
A STRING LITERAL: JSR TO ENTRY 36 AND THE LITERAL'S ADDRESS
AN INTEGER USED AS A REAL TAKES THE OPERATION+6; AN INTEGER CONSTANT IS REPLACED BY ITS REAL FORM, ENTERED NOW IF NEEDED
A LOAD (OR AND/OR TEST) OF THE VARIABLE JUST STORED IS LEFT OUT WHEN THE STORE WAS THE LAST CODE WRITTEN
STRING VARIABLES AND TEMPORARIES NEED NO MASK
A LOAD OR OTHER OPERATION, MARKED IN THE MASK
AN AND / OR TEST: OPERATION 20
AN INTEGER TAKES THREE MORE BYTES FOR THE ORA OF ITS SECOND BYTE (PASS 2 FILLS THEM IN)
20800SET THE FLAGS FOR IF
A REAL: LDA $9D (THE EXPONENT IS ZERO ONLY FOR ZERO)
AN INTEGER: LDA $A0 ...
... ORA $A1
20900COMPILATION TERMINATED: DELETE THE OBJECT FILE AND RESTORE DOS
END THE DIRECT FILE OUTPUT
CLOSE ALL FILES
AND DELETE THE UNFINISHED OBJECT FILE
(THE FILES STAY CLOSED)
PUT BACK THE SIX BYTES OF DOS THAT PASS 0 CHANGED
THE ADDRESS AND THE ORIGINAL BYTE
OPEN AND CLOSE THE LINE NUMBER FILE; THE PROGRAM ENDS HERE
Variables
| NAME | TYPE | DEFINED | COMMON | MEANING |
|---|---|---|---|---|
| BF | INTEGER | 70 | START OF THE LISTING BUFFER ($0280) | |
| BK | INTEGER | 130 | END OF THE LISTING BUFFER; A LINE THAT REACHES IT IS TOO LONG | |
| BM | INTEGER | 120 | NEXT FREE BYTE IN THE LISTING BUFFER | |
| BO | INTEGER | 100 | START OF THE TEXT OF A STRING LITERAL OR DATA ITEM IN THE LISTING BUFFER | |
| BP$ | STRING | 150 | 37 | TWO BELLS, SOUNDED BEFORE EACH ERROR MESSAGE |
| BX | INTEGER | 120 | 1 IF THE OPERATOR BEING REDUCED TAKES TWO OPERANDS | |
| C3 | INTEGER | 30 | 34 | COMMON KIND: -1 NONE, 0 DEFINE, 255 USE |
| CC | INTEGER | 110 | 25 | ADDRESS OF THE LINK WORD OF THE LAST DATA BLOCK (DATA BLOCKS ARE CHAINED) |
| CC(135) | INTEGER() | 110 | CALL TABLE: ADDRESSES OF THE LIBRARY AND ROM ROUTINES, BY INDEX | |
| CD | INTEGER | 40 | 24 | START OF THE COMMON BLOCK (THE PROGRAM START BEFORE COMMON MOVED IT) |
| CI | INTEGER | 40 | INDEX OF THE ROUTINE IN THE CALL TABLE CC() | |
| CO$ | STRING | 150 | 40 | DOS CLOSE COMMAND |
| D | INTEGER | 60 | ENTRY ADJUSTMENT: 0, OR -3 FOR THE OTHER TYPE'S ENTRY | |
| D2 | INTEGER | 120 | DECLARATION STATE: 2 BEFORE ANY STATEMENT, 1 AFTER COMMON, 0 AFTER A STATEMENT | |
| D3 | INTEGER | 90 | 1 AFTER AN UNCONDITIONAL TRANSFER: FURTHER STATEMENTS ON THE LINE ARE NOT REACHED | |
| DI$ | STRING | 150 | 38 | CONTROL-D, THE DOS COMMAND PREFIX |
| DN$ | STRING | 150 | 46 | SLOT AND DRIVE OF THE BOOT DRIVE (",S6,D1") |
| DP(5,1) | INTEGER() | 130 | 35 | DOS PATCH TABLE: DP(I,0) ADDRESS (AS A SIGNED WORD, ADDRESS-65536), DP(I,1) ORIGINAL BYTE |
| DW | INTEGER | 70 | 10 | DOS STATE BYTE AT $AA52: POKED BEFORE EACH DIRECT FILE READ OR WRITE |
| ED | INTEGER | 100 | 26 | OBJECT FILE BASE: FILE POSITION = PC - ED (THE FILE STARTS WITH THE BSAVE HEADER) |
| EL | INTEGER | 10 | 11 | LIBRARY ROUTINE ($0947) THAT RESETS THE STACK, DROPPING EVERY PENDING GOSUB AND FOR, AND RESETS THE DATA POINTER; CALLED AFTER AN ERROR |
| EO | INTEGER | 50 | 1 WHEN THE EXPRESSION IS COMPLETE | |
| EP | INTEGER | 80 | TYPE OF THE EXPRESSION: 1 INTEGER, 2 STRING, 3 REAL | |
| F | INTEGER | 70 | WHICH FILE DOS IS SET UP FOR: 1 SOURCE (READ), 2 OBJECT (WRITE), 3 LINE NUMBER FILE | |
| F(4) | INTEGER() | 70 | ARGUMENT DESCRIPTION OF A FUNCTION: F(0) NUMBER, F(1..3) TYPES, F(4) ARGUMENT BEING READ | |
| FC | INTEGER | 30 | 33 | 1 ONCE A FATAL ERROR HAS BEEN REPORTED (NO MORE CODE IS WRITTEN) |
| FD | INTEGER | 110 | 1 IF THE FLAGS ALREADY REFLECT THE RESULT (IF NEEDS NO TEST) | |
| FG | INTEGER | 130 | 1 IF THE FOR LOOP VARIABLE IS REAL, 0 IF IT IS AN INTEGER | |
| FQ | INTEGER | 70 | 1 TO WRITE TO THE LINE NUMBER FILE EVEN AFTER A FATAL ERROR | |
| FZ | INTEGER | 60 | WHICH FLAG TEST IF NEEDS: 0 INTEGER (LDA $A0/ORA $A1), 1 REAL (LDA $9D) | |
| GZ | INTEGER | 100 | INSIDE DEF FN: NAME HASH OF THE PARAMETER, ELSE 0 | |
| HE | REAL | 15520 | HIGH BYTE OF THAT WORD | |
| HW | INTEGER | 80 | 7 | LAST CHAIN HEAD IN SC(); ENTRIES ARE ALLOCATED ABOVE IT |
| HY | INTEGER | 130 | NAME HASH (99*FIRST CHARACTER+SECOND), OR LINE NUMBER-32767 | |
| IV | INTEGER | 120 | BYTE JUST READ FROM THE SOURCE FILE | |
| IX | INTEGER | 100 | 17 | ADDRESS OF THE ONE-BYTE TRANSFER CELL FOR QB AND WS ($0376) |
| IZ | INTEGER | 90 | 2 WHILE NAMES ARE BEING DECLARED INTEGER (ALSO AFTER INTEGER *), ELSE 0 | |
| J | INTEGER | 50 | INNER LOOP INDEX; 1 IF AN ARRAY WAS DIMENSIONED BEFORE | |
| J3 | INTEGER | 130 | LAST VARIABLE STORED BY THE CODE (A LOAD RIGHT AFTER IT IS LEFT OUT) | |
| JS | REAL | 8240 | CURRENT SOURCE LINE NUMBER | |
| K0 | INTEGER | 90 | NEXT FREE WORD IN THE SYMBOL TABLE SC() | |
| K4 | INTEGER | 50 | TYPE CODE (-3 REAL, -2 STRING, -1 INTEGER, +22 FOR AN ARRAY), OR AN OPERATION NUMBER | |
| K8 | INTEGER | 60 | LOOP INDEX | |
| KD | INTEGER | 60 | KIND OF THAT OPERAND (ITS TP(X,0) ENTRY) | |
| KV | INTEGER | 30 | 14 | ADDRESS OF THE FIVE PACKED BYTES LEFT BY THE USR ROUTINE ($0371) |
| KX | INTEGER | 130 | 5 | FIRST CONSTANT CHAIN HEAD IN SC() |
| L | INTEGER | 130 | 6 | FIRST LINE NUMBER CHAIN HEAD IN SC() |
| L1 | REAL | 4640 | NUMERIC VALUE OF A LINE NUMBER, DIMENSION OR CONSTANT | |
| LB | INTEGER | 40 | 19 | LIBRARY ADDRESS, STORED AS ADDRESS-32767 |
| LH | INTEGER | 60 | 23 | NUMBER OF SOURCE LINES READ |
| LK | INTEGER | 110 | OPERATION OF THE LAST TRIPLE (TELLS THE STORE WHAT IS IN THE ACCUMULATOR) | |
| LM | INTEGER | 90 | 12 | LENGTH OF THE RUNTIME LIBRARY IN BYTES (4013) |
| LN$ | STRING | 150 | 45 | NAME OF THE LINE NUMBER FILE ("CLINENUM") |
| LQ | INTEGER | 80 | 18 | ADDRESS OF THE ROUTINE THAT LISTS THE TOKENIZED LINE IN THE INPUT BUFFER ($038D) |
| LZ | INTEGER | 110 | LEFT OPERAND OF THE TRIPLE | |
| MJ | INTEGER | 90 | NEXT BYTE OF THE SOURCE LINE (ONE BYTE LOOKAHEAD); -1 AT END OF PROGRAM | |
| ML | INTEGER | 130 | SCRATCH | |
| MN | INTEGER | 10 | 9 | DRIVE MOTOR-OFF SWITCH FOR THE BOOT SLOT |
| MX | INTEGER | 80 | 8 | DRIVE MOTOR-ON SWITCH FOR THE BOOT SLOT ($C089+SLOT*16), TOUCHED TO KEEP THE DRIVE SPINNING |
| N1 | INTEGER | 20 | 30 | RESUME/DEBUG CODE OPTION (1 = YES) |
| N4 | INTEGER | 100 | NUMBER OF DIMENSIONS IN A DIM OR DECLARATION | |
| N5 | INTEGER | 80 | 1 IF THE LAST SCAN FOUND NO NAME OR NO NUMBER | |
| NB | INTEGER | 60 | OPERAND BEING LOADED OR APPLIED | |
| NG | INTEGER | 80 | 2 | NUMBER OF CONSTANT HASH CHAINS (32) |
| NK | INTEGER | 80 | 3 | NUMBER OF LINE NUMBER HASH CHAINS (32) |
| NQ | INTEGER | 60 | OPERATION CODE OF THE TRIPLE | |
| NU | INTEGER | 80 | 1 | NUMBER OF VARIABLE HASH CHAINS IN THE SYMBOL TABLE (32) |
| O2 | INTEGER | 80 | OPERATION CODE USED TO SELECT THE GENERATOR, OR A SUBSCRIPT COUNT | |
| O4 | INTEGER | 20 | 28 | COMPILATION LISTING OPTION (1 = YES) |
| OD$ | STRING | 150 | 44 | OBJECT FILE NAME |
| OE(16,2) | INTEGER() | 140 | OPERATOR TABLE: OE(I,0) TOKEN, OE(I,1) PRIORITY ON THE STACK, OE(I,2) PRIORITY ARRIVING | |
| OH | INTEGER | 80 | 32 | INTEGER CONSTANTS OPTION (1 = YES) |
| OO | INTEGER | 20 | 29 | PAUSE ON ERRORS OPTION (1 = YES) |
| OO$ | STRING | 150 | 48 | SLOT AND DRIVE OF THE OBJECT FILE |
| OP$ | STRING | 150 | 39 | DOS OPEN COMMAND |
| OW | INTEGER | 50 | BYTE TO WRITE TO THE OBJECT FILE | |
| P3 | INTEGER | 70 | BYTE WAITING TO BE COPIED INTO THE LISTING BUFFER | |
| P8 | INTEGER | 20 | 31 | INTEGER ARITHMETIC OPTION (1 = YES) |
| PC | INTEGER | 100 | 22 | ADDRESS OF THE NEXT OBJECT CODE BYTE, AS ADDRESS-32767 |
| PE | INTEGER | 70 | LOW BYTE OF THE NEXT LINE LINK (A ZERO LINK ENDS THE PROGRAM) | |
| PN | INTEGER | 130 | ADDRESS TO PATCH WITH THE CURRENT CODE ADDRESS | |
| QB | INTEGER | 30 | 15 | ADDRESS OF THE ROUTINE THAT READS ONE BYTE FROM THE OPEN FILE INTO IX ($037E) |
| RC | INTEGER | 70 | 1 FOR THE STATEMENT RIGHT AFTER THEN (NO RESUME/DEBUG CALL) | |
| RH | INTEGER | 130 | RIGHT OPERAND OF THE TRIPLE | |
| RI | INTEGER | 90 | SAVED ID DURING AN INTEGER DECLARATION LIST | |
| RN | INTEGER | 60 | 1 IF THE OPERANDS ARE USED AS REALS | |
| RV | INTEGER | 110 | 1 IF THE RESULT IS REAL | |
| RV$ | STRING | 150 | 41 | DOS READ COMMAND |
| S3 | INTEGER | 100 | SAVED SYMBOL (FOR LOOP VARIABLE), OR THE NUMBER OF LINES IN AN ON LIST | |
| S8 | INTEGER | 80 | SIZE OF THE PARSE STACK (100) | |
| SB$ | STRING | 150 | 47 | SLOT AND DRIVE OF THE SOURCE FILE |
| SC | INTEGER | 10 | 27 | 1 IF THE SOURCE AND OBJECT FILES ARE ON THE BOOT DRIVE (MOTOR KEPT ON), ELSE 0 |
| SC(5350) | INTEGER() | 10 | 36 | SYMBOL TABLE: CHAIN HEADS, THEN ENTRIES LINKED THROUGH THEIR FIRST WORD |
| SE | INTEGER | 110 | 1 WHEN THE EXPRESSION'S VALUE MUST BE REAL (A REAL TARGET OR A FUNCTION BODY) | |
| SF | INTEGER | 80 | TRIPLE BEING EXAMINED WHEN DECIDING WHERE A RESULT GOES | |
| SI$ | STRING | 150 | 43 | SOURCE FILE NAME |
| SJ | INTEGER | 70 | CODE ADDRESS OF THAT STORE | |
| SK | INTEGER | 60 | SAVED OPERATION NUMBER | |
| SS | INTEGER | 60 | SAVED OPERATION NUMBER | |
| SU | INTEGER | 40 | NEXT FREE PLACE FOR AN OPERATOR ON THE PARSE STACK (GROWS UP) | |
| SZ(100) | INTEGER() | 140 | PARSE STACK: OPERATORS FROM THE BOTTOM, OPERANDS FROM THE TOP | |
| T0 | INTEGER | 120 | CURRENT TOKEN OR CHARACTER OF THE SOURCE LINE | |
| T5 | INTEGER | 100 | INSIDE DEF FN: THE PARAMETER'S SYMBOL | |
| T9 | INTEGER | 80 | SCRATCH: A SYMBOL OR SIZE BEING WORKED ON | |
| TB | INTEGER | 130 | TRIPLE BEING GENERATED | |
| TG | INTEGER | 70 | 1 WHEN THE EXPRESSION IS THE VALUE OF AN ASSIGNMENT | |
| TP | INTEGER | 120 | OPERATOR ON TOP OF THE PARSE STACK | |
| TP(101,2) | INTEGER() | 120 | TRIPLE TABLE: TP(I,0) OPERATION OR OPERAND KIND, TP(I,1) LEFT, TP(I,2) RIGHT | |
| TU | INTEGER | 130 | SYMBOL OF THE EXPRESSION'S RESULT | |
| TZ | INTEGER | 50 | SIZE OF THE SYMBOL TABLE (5350 WORDS) | |
| U | INTEGER | 90 | OPERATION NUMBER FOR A MEMORY OPERAND, OR THE OPERAND SAVED FOR LATER | |
| U2 | INTEGER | 130 | NUMBER OF TRIPLES IN TP() PLUS ONE | |
| U7 | INTEGER | 100 | TOKEN NUMBER OF THE STATEMENT (TOKEN-128), THEN THE CALL TABLE INDEX IT SELECTS | |
| UR | INTEGER | 130 | 20 | PROGRAM START, STORED AS ADDRESS-32767; MOVED UP BY COMMON DECLARATIONS |
| UV | INTEGER | 80 | 13 | ADDRESS OF THE USR ROUTINE THAT PACKS A NUMBER INTO FIVE BYTES ($0377) |
| UZ | INTEGER | 60 | SIZE OF THE TRIPLE TABLE (100) | |
| V3 | INTEGER | 80 | NEXT FREE PLACE FOR AN OPERAND ON THE PARSE STACK (GROWS DOWN) | |
| VB | INTEGER | 50 | VALUE PASSED TO AND FROM THE STACK AND SYMBOL ROUTINES (USUALLY A SYMBOL) | |
| VC | INTEGER | 40 | 21 | VARIABLES ADDRESS ASKED FOR, AS ADDRESS-32767, OR -32767 FOR END OF PROGRAM |
| VO | INTEGER | 90 | 4 | FIRST VARIABLE CHAIN HEAD IN SC() (9; 1-4 HOLD FN AND LINE SYMBOLS, 5-8 TEMPORARIES) |
| WF | REAL | 1450 | WORD TO WRITE TO THE OBJECT FILE (A LINK OR ADDRESS) | |
| WL$ | STRING | 200 | WORK STRING: KEYWORD BEING MATCHED, DIGITS OF A NUMBER, NAME OF AN ERROR | |
| WN | INTEGER | 120 | TYPE THE CALL TABLE ENTRY IS FOR: 1 INTEGER, 3 REAL | |
| WO$ | STRING | 150 | 42 | DOS WRITE COMMAND |
| WS | INTEGER | 30 | 16 | ADDRESS OF THE ROUTINE THAT WRITES THE BYTE IN IX TO THE OPEN FILE ($0387) |
| XF | INTEGER | 100 | TOKEN OR CHARACTER EXPECTED NEXT (SYNTAX CHECK) | |
| XK | INTEGER | 130 | CALL TABLE INDEX FOR THE OPERANDS IN THE OTHER ORDER (SWAPPED COMPARISON) | |
| FN LT | REAL | TRUE IF X IS A LETTER | ||
| FN DG | REAL | TRUE IF X IS A DIGIT | ||
| FN OS | REAL | TRUE IF X IS AN OPERATOR TOKEN (+ - * / ^ AND OR > = < NOT, OR A TWO-CHARACTER RELATION) | ||
| FN OE | REAL | TRUE IF X IS AN OPERATOR, A PARENTHESIS OR THE END OF THE LINE | ||
| FN NU | REAL | TRUE IF X IS A NUMERIC FUNCTION TOKEN (SGN TO LEN, VAL, ASC) | ||
| FN SF | REAL | TRUE IF X IS A STRING FUNCTION TOKEN (STR$, CHR$, LEFT$, RIGHT$, MID$) | ||
| FN ES | REAL | TRUE IF X ENDS A STATEMENT (COLON OR END OF LINE) | ||
| FN UB | REAL | X STORED AS A WORD (X+32767) | ||
| FN IV | REAL | TRUE IF TRIPLE X GIVES AN INTEGER (INTEGER TEMPORARY, INTEGER VARIABLE OR RESULT) | ||
| FN LO | REAL | TRUE IF OPERATION X TAKES ITS LEFT OPERAND FROM THE ACCUMULATOR | ||
| FN RT | REAL | TRUE IF OPERATION X TAKES ITS RIGHT OPERAND FROM THE ACCUMULATOR | ||
| FN IA | REAL | TRUE IF TRIPLE X IS IN THE ACCUMULATOR | ||
| X | REAL | PARAMETER OF THE DEF FN FUNCTIONS (EACH FUNCTION HAS ITS OWN) |