Urbane 1.060202 RC0 - Tandy Color Computer 3 Disk Extended Color Basic Preprocessor.
MEM = 8218
1 # LIST_ON : REM CHANGE TO COMMENT LINE IF NOT WANTED
2 # XREF_ON : REM CHANGE TO COMMENT LINE IF NOT WANTED
3 # CONSTANT UBNVERSION$ = "1.060202 RC0"
4 # CONSTANT UBN_TITLE$ = "Urbane XUBNVERSION$ - Tandy Color Computer 3 Disk Extended Color Basic Preprocessor."
5 ' Original Left Hello A. Nani Mouse Inx.
6
7 # CONSTANT IN_FILE$ = "UBN_IN.TXT"
8 # CONSTANT OUT_FILE$ = "UBN_OUT.TXT"
9 # CONSTANT LST_FILE$ = "UBN_LST.TXT"
10 # CONSTANT XRF_FILE$ = "UBN_XRF.TXT"
11
12 # CONSTANT NUM_M1 = -1
13 # CONSTANT NUM_0 = 0
14 # CONSTANT NUM_1 = 1
15 # CONSTANT NUM_2 = 2
16 # CONSTANT NUM_3 = 3
17 # CONSTANT NUM_4 = 4
18 # CONSTANT TRUE = 1
19 # CONSTANT FALSE = 0
20
21 # CONSTANT UBN_XREF_LIST_INITIAL = 0 : REM ON = 1, OFF = 0
22 # CONSTANT UBN_LIST_LIST_INITIAL = 0 : REM ON = 1, OFF = 0
23
24 # CONSTANT UBN_MEM_PCLEAR = 1
25 # CONSTANT UBN_MEM_FILES_COUNT = 4
26 # CONSTANT UBN_MEM_FILES_SPACE = 100
27 # CONSTANT UBN_MEM_CLEAR = 8500
28
29 # CONSTANT UBN_MEM_LINE_LABEL_MAX_COUNT = 100
30 # CONSTANT UBN_MEM_VARIABLE_NAMES_MAX_COUNT = 150
31 # CONSTANT UBN_MEM_KEYWORD_TABLE_MAX_COUNT = 200
32 # CONSTANT UBN_MEM_ILLEGAL_2CH_VARIABLE_TABLE_MAX_COUNT = 10
33
34 # CONSTANT ASC_TAB = 09 : REM TAB
35
36 # CONSTANT ASC_BLANK = 32 : REM ASC(" ")
37
38 # CONSTANT ASC_DOUBLE_QUOTE = 34 : REM ASC(""")
39 ' CONSTANT ASC_DOUBLE_QUOTE$ is Defined as a program value, not a constant!
40 # CONSTANT ASC_POUND = 35 : REM ASC("#")
41 # CONSTANT ASC_DOLLAR = 36 : REM ASC("$")
42 # CONSTANT ASC_PERCENT = 37 : REM ASC("%")
43 # CONSTANT ASC_AMPERSAND = 38 : REM ASC("&")
44 # CONSTANT ASC_SINGLE_QUOTE = 39 : REM ASC("'")
45
46 # CONSTANT ASC_PLUS = 43 : REM ASC("+")
47 # CONSTANT ASC_MINUS = 45 : REM ASC("-")
48 # CONSTANT ASC_PERIOD = 46 : REM ASC(".")
49
50 # CONSTANT ASC_0 = 48 : REM ASC("0")
51 # CONSTANT ASC_7 = 55 : REM ASC("7")
52 # CONSTANT ASC_8 = 56 : REM ASC("8")
53 # CONSTANT ASC_9 = 57 : REM ASC("9")
54
55 # CONSTANT ASC_COLON = 58 : REM ASC(":")
56 # CONSTANT ASC_EQUALS = 61 : REM ASC("=")
57 # CONSTANT ASC_TILDE = 64 : REM ASC("")
58
59 # CONSTANT ASC_A_U = 65 : REM ASC("A")
60 # CONSTANT ASC_E_U = 69 : REM ASC("E")
61 # CONSTANT ASC_F_U = 70 : REM ASC("F")
62 # CONSTANT ASC_H_U = 72 : REM ASC("H")
63 # CONSTANT ASC_O_U = 79 : REM ASC("O")
64 # CONSTANT ASC_X_U = 88 : REM ASC("X")
65 # CONSTANT ASC_Z_U = 90 : REM ASC("Z")
66
67 # CONSTANT ASC_UNDERSCORE = 95 : REM ASC("_")
68
69 # CONSTANT ASC_a_L = 97 : REM ASC("a")
70 # CONSTANT ASC_e_L = 101 : REM ASC("e")
71 # CONSTANT ASC_f_L = 102 : REM ASC("f")
72 # CONSTANT ASC_h_L = 104 : REM ASC("h")
73 # CONSTANT ASC_o_L = 111 : REM ASC("o")
74 # CONSTANT ASC_x_L = 120 : REM ASC("x")
75 # CONSTANT ASC_z_L = 122 : REM ASC("z")
76
77 # CONSTANT UBN_XRF_TITLE = 1
78 # CONSTANT UBN_XRF_LINE_LABEL = 2
79 # CONSTANT UBN_XRF_LINE_REFERENCE = 3
80 # CONSTANT UBN_XRF_VARIABLE = 4
81 # CONSTANT UBN_XRF_VARIABLE_REFERENCE = 5
82 ' CONSTANT UBN_XRF_CONSTANT = 6
83 ' CONSTANT UBN_XRF_CONSTANT_REFERENCE = 7
84 # CONSTANT UBN_XRF_KEYWORD_REFERENCE = 8
85
86 ' Start of Executation
87 GOTO UBN_START
88
89 GET_IN_LINE_CHAR IN_LINE_CHAR_COUNTER = IN_LINE_CHAR_COUNTER + NUM_1
90 IF IN_LINE_CHAR_COUNTER > I_LINE_LENGTH GOTO END_IN_LINE
91
92 LAST_CH = IN_LINE_CH
93 IN_LINE_CH$ = MID$(IN_LINE$, IN_LINE_CHAR_COUNTER, NUM_1)
94 IN_LINE_CH = ASC(IN_LINE_CH$)
95 IF IN_LINE_CH >= ASC_BLANK THEN RETURN
96 IF IN_LINE_CH = ASC_TAB GOTO SUBSTUTE_SPACE_FOR_TAB
97
98 PRINT #FILE_L, LINE_NUMBER; " " ; IN_LINE$
99 PRINT #FILE_L, LINE_NUMBER; " Control Character "; IN_LINE_CH; " Found in Input Line at "; IN_LINE_CHAR_COUNTER
100 RETURN
101
102 SUBSTUTE_SPACE_FOR_TAB IN_LINE_CH$ = CHR$(ASC_BLANK)
103 IN_LINE_CH = ASC_BLANK
104 RETURN
105
106 END_IN_LINE IN_LINE_CH = NUM_M1
107 IN_LINE_CH$ = CHR$(ASC_TILDE)
108 RETURN
109
110 '''
111 ' On Entry, first character of label or variable is in "IN_LINE_CH$" and "IN_LINE_CH"
112 ' On Exit, "IN_LINE_CH$" and "IN_LINE_CH" have terminating character (next character not part of VLString).
113
114 GET_VLSTRING VLSTRING$ = IN_LINE_CH$
115 NEXT_VLSTRING_CH GOSUB GET_IN_LINE_CHAR
116 IF IN_LINE_CH < NUM_0 THEN RETURN
117 IF IN_LINE_CH >= ASC_A_U AND IN_LINE_CH <= ASC_Z_U GOTO VLSTRING_ADD_UPPER_ALPHA
118 IF IN_LINE_CH >= ASC_a_L AND IN_LINE_CH <= ASC_z_L GOTO VLSTRING_ADD_LOWER_ALPHA
119 IF IN_LINE_CH >= ASC_0 AND IN_LINE_CH <= ASC_9 GOTO VLSTRING_ADD_NUMBER
120 IF IN_LINE_CH = ASC_UNDERSCORE GOTO VLSTRING_ADD_SPECIAL
121 IF IN_LINE_CH = ASC_TILDE GOTO VLSTRING_ADD_SPECIAL
122 IF IN_LINE_CH = ASC_DOLLAR GOTO VLSTRING_ADD_DOLLAR
123 ' REM Character Found that cannot be in Variable or line Label
124 RETURN
125
126 VLSTRING_ADD_LOWER_ALPHA IN_LINE_CH = IN_LINE_CH - ( ASC_a_L - ASC_A_U )
127 IN_LINE_CH$ = CHR$(IN_LINE_CH)
128 VLSTRING_ADD_UPPER_ALPHA REM
129 VLSTRING_ADD_NUMBER REM
130 VLSTRING_ADD_SPECIAL REM
131 VLSTRING_ADD_DOLLAR REM
132 VLSTRING$ = VLSTRING$ + IN_LINE_CH$
133 ' If an "ASC_DOLLAR" is found, declare label or variable end found
134 IF IN_LINE_CH = ASC_DOLLAR THEN LAST_CH = IN_LINE_CH : GOSUB GET_IN_LINE_CHAR : RETURN
135 GOTO NEXT_VLSTRING_CH
136
137 '''
138 ' On Entry, "ASC_DOUBLE_QUOTE" is in "IN_LINE_CH$" and "IN_LINE_CH"
139 ' On Exit, "IN_LINE_CH$" and "IN_LINE_CH" have terminating character or next character.
140
141 GET_QSTRING QSTRING$ = IN_LINE_CH$
142 QSTRING_SKIP_VARIABLE = FALSE
143 MORE_QSTRING GOSUB GET_IN_LINE_CHAR
144
145 IF IN_LINE_CH <= NUM_0 GOTO BAD_QSTRING
146 QSTRING$ = QSTRING$ + IN_LINE_CH$
147 IF IN_LINE_CH = ASC_BLANK THEN QSTRING_SKIP_VARIABLE = FALSE
148 IF QSTRING_SKIP_VARIABLE = TRUE GOTO SKIP_VARIABLE
149 IF IN_LINE_CH = ASC_X_U OR IN_LINE_CH = ASC_x_L GOTO GET_QSTRING_VARIABLE
150 SKIP_VARIABLE IF IN_LINE_CH <> ASC_DOUBLE_QUOTE GOTO MORE_QSTRING
151
152 GOSUB GET_IN_LINE_CHAR
153 RETURN
154
155 GET_QSTRING_VARIABLE GOSUB GET_IN_LINE_CHAR
156 IF IN_LINE_CH <= NUM_0 GOTO BAD_QSTRING
157 IF IN_LINE_CH = ASC_DOUBLE_QUOTE GOTO NO_QSVARIABLE
158 IF IN_LINE_CH >= ASC_A_U AND IN_LINE_CH <= ASC_Z_U GOTO GET_QSTRING_VAR
159 IF IN_LINE_CH >= ASC_a_L AND IN_LINE_CH <= ASC_z_L GOTO GET_QSTRING_VAR
160 IF IN_LINE_CH = ASC_UNDERSCORE GOTO GET_QSTRING_VAR
161 GOTO MORE_QSTRING
162 NO_QSVARIABLE QSTRING$ = QSTRING$ + IN_LINE_CH$
163 GOSUB GET_IN_LINE_CHAR
164 RETURN
165
166 GET_QSTRING_VAR QSTRING_CHAR_COUNTER_SAVE = IN_LINE_CHAR_COUNTER
167 QSTRING_LAST_CHAR_SAVE$ = IN_LINE_CH$
168 GOSUB GET_VLSTRING
169
170 IF LAST_CH <> ASC_DOLLAR GOTO NOT_QSTRING_VAR
171 FOR VARIABLE_NAMES_COUNTER = VARIABLE_NAMES_START TO VARIABLE_NAMES_COUNT
172 IF VLSTRING$ = VARIABLE_NAMES$(VARIABLE_NAMES_COUNTER,VARIABLE_NAMES_NAME) GOTO HAVE_QSTRING_VARIABLE
173 NEXT VARIABLE_NAMES_COUNTER
174
175 ' Have New Variable
176
177 VARIABLE_NAMES_COUNT = VARIABLE_NAMES_COUNT + NUM_1
178 IF VARIABLE_NAMES_COUNT > VARIABLE_NAMES_MAX_COUNT THEN PRINT #FILE_L, " VARIABLE_NAMES_MAX_COUNT Exceeded" : STOP
179
180 VARIABLE_NAMES$(VARIABLE_NAMES_COUNT,VARIABLE_NAMES_NAME) = VLSTRING$
181 VARIABLE_NAMES$(VARIABLE_NAMES_COUNT,VARIABLE_NAMES_2CH) = "Pending"
182
183 GOSUB GET_NEW_2CH_VARIABLE
184
185 VARIABLE_NAMES$(VARIABLE_NAMES_COUNT,VARIABLE_NAMES_2CH) = NEW_2CH_VARIABLE$ + "$"
186 VARIABLE_NAMES_COUNTER = VARIABLE_NAMES_COUNT
187
188 HAVE_QSTRING_VARIABLE IF ASC(VARIABLE_NAMES$(VARIABLE_NAMES_COUNTER,VARIABLE_NAMES_2CH)) = ASC_DOUBLE_QUOTE GOTO ADD_QSTRING_CONSTANT
189
190 ' Add existing 2ch variable to QUOTE string
191
192 QSTRING$ = QSTRING$ + VARIABLE_NAMES$(VARIABLE_NAMES_COUNTER,VARIABLE_NAMES_2CH)
193 GOTO MORE_QSTRING
194
195 ' Do Not Include the 'X'
196 ' Add Constant Without Leading and Trailing Quotes
197
198 ADD_QSTRING_CONSTANT QSTRING_LENGTH = LEN(QSTRING$) - NUM_1
199 QSTRING$ = LEFT$(QSTRING$,QSTRING_LENGTH)
200 QSTRING_CONSTANT_LENGTH = LEN(VARIABLE_NAMES$(VARIABLE_NAMES_COUNTER,VARIABLE_NAMES_2CH)) - NUM_2
201 QSTRING$ = QSTRING$ + MID$(VARIABLE_NAMES$(VARIABLE_NAMES_COUNTER,VARIABLE_NAMES_2CH),NUM_2,QSTRING_CONSTANT_LENGTH)
202 GOTO MORE_QSTRING
203
204 NOT_QSTRING_VAR IN_LINE_CHAR_COUNTER = QSTRING_CHAR_COUNTER_SAVE
205 IN_LINE_CH$ = QSTRING_LAST_CHAR_SAVE$
206 QSTRING_SKIP_VARIABLE = TRUE
207 QSTRING$ = QSTRING$ + IN_LINE_CH$
208 ' PRINT #FILE_L, LINE_NUMBER ; " QSTRING$ = "; QSTRING$; ", IN_LINE_CH = "; IN_LINE_CH
209 ' PRINT #FILE_L, LINE_NUMBER ; " VLSTRING$ = "; VLSTRING$
210 GOTO MORE_QSTRING
211
212 GOSUB GET_IN_LINE_CHAR
213 RETURN
214
215 BAD_QSTRING PRINT #FILE_L, LINE_NUMBER ; " ERROR - Missing end of Quoted String " ; QSTRING$
216 ERRORS = ERRORS + NUM_1
217 RETURN
218 GET_NEW_2CH_VARIABLE NEW_2CH_VARIABLE$ = CHR$(HIGH_2CH_VARIABLE) + CHR$(LOW_2CH_VARIABLE)
219
220 LOW_2CH_VARIABLE = LOW_2CH_VARIABLE + NUM_1
221 IF LOW_2CH_VARIABLE <= ASC_Z_U GOTO CHECK_NEW_2CH_VARIABLE
222 LOW_2CH_VARIABLE = ASC_A_U
223
224 HIGH_2CH_VARIABLE = HIGH_2CH_VARIABLE + NUM_1
225 IF HIGH_2CH_VARIABLE <= ASC_Z_U GOTO CHECK_NEW_2CH_VARIABLE
226 HIGH_2CH_VARIABLE = ASC_A_U : REM Ignore Possibility of 'ZZ' being exceeded FOR NOW (676 Variables)
227
228 CHECK_NEW_2CH_VARIABLE FOR ILLEGAL_2CH_VARIABLE_TABLE_COUNTER = ILLEGAL_2CH_VARIABLE_TABLE_START TO ILLEGAL_2CH_VARIABLE_TABLE_COUNT
229 IF NEW_2CH_VARIABLE$ = ILLEGAL_2CH_VARIABLE_TABLE$(ILLEGAL_2CH_VARIABLE_TABLE_COUNTER) GOTO GET_NEW_2CH_VARIABLE
230 NEXT ILLEGAL_2CH_VARIABLE_TABLE_COUNTER
231
232 RETURN
233
234 ' This is checking if only allowable characters are present
235 ' It does NOT check for valid number syntax
236 CHECK_IF_NUMBER IS_NUMBER = FALSE
237 NUMBER_LENGTH = LEN(VLSTRING$)
238 FOR NUMBER_COUNTER = NUM_1 TO NUMBER_LENGTH
239
240 NUMBER_CH$ = MID$(VLSTRING$, NUMBER_COUNTER, NUM_1)
241 NUMBER_CH = ASC(NUMBER_CH$)
242
243 IF NUMBER_CH >= ASC_0 AND NUMBER_CH <= ASC_9 GOTO MORE_NUMBERS
244 IF NUMBER_CH = ASC_PERIOD OR NUMBER_CH = ASC_PLUS OR NUMBER_CH = ASC_MINUS GOTO MORE_NUMBERS
245 IF NUMBER_CH = ASC_E_U OR NUMBER_CH = ASC_e_L GOTO MORE_NUMBERS
246
247 RETURN : REM Not a number
248
249 MORE_NUMBERS NEXT NUMBER_COUNTER
250 IS_NUMBER = TRUE
251 RETURN
252
253 ' Prepare line number for output, no leading space, No trailing space
254 PREPARE_LINE_NUMBER LNR_$ = STR$(LINE_NUMBER)
255 ' IF LEN(LNR_$) < 2 THEN PRINT #FILE_L, "LINE NUMBER LENGTH LESS THAN 2 >>" ; LEN(LNR_$)
256 LN_LENGTH = LEN(LNR_$) - NUM_1
257 LN_$ = MID$(LNR_$, NUM_2, LN_LENGTH)
258 RETURN
259
260 NEXT_LINE LINE INPUT #FILE_I, IN_LINE$
261
262 IN_LINE_CHAR_COUNTER = NUM_0
263 LAST_CH = ASC_TILDE
264 DEF_CONSTANT = FALSE
265 DATA_LINE = FALSE
266 VLSTRING_COUNT = NUM_0
267 ' Let User Know we are still processing
268 IF PASS = NUM_2 THEN PRINT LINE_NUMBER ;
269 I_EOF = EOF(FILE_I)
270
271 IF I_EOF = NUM_M1 GOTO I_FILE_END
272 I_LINE_LENGTH = LEN(IN_LINE$)
273 IF I_LINE_LENGTH = NUM_0 GOTO BLANK_LINE
274
275 ''' CHARACTERS IN COLUMN ONE
276 ' "A-Za-z", "_", "0-9" = LINE LABLE
277 ' "#" = Urbane COMMAND
278 ' " " = NO LINE LABLE
279 ' "'" = COMMENT
280 ' any other character = COMMENT
281
282 COLUMN_ONE GOSUB GET_IN_LINE_CHAR
283 IF IN_LINE_CH = ASC_POUND GOTO URBANE_COMMAND
284 IF IN_LINE_CH = ASC_BLANK GOTO NO_LINE_LABLE
285 IF IN_LINE_CH = ASC_SINGLE_QUOTE GOTO COMMENT
286
287 IF IN_LINE_CH >= ASC_A_U AND IN_LINE_CH <= ASC_Z_U GOTO LINE_LABEL
288 IF IN_LINE_CH >= ASC_a_L AND IN_LINE_CH <= ASC_z_L GOTO LINE_LABEL
289 IF IN_LINE_CH >= ASC_0 AND IN_LINE_CH <= ASC_9 GOTO LINE_LABEL
290 IF IN_LINE_CH = ASC_UNDERSCORE GOTO LINE_LABEL
291
292 COMMENT ON PASS GOTO OUTPUT_LINE, PASS2_CONTINUE
293
294 URBANE_COMMAND IF INSTR(NUM_2, IN_LINE$, "LIST_ON") <> NUM_0 THEN OUTPUT_LISTING = TRUE
295 IF INSTR(NUM_2, IN_LINE$, "LIST_OFF") <> NUM_0 THEN OUTPUT_LISTING = FALSE
296
297 IF INSTR(NUM_2, IN_LINE$, "XREF_ON") <> NUM_0 THEN OUTPUT_XREF = TRUE
298 IF INSTR(NUM_2, IN_LINE$, "XREF_OFF") <> NUM_0 THEN OUTPUT_XREF = FALSE
299
300 IF INSTR(NUM_2, IN_LINE$, "CONSTANT") <> NUM_0 THEN DEF_CONSTANT = TRUE : GOTO NO_LINE_LABLE
301
302 ' ON PASS GOTO OUTPUT_LINE, PASS2_CONTINUE
303
304 BLANK_LINE ON PASS GOTO OUTPUT_LINE, PASS2_CONTINUE
305
306 NO_LINE_LABLE ON PASS GOTO OUTPUT_LINE, PARSE_LINE
307
308 LINE_LABEL GOSUB GET_VLSTRING
309 VLSTRING_COUNT = NUM_1
310
311 IF LAST_CH <> ASC_DOLLAR GOTO LINE_LABEL_GOOD
312 PRINT #FILE_L, "WARNING - '$' SHOULD NOT BE USED IN LABELS " ; VLSTRING$
313 PRINT "WARNING - '$' SHOULD NOT BE USED IN LABELS " ; VLSTRING$
314 WARNINGS = WARNINGS + NUM_1
315
316 LINE_LABEL_GOOD IF PASS = NUM_2 GOTO PARSE_LINE
317
318 FOR LINE_LABEL_COUNTER = LINE_LABEL_START TO LINE_LABEL_COUNT
319 IF VLSTRING$ = LINE_LABELS$(LINE_LABEL_COUNTER,LINE_LABELS_NAME) GOTO DUP_LINE_LABEL
320 NEXT LINE_LABEL_COUNTER
321
322 LINE_LABEL_COUNT = LINE_LABEL_COUNT + NUM_1
323 IF LINE_LABEL_COUNT > LINE_LABEL_MAX_COUNT THEN PRINT #FILE_L, " LINE_LABEL_MAX_COUNT Exceeded" : STOP
324
325 LINE_LABELS$(LINE_LABEL_COUNT,LINE_LABELS_NAME) = VLSTRING$
326 GOSUB PREPARE_LINE_NUMBER
327 LINE_LABELS$(LINE_LABEL_COUNT,LINE_LABELS_NUMBER) = LN_$
328 IF OUTPUT_XREF = TRUE THEN PRINT #FILE_X, " "; UBN_XRF_LINE_LABEL; " "; LN_$; " "; VLSTRING$
329 GOTO OUTPUT_LINE
330
331 DUP_LINE_LABEL PRINT #FILE_L, LINE_NUMBER ; " ERROR - DUPLICATE LINE LABEL = " ; VLSTRING$
332 ERRORS = ERRORS + NUM_1
333 GOTO OUTPUT_LINE
334
335 PARSE_LINE GOSUB PREPARE_LINE_NUMBER
336 OUTPUT_STRING$ = LN_$
337 CONSTANT_NAME$ = ""
338 CONSTANT_INDEX = NUM_0
339 EQUALS_FOUND = FALSE
340
341 PARSE_CONTINUE IF IN_LINE_CH < NUM_0 GOTO OUTPUT_LINE
342 IF IN_LINE_CH >= ASC_A_U AND IN_LINE_CH <= ASC_Z_U GOTO LABEL_OR_VARIABLE
343 IF IN_LINE_CH >= ASC_a_L AND IN_LINE_CH <= ASC_z_L GOTO LABEL_OR_VARIABLE
344 IF IN_LINE_CH >= ASC_0 AND IN_LINE_CH <= ASC_9 GOTO LABEL_OR_VARIABLE
345 IF IN_LINE_CH = ASC_UNDERSCORE GOTO LABEL_OR_VARIABLE
346 IF IN_LINE_CH = ASC_DOUBLE_QUOTE GOTO HAVE_QUOTED_STRING
347 IF IN_LINE_CH = ASC_AMPERSAND GOTO HEX_OR_OCTAL
348
349 IF IN_LINE_CH = ASC_EQUALS THEN EQUALS_FOUND = TRUE
350
351 ' Skip blanks
352 IF IN_LINE_CH = ASC_BLANK AND LAST_CH = ASC_BLANK GOTO PARSE_GET_NEXT_CH
353
354 OUTPUT_STRING$ = OUTPUT_STRING$ + IN_LINE_CH$
355
356 PARSE_GET_NEXT_CH GOSUB GET_IN_LINE_CHAR
357 GOTO PARSE_CONTINUE
358
359 LABEL_OR_VARIABLE VLSTRING_COUNT = VLSTRING_COUNT + NUM_1
360 GOSUB GET_VLSTRING
361
362 GOSUB CHECK_IF_NUMBER
363 IF IS_NUMBER = TRUE GOTO HAVE_NUMBER
364
365 FOR KEYWORD_TABLE_COUNTER = KEYWORD_TABLE_START TO KEYWORD_TABLE_COUNT
366 IF VLSTRING$ = KEYWORD_TABLE$(KEYWORD_TABLE_COUNTER) GOTO HAVE_KEYWORD
367 NEXT KEYWORD_TABLE_COUNTER
368
369 FOR LINE_LABEL_COUNTER = LINE_LABEL_START TO LINE_LABEL_COUNT
370 IF VLSTRING$ = LINE_LABELS$(LINE_LABEL_COUNTER,VARIABLE_NAMES_NAME) GOTO HAVE_LINE_LABEL
371 NEXT LINE_LABEL_COUNTER
372
373 FOR VARIABLE_NAMES_COUNTER = VARIABLE_NAMES_START TO VARIABLE_NAMES_COUNT
374 IF VLSTRING$ = VARIABLE_NAMES$(VARIABLE_NAMES_COUNTER,VARIABLE_NAMES_NAME) GOTO HAVE_VARIABLE
375 NEXT VARIABLE_NAMES_COUNTER
376
377 ' NEW_VARIABLE FOUND
378 VARIABLE_NAMES_COUNT = VARIABLE_NAMES_COUNT + NUM_1
379 IF VARIABLE_NAMES_COUNT > VARIABLE_NAMES_MAX_COUNT THEN PRINT #FILE_L, " VARIABLE_NAMES_MAX_COUNT Exceeded" : STOP
380
381 VARIABLE_NAMES$(VARIABLE_NAMES_COUNT,VARIABLE_NAMES_NAME) = VLSTRING$
382 VARIABLE_NAMES$(VARIABLE_NAMES_COUNT,VARIABLE_NAMES_2CH) = "Pending"
383 IF DEF_CONSTANT <> TRUE GOTO GET_NEW_2CH
384 CONSTANT_NAME$ = VLSTRING$
385 CONSTANT_INDEX = VARIABLE_NAMES_COUNT
386 IF OUTPUT_XREF = TRUE THEN PRINT #FILE_X, " "; UBN_XRF_VARIABLE; " "; LN_$; " "; VLSTRING$
387 GOTO PARSE_CONTINUE
388
389 ' Generate new 2 character variable name and put it into variable name table
390 GET_NEW_2CH GOSUB GET_NEW_2CH_VARIABLE
391
392 VARIABLE_NAMES$(VARIABLE_NAMES_COUNT,VARIABLE_NAMES_2CH) = NEW_2CH_VARIABLE$
393 VARIABLE_NAMES_COUNTER = VARIABLE_NAMES_COUNT
394 IF OUTPUT_XREF = TRUE THEN PRINT #FILE_X, " "; UBN_XRF_VARIABLE; " "; LN_$; " "; VLSTRING$
395 IF LAST_CH <> ASC_DOLLAR GOTO HAVE_VARIABLE
396 VARIABLE_NAMES$(VARIABLE_NAMES_COUNT,VARIABLE_NAMES_2CH) = NEW_2CH_VARIABLE$ + "$"
397 GOTO HAVE_VARIABLE
398
399 HAVE_KEYWORD IF OUTPUT_XREF = TRUE AND DATA_LINE = FALSE THEN PRINT #FILE_X, " "; UBN_XRF_KEYWORD_REFERENCE; " "; LN_$; " "; VLSTRING$
400 ' Add keyword to output string
401 IF DATA_LINE = TRUE GOTO HAVE_DATA_LINE
402 IF VLSTRING$ = "REM" GOTO HAVE_REM
403 IF VLSTRING$ = "LET" GOTO HAVE_LET
404 IF VLSTRING$ = "DATA" THEN DATA_LINE = TRUE
405 IF VLSTRING$ = "CONSTANT" GOTO PARSE_CONTINUE
406 HAVE_DATA_LINE OUTPUT_STRING$ = OUTPUT_STRING$ + VLSTRING$
407
408 GOTO PARSE_CONTINUE
409
410 ' Line with no Line Label and first Keyword "REM" can be removed
411 ' DECB requires the "REM keyword if there is a label on the line
412
413 HAVE_REM IF VLSTRING_COUNT = NUM_1 GOTO PASS2_CONTINUE
414 OUTPUT_STRING$ = OUTPUT_STRING$ + "REM"
415 GOTO OUTPUT_LINE
416
417 ' Remove unnecessary "LET" and next Blank
418 HAVE_LET IF IN_LINE_CH = ASC_BLANK GOTO PARSE_GET_NEXT_CH
419 GOTO PARSE_CONTINUE
420
421 HAVE_LINE_LABEL IF OUTPUT_XREF = TRUE THEN PRINT #FILE_X, " "; UBN_XRF_LINE_REFERENCE; " "; LN_$; " "; LINE_LABELS$(LINE_LABEL_COUNTER,LINE_LABELS_NUMBER)
422 ' Add line number to output string
423 OUTPUT_STRING$ = OUTPUT_STRING$ + LINE_LABELS$(LINE_LABEL_COUNTER,LINE_LABELS_NUMBER)
424 GOTO PARSE_CONTINUE
425
426 HAVE_NUMBER IF DEF_CONSTANT <> TRUE GOTO ADD_NUMBER
427 IF CONSTANT_INDEX = NUM_0 GOTO ADD_NUMBER
428 IF EQUALS_FOUND <> TRUE GOTO ADD_NUMBER
429
430 NUM_PREFIX$ = ""
431 IF LAST_CH = ASC_MINUS THEN NUM_PREFIX$ = "-"
432 IF LAST_CH = ASC_PLUS THEN NUM_PREFIX$ = "+"
433
434 VARIABLE_NAMES$(CONSTANT_INDEX,VARIABLE_NAMES_2CH) = NUM_PREFIX$ + VLSTRING$
435 GOTO PARSE_CONTINUE
436
437 ' Add number to output string
438 ADD_NUMBER OUTPUT_STRING$ = OUTPUT_STRING$ + VLSTRING$
439 GOTO PARSE_CONTINUE
440
441 HAVE_VARIABLE IF DEF_CONSTANT = TRUE GOTO PARSE_CONTINUE
442 IF OUTPUT_XREF = TRUE THEN PRINT #FILE_X, " "; UBN_XRF_VARIABLE_REFERENCE; " "; LN_$; " "; VLSTRING$
443 ' Add existing 2ch variable to output string
444 OUTPUT_STRING$ = OUTPUT_STRING$ + VARIABLE_NAMES$(VARIABLE_NAMES_COUNTER,VARIABLE_NAMES_2CH)
445 GOTO PARSE_CONTINUE
446
447 HAVE_QUOTED_STRING GOSUB GET_QSTRING
448 IF DEF_CONSTANT <> TRUE GOTO ADD_QUOTED
449 IF CONSTANT_INDEX = NUM_0 GOTO ADD_QUOTED
450 IF EQUALS_FOUND <> TRUE GOTO ADD_QUOTED
451
452 VARIABLE_NAMES$(CONSTANT_INDEX,VARIABLE_NAMES_2CH) = QSTRING$
453 GOTO PARSE_CONTINUE
454
455 ' Copy Quoted string to output, with double quotes
456
457 ADD_QUOTED OUTPUT_STRING$ = OUTPUT_STRING$ + QSTRING$
458 GOTO PARSE_CONTINUE
459
460 ' On Entry, "ASC_AMPERSAND" is in "IN_LINE_CH$" and "IN_LINE_CH"
461 ' On Exit, "IN_LINE_CH$" and "IN_LINE_CH" have next character.
462 HEX_OR_OCTAL HO_STRING$ = IN_LINE_CH$
463
464 GOSUB GET_IN_LINE_CHAR
465 HO_STRING$ = HO_STRING$ + IN_LINE_CH$
466
467 HEX = FALSE
468 OCTAL = FALSE
469 IF IN_LINE_CH = ASC_H_U OR IN_LINE_CH = ASC_h_L THEN HEX = TRUE
470 IF IN_LINE_CH = ASC_O_U OR IN_LINE_CH = ASC_o_L THEN OCTAL = TRUE
471 IF HEX = FALSE AND OCTAL = FALSE GOTO BAD_HEX_OR_OCTAL
472
473 MORE_HEX_OR_OCTAL GOSUB GET_IN_LINE_CHAR
474
475 IF IN_LINE_CH >= ASC_A_U AND IN_LINE_CH <= ASC_F_U GOTO HOSTRING_ADD_UPPER_HEX
476 IF IN_LINE_CH >= ASC_a_L AND IN_LINE_CH <= ASC_f_L GOTO HOSTRING_ADD_LOWER_HEX
477 IF IN_LINE_CH >= ASC_0 AND IN_LINE_CH <= ASC_7 GOTO HOSTRING_ADD_OCTAL
478 IF IN_LINE_CH >= ASC_8 AND IN_LINE_CH <= ASC_9 GOTO HOSTRING_ADD_UPPER_HEX
479
480 ' End of Hex or Octal Number
481 OUTPUT_STRING$ = OUTPUT_STRING$ + HO_STRING$
482 GOTO PARSE_CONTINUE
483
484 HOSTRING_ADD_LOWER_HEX IN_LINE_CH = IN_LINE_CH - ( ASC_a_L - ASC_A_U )
485 IN_LINE_CH$ = CHR$(IN_LINE_CH)
486
487 HOSTRING_ADD_UPPER_HEX HO_STRING$ = HO_STRING$ + IN_LINE_CH$
488 IF HEX = TRUE GOTO MORE_HEX_OR_OCTAL
489
490 PRINT #FILE_L, "WARNING - Invalid Octal Number " ; HO_STRING$
491 PRINT "WARNING - Invalid Octal Number " ; HO_STRING$
492 WARNINGS = WARNINGS + NUM_1
493 GOTO OUTPUT_LINE
494
495 HOSTRING_ADD_OCTAL HO_STRING$ = HO_STRING$ + IN_LINE_CH$
496 GOTO MORE_HEX_OR_OCTAL
497
498 BAD_HEX_OR_OCTAL PRINT #FILE_L, "WARNING - '&' Not followed by 'H' or 'O' " ; HO_STRING$
499 PRINT "WARNING - '&' Not followed by 'H' or 'O' " ; HO_STRING$
500 WARNINGS = WARNINGS + NUM_1
501 ' GOTO OUTPUT_LINE
502
503 OUTPUT_LINE IF PASS = NUM_1 AND OUTPUT_LISTING = TRUE THEN PRINT #FILE_L, LINE_NUMBER ; IN_LINE$
504
505 IF DEF_CONSTANT = TRUE GOTO PASS2_CONTINUE
506
507 IF PASS = NUM_2 THEN PRINT #FILE_O, OUTPUT_STRING$
508
509 PASS2_CONTINUE LINE_NUMBER = LINE_NUMBER + NUM_1
510 GOTO NEXT_LINE
511
512 I_FILE_END LINE_COUNT = LINE_NUMBER - NUM_1
513 PRINT #FILE_L, "Urbane Pass "; PASS; " Done, Lines = "; LINE_COUNT
514 PRINT "Urbane Pass "; PASS; " Done, Lines = "; LINE_COUNT
515
516 IF PASS = NUM_2 GOTO ALL_DONE
517 ' GOSUB DUMP_LINE_LABELS
518
519 PRINT #FILE_L, " MEM = " ; MEM
520 PRINT " MEM = " ; MEM
521
522 LOAD_KEYWORDS DIM KEYWORD_TABLE$(UBN_MEM_KEYWORD_TABLE_MAX_COUNT)
523 KEYWORD_TABLE_MAX_COUNT = UBN_MEM_KEYWORD_TABLE_MAX_COUNT
524 KEYWORD_TABLE_START = NUM_1
525 KEYWORD_TABLE_COUNT = NUM_0
526
527 LOOP_KEYWORDS READ KEYWORD$
528 IF KEYWORD$ = "\" GOTO END_OF_KEYWORDS
529 KEYWORD_TABLE_COUNT = KEYWORD_TABLE_COUNT + NUM_1
530 KEYWORD_TABLE$(KEYWORD_TABLE_COUNT) = KEYWORD$
531 GOTO LOOP_KEYWORDS
532
533 END_OF_KEYWORDS DIM ILLEGAL_2CH_VARIABLE_TABLE$(UBN_MEM_ILLEGAL_2CH_VARIABLE_TABLE_MAX_COUNT)
534 ILLEGAL_2CH_VARIABLE_TABLE_MAX_COUNT = UBN_MEM_ILLEGAL_2CH_VARIABLE_TABLE_MAX_COUNT
535 ILLEGAL_2CH_VARIABLE_TABLE_START = NUM_1
536 ILLEGAL_2CH_VARIABLE_TABLE_COUNT = NUM_0
537
538 LOOP_ILLEGAL_2CH_VARIABLES READ ILLEGAL_2CH_VARIABLE$
539 IF ILLEGAL_2CH_VARIABLE$ = "\" GOTO END_OF_ILLEGAL_2CH_VARIABLES
540 ILLEGAL_2CH_VARIABLE_TABLE_COUNT = ILLEGAL_2CH_VARIABLE_TABLE_COUNT + NUM_1
541 ILLEGAL_2CH_VARIABLE_TABLE$(ILLEGAL_2CH_VARIABLE_TABLE_COUNT) = ILLEGAL_2CH_VARIABLE$
542 GOTO LOOP_ILLEGAL_2CH_VARIABLES
543
544 END_OF_ILLEGAL_2CH_VARIABLES DIM VARIABLE_NAMES$(UBN_MEM_VARIABLE_NAMES_MAX_COUNT,NUM_2)
545 VARIABLE_NAMES_MAX_COUNT = UBN_MEM_VARIABLE_NAMES_MAX_COUNT
546 VARIABLE_NAMES_START = NUM_1
547 VARIABLE_NAMES_COUNT = NUM_0
548 VARIABLE_NAMES_NAME = NUM_1
549 VARIABLE_NAMES_2CH = NUM_2
550
551 HIGH_2CH_VARIABLE = ASC_A_U
552 LOW_2CH_VARIABLE = ASC_A_U
553
554 PASS = NUM_2
555 LINE_NUMBER = NUM_1
556 I_EOF = NUM_0
557 PRINT #FILE_L, " ---------PASS 2 STARTING------"
558 PRINT " ---------PASS 2 STARTING------"
559 CLOSE FILE_I
560
561 OPEN "I", #NUM_1, IN_FILE$
562
563 GOTO NEXT_LINE
564
565 ' REM Startup code here so Basic does not have to search it each time it is looking for a line number
566 UBN_START FILES UBN_MEM_FILES_COUNT, UBN_MEM_FILES_SPACE
567 PCLEAR UBN_MEM_PCLEAR
568 CLEAR UBN_MEM_CLEAR
569 PRINT "Urbane Starting - Urbane XUBNVERSION$ "
570 PRINT " MEM = " ; MEM
571
572 PASS = NUM_1
573 LINE_NUMBER = NUM_1
574
575 ERRORS = NUM_0
576 WARNINGS = NUM_0
577
578 ASC_DOUBLE_QUOTE$ = CHR$(34)
579
580 OUTPUT_LISTING = UBN_LIST_LIST_INITIAL
581 OUTPUT_XREF = UBN_XREF_LIST_INITIAL
582 FILE_I = NUM_1
583 FILE_O = NUM_2
584 FILE_L = NUM_3
585 FILE_X = NUM_4
586
587 OPEN "I", #NUM_1, IN_FILE$
588
589 OPEN "O", #NUM_2, OUT_FILE$
590
591 OPEN "O", #NUM_3, LST_FILE$
592
593 OPEN "O", #NUM_4, XRF_FILE$
594
595 DIM LINE_LABELS$(UBN_MEM_LINE_LABEL_MAX_COUNT,NUM_2)
596 LINE_LABEL_MAX_COUNT = UBN_MEM_LINE_LABEL_MAX_COUNT
597 LINE_LABEL_START = NUM_1
598 LINE_LABEL_COUNT = NUM_0
599 LINE_LABELS_NAME = NUM_1
600 LINE_LABELS_NUMBER = NUM_2
601
602 PRINT #FILE_L, " "; UBN_TITLE$
603 PRINT #FILE_X, " "; UBN_XRF_TITLE; " "; NUM_0; " "; UBN_TITLE$
604
605 PRINT #FILE_L, " MEM = " ; MEM
606 GOTO NEXT_LINE
607
608 ' Keyword Table
609 DATA REM
610 DATA ATTR,AUDIO,BACKUP,CIRCLE,CLEAR,CLOAD,CLOADM,CLOSE,CLS,COLOR,CONSTANT,CONT,COPY,CSAVE
611 DATA CSAVEM,DATA,DEF,DEFUSR,DEL,DIM,DIR,DLOAD,DRAW,DRIVE,DSKI$,DSKINI,DSKO$,EDIT
612 DATA END,EXEC,FIELD,FILES,FN,FOR,GET,GOSUB
613 DATA GOTO,HBUFF,HCIRCLE,HCLS,HCOLOR,HDRAW,HGET,HLINE,HPAINT,HPRINT,HPUT,HRESET
614 DATA HSCREEN,HSET,HSTAT,IF,INPUT,KILL,LET,LINE,LIST,LLIST,LOCATE,LPOKE,LOAD,LOADM,LSET,MERGE
615 DATA MOTOR,NEW,NEXT,OLD,ON,OPEN,PAINT,PALETTE,PCLEAR,PCLS,PCOPY,PLAY,PMODE,POKE,PRESET,PRINT
616 DATA PSET,PUT,READ,RENAME,RENUM,RESET,RSET,RESTORE,RESUME,RETURN,RUN,SAVE,SAVEM,SCREEN
617 DATA SET,SKIPF,SOUND,STOP,TO,TROFF,TRON,WIDTH,WRITE,UNLOAD,VERIFY
618 DATA MEM,TIMER,AND,NOT,OR,ELSE,STEP,FREE,AS,BRK,ERR,CMP,RGB,USING
619 DATA ERROR,FREE,OFF,TAB,USING,THEN,TO,G,BF,B,R,A,"?"
620 DATA AS,BF,OR,PI
621
622 ' Functions, keywords that require next character to be an open parentheses
623 DATA ABS,ASC,ATN,BUTTON,CHR$,COS,CVN,EOF,ERLIN,ERNO,EXP,FIX,HEX$,HPOINT,INKEY$,INSTR,INT
624 DATA JOYSTK,LEFT$,LEN,LOC,LOF,LOG,LPEEK,MID$,MKN$,PEEK,POINT,POS,PPOINT,RIGHT$,RND,SGN,SIN
625 DATA STRING$,STR$,SQR,TAN,USR,VAL,VARPTR
626 DATA "\"
627
628 ' Illegal Two Character Variable Table NOTE: "PI" is a variable that is NOT replaced
629 DATA AS,BF,FN,IF,ON,OR,PI,TO,"\"
630
631 ALL_DONE PRINT #FILE_L, " MEM = " ; MEM
632 PRINT " MEM = " ; MEM
633 ' GOSUB DUMP_VARIABLES
634 PRINT "Urbane Done, Errors = " ; ERRORS ; " Warnings = "; WARNINGS ; " Lines = " ; LINE_COUNT ; "Line Label Count = " ; LINE_LABEL_COUNT ; " Variables Count = " ; VARIABLE_NAMES_COUNT
635 PRINT #FILE_L, "Urbane Done, Errors = " ; ERRORS ; " Warnings = "; WARNINGS ; " Lines = " ; LINE_COUNT ; "Line Label Count = " ; LINE_LABEL_COUNT ; " Variables Count = " ; VARIABLE_NAMES_COUNT
636 CLOSE FILE_I
637 CLOSE FILE_O
638 CLOSE FILE_L
639 CLOSE FILE_X
640
641 END
Urbane Pass 1 Done, Lines = 641
MEM = 8106
---------PASS 2 STARTING------
Urbane Pass 2 Done, Lines = 641
MEM = 4477
Urbane Done, Errors = 0 Warnings = 0 Lines = 641 Line Label Count = 65 Variables Count = 137