1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 basic_system: bsys: bs: procedure;
20
21
22
23
24
25
26 declare
27
28 hcs_$make_seg entry (aligned char(*), aligned char(*), aligned char(*),
29 fixed bin(5), ptr, fixed bin(35)),
30 hcs_$initiate_count entry (aligned char(*), aligned char(*), aligned char(*),
31 fixed bin(24), fixed bin(12), ptr, fixed bin(35)),
32 hcs_$set_bc_seg entry (ptr, fixed bin(24), fixed bin(35)),
33 hcs_$truncate_seg entry (ptr, fixed bin, fixed bin(35)),
34 hcs_$terminate_noname entry (pointer, fixed bin(35)),
35 hcs_$delentry_seg entry ( pointer, fixed bin(35)),
36 ioa_ entry options (variable),
37 ioa_$rsnnl entry options (variable),
38 cu_$arg_ptr entry (fixed bin, ptr, fixed bin, fixed bin(35)),
39 cu_$cp entry (ptr, fixed bin, fixed bin(35)),
40 cu_$cl entry,
41 cu_$ptr_call entry(ptr),
42 expand_path_ entry (ptr, fixed bin, ptr, ptr, fixed bin(35)),
43 com_err_ entry options (variable),
44 timer_manager_$cpu_call entry(fixed bin(71),bit(2),entry),
45 timer_manager_$reset_cpu_call entry(entry);
46
47 declare
48
49 sys_info$max_seg_size ext fixed (35),
50 iox_$user_input ext ptr,
51 iox_$user_output ext ptr;
52
53 declare
54
55 basic_ entry(ptr, fixed bin, ptr, ptr, ptr, fixed bin),
56 basic_resequence_ entry (fixed bin, fixed bin, ptr, ptr,
57 fixed bin, fixed bin, fixed bin(35));
58
59 declare
60
61 id char(12) aligned static init("basic_system"),
62 language char(6) aligned static init(".basic");
63
64 declare
65
66 old_linum char(10) aligned;
67
68 declare
69
70 1 segment based aligned,
71 2 program (0:21503) fixed bin(35),
72 2 text (0:44031) fixed bin(35),
73
74 1 table (0:99999) based aligned,
75 2 indx fixed bin(17) unal,
76 2 chcount fixed bin(17) unal,
77
78 long_string char(262144) aligned based,
79
80 ch(0:262143) char(1) unaligned based,
81
82 copy_overlay (count) fixed bin(35) based,
83 count fixed bin(17);
84
85 declare
86
87 name char(lname) based (np),
88 lname fixed bin,
89 np pointer,
90 dirname char(168) aligned,
91 ename char(32) aligned,
92 source char(168) aligned,
93 prog char(32) aligned,
94 cs char(168) based aligned;
95
96 declare
97
98 sptr pointer,
99 tptr pointer,
100 txt pointer,
101 tbl pointer,
102 inp pointer,
103 obj pointer,
104 main pointer;
105
106 declare
107
108 (perm_tptr,
109 perm_tbl,
110 perm_obj) ptr static init(null);
111
112 declare
113
114 error_table_$noentry fixed bin(35) external,
115 status bit(72) aligned,
116 code fixed bin(35),
117
118 program_interrupt condition,
119 cleanup condition,
120
121 level fixed bin static init(0),
122
123 (i, j) fixed bin,
124 k fixed bin(21),
125 nl char(1) static aligned initial ("
126 "), tab char(1) static aligned initial(" "),
127 chr char(1) aligned,
128 s char(1),
129 time_limit fixed bin(71) initial (0),
130 (js, jt) fixed bin initial(0),
131 numl fixed bin,
132 csize fixed bin(24),
133 (first, last) fixed bin,
134 increment fixed bin defined (last),
135 linum fixed bin,
136 err_count fixed bin,
137 lmax fixed bin initial(1),
138 (newline, compiling initial ("0"b), save_sw, known,
139 resequencing initial ("0"b), reading initial ("0"b)) bit(1) aligned,
140 (null, addr, fixed, divide, index, substr, mod, max,
141 min, unspec, verify, search, string, convert) builtin;
142
143 declare
144
145 input_iocb ptr int static,
146 output_iocb ptr int static,
147 buffer char(159);
148
149 %include iocb;
150 ^L
151
152
153
154
155 get_line_number: procedure (place) returns (fixed bin);
156
157 declare
158
159 place, d fixed bin(17),
160 error bit(1) initial ("1"b),
161 line fixed bin;
162
163 line = 0;
164
165 do numl = 0 by 1;
166 chr = txt->ch(place+numl);
167 d = index("0123456789", chr) - 1;
168 if d < 0
169 then do;
170 if error
171 then do;
172 if (chr^=" ") & (chr^=tab)
173 then return (-1);
174 end;
175 else do;
176 newline = (chr = nl);
177 return (line);
178 end;
179 end;
180 else do;
181 line = (line*10)+d;
182 error = "0"b;
183 end;
184 end;
185
186 end get_line_number;
187
188
189
190 get_lines: procedure (place);
191
192 declare place fixed bin;
193
194 first = get_line_number (place);
195 if first < 0 then go to mistake;
196 if newline
197 then do;
198 if resequencing
199 then last = 10;
200 else last = first;
201 end;
202 else do;
203 last = get_line_number (place+numl);
204 if last < 0 | ^newline then go to mistake;
205 if resequencing then return;
206 last = min(lmax, last);
207 end;
208 return;
209
210 mistake:
211 call error ("Bad line number specification.", "", "0"b);
212
213 end get_lines;
214
215
216
217 error: procedure (message, info, fatal);
218
219 declare
220
221 message char(*) aligned,
222 info char(*) aligned,
223 fatal bit(1) aligned;
224
225 resequencing, compiling = "0"b;
226
227 if message = ""
228 then call com_err_ (code, id, info);
229 else call ioa_ ("^a ^a", message, info);
230
231 if fatal
232 then call cu_$cl;
233 else if reading
234 then go to move;
235 else do;
236 call input_iocb -> iocb.control (input_iocb, "resetread", null(), code);
237 call ioa_ ("RESET");
238 go to next;
239 end;
240
241 end error;
242
243
244
245 get_seg: proc(name,type,pt);
246
247 declare
248
249 name char(*) aligned,
250 type fixed bin(5),
251 pt ptr;
252
253 call hcs_$make_seg("", name, "", type, pt, code);
254 if pt = null then call error("", name, "1"b);
255
256 end get_seg;
257
258
259
260 clean_up: proc;
261
262 if compiling & (time_limit ^= 0) then call timer_manager_$reset_cpu_call(cpu_limit);
263
264 if level = 1
265 then do;
266
267
268
269 call hcs_$truncate_seg(tptr, 0, code);
270 call hcs_$truncate_seg(tbl, 0, code);
271 call hcs_$truncate_seg(obj, 0, code);
272 end;
273 else do;
274
275
276
277
278 call hcs_$delentry_seg(tptr, code);
279 call hcs_$delentry_seg(tbl, code);
280 call hcs_$delentry_seg(obj, code);
281 end;
282
283 level = level - 1;
284
285 end clean_up;
286
287
288
289 cpu_limit: proc;
290
291 compiling = "1"b;
292 call ioa_("Time limit exceeded.");
293 goto edit;
294 end;
295 ^L
296
297
298
299
300 start:
301
302 on program_interrupt begin;
303 if resequencing then do;
304 call ioa_ ("Resequencing aborted.");
305 resequencing = "0"b;
306 end;
307 else if compiling then do;
308 call ioa_ ("Execution aborted.");
309 compiling = "0"b;
310 if time_limit ^= 0 then call timer_manager_$reset_cpu_call(cpu_limit);
311 end;
312 go to edit;
313 end;
314
315
316 level = level + 1;
317
318 if level = 1
319 then do;
320
321 input_iocb = iox_$user_input;
322 output_iocb = iox_$user_output;
323 if perm_tptr = null
324 then do;
325
326
327
328 call get_seg("basic_system_text_",01011b,perm_tptr);
329 call get_seg("basic_system_table_",01011b,perm_tbl);
330 call get_seg("basic_system_object_",01111b,perm_obj);
331 end;
332
333 tptr = perm_tptr;
334 tbl = perm_tbl;
335 obj = perm_obj;
336 end;
337 else do;
338
339
340
341 call get_seg("",01011b,tptr);
342 call get_seg("",01011b,tbl);
343 call get_seg("",01111b,obj);
344 end;
345
346 on cleanup call clean_up;
347 txt = addr(tptr->segment.text);
348
349
350
351 call cu_$arg_ptr (1, np, lname, code);
352 if lname = 0 | code ^= 0 then do;
353 known = "0"b;
354 call ioa_ ("Input.^/");
355 go to next;
356 end;
357 known = "1"b;
358 source = name;
359
360 get_source:
361 k = index(source," ");
362 if k ^= 0
363 then if substr(source,k+1) ^= ""
364 then do;
365 known = "0"b;
366 call error ("Improper segment name.", source, "0"b);
367 end;
368 if index (source, language) = 0
369 then do;
370 substr(source, lname+1, 6) = language;
371 lname = lname + 6;
372 end;
373 call expand_path_ (addr(source), lname, addr(dirname), addr(ename), code);
374 if code ^= 0 then call error ("", source, "0"b);
375 prog = substr(ename, 1, index(ename, language)-1);
376 call ioa_$rsnnl ("^a>^a", source, i, dirname, ename);
377 call hcs_$initiate_count (dirname, ename, "", csize, 0, sptr, code);
378 if sptr = null then do;
379 if code ^= error_table_$noentry
380 then call error ("", source, "1"b);
381 else do;
382 call ioa_ ("Program not found.^/Input.^/");
383 go to next;
384 end;
385 end;
386 csize = divide(csize,9,17,0);
387
388
389
390
391
392 move:
393 reading = "1"b;
394 old_linum = "-1";
395 do while (js < csize);
396 k = index (substr(sptr->long_string, js+1), nl);
397 if k = 0 then k = csize - js;
398 substr (txt->long_string, jt+1, k) =
399 substr (sptr->long_string, js+1, k);
400 js = js + k;
401 linum = get_line_number (jt);
402 if linum < 0
403 then call error ("Bad line number in source. Line deleted after line", old_linum, "0"b);
404 else if linum > 99999
405 then call error ("Line number in source too large. Line deleted after line", old_linum, "0"b);
406 lmax = max(lmax, linum);
407 old_linum = substr(convert(old_linum, linum), 6);
408 tbl->table(linum).indx = jt;
409 tbl->table(linum).chcount = k;
410 jt = jt + k + 3;
411 jt = jt - mod(jt,4);
412 end;
413 reading = "0"b;
414
415
416
417
418 edit:
419 call ioa_ ("Edit.^/");
420
421 next:
422 inp = addr(txt->ch(jt));
423 call input_iocb -> iocb.get_line (input_iocb, inp, 158, k, code);
424 if code ^= 0 then do;
425 call com_err_ (code, "basic_system");
426 go to next;
427 end;
428 if k <= 1 then go to next;
429 j = verify(inp->cs," ");
430 if j > 1 then do;
431 k = k - j + 1;
432 substr(inp->cs, 1, k) = substr(inp->cs, j, k);
433 end;
434
435 if search(substr(inp->cs, 1, 1), "0123456789") > 0
436 then do;
437 linum = get_line_number (jt);
438 if linum < 0 then call error ("Bad line number.", "", "0"b);
439 else if linum > 99999 then call error ("Line number too large.", "", "0"b);
440 if newline
441 then tbl->table(linum).chcount = 0;
442 else do;
443 lmax = max(lmax, linum);
444 tbl->table(linum).indx = jt;
445 tbl->table(linum).chcount = k;
446 jt = jt + k + 3;
447 jt = jt-mod(jt,4);
448 end;
449 go to next;
450 end;
451
452 if substr(inp->cs, 1, 3) = "run" then
453 if substr(inp->cs, 4, 1) = nl then go to run;
454
455 if substr(inp->cs, 1, 4) = "save" then go to save;
456
457 if substr(inp->cs, 1, 4) = "list" then go to list;
458
459 if substr(inp->cs, 1, 4) = "quit" then
460 if substr(inp->cs, 5, 1) = nl then go to quit;
461
462 if substr(inp->cs, 1, 6) = "delete" then go to delete;
463
464 if substr(inp->cs, 1, 4) = "rseq" then go to resequence;
465
466 if substr(inp->cs, 1, 4) = "exec"
467 then do;
468 call cu_$cp (addr(inp->ch(4)), k-4, code);
469 go to next;
470 end;
471
472 if substr(inp->cs, 1, 4) = "time"
473 then do;
474 time_limit = get_line_number (jt+4);
475 if time_limit < 0 then call error("Negative time limit given.","","0"b);
476 go to next;
477 end;
478
479 if substr(inp->cs, 1, 3) = "get"
480 then do;
481 known = "0"b;
482 if substr (inp->cs, 4, 1) = nl
483 then call ioa_ ("Input.^/");
484 else do;
485 j = verify (substr(inp->cs, 4), " ") + 3;
486 if j = 0 then call error ("Improper syntax in get command.", "", "0"b);
487 lname = index (substr(inp->cs, j), nl) - 1;
488 source = substr (inp->cs, j , lname);
489 known = "1"b;
490 end;
491
492 call hcs_$truncate_seg (tptr, 0, code);
493 if code ^= 0 then call error ("", "Temporary.", "1"b);
494 call hcs_$truncate_seg (tbl, 0, code);
495 if code ^= 0 then call error ("", "Temporary.", "1"b);
496 lmax, js, jt = 0;
497
498 if known
499 then go to get_source;
500 else go to next;
501
502 end;
503
504 call ioa_ ("Command not understood.");
505 call input_iocb -> iocb.control (input_iocb, "resetread", null(), code);
506 call ioa_("RESET");
507 go to next;
508
509
510
511
512
513 run:
514 save_sw = "0"b;
515
516 finish:
517 j = 1;
518 do k = 0 to lmax;
519 if tbl->table(k).chcount ^= 0 then
520 substr (tptr->long_string, j, tbl->table(k).chcount) =
521 substr (txt->long_string, tbl->table(k).indx+1, tbl->table(k).chcount);
522 j = j + tbl->table(k).chcount;
523 end;
524 j = j - 1;
525
526 if save_sw
527 then do;
528 call hcs_$make_seg (dirname, ename, "", 01011b, sptr, code);
529 if sptr = null then call error ("", source, "0"b);
530 count = divide(j+3,4,17,0);
531 sptr->copy_overlay = tptr->copy_overlay;
532 call hcs_$set_bc_seg (sptr, fixed(j*9,24,0), code);
533 if code ^= 0 then call error ("", source, "0"b);
534 call hcs_$truncate_seg (sptr, count, code);
535 if code ^= 0 then call error ("", source, "0"b);
536 go to edit;
537 end;
538 else do;
539 compiling = "1"b;
540 call hcs_$truncate_seg(obj,0,code);
541 if code ^= 0 then call error("","","0"b);
542
543 call basic_(tptr,j,obj,null,main,err_count);
544
545 if err_count = 0
546 then if main = null
547 then call ioa_("No main program.");
548 else if time_limit = 0 then call cu_$ptr_call(main);
549 else do;
550 call timer_manager_$cpu_call(time_limit,"11"b,cpu_limit);
551 call cu_$ptr_call(main);
552 call timer_manager_$reset_cpu_call(cpu_limit);
553 end;
554 else do;
555 if err_count = 1 then s = ""; else s = "s";
556 call ioa_("^d error^a found, no execution.",err_count,s);
557 end;
558
559 compiling = "0"b;
560 go to edit;
561 end;
562
563 save:
564 save_sw = "1"b;
565 if substr(inp->cs, 5, 1) = nl
566 then if known
567 then go to finish;
568 else call error ("No name given.", "", "0"b);
569
570 j = verify (substr(inp->cs, 5), " ") + 4;
571 if j = 0 then call error ("Improper syntax in save command.", "", "0"b);
572 lname = index (substr(inp->cs, j), nl) - 1;
573 source = substr(inp->cs, j, lname);
574 k = index(source, " ");
575 if k ^= 0
576 then if substr(source,k+1) ^= ""
577 then do;
578 known = "0"b;
579 call error ("Improper segment name.", source, "0"b);
580 end;
581 if index(source, language) = 0
582 then do;
583 substr(source, lname+1, 6) = language;
584 lname = lname + 6;
585 end;
586 call expand_path_ (addr(source), lname, addr(dirname), addr(ename), code);
587 if code ^= 0 then call error ("", source, "0"b);
588 prog = substr(ename, 1, index(ename, language)-1);
589 call ioa_$rsnnl ("^a>^a", source, i, dirname, ename);
590 known = "1"b;
591 go to finish;
592
593 list:
594 if substr(inp->cs, 5, 1) = nl
595 then do;
596 first = 0;
597 last = lmax;
598 end;
599 else call get_lines (jt + 4);
600
601 if first > last then do;
602 i = last;
603 last = first;
604 first = i;
605 end;
606
607 if first ^= last
608 then call output_iocb -> put_chars (output_iocb, addr(nl), 1, code);
609 else if tbl->table.chcount(first) = 0
610 then call error ("No line.", "", "0"b);
611
612 do i = first to last;
613 k = tbl->table(i).chcount;
614 substr(buffer, 1, k+1) = substr(txt->long_string, tbl->table(i).indx + 1, k) || nl;
615 if k ^= 0 then call output_iocb -> iocb.put_chars (output_iocb, addr(buffer), k, code);
616 end;
617
618 call output_iocb -> iocb.put_chars (output_iocb, addr(nl), 1, code);
619 go to next;
620
621 quit: call clean_up;
622 return;
623
624 delete:
625 if substr(inp->cs, 7, 1) = nl
626 then call error ("No line numbers given.", "", "0"b);
627 else do;
628 if substr(inp->cs, 7, 4) = " all"
629 then do;
630 first = 0;
631 last = lmax;
632 end;
633 else call get_lines (jt + 6);
634 end;
635
636 do i = first to last;
637 tbl->table(i).chcount = 0;
638 end;
639
640 go to next;
641
642 resequence:
643 resequencing = "1"b;
644
645 if substr(inp->cs, 5, 1) = nl
646 then do;
647 first = 100;
648 increment = 10;
649 end;
650 else call get_lines (jt + 4);
651
652 call basic_resequence_ (first, increment, tbl, txt, jt, lmax, code);
653 if code ^= 0 then call error ("", "Error occurred while resequencing.", "0"b);
654 resequencing = "0"b;
655
656 go to edit;
657
658 end basic_system;