home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / PASCAL / PT03.ZIP / MACRO.AR < prev    next >
Encoding:
Text File  |  1983-09-06  |  20.3 KB  |  864 lines

  1. -h- cscopy.mac 247
  2. { cscopy -- copy cb[i]... to string s }
  3. procedure cscopy (var cb : charbuf; i : charpos;
  4.   var s : string);
  5. var
  6.  j : integer;
  7. begin
  8.  j := 1;
  9.  while (cb[i] <> ENDSTR) do begin
  10.   s[j] := cb[i];
  11.   i := i + 1;
  12.   j := j + 1
  13.  end;
  14.  s[j] := ENDSTR
  15. end;
  16.  
  17. -h- defcons.mac 268
  18. { defcons -- const declarations for define }
  19. const
  20.  BUFSIZE = 500;  { size of pushback buffer }
  21.  MAXCHARS = 5000; { size of name-defn table }
  22.  MAXDEF = MAXSTR; { max chars in a defn }
  23.  MAXTOK = MAXSTR; { max chars in a token }
  24.  HASHSIZE = 53;  { size of hash table }
  25.  
  26. -h- define.mac 764
  27. { define -- simple string replacement macro processor }
  28. procedure define;
  29. $include:"defcons.p"
  30. $include:"deftype.p"
  31. $include:"defvar.p"
  32.  defn : string;
  33.  token : string;
  34.  toktype : sttype; { type returned by lookup }
  35.  defname : string; { value is 'define' }
  36.  null : string;  { value is '' }
  37. $include:"defproc.p"
  38. begin
  39.  null[1] := ENDSTR;
  40.  initdef;
  41.  install(defname, null, DEFTYPE);
  42.  while (gettok(token, MAXTOK) <> ENDFILE) do
  43.   if (not isletter(token[1])) then
  44.    putstr(token, STDOUT)
  45.   else if (not lookup(token, defn, toktype)) then
  46.    putstr(token, STDOUT) { undefined }
  47.   else if (toktype = DEFTYPE) then begin { defn }
  48.    getdef(token, MAXTOK, defn, MAXDEF);
  49.    install(token, defn, MACTYPE)
  50.   end
  51.   else
  52.    pbstr(defn) { push replacement onto input }
  53. end;
  54.  
  55. -h- defproc.mac 308
  56. { defproc -- procedures needed by define }
  57. $include:"cscopy.p"
  58. $include:"sccopy.p"
  59. $include:"putback.p"
  60. $include:"getpbc.p"
  61. $include:"pbstr.p"
  62. $include:"gettok.p"
  63. $include:"getdef.p"
  64. $include:"inithash.p"
  65. $include:"hash.p"
  66. $include:"hashfind.p"
  67. $include:"install.p"
  68. $include:"lookup.p"
  69. $include:"initdef.p"
  70.  
  71. -h- deftype.mac 346
  72. { deftype -- type definitions for define }
  73. type
  74.  charpos = 1..MAXCHARS;
  75.  charbuf = array [1..MAXCHARS] of character;
  76.  sttype = (DEFTYPE, MACTYPE); { symbol table types }
  77.  ndptr = ^ndblock; { pointer to a name-defn block }
  78.  ndblock =
  79.   record  { name-defn block }
  80.    name : charpos;
  81.    defn : charpos;
  82.    kind : sttype;
  83.    nextptr : ndptr
  84.   end;
  85.  
  86. -h- defvar.mac 275
  87. { defvar -- var declarations for define }
  88. var
  89.  hashtab : array [1..HASHSIZE] of ndptr;
  90.  ndtable : charbuf;
  91.  nexttab : charpos; { first free position in ndtable }
  92.  buf : array [1..BUFSIZE] of character; { for pushback }
  93.  bp : 0..BUFSIZE; { next available character; init=0 }
  94.  
  95. -h- dochq.mac 402
  96. { dochq -- change quote characters }
  97. procedure dochq (var argstk : posbuf; i, j : integer);
  98. var
  99.  temp : string;
  100.  n : integer;
  101. begin
  102.  cscopy(evalstk, argstk[i+2], temp);
  103.  n := length(temp);
  104.  if (n <= 0) then begin
  105.   lquote := ord(GRAVE);
  106.   rquote := ord(ACUTE)
  107.  end
  108.  else if (n = 1) then begin
  109.   lquote := temp[1];
  110.   rquote := lquote
  111.  end
  112.  else begin
  113.   lquote := temp[1];
  114.   rquote := temp[2]
  115.  end
  116. end;
  117.  
  118. -h- dodef.mac 279
  119. { dodef -- install definition in table }
  120. procedure dodef (var argstk : posbuf; i, j : integer);
  121. var
  122.  temp1, temp2 : string;
  123. begin
  124.  if (j - i > 2) then begin
  125.   cscopy(evalstk, argstk[i+2], temp1);
  126.   cscopy(evalstk, argstk[i+3], temp2);
  127.   install(temp1, temp2, MACTYPE)
  128.  end
  129. end;
  130.  
  131. -h- doexpr.mac 225
  132. { doexpr -- evaluate arithmetic expressions }
  133. procedure doexpr (var argstk : posbuf; i, j : integer);
  134. var
  135.  temp : string;
  136.  junk : integer;
  137. begin
  138.  cscopy(evalstk, argstk[i+2], temp);
  139.  junk := 1;
  140.  pbnum(expr(temp, junk))
  141. end;
  142.  
  143. -h- doif.mac 435
  144. { doif -- select one of two arguments }
  145. procedure doif (var argstk : posbuf; i, j : integer);
  146. var
  147.  temp1, temp2, temp3 : string;
  148. begin
  149.  if (j - i >= 4) then begin
  150.   cscopy(evalstk, argstk[i+2], temp1);
  151.   cscopy(evalstk, argstk[i+3], temp2);
  152.   if (equal(temp1, temp2)) then
  153.    cscopy(evalstk, argstk[i+4], temp3)
  154.   else if (j - i >= 5) then
  155.    cscopy(evalstk, argstk[i+5], temp3)
  156.   else
  157.    temp3[1] := ENDSTR;
  158.   pbstr(temp3)
  159.  end
  160. end;
  161.  
  162. -h- dolen.mac 234
  163. { dolen -- return length of argument }
  164. procedure dolen(var argstk : posbuf; i, j : integer);
  165. var
  166.  temp : string;
  167. begin
  168.  if (j - i > 1) then begin
  169.   cscopy(evalstk, argstk[i+2], temp);
  170.   pbnum(length(temp))
  171.  end
  172.  else
  173.   pbnum(0)
  174. end;
  175.  
  176. -h- dosub.mac 663
  177. { dosub -- select substring }
  178. procedure dosub (var argstk : posbuf; i, j : integer);
  179. var
  180.  ap, fc, k, nc : integer;
  181.  temp1, temp2 : string;
  182. begin
  183.  if (j - i >= 3) then begin
  184.   if (j - i < 4) then
  185.    nc := MAXTOK
  186.   else begin
  187.    cscopy(evalstk, argstk[i+4], temp1);
  188.    k := 1;
  189.    nc := expr(temp1, k)
  190.   end;
  191.   cscopy(evalstk, argstk[i+3], temp1); { origin }
  192.   ap := argstk[i+2]; { target string }
  193.   k := 1;
  194.   fc := ap + expr(temp1, k) - 1; { first char }
  195.   cscopy(evalstk, ap, temp2);
  196.   if (fc >= ap) and (fc < ap+length(temp2)) then begin
  197.    cscopy(evalstk, fc, temp1);
  198.    for k := fc+imin(nc,length(temp1))-1 downto fc do
  199.     putback(evalstk[k])
  200.   end
  201.  end
  202. end;
  203.  
  204. -h- eval.mac 1007
  205. { eval -- expand args i..j: do built-in or push back defn }
  206. procedure eval (var argstk : posbuf; td : sttype;
  207.   i, j : integer);
  208. var
  209.  argno, k, t : integer;
  210.  temp : string;
  211. begin
  212.  t := argstk[i];
  213.  if (td = DEFTYPE) then
  214.   dodef(argstk, i, j)
  215.  else if (td = EXPRTYPE) then
  216.   doexpr(argstk, i, j)
  217.  else if (td = SUBTYPE) then
  218.   dosub(argstk, i, j)
  219.  else if (td = IFTYPE) then
  220.   doif(argstk, i, j)
  221.  else if (td = LENTYPE) then
  222.   dolen(argstk, i, j)
  223.  else if (td = CHQTYPE) then
  224.   dochq(argstk, i, j)
  225.  else begin
  226.   k := t;
  227.   while (evalstk[k] <> ENDSTR) do
  228.    k := k + 1;
  229.   k := k - 1; { last character of defn }
  230.   while (k > t) do begin
  231.    if (evalstk[k-1] <> ARGFLAG) then
  232.     putback(evalstk[k])
  233.    else begin
  234.     argno := ord(evalstk[k]) - ord('0');
  235.     if (argno >= 0) and (argno < j-i) then begin
  236.      cscopy(evalstk, argstk[i+argno+1], temp);
  237.      pbstr(temp)
  238.     end;
  239.     k := k - 1 { skip over $ }
  240.    end;
  241.    k := k - 1
  242.   end;
  243.   if (k = t) then  { do last character }
  244.    putback(evalstk[k])
  245.  end
  246. end;
  247.  
  248. -h- expr.mac 402
  249. { expr -- recursive expression evaluation }
  250. function expr (var s : string; var i : integer) : integer;
  251. var
  252.  v : integer;
  253.  t : character;
  254. {$include:'gnbchar.mac'}
  255. {$include:'term.mac'   }
  256. begin
  257.  v := term(s, i);
  258.  t := gnbchar(s, i);
  259.  while (t in [PLUS, MINUS]) do begin
  260.   i := i + 1;
  261.   if (t = PLUS) then
  262.    v := v + term(s, i)
  263.   else
  264.    v := v - term(s, i);
  265.   t := gnbchar(s, i)
  266.  end;
  267.  expr := v
  268. end;
  269.  
  270. -h- factor.mac 342
  271. { factor -- evaluate factor of arithmetic expression }
  272. function factor (var s : string; var i : integer)
  273.    : integer;
  274. begin
  275.  if (gnbchar(s, i) = LPAREN) then begin
  276.   i := i + 1;
  277.   factor := expr(s, i);
  278.   if (gnbchar(s, i) = RPAREN) then
  279.    i := i + 1
  280.   else
  281.    message('macro: missing paren in expr')
  282.  end
  283.  else
  284.   factor := ctoi(s, i)
  285. end;
  286.  
  287. -h- getdef.mac 1044
  288. { getdef -- get name and definition }
  289. procedure getdef (var token : string; toksize : integer;
  290.   var defn : string; defsize : integer);
  291. var
  292.  i, nlpar : integer;
  293.  c : character;
  294. begin
  295.  token[1] := ENDSTR; { in case of bad input }
  296.  defn[1] := ENDSTR;
  297.  if (getpbc(c) <> LPAREN) then
  298.   message('define: missing left paren')
  299.  else if (not isletter(gettok(token, toksize))) then
  300.   message('define: non-alphanumeric name')
  301.  else if (getpbc(c) <> COMMA) then
  302.   message('define: missing comma in define')
  303.  else begin { got '(name,' so far }
  304.   while (getpbc(c) = BLANK) do
  305.    ; { skip leading blanks }
  306.   putback(c); { went one too far }
  307.   nlpar := 0;
  308.   i := 1;
  309.   while (nlpar >= 0) do begin
  310.    if (i >= defsize) then
  311.     error('define: definition too long')
  312.    else if (getpbc(defn[i]) = ENDFILE) then
  313.     error('define: missing right paren')
  314.    else if (defn[i] = LPAREN) then
  315.     nlpar := nlpar + 1
  316.    else if (defn[i] = RPAREN) then
  317.     nlpar := nlpar - 1;
  318.    { else normal character in defn[i] }
  319.    i := i + 1
  320.   end;
  321.   defn[i-1] := ENDSTR
  322.  end
  323. end;
  324.  
  325. -h- getpbc.mac 250
  326. { getpbc -- get a (possibly pushed back) character }
  327. function getpbc (var c : character) : character;
  328. begin
  329.  if (bp > 0) then
  330.   c := buf[bp]
  331.  else begin
  332.   bp := 1;
  333.   buf[bp] := getc(c)
  334.  end;
  335.  if (c <> ENDFILE) then
  336.   bp := bp - 1;
  337.  getpbc := c
  338. end;
  339.  
  340. -h- gettok.mac 567
  341. { gettok -- get token for define }
  342. function gettok (var token : string; toksize : integer)
  343.   : character;
  344. var
  345.  i : integer;
  346.  done : boolean;
  347.  c : character;
  348. begin
  349.  i := 1;
  350.  done := false;
  351.  while (not done) and (i < toksize) do begin
  352.   token[i] := getpbc(c);
  353.   if (isalphanum(c)) then
  354.    i := i + 1
  355.   else
  356.    done := true;
  357.  end;
  358.  if (i >= toksize) then
  359.   error('define: token too long');
  360.  if (i > 1) then begin { some alpha was seen }
  361.   c := token[i];
  362.   putback(c);
  363.   i := i - 1
  364.  end;
  365.  { else single non-alphanumeric }
  366.  token[i+1] := ENDSTR;
  367.  gettok := token[1]
  368. end;
  369.  
  370. -h- gnbchar.mac 195
  371. { gnbchar -- get next non-blank character }
  372. function gnbchar (var s : string; var i : integer)
  373.   : character;
  374. begin
  375.  while (s[i] in [BLANK, TAB, NEWLINE]) do
  376.   i := i + 1;
  377.  gnbchar := s[i]
  378. end;
  379.  
  380. -h- hash.mac 216
  381. { hash -- compute hash function of a name }
  382. function hash (var name : string) : integer;
  383. var
  384.  i, h : integer;
  385. begin
  386.  h := 0;
  387.  for i := 1 to length(name) do
  388.   h := (3 * h + name[i]) mod HASHSIZE;
  389.  hash := h + 1
  390. end;
  391.  
  392. -h- hashfind.mac 376
  393. { hashfind -- find name in hash table }
  394. function hashfind (var name : string) : ndptr;
  395. var
  396.  p : ndptr;
  397.  tempname : string;
  398.  found : boolean;
  399. begin
  400.  found := false;
  401.  p := hashtab[hash(name)];
  402.  while (not found) and (p <> nil) do begin
  403.   cscopy(ndtable, p^.name, tempname);
  404.   if (equal(name, tempname)) then
  405.    found := true
  406.   else
  407.    p := p^.nextptr
  408.  end;
  409.  hashfind := p
  410. end;
  411.  
  412. -h- initdef.mac 341
  413. { initdef -- initialize variables for define }
  414. procedure initdef;
  415. begin
  416.  { setstring(defname, 'define'); }
  417.   defname[1] := ord('d');
  418.   defname[2] := ord('e');
  419.   defname[3] := ord('f');
  420.   defname[4] := ord('i');
  421.   defname[5] := ord('n');
  422.   defname[6] := ord('e');
  423.   defname[7] := ENDSTR;
  424.  bp := 0; { pushback buffer pointer }
  425.  inithash
  426. end;
  427.  
  428. -h- inithash.mac 190
  429. { inithash -- initialize hash table to nil }
  430. procedure inithash;
  431. var
  432.  i : 1..HASHSIZE;
  433. begin
  434.  nexttab := 1; { first free slot in table }
  435.  for i := 1 to HASHSIZE do
  436.   hashtab[i] := nil
  437. end;
  438.  
  439. -h- initmacr.mac 1375
  440. { initmacro -- initialize variables for macro }
  441. procedure initmacro;
  442. begin
  443.  null[1] := ENDSTR;
  444.  { setstring(defname, 'define'); }
  445.   defname[1] := ord('d');
  446.   defname[2] := ord('e');
  447.   defname[3] := ord('f');
  448.   defname[4] := ord('i');
  449.   defname[5] := ord('n');
  450.   defname[6] := ord('e');
  451.   defname[7] := ENDSTR;
  452.  { setstring(subname, 'substr'); }
  453.   subname[1] := ord('s');
  454.   subname[2] := ord('u');
  455.   subname[3] := ord('b');
  456.   subname[4] := ord('s');
  457.   subname[5] := ord('t');
  458.   subname[6] := ord('r');
  459.   subname[7] := ENDSTR;
  460.  { setstring(exprname, 'expr'); }
  461.   exprname[1] := ord('e');
  462.   exprname[2] := ord('x');
  463.   exprname[3] := ord('p');
  464.   exprname[4] := ord('r');
  465.   exprname[5] := ENDSTR;
  466.  { setstring(ifname, 'ifelse'); }
  467.   ifname[1] := ord('i');
  468.   ifname[2] := ord('f');
  469.   ifname[3] := ord('e');
  470.   ifname[4] := ord('l');
  471.   ifname[5] := ord('s');
  472.   ifname[6] := ord('e');
  473.   ifname[7] := ENDSTR;
  474.  { setstring(lenname, 'len'); }
  475.   lenname[1] := ord('l');
  476.   lenname[2] := ord('e');
  477.   lenname[3] := ord('n');
  478.   lenname[4] := ENDSTR;
  479.  { setstring(chqname, 'changeq'); }
  480.   chqname[1] := ord('c');
  481.   chqname[2] := ord('h');
  482.   chqname[3] := ord('a');
  483.   chqname[4] := ord('n');
  484.   chqname[5] := ord('g');
  485.   chqname[6] := ord('e');
  486.   chqname[7] := ord('q');
  487.   chqname[8] := ENDSTR;
  488.  bp := 0; { pushback buffer pointer }
  489.  inithash;
  490.  lquote := ord(GRAVE);
  491.  rquote := ord(ACUTE)
  492. end;
  493.  
  494. -h- install.mac 656
  495. { install -- add name, definition and type to table }
  496. procedure install (var name, defn : string; t : sttype);
  497. var
  498.  h, dlen, nlen : integer;
  499.  p : ndptr;
  500. begin
  501.  nlen := length(name) + 1; { 1 for ENDSTR }
  502.  dlen := length(defn) + 1;
  503.  if (nexttab + nlen + dlen > MAXCHARS) then begin
  504.   putstr(name, STDERR);
  505.   error(': too many definitions')
  506.  end
  507.  else begin { put it at front of chain }
  508.   h := hash(name);
  509.   new(p);
  510.   p^.nextptr := hashtab[h];
  511.   hashtab[h] := p;
  512.   p^.name := nexttab;
  513.   sccopy(name, ndtable, nexttab);
  514.   nexttab := nexttab + nlen;
  515.   p^.defn := nexttab;
  516.   sccopy(defn, ndtable, nexttab);
  517.   nexttab := nexttab + dlen;
  518.   p^.kind := t
  519.  end
  520. end;
  521.  
  522. -h- lookup.mac 298
  523. { lookup -- locate name, get defn and type from table }
  524. function lookup (var name, defn : string; var t : sttype)
  525.   : boolean;
  526. var
  527.  p : ndptr;
  528. begin
  529.  p := hashfind(name);
  530.  if (p = nil) then
  531.   lookup := false
  532.  else begin
  533.   lookup := true;
  534.   cscopy(ndtable, p^.defn, defn);
  535.   t := p^.kind
  536.  end
  537. end;
  538.  
  539. -h- maccons.mac 422
  540. { maccons -- const declarations for macro }
  541. const
  542.  BUFSIZE = 1000;  { size of pushback buffer }
  543.  MAXCHARS = 5000; { size of name-defn table }
  544.  MAXPOS = 500;    { size of position arrays }
  545.  CALLSIZE = MAXPOS;
  546.  ARGSIZE = MAXPOS;
  547.  EVALSIZE = MAXCHARS;
  548.  MAXDEF = MAXSTR; { max chars in a defn }
  549.  MAXTOK = MAXSTR; { max chars in a token }
  550.  HASHSIZE = 53;  { size of hash table }
  551.  ARGFLAG = DOLLAR; { macro invocation character }
  552.  
  553. -h- macproc.mac 661
  554. { macproc -- procedures for macro }
  555. {$include:'cscopy.mac'  }
  556. {$include:'sccopy.mac'  }
  557. {$include:'putback.mac' }
  558. {$include:'getpbc.mac'  }
  559. {$include:'pbstr.mac'   }
  560. {$include:'pbnum.mac'   }
  561. {$include:'gettok.mac'  }
  562. {$include:'inithash.mac'}
  563. {$include:'hash.mac'    }
  564. {$include:'hashfind.mac'}
  565. {$include:'install.mac' }
  566. {$include:'lookup.mac'  }
  567. {$include:'push.mac'    }
  568. {$include:'putchr.mac'  }
  569. {$include:'puttok.mac'  }
  570. {$include:'expr.mac'    }
  571. {$include:'dodef.mac'   }
  572. {$include:'doif.mac'    }
  573. {$include:'doexpr.mac'  }
  574. {$include:'dolen.mac'   }
  575. {$include:'dochq.mac'   }
  576. {$include:'dosub.mac'   }
  577. {$include:'eval.mac'    }
  578. {$include:'initmacr.mac'}
  579.  
  580. -h- macro.mac 2335
  581. { macro -- expand macros with arguments }
  582. procedure macro;
  583. {$include:'maccons.mac'}
  584. {$include:'mactype.mac'}
  585. {$include:'macvar.mac' }
  586.  defn : string;
  587.  token : string;
  588.  toktype : sttype;
  589.  t : character;
  590.  nlpar : integer;
  591. {$include:'macproc.mac'}
  592. begin
  593.  initmacro;
  594.  install(defname, null, DEFTYPE);
  595.  install(exprname, null, EXPRTYPE);
  596.  install(subname, null, SUBTYPE);
  597.  install(ifname, null, IFTYPE);
  598.  install(lenname, null, LENTYPE);
  599.  install(chqname, null, CHQTYPE);
  600.  
  601.  cp := 0;
  602.  ap := 1;
  603.  ep := 1;
  604.  while (gettok(token, MAXTOK) <> ENDFILE) do
  605.   if (isletter(token[1])) then begin
  606.    if (not lookup(token, defn, toktype)) then
  607.     puttok(token)
  608.    else begin { defined; put it in eval stack }
  609.     cp := cp + 1;
  610.     if (cp > CALLSIZE) then
  611.      error('macro: call stack overflow');
  612.     callstk[cp] := ap;
  613.     typestk[cp] := toktype;
  614.     ap := push(ep, argstk, ap);
  615.     puttok(defn); { push definition }
  616.     putchr(ENDSTR);
  617.     ap := push(ep, argstk, ap);
  618.     puttok(token); { stack name }
  619.     putchr(ENDSTR);
  620.     ap := push(ep, argstk, ap);
  621.     t := gettok(token, MAXTOK); { peek at next }
  622.     pbstr(token);
  623.     if (t <> LPAREN) then begin { add () }
  624.      putback(RPAREN);
  625.      putback(LPAREN)
  626.     end;
  627.     plev[cp] := 0
  628.    end
  629.   end
  630.   else if (token[1] = lquote) then begin { strip quotes }
  631.    nlpar := 1;
  632.    repeat
  633.     t := gettok(token, MAXTOK);
  634.     if (t = rquote) then
  635.      nlpar := nlpar - 1
  636.     else if (t = lquote) then
  637.      nlpar := nlpar + 1
  638.     else if (t = ENDFILE) then
  639.      error('macro: missing right quote');
  640.     if (nlpar > 0) then
  641.      puttok(token)
  642.    until (nlpar = 0)
  643.   end
  644.   else if (cp = 0) then  { not in a macro at all }
  645.    puttok(token)
  646.   else if (token[1] = LPAREN) then begin
  647.    if (plev[cp] > 0) then
  648.     puttok(token);
  649.    plev[cp] := plev[cp] + 1
  650.   end
  651.   else if (token[1] = RPAREN) then begin
  652.    plev[cp] := plev[cp] - 1;
  653.    if (plev[cp] > 0) then
  654.     puttok(token)
  655.    else begin { end of argument list }
  656.     putchr(ENDSTR);
  657.     eval(argstk, typestk[cp], callstk[cp], ap-1);
  658.     ap := callstk[cp]; { pop eval stack }
  659.     ep := argstk[ap];
  660.     cp := cp - 1
  661.    end
  662.   end
  663.   else if (token[1]=COMMA) and (plev[cp]=1) then begin
  664.    putchr(ENDSTR); { new argument }
  665.    ap := push(ep, argstk, ap)
  666.   end
  667.   else
  668.    puttok(token); { just stack it }
  669.  if (cp <> 0) then
  670.   error('macro: unexpected end of input')
  671. end;
  672.  
  673. -h- mactype.mac 397
  674. { mactype -- type declarations for macro }
  675. type
  676.  charpos = 1..MAXCHARS;
  677.  charbuf = array [1..MAXCHARS] of character;
  678.  posbuf = array [1..MAXPOS] of charpos;
  679.  pos = 0..MAXPOS;
  680.  sttype = (DEFTYPE, MACTYPE, IFTYPE, SUBTYPE,
  681.   EXPRTYPE, LENTYPE, CHQTYPE); { symbol table types }
  682.  ndptr = ^ndblock;
  683.  ndblock =
  684.   record
  685.    name : charpos;
  686.    defn : charpos;
  687.    kind : sttype;
  688.    nextptr : ndptr
  689.   end;
  690.  
  691. -h- macvar.mac 1035
  692. { macvar -- var declarations for macro }
  693. var
  694.  buf : array [1..BUFSIZE] of character; { for pushback }
  695.  bp : 0..BUFSIZE; { next available character; init=0 }
  696.  
  697.  hashtab : array [1..HASHSIZE] of ndptr;
  698.  ndtable : charbuf;
  699.  nexttab : charpos; { first free position in ndtable }
  700.  
  701.  callstk : posbuf; { call stack }
  702.  cp : pos;   { current call stack position }
  703.  typestk : array[1..CALLSIZE] of sttype; { type }
  704.  plev : array [1..CALLSIZE] of integer; { paren level }
  705.  argstk : posbuf; { argument stack for this call }
  706.  ap : pos;   { current argument position }
  707.  evalstk : charbuf; { evaluation stack }
  708.  ep : charpos;    { first character unused in evalstk }
  709.  
  710.  { built-ins: }
  711.  defname : string; { value is 'define' }
  712.  exprname : string; { value is 'expr' }
  713.  subname : string; { value is 'substr' }
  714.  ifname : string; { value is 'ifelse' }
  715.  lenname : string; { value is 'len' }
  716.  chqname : string; { value is 'changeq' }
  717.  
  718.  null : string;  { value is '' }
  719.  lquote : character; { left quote character }
  720.  rquote : character; { right quote character }
  721.  
  722. -h- pbnum.mac 178
  723. { pbnum -- convert number to string, push back on input }
  724. procedure pbnum (n : integer);
  725. var
  726.  temp : string;
  727.  junk : integer;
  728. begin
  729.  junk := itoc(n, temp, 1);
  730.  pbstr(temp)
  731. end;
  732.  
  733. -h- pbstr.mac 153
  734. { pbstr -- push string back onto input }
  735. procedure pbstr (var s : string);
  736. var
  737.  i : integer;
  738. begin
  739.  for i := length(s) downto 1 do
  740.   putback(s[i])
  741. end;
  742.  
  743. -h- push.mac 247
  744. { push -- push ep onto argstk, return new position ap }
  745. function push (ep : integer; var argstk : posbuf;
  746.   ap : integer) : integer;
  747. begin
  748.  if (ap > ARGSIZE) then
  749.   error('macro: argument stack overflow');
  750.  argstk[ap] := ep;
  751.  push := ap + 1
  752. end;
  753.  
  754. -h- putback.mac 191
  755. { putback -- push character back onto input }
  756. procedure putback (c : character);
  757. begin
  758.  if (bp >= BUFSIZE) then
  759.   error('too many characters pushed back');
  760.  bp := bp + 1;
  761.  buf[bp] := c
  762. end;
  763.  
  764. -h- putchr.mac 259
  765. { putchr -- put single char on output or evaluation stack }
  766. procedure putchr (c : character);
  767. begin
  768.  if (cp <= 0) then
  769.   putc(c)
  770.  else begin
  771.   if (ep > EVALSIZE) then
  772.    error('macro: evaluation stack overflow');
  773.   evalstk[ep] := c;
  774.   ep := ep + 1
  775.  end
  776. end;
  777.  
  778. -h- puttok.mac 195
  779. { puttok -- put token on output or evaluation stack }
  780. procedure puttok (var s : string);
  781. var
  782.  i : integer;
  783. begin
  784.  i := 1;
  785.  while (s[i] <> ENDSTR) do begin
  786.   putchr(s[i]);
  787.   i := i + 1
  788.  end
  789. end;
  790.  
  791. -h- sccopy.mac 247
  792. { sccopy -- copy string s to cb[i]... }
  793. procedure sccopy (var s : string; var cb : charbuf;
  794.   i : charpos);
  795. var
  796.  j : integer;
  797. begin
  798.  j := 1;
  799.  while (s[j] <> ENDSTR) do begin
  800.   cb[i] := s[j];
  801.   j := j + 1;
  802.   i := i + 1
  803.  end;
  804.  cb[i] := ENDSTR
  805. end;
  806.  
  807. -h- term.mac 446
  808. { term -- evaluate term of arithmetic expression }
  809. function term (var s : string; var i : integer) : integer;
  810. var
  811.  v : integer;
  812.  t : character;
  813. {$include:'factor.mac'}
  814. begin
  815.  v := factor(s, i);
  816.  t := gnbchar(s, i);
  817.  while (t in [STAR, SLASH, PERCENT]) do begin
  818.   i := i + 1;
  819.   case t of
  820.   STAR:
  821.    v := v * factor(s, i);
  822.   SLASH:
  823.    v := v div factor(s, i);
  824.   PERCENT:
  825.    v := v mod factor(s, i)
  826.   end;
  827.   t := gnbchar(s, i)
  828.  end;
  829.  term := v
  830. end;
  831. -h- macro.pas 533
  832. {$debug-}
  833. program outer (input,output);
  834.  
  835. {$include:'globcons.inc'}
  836. {$include:'globtyps.inc'}
  837.  
  838. {$include:'initio.dcl'}
  839. {$include:'flush.dcl' }
  840.  
  841. {$include:'isletter.dcl'}
  842. {$include:'isalphan.dcl'}
  843. {$include:'error.dcl'   }
  844. {$include:'getc.dcl'    }
  845. {$include:'putc.dcl'    }
  846. {$include:'putstr.dcl'  }
  847. {$include:'imin.dcl'    }
  848. {$include:'itoc.dcl'    }
  849. {$include:'ctoi.dcl'    }
  850. {$include:'length.dcl'  }
  851. {$include:'equal.dcl'   }
  852. {$include:'message.dcl' }
  853.  
  854. {$include:'macro.mac'   }
  855. BEGIN
  856.   minitio; initio;
  857.   macro;
  858.   flush(0);
  859. END.
  860. -h- macro.mak 119
  861. macro+initio+getfcb+flush+error+isletter+isalphan+getc+
  862. length+itoc+ctoi+equal+message+putstr+imin+putc+putcf+
  863. isdigit
  864.