home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume21 / p2c / part19 < prev    next >
Text File  |  1990-04-05  |  52KB  |  1,609 lines

  1. Subject:  v21i064:  Pascal to C translator, Part19/32
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: da6cea1c d014eb81 886e97ce e7773e24
  5.  
  6. Submitted-by: Dave Gillespie <daveg@csvax.caltech.edu>
  7. Posting-number: Volume 21, Issue 64
  8. Archive-name: p2c/part19
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 19 (of 32)."
  17. # Contents:  examples/basic.p.1
  18. # Wrapped by rsalz@litchi.bbn.com on Mon Mar 26 14:29:42 1990
  19. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  20. if test -f 'examples/basic.p.1' -a "${1}" != "-c" ; then 
  21.   echo shar: Will not clobber existing file \"'examples/basic.p.1'\"
  22. else
  23. echo shar: Extracting \"'examples/basic.p.1'\" \(48192 characters\)
  24. sed "s/^X//" >'examples/basic.p.1' <<'END_OF_FILE'
  25. X
  26. X$ sysprog, ucsd, heap_dispose, partial_eval $
  27. X
  28. X{$ debug$}
  29. X
  30. X
  31. Xprogram basic(input, output);
  32. X
  33. X
  34. Xconst
  35. X
  36. X   checking = true;
  37. X
  38. X   varnamelen = 20;
  39. X   maxdims = 4;
  40. X
  41. X
  42. X
  43. Xtype
  44. X
  45. X   varnamestring = string[varnamelen];
  46. X
  47. X   string255 = string[255];
  48. X   string255ptr = ^string255;
  49. X
  50. X   tokenkinds = (tokvar, toknum, tokstr, toksnerr,
  51. X
  52. X                 tokplus, tokminus, toktimes, tokdiv, tokup, toklp, tokrp, 
  53. X                 tokcomma, toksemi, tokcolon, tokeq, toklt, tokgt,
  54. X                 tokle, tokge, tokne,
  55. X
  56. X                 tokand, tokor, tokxor, tokmod, toknot, toksqr, toksqrt, toksin,
  57. X                 tokcos, toktan, tokarctan, toklog, tokexp, tokabs, toksgn,
  58. X                 tokstr_, tokval, tokchr_, tokasc, toklen, tokmid_, tokpeek,
  59. X
  60. X                 tokrem, toklet, tokprint, tokinput, tokgoto, tokif, tokend, 
  61. X                 tokstop, tokfor, toknext, tokwhile, tokwend, tokgosub,
  62. X                 tokreturn, tokread, tokdata, tokrestore, tokgotoxy, tokon,
  63. X                 tokdim, tokpoke,
  64. X
  65. X                 toklist, tokrun, toknew, tokload, tokmerge, toksave, tokbye,
  66. X                 tokdel, tokrenum,
  67. X
  68. X                 tokthen, tokelse, tokto, tokstep);
  69. X
  70. X   realptr = ^real;
  71. X   basicstring = string255ptr;
  72. X   stringptr = ^basicstring;
  73. X   numarray = array[0..maxint] of real;
  74. X   arrayptr = ^numarray;
  75. X   strarray = array[0..maxint] of basicstring;
  76. X   strarrayptr = ^strarray;
  77. X
  78. X   tokenptr = ^tokenrec;
  79. X   lineptr = ^linerec;
  80. X   varptr = ^varrec;
  81. X   loopptr = ^looprec;
  82. X
  83. X   tokenrec =
  84. X      record
  85. X         next : tokenptr;
  86. X         case kind : tokenkinds of
  87. X            tokvar : (vp : varptr);
  88. X            toknum : (num : real);
  89. X            tokstr, tokrem : (sp : string255ptr);
  90. X            toksnerr : (snch : char);
  91. X      end;
  92. X
  93. X   linerec =
  94. X      record
  95. X         num, num2 : integer;
  96. X         txt : tokenptr;
  97. X         next : lineptr;
  98. X      end;
  99. X
  100. X   varrec =
  101. X      record
  102. X         name : varnamestring;
  103. X         next : varptr;
  104. X         dims : array [1..maxdims] of integer;
  105. X         numdims : 0..maxdims;
  106. X         case stringvar : boolean of
  107. X            false : (arr : arrayptr;  val : realptr;  rv : real);
  108. X            true : (sarr : strarrayptr;  sval : stringptr;  sv : basicstring);
  109. X      end;
  110. X
  111. X   valrec =
  112. X      record
  113. X         case stringval : boolean of
  114. X            false : (val : real);
  115. X            true : (sval : basicstring);
  116. X      end;
  117. X
  118. X   loopkind = (forloop, whileloop, gosubloop);
  119. X   looprec =
  120. X      record
  121. X         next : loopptr;
  122. X         homeline : lineptr;
  123. X         hometok : tokenptr;
  124. X         case kind : loopkind of
  125. X            forloop :
  126. X               ( vp : varptr;
  127. X                 max, step : real );
  128. X      end;
  129. X
  130. X
  131. X
  132. Xvar
  133. X
  134. X   inbuf : string255ptr;
  135. X
  136. X   linebase : lineptr;
  137. X   varbase : varptr;
  138. X   loopbase : loopptr;
  139. X
  140. X   curline : integer;
  141. X   stmtline, dataline : lineptr;
  142. X   stmttok, datatok, buf : tokenptr;
  143. X
  144. X   exitflag : boolean;
  145. X
  146. X   excp_line ['EXCP_LINE'] : integer;
  147. X
  148. X
  149. X
  150. X$if not checking$
  151. X   $range off$
  152. X$end$
  153. X
  154. X
  155. X
  156. Xprocedure misc_getioerrmsg(var s : string; io : integer);
  157. X   external;
  158. X
  159. Xprocedure misc_printerror(er, io : integer);
  160. X   external;
  161. X
  162. Xfunction asm_iand(a, b : integer) : integer;
  163. X   external;
  164. X
  165. Xfunction asm_ior(a, b : integer) : integer;
  166. X   external;
  167. X
  168. Xprocedure hpm_new(var p : anyptr; size : integer);
  169. X   external;
  170. X
  171. Xprocedure hpm_dispose(var p : anyptr; size : integer);
  172. X   external;
  173. X
  174. X
  175. X
  176. Xprocedure restoredata;
  177. X   begin
  178. X      dataline := nil;
  179. X      datatok := nil;
  180. X   end;
  181. X
  182. X
  183. X
  184. Xprocedure clearloops;
  185. X   var
  186. X      l : loopptr;
  187. X   begin
  188. X      while loopbase <> nil do
  189. X         begin
  190. X            l := loopbase^.next;
  191. X            dispose(loopbase);
  192. X            loopbase := l;
  193. X         end;
  194. X   end;
  195. X
  196. X
  197. X
  198. Xfunction arraysize(v : varptr) : integer;
  199. X   var
  200. X      i, j : integer;
  201. X   begin
  202. X      with v^ do
  203. X         begin
  204. X            if stringvar then
  205. X               j := 4
  206. X            else
  207. X               j := 8;
  208. X            for i := 1 to numdims do
  209. X               j := j * dims[i];
  210. X         end;
  211. X      arraysize := j;
  212. X   end;
  213. X
  214. X
  215. Xprocedure clearvar(v : varptr);
  216. X   begin
  217. X      with v^ do
  218. X         begin
  219. X            if numdims <> 0 then
  220. X               hpm_dispose(arr, arraysize(v))
  221. X            else if stringvar and (sv <> nil) then
  222. X               dispose(sv);
  223. X            numdims := 0;
  224. X            if stringvar then
  225. X               begin
  226. X                  sv := nil;
  227. X                  sval := addr(sv);
  228. X               end
  229. X            else
  230. X               begin
  231. X                  rv := 0;
  232. X                  val := addr(rv);
  233. X               end;
  234. X         end;
  235. X   end;
  236. X
  237. X
  238. Xprocedure clearvars;
  239. X   var
  240. X      v : varptr;
  241. X   begin
  242. X      v := varbase;
  243. X      while v <> nil do
  244. X         begin
  245. X            clearvar(v);
  246. X            v := v^.next;
  247. X         end;
  248. X   end;
  249. X
  250. X
  251. X
  252. Xfunction numtostr(n : real) : string255;
  253. X   var
  254. X      s : string255;
  255. X      i : integer;
  256. X   begin
  257. X      setstrlen(s, 255);
  258. X      if (n <> 0) and (abs(n) < 1e-2) or (abs(n) >= 1e12) then
  259. X         begin
  260. X            strwrite(s, 1, i, n);
  261. X            setstrlen(s, i-1);
  262. X            numtostr := s;
  263. X         end
  264. X      else
  265. X         begin
  266. X            strwrite(s, 1, i, n:30:10);
  267. X            repeat
  268. X               i := i - 1;
  269. X            until s[i] <> '0';
  270. X            if s[i] = '.' then
  271. X               i := i - 1;
  272. X            setstrlen(s, i);
  273. X            numtostr := strltrim(s);
  274. X         end;
  275. X   end;
  276. X
  277. X
  278. X
  279. Xprocedure parse(inbuf : string255ptr; var buf : tokenptr);
  280. X
  281. X   const
  282. X      toklength = 20;
  283. X
  284. X   type
  285. X      chset = set of char;
  286. X
  287. X   const
  288. X      idchars = chset ['A'..'Z','a'..'z','0'..'9','_','$'];
  289. X
  290. X   var
  291. X      i, j, k : integer;
  292. X      token : string[toklength];
  293. X      t, tptr : tokenptr;
  294. X      v : varptr;
  295. X      ch : char;
  296. X      n, d, d1 : real;
  297. X
  298. X   begin
  299. X      tptr := nil;
  300. X      buf := nil;
  301. X      i := 1;
  302. X      repeat
  303. X         ch := ' ';
  304. X         while (i <= strlen(inbuf^)) and (ch = ' ') do
  305. X            begin
  306. X               ch := inbuf^[i];
  307. X               i := i + 1;
  308. X            end;
  309. X         if ch <> ' ' then
  310. X            begin
  311. X               new(t);
  312. X               if tptr = nil then
  313. X                  buf := t
  314. X               else
  315. X                  tptr^.next := t;
  316. X               tptr := t;
  317. X               t^.next := nil;
  318. X               case ch of
  319. X                  'A'..'Z', 'a'..'z' :
  320. X                     begin
  321. X                        i := i - 1;
  322. X                        j := 0;
  323. X                        setstrlen(token, strmax(token));
  324. X                        while (i <= strlen(inbuf^)) and (inbuf^[i] in idchars) do
  325. X                           begin
  326. X                              if j < toklength then
  327. X                                 begin
  328. X                                    j := j + 1;
  329. X                                    token[j] := inbuf^[i];
  330. X                                 end;
  331. X                              i := i + 1;
  332. X                           end;
  333. X                        setstrlen(token, j);
  334. X                        if (token = 'and')     or (token = 'AND')     then t^.kind := tokand     
  335. X                   else if (token = 'or')      or (token = 'OR')      then t^.kind := tokor      
  336. X                   else if (token = 'xor')     or (token = 'XOR')     then t^.kind := tokxor     
  337. X                   else if (token = 'not')     or (token = 'NOT')     then t^.kind := toknot     
  338. X                   else if (token = 'mod')     or (token = 'MOD')     then t^.kind := tokmod     
  339. X                   else if (token = 'sqr')     or (token = 'SQR')     then t^.kind := toksqr     
  340. X                   else if (token = 'sqrt')    or (token = 'SQRT')    then t^.kind := toksqrt    
  341. X                   else if (token = 'sin')     or (token = 'SIN')     then t^.kind := toksin     
  342. X                   else if (token = 'cos')     or (token = 'COS')     then t^.kind := tokcos     
  343. X                   else if (token = 'tan')     or (token = 'TAN')     then t^.kind := toktan     
  344. X                   else if (token = 'arctan')  or (token = 'ARCTAN')  then t^.kind := tokarctan  
  345. X                   else if (token = 'log')     or (token = 'LOG')     then t^.kind := toklog     
  346. X                   else if (token = 'exp')     or (token = 'EXP')     then t^.kind := tokexp     
  347. X                   else if (token = 'abs')     or (token = 'ABS')     then t^.kind := tokabs     
  348. X                   else if (token = 'sgn')     or (token = 'SGN')     then t^.kind := toksgn     
  349. X                   else if (token = 'str$')    or (token = 'STR$')    then t^.kind := tokstr_    
  350. X                   else if (token = 'val')     or (token = 'VAL')     then t^.kind := tokval     
  351. X                   else if (token = 'chr$')    or (token = 'CHR$')    then t^.kind := tokchr_    
  352. X                   else if (token = 'asc')     or (token = 'ASC')     then t^.kind := tokasc     
  353. X                   else if (token = 'len')     or (token = 'LEN')     then t^.kind := toklen     
  354. X                   else if (token = 'mid$')    or (token = 'MID$')    then t^.kind := tokmid_    
  355. X                   else if (token = 'peek')    or (token = 'PEEK')    then t^.kind := tokpeek    
  356. X                   else if (token = 'let')     or (token = 'LET')     then t^.kind := toklet     
  357. X                   else if (token = 'print')   or (token = 'PRINT')   then t^.kind := tokprint   
  358. X                   else if (token = 'input')   or (token = 'INPUT')   then t^.kind := tokinput   
  359. X                   else if (token = 'goto')    or (token = 'GOTO')    then t^.kind := tokgoto    
  360. X                   else if (token = 'go to')   or (token = 'GO TO')   then t^.kind := tokgoto    
  361. X                   else if (token = 'if')      or (token = 'IF')      then t^.kind := tokif      
  362. X                   else if (token = 'end')     or (token = 'END')     then t^.kind := tokend     
  363. X                   else if (token = 'stop')    or (token = 'STOP')    then t^.kind := tokstop    
  364. X                   else if (token = 'for')     or (token = 'FOR')     then t^.kind := tokfor     
  365. X                   else if (token = 'next')    or (token = 'NEXT')    then t^.kind := toknext    
  366. X                   else if (token = 'while')   or (token = 'WHILE')   then t^.kind := tokwhile   
  367. X                   else if (token = 'wend')    or (token = 'WEND')    then t^.kind := tokwend    
  368. X                   else if (token = 'gosub')   or (token = 'GOSUB')   then t^.kind := tokgosub   
  369. X                   else if (token = 'return')  or (token = 'RETURN')  then t^.kind := tokreturn  
  370. X                   else if (token = 'read')    or (token = 'READ')    then t^.kind := tokread    
  371. X                   else if (token = 'data')    or (token = 'DATA')    then t^.kind := tokdata    
  372. X                   else if (token = 'restore') or (token = 'RESTORE') then t^.kind := tokrestore 
  373. X                   else if (token = 'gotoxy')  or (token = 'GOTOXY')  then t^.kind := tokgotoxy  
  374. X                   else if (token = 'on')      or (token = 'ON')      then t^.kind := tokon      
  375. X                   else if (token = 'dim')     or (token = 'DIM')     then t^.kind := tokdim     
  376. X                   else if (token = 'poke')    or (token = 'POKE')    then t^.kind := tokpoke    
  377. X                   else if (token = 'list')    or (token = 'LIST')    then t^.kind := toklist    
  378. X                   else if (token = 'run')     or (token = 'RUN')     then t^.kind := tokrun     
  379. X                   else if (token = 'new')     or (token = 'NEW')     then t^.kind := toknew     
  380. X                   else if (token = 'load')    or (token = 'LOAD')    then t^.kind := tokload    
  381. X                   else if (token = 'merge')   or (token = 'MERGE')   then t^.kind := tokmerge   
  382. X                   else if (token = 'save')    or (token = 'SAVE')    then t^.kind := toksave    
  383. X                   else if (token = 'bye')     or (token = 'BYE')     then t^.kind := tokbye     
  384. X                   else if (token = 'quit')    or (token = 'QUIT')    then t^.kind := tokbye     
  385. X                   else if (token = 'del')     or (token = 'DEL')     then t^.kind := tokdel     
  386. X                   else if (token = 'renum')   or (token = 'RENUM')   then t^.kind := tokrenum   
  387. X                   else if (token = 'then')    or (token = 'THEN')    then t^.kind := tokthen    
  388. X                   else if (token = 'else')    or (token = 'ELSE')    then t^.kind := tokelse    
  389. X                   else if (token = 'to')      or (token = 'TO')      then t^.kind := tokto      
  390. X                   else if (token = 'step')    or (token = 'STEP')    then t^.kind := tokstep    
  391. X                   else if (token = 'rem')     or (token = 'REM')     then
  392. X                           begin
  393. X                              t^.kind := tokrem;
  394. X                              new(t^.sp);
  395. X                              t^.sp^ := str(inbuf^, i, strlen(inbuf^)-i+1);
  396. X                              i := strlen(inbuf^)+1;
  397. X                           end
  398. X                        else
  399. X                           begin
  400. X                              t^.kind := tokvar;
  401. X                              v := varbase;
  402. X                              while (v <> nil) and (v^.name <> token) do
  403. X                                 v := v^.next;
  404. X                              if v = nil then
  405. X                                 begin
  406. X                                    new(v);
  407. X                                    v^.next := varbase;
  408. X                                    varbase := v;
  409. X                                    v^.name := token;
  410. X                                    v^.numdims := 0;
  411. X                                    if token[strlen(token)] = '$' then
  412. X                                       begin
  413. X                                          v^.stringvar := true;
  414. X                                          v^.sv := nil;
  415. X                                          v^.sval := addr(v^.sv);
  416. X                                       end
  417. X                                    else
  418. X                                       begin
  419. X                                          v^.stringvar := false;
  420. X                                          v^.rv := 0;
  421. X                                          v^.val := addr(v^.rv);
  422. X                                       end;
  423. X                                 end;
  424. X                              t^.vp := v;
  425. X                           end;
  426. X                     end;
  427. X                  '"', '''' :
  428. X                     begin
  429. X                        t^.kind := tokstr;
  430. X                        new(t^.sp);
  431. X                        setstrlen(t^.sp^, 255);
  432. X                        j := 0;
  433. X                        while (i <= strlen(inbuf^)) and (inbuf^[i] <> ch) do
  434. X                           begin
  435. X                              j := j + 1;
  436. X                              t^.sp^[j] := inbuf^[i];
  437. X                              i := i + 1;
  438. X                           end;
  439. X                        setstrlen(t^.sp^, j);
  440. X                        i := i + 1;
  441. X                     end;
  442. X                  '0'..'9', '.' :
  443. X                     begin
  444. X                        t^.kind := toknum;
  445. X                        n := 0;
  446. X                        d := 1;
  447. X                        d1 := 1;
  448. X                        i := i - 1;
  449. X                        while (i <= strlen(inbuf^)) and ((inbuf^[i] in ['0'..'9'])
  450. X                                    or ((inbuf^[i] = '.') and (d1 = 1))) do
  451. X                           begin
  452. X                              if inbuf^[i] = '.' then
  453. X                                 d1 := 10
  454. X                              else
  455. X                                 begin
  456. X                                    n := n * 10 + ord(inbuf^[i]) - 48;
  457. X                                    d := d * d1;
  458. X                                 end;
  459. X                              i := i + 1;
  460. X                           end;
  461. X                        n := n / d;
  462. X                        if (i <= strlen(inbuf^)) and (inbuf^[i] in ['e','E']) then
  463. X                           begin
  464. X                              i := i + 1;
  465. X                              d1 := 10;
  466. X                              if (i <= strlen(inbuf^)) and (inbuf^[i] in ['+','-']) then
  467. X                                 begin
  468. X                                    if inbuf^[i] = '-' then
  469. X                                       d1 := 0.1;
  470. X                                    i := i + 1;
  471. X                                 end;
  472. X                              j := 0;
  473. X                              while (i <= strlen(inbuf^)) and (inbuf^[i] in ['0'..'9']) do
  474. X                                 begin
  475. X                                    j := j * 10 + ord(inbuf^[i]) - 48;
  476. X                                    i := i + 1;
  477. X                                 end;
  478. X                              for k := 1 to j do
  479. X                                 n := n * d1;
  480. X                           end;
  481. X                        t^.num := n;
  482. X                     end;
  483. X                  '+' : t^.kind := tokplus;
  484. X                  '-' : t^.kind := tokminus;
  485. X                  '*' : t^.kind := toktimes;
  486. X                  '/' : t^.kind := tokdiv;
  487. X                  '^' : t^.kind := tokup;
  488. X                  '(', '[' : t^.kind := toklp;
  489. X                  ')', ']' : t^.kind := tokrp;
  490. X                  ',' : t^.kind := tokcomma;
  491. X                  ';' : t^.kind := toksemi;
  492. X                  ':' : t^.kind := tokcolon;
  493. X                  '?' : t^.kind := tokprint;
  494. X                  '=' : t^.kind := tokeq;
  495. X                  '<' : 
  496. X                     begin
  497. X                        if (i <= strlen(inbuf^)) and (inbuf^[i] = '=') then
  498. X                           begin
  499. X                              t^.kind := tokle;
  500. X                              i := i + 1;
  501. X                           end
  502. X                        else if (i <= strlen(inbuf^)) and (inbuf^[i] = '>') then
  503. X                           begin
  504. X                              t^.kind := tokne;
  505. X                              i := i + 1;
  506. X                           end
  507. X                        else
  508. X                           t^.kind := toklt;
  509. X                     end;
  510. X                  '>' :
  511. X                     begin
  512. X                        if (i <= strlen(inbuf^)) and (inbuf^[i] = '=') then
  513. X                           begin
  514. X                              t^.kind := tokge;
  515. X                              i := i + 1;
  516. X                           end
  517. X                        else
  518. X                           t^.kind := tokgt;
  519. X                     end;
  520. X                  otherwise
  521. X                     begin
  522. X                        t^.kind := toksnerr;
  523. X                        t^.snch := ch;
  524. X                     end;
  525. X               end;
  526. X            end;
  527. X      until i > strlen(inbuf^);
  528. X   end;
  529. X
  530. X
  531. X
  532. Xprocedure listtokens(var f : text; buf : tokenptr);
  533. X   var
  534. X      ltr, ltr0 : boolean;
  535. X   begin
  536. X      ltr := false;
  537. X      while buf <> nil do
  538. X         begin
  539. X            if buf^.kind in [tokvar, toknum, toknot..tokrenum] then
  540. X               begin
  541. X                  if ltr then write(f, ' ');
  542. X                  ltr := (buf^.kind <> toknot);
  543. X               end
  544. X            else
  545. X               ltr := false;
  546. X            case buf^.kind of
  547. X               tokvar     : write(f, buf^.vp^.name);
  548. X               toknum     : write(f, numtostr(buf^.num));
  549. X               tokstr     : write(f, '"', buf^.sp^, '"');
  550. X               toksnerr   : write(f, '{', buf^.snch, '}');
  551. X               tokplus    : write(f, '+');
  552. X               tokminus   : write(f, '-');
  553. X               toktimes   : write(f, '*');
  554. X               tokdiv     : write(f, '/');
  555. X               tokup      : write(f, '^');
  556. X               toklp      : write(f, '(');
  557. X               tokrp      : write(f, ')');
  558. X               tokcomma   : write(f, ',');
  559. X               toksemi    : write(f, ';');
  560. X               tokcolon   : write(f, ' : ');
  561. X               tokeq      : write(f, ' = ');
  562. X               toklt      : write(f, ' < ');
  563. X               tokgt      : write(f, ' > ');
  564. X               tokle      : write(f, ' <= ');
  565. X               tokge      : write(f, ' >= ');
  566. X               tokne      : write(f, ' <> ');
  567. X               tokand     : write(f, ' AND ');
  568. X               tokor      : write(f, ' OR ');
  569. X               tokxor     : write(f, ' XOR ');
  570. X               tokmod     : write(f, ' MOD ');
  571. X               toknot     : write(f, 'NOT ');
  572. X               toksqr     : write(f, 'SQR');
  573. X               toksqrt    : write(f, 'SQRT');
  574. X               toksin     : write(f, 'SIN');
  575. X               tokcos     : write(f, 'COS');
  576. X               toktan     : write(f, 'TAN');
  577. X               tokarctan  : write(f, 'ARCTAN');
  578. X               toklog     : write(f, 'LOG');
  579. X               tokexp     : write(f, 'EXP');
  580. X               tokabs     : write(f, 'ABS');
  581. X               toksgn     : write(f, 'SGN');
  582. X               tokstr_    : write(f, 'STR$');
  583. X               tokval     : write(f, 'VAL');
  584. X               tokchr_    : write(f, 'CHR$');
  585. X               tokasc     : write(f, 'ASC');
  586. X               toklen     : write(f, 'LEN');
  587. X               tokmid_    : write(f, 'MID$');
  588. X               tokpeek    : write(f, 'PEEK');
  589. X               toklet     : write(f, 'LET');
  590. X               tokprint   : write(f, 'PRINT');
  591. X               tokinput   : write(f, 'INPUT');
  592. X               tokgoto    : write(f, 'GOTO');
  593. X               tokif      : write(f, 'IF');
  594. X               tokend     : write(f, 'END');
  595. X               tokstop    : write(f, 'STOP');
  596. X               tokfor     : write(f, 'FOR');
  597. X               toknext    : write(f, 'NEXT');
  598. X               tokwhile   : write(f, 'WHILE');
  599. X               tokwend    : write(f, 'WEND');
  600. X               tokgosub   : write(f, 'GOSUB');
  601. X               tokreturn  : write(f, 'RETURN');
  602. X               tokread    : write(f, 'READ');
  603. X               tokdata    : write(f, 'DATA');
  604. X               tokrestore : write(f, 'RESTORE');
  605. X               tokgotoxy  : write(f, 'GOTOXY');
  606. X               tokon      : write(f, 'ON');
  607. X               tokdim     : write(f, 'DIM');
  608. X               tokpoke    : write(f, 'POKE');
  609. X               toklist    : write(f, 'LIST');
  610. X               tokrun     : write(f, 'RUN');
  611. X               toknew     : write(f, 'NEW');
  612. X               tokload    : write(f, 'LOAD');
  613. X               tokmerge   : write(f, 'MERGE');
  614. X               toksave    : write(f, 'SAVE');
  615. X               tokdel     : write(f, 'DEL');
  616. X               tokbye     : write(f, 'BYE');
  617. X               tokrenum   : write(f, 'RENUM');
  618. X               tokthen    : write(f, ' THEN ');
  619. X               tokelse    : write(f, ' ELSE ');
  620. X               tokto      : write(f, ' TO ');
  621. X               tokstep    : write(f, ' STEP ');
  622. X               tokrem     : write(f, 'REM', buf^.sp^);
  623. X            end;
  624. X            buf := buf^.next;
  625. X         end;
  626. X   end;
  627. X
  628. X
  629. X
  630. Xprocedure disposetokens(var tok : tokenptr);
  631. X   var
  632. X      tok1 : tokenptr;
  633. X   begin
  634. X      while tok <> nil do
  635. X         begin
  636. X            tok1 := tok^.next;
  637. X            if tok^.kind in [tokstr, tokrem] then
  638. X               dispose(tok^.sp);
  639. X            dispose(tok);
  640. X            tok := tok1;
  641. X         end;
  642. X   end;
  643. X
  644. X
  645. X
  646. Xprocedure parseinput(var buf : tokenptr);
  647. X   var
  648. X      l, l0, l1 : lineptr;
  649. X   begin
  650. X      inbuf^ := strltrim(inbuf^);
  651. X      curline := 0;
  652. X      while (strlen(inbuf^) <> 0) and (inbuf^[1] in ['0'..'9']) do
  653. X         begin
  654. X            curline := curline * 10 + ord(inbuf^[1]) - 48;
  655. X            strdelete(inbuf^, 1, 1);
  656. X         end;
  657. X      parse(inbuf, buf);
  658. X      if curline <> 0 then
  659. X         begin
  660. X            l := linebase;
  661. X            l0 := nil;
  662. X            while (l <> nil) and (l^.num < curline) do
  663. X               begin
  664. X                  l0 := l;
  665. X                  l := l^.next;
  666. X               end;
  667. X            if (l <> nil) and (l^.num = curline) then
  668. X               begin
  669. X                  l1 := l;
  670. X                  l := l^.next;
  671. X                  if l0 = nil then
  672. X                     linebase := l
  673. X                  else
  674. X                     l0^.next := l;
  675. X                  disposetokens(l1^.txt);
  676. X                  dispose(l1);
  677. X               end;
  678. X            if buf <> nil then
  679. X               begin
  680. X                  new(l1);
  681. X                  l1^.next := l;
  682. X                  if l0 = nil then
  683. X                     linebase := l1
  684. X                  else
  685. X                     l0^.next := l1;
  686. X                  l1^.num := curline;
  687. X                  l1^.txt := buf;
  688. X               end;
  689. X            clearloops;
  690. X            restoredata;
  691. X         end;
  692. X   end;
  693. X
  694. X
  695. X
  696. X
  697. X
  698. Xprocedure errormsg(s : string255);
  699. X   begin
  700. X      write(#7, s);
  701. X      escape(42);
  702. X   end;
  703. X
  704. X
  705. Xprocedure snerr;
  706. X   begin
  707. X      errormsg('Syntax error');
  708. X   end;
  709. X
  710. Xprocedure tmerr;
  711. X   begin
  712. X      errormsg('Type mismatch error');
  713. X   end;
  714. X
  715. Xprocedure badsubscr;
  716. X   begin
  717. X      errormsg('Bad subscript');
  718. X   end;
  719. X
  720. X
  721. X
  722. X
  723. X
  724. X
  725. Xprocedure exec;
  726. X
  727. X   var
  728. X      gotoflag, elseflag : boolean;
  729. X      t : tokenptr;
  730. X      ioerrmsg : string255ptr;
  731. X
  732. X
  733. X   function factor : valrec;
  734. X      forward;
  735. X
  736. X   function expr : valrec;
  737. X      forward;
  738. X
  739. X   function realfactor : real;
  740. X      var
  741. X         n : valrec;
  742. X      begin
  743. X         n := factor;
  744. X         if n.stringval then tmerr;
  745. X         realfactor := n.val;
  746. X      end;
  747. X
  748. X   function strfactor : basicstring;
  749. X      var
  750. X         n : valrec;
  751. X      begin
  752. X         n := factor;
  753. X         if not n.stringval then tmerr;
  754. X         strfactor := n.sval;
  755. X      end;
  756. X
  757. X   function stringfactor : string255;
  758. X      var
  759. X         n : valrec;
  760. X      begin
  761. X         n := factor;
  762. X         if not n.stringval then tmerr;
  763. X         stringfactor := n.sval^;
  764. X         dispose(n.sval);
  765. X      end;
  766. X
  767. X   function intfactor : integer;
  768. X      begin
  769. X         intfactor := round(realfactor);
  770. X      end;
  771. X
  772. X   function realexpr : real;
  773. X      var
  774. X         n : valrec;
  775. X      begin
  776. X         n := expr;
  777. X         if n.stringval then tmerr;
  778. X         realexpr := n.val;
  779. X      end;
  780. X
  781. X   function strexpr : basicstring;
  782. X      var
  783. X         n : valrec;
  784. X      begin
  785. X         n := expr;
  786. X         if not n.stringval then tmerr;
  787. X         strexpr := n.sval;
  788. X      end;
  789. X
  790. X   function stringexpr : string255;
  791. X      var
  792. X         n : valrec;
  793. X      begin
  794. X         n := expr;
  795. X         if not n.stringval then tmerr;
  796. X         stringexpr := n.sval^;
  797. X         dispose(n.sval);
  798. X      end;
  799. X
  800. X   function intexpr : integer;
  801. X      begin
  802. X         intexpr := round(realexpr);
  803. X      end;
  804. X
  805. X
  806. X   procedure require(k : tokenkinds);
  807. X      begin
  808. X         if (t = nil) or (t^.kind <> k) then
  809. X            snerr;
  810. X         t := t^.next;
  811. X      end;
  812. X
  813. X
  814. X   procedure skipparen;
  815. X      label 1;
  816. X      begin
  817. X         repeat
  818. X            if t = nil then snerr;
  819. X            if (t^.kind = tokrp) or (t^.kind = tokcomma) then
  820. X               goto 1;
  821. X            if t^.kind = toklp then
  822. X               begin
  823. X                  t := t^.next;
  824. X                  skipparen;
  825. X               end;
  826. X            t := t^.next;
  827. X         until false;
  828. X       1 :
  829. X      end;
  830. X
  831. X
  832. X   function findvar : varptr;
  833. X      var
  834. X         v : varptr;
  835. X         i, j, k : integer;
  836. X         tok : tokenptr;
  837. X      begin
  838. X         if (t = nil) or (t^.kind <> tokvar) then snerr;
  839. X         v := t^.vp;
  840. X         t := t^.next;
  841. X         if (t <> nil) and (t^.kind = toklp) then
  842. X            with v^ do
  843. X               begin
  844. X                  if numdims = 0 then
  845. X                     begin
  846. X                        tok := t;
  847. X                        i := 0;
  848. X                        j := 1;
  849. X                        repeat
  850. X                           if i >= maxdims then badsubscr;
  851. X                           t := t^.next;
  852. X                           skipparen;
  853. X                           j := j * 11;
  854. X                           i := i + 1;
  855. X                           dims[i] := 11;
  856. X                        until t^.kind = tokrp;
  857. X                        numdims := i;
  858. X                        if stringvar then
  859. X                           begin
  860. X                              hpm_new(sarr, j*4);
  861. X                              for k := 0 to j-1 do
  862. X                                 sarr^[k] := nil;
  863. X                           end
  864. X                        else
  865. X                           begin
  866. X                              hpm_new(arr, j*8);
  867. X                              for k := 0 to j-1 do
  868. X                                 arr^[k] := 0;
  869. X                           end;
  870. X                        t := tok;
  871. X                     end;
  872. X                  k := 0;
  873. X                  t := t^.next;
  874. X                  for i := 1 to numdims do
  875. X                     begin
  876. X                        j := intexpr;
  877. X                        if (j < 0) or (j >= dims[i]) then
  878. X                           badsubscr;
  879. X                        k := k * dims[i] + j;
  880. X                        if i < numdims then
  881. X                           require(tokcomma);
  882. X                     end;
  883. X                  require(tokrp);
  884. X                  if stringvar then
  885. X                      sval := addr(sarr^[k])
  886. X                  else
  887. X                      val := addr(arr^[k]);
  888. X               end
  889. X         else
  890. X            begin
  891. X               if v^.numdims <> 0 then
  892. X                  badsubscr;
  893. X            end;
  894. X         findvar := v;
  895. X      end;
  896. X
  897. X
  898. X   function inot(i : integer) : integer;
  899. X      begin
  900. X         inot := -1 - i;
  901. X      end;
  902. X
  903. X   function ixor(a, b : integer) : integer;
  904. X      begin
  905. X         ixor := asm_ior(asm_iand(a, inot(b)), asm_iand(inot(a), b));
  906. X      end;
  907. X
  908. X
  909. X   function factor : valrec;
  910. X      var
  911. X         v : varptr;
  912. X         facttok : tokenptr;
  913. X         n : valrec;
  914. X         i, j : integer;
  915. X         tok, tok1 : tokenptr;
  916. X         s : basicstring;
  917. X         trick :
  918. X            record
  919. X               case boolean of
  920. X                  true : (i : integer);
  921. X                  false : (c : ^char);
  922. X            end;
  923. X      begin
  924. X         if t = nil then snerr;
  925. X         facttok := t;
  926. X         t := t^.next;
  927. X         n.stringval := false;
  928. X         case facttok^.kind of
  929. X            toknum :
  930. X               n.val := facttok^.num;
  931. X            tokstr :
  932. X               begin
  933. X                  n.stringval := true;
  934. X                  new(n.sval);
  935. X                  n.sval^ := facttok^.sp^;
  936. X               end;
  937. X            tokvar :
  938. X               begin
  939. X                  t := facttok;
  940. X                  v := findvar;
  941. X                  n.stringval := v^.stringvar;
  942. X                  if n.stringval then
  943. X                     begin
  944. X                        new(n.sval);
  945. X                        n.sval^ := v^.sval^^;
  946. X                     end
  947. X                  else
  948. X                     n.val := v^.val^;
  949. X               end;
  950. X            toklp :
  951. X               begin
  952. X                  n := expr;
  953. X                  require(tokrp);
  954. X               end;
  955. X            tokminus :
  956. X               n.val := - realfactor;
  957. X            tokplus :
  958. X               n.val := realfactor;
  959. X            toknot :
  960. X               n.val := inot(intfactor);
  961. X            toksqr :
  962. X               n.val := sqr(realfactor);
  963. X            toksqrt :
  964. X               n.val := sqrt(realfactor);
  965. X            toksin :
  966. X               n.val := sin(realfactor);
  967. X            tokcos :
  968. X               n.val := cos(realfactor);
  969. X            toktan :
  970. X               begin
  971. X                  n.val := realfactor;
  972. X                  n.val := sin(n.val) / cos(n.val);
  973. X               end;
  974. X            tokarctan :
  975. X               n.val := arctan(realfactor);
  976. X            toklog:
  977. X               n.val := ln(realfactor);
  978. X            tokexp :
  979. X               n.val := exp(realfactor);
  980. X            tokabs :
  981. X               n.val := abs(realfactor);
  982. X            toksgn :
  983. X               begin
  984. X                  n.val := realfactor;
  985. X                  n.val := ord(n.val > 0) - ord(n.val < 0);
  986. X               end;
  987. X            tokstr_ :
  988. X               begin
  989. X                  n.stringval := true;
  990. X                  new(n.sval);
  991. X                  n.sval^ := numtostr(realfactor);
  992. X               end;
  993. X            tokval :
  994. X               begin
  995. X                  s := strfactor;
  996. X                  tok1 := t;
  997. X                  parse(s, t);
  998. X                  tok := t;
  999. X                  if tok = nil then
  1000. X                     n.val := 0
  1001. X                  else
  1002. X                     n := expr;
  1003. X                  disposetokens(tok);
  1004. X                  t := tok1;
  1005. X                  dispose(s);
  1006. X               end;
  1007. X            tokchr_ :
  1008. X               begin
  1009. X                  n.stringval := true;
  1010. X                  new(n.sval);
  1011. X                  n.sval^ := ' ';
  1012. X                  n.sval^[1] := chr(intfactor);
  1013. X               end;
  1014. X            tokasc :
  1015. X               begin
  1016. X                  s := strfactor;
  1017. X                  if strlen(s^) = 0 then
  1018. X                     n.val := 0
  1019. X                  else
  1020. X                     n.val := ord(s^[1]);
  1021. X                  dispose(s);
  1022. X               end;
  1023. X            tokmid_ :
  1024. X               begin
  1025. X                  n.stringval := true;
  1026. X                  require(toklp);
  1027. X                  n.sval := strexpr;
  1028. X                  require(tokcomma);
  1029. X                  i := intexpr;
  1030. X                  if i < 1 then i := 1;
  1031. X                  j := 255;
  1032. X                  if (t <> nil) and (t^.kind = tokcomma) then
  1033. X                     begin
  1034. X                        t := t^.next;
  1035. X                        j := intexpr;
  1036. X                     end;
  1037. X                  if j > strlen(n.sval^)-i+1 then
  1038. X                     j := strlen(n.sval^)-i+1;
  1039. X                  if i > strlen(n.sval^) then
  1040. X                     n.sval^ := ''
  1041. X                  else
  1042. X                     n.sval^ := str(n.sval^, i, j);
  1043. X                  require(tokrp);
  1044. X               end;
  1045. X            toklen :
  1046. X               begin
  1047. X                  s := strfactor;
  1048. X                  n.val := strlen(s^);
  1049. X                  dispose(s);
  1050. X               end;
  1051. X            tokpeek :
  1052. X               begin
  1053. X                  $range off$
  1054. X                  trick.i := intfactor;
  1055. X                  n.val := ord(trick.c^);
  1056. X                  $if checking$ $range on$ $end$
  1057. X               end;
  1058. X            otherwise
  1059. X               snerr;
  1060. X         end;
  1061. X         factor := n;
  1062. X      end;
  1063. X
  1064. X   function upexpr : valrec;
  1065. X      var
  1066. X         n, n2 : valrec;
  1067. X      begin
  1068. X         n := factor;
  1069. X         while (t <> nil) and (t^.kind = tokup) do
  1070. X            begin
  1071. X               if n.stringval then tmerr;
  1072. X               t := t^.next;
  1073. X               n2 := upexpr;
  1074. X               if n2.stringval then tmerr;
  1075. X               if n.val < 0 then
  1076. X                  begin
  1077. X                     if n2.val <> trunc(n2.val) then n.val := ln(n.val);
  1078. X                     n.val := exp(n2.val * ln(-n.val));
  1079. X                     if odd(trunc(n2.val)) then
  1080. X                        n.val := - n.val;
  1081. X                  end
  1082. X               else
  1083. X                  n.val := exp(n2.val * ln(n.val));
  1084. X            end;
  1085. X         upexpr := n;
  1086. X      end;
  1087. X
  1088. X   function term : valrec;
  1089. X      var
  1090. X         n, n2 : valrec;
  1091. X         k : tokenkinds;
  1092. X      begin
  1093. X         n := upexpr;
  1094. X         while (t <> nil) and (t^.kind in [toktimes, tokdiv, tokmod]) do
  1095. X            begin
  1096. X               k := t^.kind;
  1097. X               t := t^.next;
  1098. X               n2 := upexpr;
  1099. X               if n.stringval or n2.stringval then tmerr;
  1100. X               if k = tokmod then
  1101. X                  n.val := round(n.val) mod round(n2.val)
  1102. X               else if k = toktimes then
  1103. X                  n.val := n.val * n2.val
  1104. X               else
  1105. X                  n.val := n.val / n2.val;
  1106. X            end;
  1107. X         term := n;
  1108. X      end;
  1109. X
  1110. X   function sexpr : valrec;
  1111. X      var
  1112. X         n, n2 : valrec;
  1113. X         k : tokenkinds;
  1114. X      begin
  1115. X         n := term;
  1116. X         while (t <> nil) and (t^.kind in [tokplus, tokminus]) do
  1117. X            begin
  1118. X               k := t^.kind;
  1119. X               t := t^.next;
  1120. X               n2 := term;
  1121. X               if n.stringval <> n2.stringval then tmerr;
  1122. X               if k = tokplus then
  1123. X                  if n.stringval then
  1124. X                     begin
  1125. X                        n.sval^ := n.sval^ + n2.sval^;
  1126. X                        dispose(n2.sval);
  1127. X                     end
  1128. X                  else
  1129. X                     n.val := n.val + n2.val
  1130. X               else
  1131. X                  if n.stringval then
  1132. X                     tmerr
  1133. X                  else
  1134. X                     n.val := n.val - n2.val;
  1135. X            end;
  1136. X         sexpr := n;
  1137. X      end;
  1138. X
  1139. X   function relexpr : valrec;
  1140. X      var
  1141. X         n, n2 : valrec;
  1142. X         f : boolean;
  1143. X         k : tokenkinds;
  1144. X      begin
  1145. X         n := sexpr;
  1146. X         while (t <> nil) and (t^.kind in [tokeq..tokne]) do
  1147. X            begin
  1148. X               k := t^.kind;
  1149. X               t := t^.next;
  1150. X               n2 := sexpr;
  1151. X               if n.stringval <> n2.stringval then tmerr;
  1152. X               if n.stringval then
  1153. X                  begin
  1154. X                     f := ((n.sval^ = n2.sval^) and (k in [tokeq, tokge, tokle]) or
  1155. X                           (n.sval^ < n2.sval^) and (k in [toklt, tokle, tokne]) or
  1156. X                           (n.sval^ > n2.sval^) and (k in [tokgt, tokge, tokne]));
  1157. X                     dispose(n.sval);
  1158. X                     dispose(n2.sval);
  1159. X                  end
  1160. X               else
  1161. X                  f := ((n.val = n2.val) and (k in [tokeq, tokge, tokle]) or
  1162. X                        (n.val < n2.val) and (k in [toklt, tokle, tokne]) or
  1163. X                        (n.val > n2.val) and (k in [tokgt, tokge, tokne]));
  1164. X               n.stringval := false;
  1165. X               n.val := ord(f);
  1166. X            end;
  1167. X         relexpr := n;
  1168. X      end;
  1169. X
  1170. X   function andexpr : valrec;
  1171. X      var
  1172. X         n, n2 : valrec;
  1173. X      begin
  1174. X         n := relexpr;
  1175. X         while (t <> nil) and (t^.kind = tokand) do
  1176. X            begin
  1177. X               t := t^.next;
  1178. X               n2 := relexpr;
  1179. X               if n.stringval or n2.stringval then tmerr;
  1180. X               n.val := asm_iand(trunc(n.val), trunc(n2.val));
  1181. X            end;
  1182. X         andexpr := n;
  1183. X      end;
  1184. X
  1185. X   function expr : valrec;
  1186. X      var
  1187. X         n, n2 : valrec;
  1188. X         k : tokenkinds;
  1189. X      begin
  1190. X         n := andexpr;
  1191. X         while (t <> nil) and (t^.kind in [tokor, tokxor]) do
  1192. X            begin
  1193. X               k := t^.kind;
  1194. X               t := t^.next;
  1195. X               n2 := andexpr;
  1196. X               if n.stringval or n2.stringval then tmerr;
  1197. X               if k = tokor then
  1198. X                  n.val := asm_ior(trunc(n.val), trunc(n2.val))
  1199. X               else
  1200. X                  n.val := ixor(trunc(n.val), trunc(n2.val));
  1201. X            end;
  1202. X         expr := n;
  1203. X      end;
  1204. X
  1205. X
  1206. X   procedure checkextra;
  1207. X      begin
  1208. X         if t <> nil then
  1209. X            errormsg('Extra information on line');
  1210. X      end;
  1211. X
  1212. X
  1213. X   function iseos : boolean;
  1214. X      begin
  1215. X         iseos := (t = nil) or (t^.kind in [tokcolon, tokelse]);
  1216. X      end;
  1217. X
  1218. X
  1219. X   procedure skiptoeos;
  1220. X      begin
  1221. X         while not iseos do
  1222. X            t := t^.next;
  1223. X      end;
  1224. X
  1225. X
  1226. X   function findline(n : integer) : lineptr;
  1227. X      var
  1228. X         l : lineptr;
  1229. X      begin
  1230. X         l := linebase;
  1231. X         while (l <> nil) and (l^.num <> n) do
  1232. X            l := l^.next;
  1233. X         findline := l;
  1234. X      end;
  1235. X
  1236. X
  1237. X   function mustfindline(n : integer) : lineptr;
  1238. X      var
  1239. X         l : lineptr;
  1240. X      begin
  1241. X         l := findline(n);
  1242. X         if l = nil then
  1243. X            errormsg('Undefined line');
  1244. X         mustfindline := l;
  1245. X      end;
  1246. X
  1247. X
  1248. X   procedure cmdend;
  1249. X      begin
  1250. X         stmtline := nil;
  1251. X         t := nil;
  1252. X      end;
  1253. X
  1254. X
  1255. X   procedure cmdnew;
  1256. X      var
  1257. X         p : anyptr;
  1258. X      begin
  1259. X         cmdend;
  1260. X         clearloops;
  1261. X         restoredata;
  1262. X         while linebase <> nil do
  1263. X            begin
  1264. X               p := linebase^.next;
  1265. X               disposetokens(linebase^.txt);
  1266. X               dispose(linebase);
  1267. X               linebase := p;
  1268. X            end;
  1269. X         while varbase <> nil do
  1270. X            begin
  1271. X               p := varbase^.next;
  1272. X               if varbase^.stringvar then
  1273. X                  if varbase^.sval^ <> nil then
  1274. X                     dispose(varbase^.sval^);
  1275. X               dispose(varbase);
  1276. X               varbase := p;
  1277. X            end;
  1278. X      end;
  1279. X
  1280. X
  1281. X   procedure cmdlist;
  1282. X      var
  1283. X         l : lineptr;
  1284. X         n1, n2 : integer;
  1285. X      begin
  1286. X         repeat
  1287. X            n1 := 0;
  1288. X            n2 := maxint;
  1289. X            if (t <> nil) and (t^.kind = toknum) then
  1290. X               begin
  1291. X                  n1 := trunc(t^.num);
  1292. X                  t := t^.next;
  1293. X                  if (t = nil) or (t^.kind <> tokminus) then
  1294. X                     n2 := n1;
  1295. X               end;
  1296. X            if (t <> nil) and (t^.kind = tokminus) then
  1297. X               begin
  1298. X                  t := t^.next;
  1299. X                  if (t <> nil) and (t^.kind = toknum) then
  1300. X                     begin
  1301. X                        n2 := trunc(t^.num);
  1302. X                        t := t^.next;
  1303. X                     end
  1304. X                  else
  1305. X                     n2 := maxint;
  1306. X               end;
  1307. X            l := linebase;
  1308. X            while (l <> nil) and (l^.num <= n2) do
  1309. X               begin
  1310. X                  if (l^.num >= n1) then
  1311. X                     begin
  1312. X                        write(l^.num:1, ' ');
  1313. X                        listtokens(output, l^.txt);
  1314. X                        writeln;
  1315. X                     end;
  1316. X                  l := l^.next;
  1317. X               end;
  1318. X            if not iseos then
  1319. X               require(tokcomma);
  1320. X         until iseos;
  1321. X      end;
  1322. X
  1323. X
  1324. X   procedure cmdload(merging : boolean; name : string255);
  1325. X      var
  1326. X         f : text;
  1327. X         buf : tokenptr;
  1328. X      begin
  1329. X         if not merging then
  1330. X            cmdnew;
  1331. X         reset(f, name + '.TEXT', 'shared');
  1332. X         while not eof(f) do
  1333. X            begin
  1334. X               readln(f, inbuf^);
  1335. X               parseinput(buf);
  1336. X               if curline = 0 then
  1337. X                  begin
  1338. X                     writeln('Bad line in file');
  1339. X                     disposetokens(buf);
  1340. X                  end;
  1341. X            end;
  1342. X         close(f);
  1343. X      end;
  1344. X
  1345. X
  1346. X   procedure cmdrun;
  1347. X      var
  1348. X         l : lineptr;
  1349. X         i : integer;
  1350. X         s : string255;
  1351. X      begin
  1352. X         l := linebase;
  1353. X         if not iseos then
  1354. X            begin
  1355. X               if t^.kind = toknum then
  1356. X                  l := mustfindline(intexpr)
  1357. X               else
  1358. X                  begin
  1359. X                     s := stringexpr;
  1360. X                     i := 0;
  1361. X                     if not iseos then
  1362. X                        begin
  1363. X                           require(tokcomma);
  1364. X                           i := intexpr;
  1365. X                        end;
  1366. X                     checkextra;
  1367. X                     cmdload(false, s);
  1368. X                     if i = 0 then
  1369. X                        l := linebase
  1370. X                     else
  1371. X                        l := mustfindline(i)
  1372. X                  end
  1373. X            end;
  1374. X         stmtline := l;
  1375. X         gotoflag := true;
  1376. X         clearvars;
  1377. X         clearloops;
  1378. X         restoredata;
  1379. X      end;
  1380. X
  1381. X
  1382. X   procedure cmdsave;
  1383. X      var
  1384. X         f : text;
  1385. X         l : lineptr;
  1386. X      begin
  1387. X         rewrite(f, stringexpr + '.TEXT');
  1388. X         l := linebase;
  1389. X         while l <> nil do
  1390. X            begin
  1391. X               write(f, l^.num:1, ' ');
  1392. X               listtokens(f, l^.txt);
  1393. X               writeln(f);
  1394. X               l := l^.next;
  1395. X            end;
  1396. X         close(f, 'save');
  1397. X      end;
  1398. X
  1399. X
  1400. X   procedure cmdbye;
  1401. X      begin
  1402. X         exitflag := true;
  1403. X      end;
  1404. X
  1405. X
  1406. X   procedure cmddel;
  1407. X      var
  1408. X         l, l0, l1 : lineptr;
  1409. X         n1, n2 : integer;
  1410. X      begin
  1411. X         repeat
  1412. X            if iseos then snerr;
  1413. X            n1 := 0;
  1414. X            n2 := maxint;
  1415. X            if (t <> nil) and (t^.kind = toknum) then
  1416. X               begin
  1417. X                  n1 := trunc(t^.num);
  1418. X                  t := t^.next;
  1419. X                  if (t = nil) or (t^.kind <> tokminus) then
  1420. X                     n2 := n1;
  1421. X               end;
  1422. X            if (t <> nil) and (t^.kind = tokminus) then
  1423. X               begin
  1424. X                  t := t^.next;
  1425. X                  if (t <> nil) and (t^.kind = toknum) then
  1426. X                     begin
  1427. X                        n2 := trunc(t^.num);
  1428. X                        t := t^.next;
  1429. X                     end
  1430. X                  else
  1431. X                     n2 := maxint;
  1432. X               end;
  1433. X            l := linebase;
  1434. X            l0 := nil;
  1435. X            while (l <> nil) and (l^.num <= n2) do
  1436. X               begin
  1437. X                  l1 := l^.next;
  1438. X                  if (l^.num >= n1) then
  1439. X                     begin
  1440. X                        if l = stmtline then
  1441. X                           begin
  1442. X                              cmdend;
  1443. X                              clearloops;
  1444. X                              restoredata;
  1445. X                           end;
  1446. X                        if l0 = nil then
  1447. X                           linebase := l^.next
  1448. X                        else
  1449. X                           l0^.next := l^.next;
  1450. X                        disposetokens(l^.txt);
  1451. X                        dispose(l);
  1452. X                     end
  1453. X                  else
  1454. X                     l0 := l;
  1455. X                  l := l1;
  1456. X               end;
  1457. X            if not iseos then
  1458. X               require(tokcomma);
  1459. X         until iseos;
  1460. X      end;
  1461. X
  1462. X
  1463. X   procedure cmdrenum;
  1464. X      var
  1465. X         l, l1 : lineptr;
  1466. X         tok : tokenptr;
  1467. X         lnum, step : integer;
  1468. X      begin
  1469. X         lnum := 10;
  1470. X         step := 10;
  1471. X         if not iseos then
  1472. X            begin
  1473. X               lnum := intexpr;
  1474. X               if not iseos then
  1475. X                  begin
  1476. X                     require(tokcomma);
  1477. X                     step := intexpr;
  1478. X                  end;
  1479. X            end;
  1480. X         l := linebase;
  1481. X         if l <> nil then
  1482. X            begin
  1483. X               while l <> nil do
  1484. X                  begin
  1485. X                     l^.num2 := lnum;
  1486. X                     lnum := lnum + step;
  1487. X                     l := l^.next;
  1488. X                  end;
  1489. X               l := linebase;
  1490. X               repeat
  1491. X                  tok := l^.txt;
  1492. X                  repeat
  1493. X                     if tok^.kind in [tokgoto, tokgosub, tokthen, tokelse, 
  1494. X                                      tokrun, toklist, tokrestore, tokdel] then
  1495. X                        while (tok^.next <> nil) and (tok^.next^.kind = toknum) do
  1496. X                           begin
  1497. X                              tok := tok^.next;
  1498. X                              lnum := round(tok^.num);
  1499. X                              l1 := linebase;
  1500. X                              while (l1 <> nil) and (l1^.num <> lnum) do
  1501. X                                 l1 := l1^.next;
  1502. X                              if l1 = nil then
  1503. X                                 writeln('Undefined line ', lnum:1, ' in line ', l^.num2:1)
  1504. X                              else
  1505. X                                 tok^.num := l1^.num2;
  1506. X                              if (tok^.next <> nil) and (tok^.next^.kind = tokcomma) then
  1507. X                                 tok := tok^.next;
  1508. X                           end;
  1509. X                     tok := tok^.next;
  1510. X                  until tok = nil;
  1511. X                  l := l^.next;
  1512. X               until l = nil;
  1513. X               l := linebase;
  1514. X               while l <> nil do
  1515. X                  begin
  1516. X                     l^.num := l^.num2;
  1517. X                     l := l^.next;
  1518. X                  end;
  1519. X            end;
  1520. X      end;
  1521. X
  1522. X
  1523. X   procedure cmdprint;
  1524. X      var
  1525. X         semiflag : boolean;
  1526. X         n : valrec;
  1527. X      begin
  1528. X         semiflag := false;
  1529. X         while not iseos do
  1530. X            begin
  1531. X               semiflag := false;
  1532. X               if t^.kind in [toksemi, tokcomma] then
  1533. X                  begin
  1534. X                     semiflag := true;
  1535. X                     t := t^.next;
  1536. X                  end
  1537. X               else
  1538. X                  begin
  1539. X                     n := expr;
  1540. X                     if n.stringval then
  1541. X                        begin
  1542. X                           write(n.sval^);
  1543. X                           dispose(n.sval);
  1544. X                        end
  1545. X                     else
  1546. X                        write(numtostr(n.val), ' ');
  1547. X                  end;
  1548. X            end;
  1549. X         if not semiflag then 
  1550. X            writeln;
  1551. X      end;
  1552. X
  1553. X
  1554. X   procedure cmdinput;
  1555. X      var
  1556. X         v : varptr;
  1557. X         s : string255;
  1558. X         tok, tok0, tok1 : tokenptr;
  1559. X         strflag : boolean;
  1560. X      begin
  1561. X         if (t <> nil) and (t^.kind = tokstr) then
  1562. X            begin
  1563. X               write(t^.sp^);
  1564. X               t := t^.next;
  1565. X               require(toksemi);
  1566. X            end
  1567. X         else
  1568. X            begin
  1569. X               write('? ');
  1570. X            end;
  1571. X         tok := t;
  1572. X         if (t = nil) or (t^.kind <> tokvar) then snerr;
  1573. X         strflag := t^.vp^.stringvar;
  1574. X         repeat
  1575. X            if (t <> nil) and (t^.kind = tokvar) then
  1576. X               if t^.vp^.stringvar <> strflag then snerr;
  1577. X            t := t^.next;
  1578. X         until iseos;
  1579. X         t := tok;
  1580. X         if strflag then
  1581. X            begin
  1582. X               repeat
  1583. X                  readln(s);
  1584. X                  v := findvar;
  1585. END_OF_FILE
  1586. if test 48192 -ne `wc -c <'examples/basic.p.1'`; then
  1587.     echo shar: \"'examples/basic.p.1'\" unpacked with wrong size!
  1588. fi
  1589. # end of 'examples/basic.p.1'
  1590. fi
  1591. echo shar: End of archive 19 \(of 32\).
  1592. cp /dev/null ark19isdone
  1593. MISSING=""
  1594. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ; do
  1595.     if test ! -f ark${I}isdone ; then
  1596.     MISSING="${MISSING} ${I}"
  1597.     fi
  1598. done
  1599. if test "${MISSING}" = "" ; then
  1600.     echo You have unpacked all 32 archives.
  1601.     echo "Now see PACKNOTES and the README"
  1602.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1603. else
  1604.     echo You still need to unpack the following archives:
  1605.     echo "        " ${MISSING}
  1606. fi
  1607. ##  End of shell archive.
  1608. exit 0
  1609.