00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 #include "ansidecl.h"
00090 #include "sysdep.h"
00091 #include <assert.h>
00092 #include <stdio.h>
00093 #include <ctype.h>
00094
00095 #define DEF_SIZE 5000
00096 #define STACK 50
00097
00098 int internal_wanted;
00099 int internal_mode;
00100
00101 int warning;
00102
00103
00104
00105 typedef struct buffer
00106 {
00107 char *ptr;
00108 unsigned long write_idx;
00109 unsigned long size;
00110 } string_type;
00111
00112 #ifdef __STDC__
00113 static void init_string_with_size (string_type *, unsigned int);
00114 static void init_string (string_type *);
00115 static int find (string_type *, char *);
00116 static void write_buffer (string_type *, FILE *);
00117 static void delete_string (string_type *);
00118 static char *addr (string_type *, unsigned int);
00119 static char at (string_type *, unsigned int);
00120 static void catchar (string_type *, int);
00121 static void overwrite_string (string_type *, string_type *);
00122 static void catbuf (string_type *, char *, unsigned int);
00123 static void cattext (string_type *, char *);
00124 static void catstr (string_type *, string_type *);
00125 #endif
00126
00127 static void
00128 init_string_with_size (buffer, size)
00129 string_type *buffer;
00130 unsigned int size;
00131 {
00132 buffer->write_idx = 0;
00133 buffer->size = size;
00134 buffer->ptr = malloc (size);
00135 }
00136
00137 static void
00138 init_string (buffer)
00139 string_type *buffer;
00140 {
00141 init_string_with_size (buffer, DEF_SIZE);
00142 }
00143
00144 static int
00145 find (str, what)
00146 string_type *str;
00147 char *what;
00148 {
00149 unsigned int i;
00150 char *p;
00151 p = what;
00152 for (i = 0; i < str->write_idx && *p; i++)
00153 {
00154 if (*p == str->ptr[i])
00155 p++;
00156 else
00157 p = what;
00158 }
00159 return (*p == 0);
00160 }
00161
00162 static void
00163 write_buffer (buffer, f)
00164 string_type *buffer;
00165 FILE *f;
00166 {
00167 fwrite (buffer->ptr, buffer->write_idx, 1, f);
00168 }
00169
00170 static void
00171 delete_string (buffer)
00172 string_type *buffer;
00173 {
00174 free (buffer->ptr);
00175 }
00176
00177 static char *
00178 addr (buffer, idx)
00179 string_type *buffer;
00180 unsigned int idx;
00181 {
00182 return buffer->ptr + idx;
00183 }
00184
00185 static char
00186 at (buffer, pos)
00187 string_type *buffer;
00188 unsigned int pos;
00189 {
00190 if (pos >= buffer->write_idx)
00191 return 0;
00192 return buffer->ptr[pos];
00193 }
00194
00195 static void
00196 catchar (buffer, ch)
00197 string_type *buffer;
00198 int ch;
00199 {
00200 if (buffer->write_idx == buffer->size)
00201 {
00202 buffer->size *= 2;
00203 buffer->ptr = realloc (buffer->ptr, buffer->size);
00204 }
00205
00206 buffer->ptr[buffer->write_idx++] = ch;
00207 }
00208
00209 static void
00210 overwrite_string (dst, src)
00211 string_type *dst;
00212 string_type *src;
00213 {
00214 free (dst->ptr);
00215 dst->size = src->size;
00216 dst->write_idx = src->write_idx;
00217 dst->ptr = src->ptr;
00218 }
00219
00220 static void
00221 catbuf (buffer, buf, len)
00222 string_type *buffer;
00223 char *buf;
00224 unsigned int len;
00225 {
00226 if (buffer->write_idx + len >= buffer->size)
00227 {
00228 while (buffer->write_idx + len >= buffer->size)
00229 buffer->size *= 2;
00230 buffer->ptr = realloc (buffer->ptr, buffer->size);
00231 }
00232 memcpy (buffer->ptr + buffer->write_idx, buf, len);
00233 buffer->write_idx += len;
00234 }
00235
00236 static void
00237 cattext (buffer, string)
00238 string_type *buffer;
00239 char *string;
00240 {
00241 catbuf (buffer, string, (unsigned int) strlen (string));
00242 }
00243
00244 static void
00245 catstr (dst, src)
00246 string_type *dst;
00247 string_type *src;
00248 {
00249 catbuf (dst, src->ptr, src->write_idx);
00250 }
00251
00252 static unsigned int
00253 skip_white_and_stars (src, idx)
00254 string_type *src;
00255 unsigned int idx;
00256 {
00257 char c;
00258 while ((c = at (src, idx)),
00259 isspace ((unsigned char) c)
00260 || (c == '*'
00261
00262
00263 && at (src, idx +1) != '/'
00264 && at (src, idx -1) != '\n'))
00265 idx++;
00266 return idx;
00267 }
00268
00269
00270
00271 string_type stack[STACK];
00272 string_type *tos;
00273
00274 unsigned int idx = 0;
00275 string_type *ptr;
00276 typedef void (*stinst_type)();
00277 stinst_type *pc;
00278 stinst_type sstack[STACK];
00279 stinst_type *ssp = &sstack[0];
00280 long istack[STACK];
00281 long *isp = &istack[0];
00282
00283 typedef int *word_type;
00284
00285 struct dict_struct
00286 {
00287 char *word;
00288 struct dict_struct *next;
00289 stinst_type *code;
00290 int code_length;
00291 int code_end;
00292 int var;
00293 };
00294
00295 typedef struct dict_struct dict_type;
00296
00297 static void
00298 die (msg)
00299 char *msg;
00300 {
00301 fprintf (stderr, "%s\n", msg);
00302 exit (1);
00303 }
00304
00305 static void
00306 check_range ()
00307 {
00308 if (tos < stack)
00309 die ("underflow in string stack");
00310 if (tos >= stack + STACK)
00311 die ("overflow in string stack");
00312 }
00313
00314 static void
00315 icheck_range ()
00316 {
00317 if (isp < istack)
00318 die ("underflow in integer stack");
00319 if (isp >= istack + STACK)
00320 die ("overflow in integer stack");
00321 }
00322
00323 #ifdef __STDC__
00324 static void exec (dict_type *);
00325 static void call (void);
00326 static void remchar (void), strip_trailing_newlines (void), push_number (void);
00327 static void push_text (void);
00328 static void remove_noncomments (string_type *, string_type *);
00329 static void print_stack_level (void);
00330 static void paramstuff (void), translatecomments (void);
00331 static void outputdots (void), courierize (void), bulletize (void);
00332 static void do_fancy_stuff (void);
00333 static int iscommand (string_type *, unsigned int);
00334 static int copy_past_newline (string_type *, unsigned int, string_type *);
00335 static void icopy_past_newline (void), kill_bogus_lines (void), indent (void);
00336 static void get_stuff_in_command (void), swap (void), other_dup (void);
00337 static void drop (void), idrop (void);
00338 static void icatstr (void), skip_past_newline (void), internalmode (void);
00339 static void maybecatstr (void);
00340 static char *nextword (char *, char **);
00341 dict_type *lookup_word (char *);
00342 static void perform (void);
00343 dict_type *newentry (char *);
00344 unsigned int add_to_definition (dict_type *, stinst_type);
00345 void add_intrinsic (char *, void (*)());
00346 void add_var (char *);
00347 void compile (char *);
00348 static void bang (void);
00349 static void atsign (void);
00350 static void hello (void);
00351 static void stdout_ (void);
00352 static void stderr_ (void);
00353 static void print (void);
00354 static void read_in (string_type *, FILE *);
00355 static void usage (void);
00356 static void chew_exit (void);
00357 #endif
00358
00359 static void
00360 exec (word)
00361 dict_type *word;
00362 {
00363 pc = word->code;
00364 while (*pc)
00365 (*pc) ();
00366 }
00367
00368 static void
00369 call ()
00370 {
00371 stinst_type *oldpc = pc;
00372 dict_type *e;
00373 e = (dict_type *) (pc[1]);
00374 exec (e);
00375 pc = oldpc + 2;
00376 }
00377
00378 static void
00379 remchar ()
00380 {
00381 if (tos->write_idx)
00382 tos->write_idx--;
00383 pc++;
00384 }
00385
00386 static void
00387 strip_trailing_newlines ()
00388 {
00389 while ((isspace ((unsigned char) at (tos, tos->write_idx - 1))
00390 || at (tos, tos->write_idx - 1) == '\n')
00391 && tos->write_idx > 0)
00392 tos->write_idx--;
00393 pc++;
00394 }
00395
00396 static void
00397 push_number ()
00398 {
00399 isp++;
00400 icheck_range ();
00401 pc++;
00402 *isp = (long) (*pc);
00403 pc++;
00404 }
00405
00406 static void
00407 push_text ()
00408 {
00409 tos++;
00410 check_range ();
00411 init_string (tos);
00412 pc++;
00413 cattext (tos, *((char **) pc));
00414 pc++;
00415 }
00416
00417
00418
00419
00420
00421
00422 static void
00423 remove_noncomments (src, dst)
00424 string_type *src;
00425 string_type *dst;
00426 {
00427 unsigned int idx = 0;
00428
00429 while (at (src, idx))
00430 {
00431
00432 if (at (src, idx) == '\n'
00433 && at (src, idx + 1) == '/'
00434 && at (src, idx + 2) == '*')
00435 {
00436 idx += 3;
00437
00438 idx = skip_white_and_stars (src, idx);
00439
00440
00441 if (at (src, idx) == '.')
00442 idx++;
00443
00444
00445
00446 while (at (src, idx))
00447 {
00448 if (at (src, idx) == '\n')
00449 {
00450
00451 if (at (src, idx + 1) == '\n')
00452 catchar (dst, '\n');
00453 catchar (dst, '\n');
00454 idx++;
00455 idx = skip_white_and_stars (src, idx);
00456 }
00457 else if (at (src, idx) == '*' && at (src, idx + 1) == '/')
00458 {
00459 idx += 2;
00460 cattext (dst, "\nENDDD\n");
00461 break;
00462 }
00463 else
00464 {
00465 catchar (dst, at (src, idx));
00466 idx++;
00467 }
00468 }
00469 }
00470 else
00471 idx++;
00472 }
00473 }
00474
00475 static void
00476 print_stack_level ()
00477 {
00478 fprintf (stderr, "current string stack depth = %d, ", tos - stack);
00479 fprintf (stderr, "current integer stack depth = %d\n", isp - istack);
00480 pc++;
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491 static void
00492 paramstuff ()
00493 {
00494 unsigned int openp;
00495 unsigned int fname;
00496 unsigned int idx;
00497 unsigned int len;
00498 string_type out;
00499 init_string (&out);
00500
00501 #define NO_PARAMS 1
00502
00503
00504 if (NO_PARAMS
00505 || find (tos, "PARAMS") || find (tos, "PROTO") || !find (tos, "("))
00506 {
00507 catstr (&out, tos);
00508 }
00509 else
00510 {
00511
00512 for (openp = 0; at (tos, openp) != '(' && at (tos, openp); openp++)
00513 ;
00514
00515 fname = openp;
00516
00517 fname--;
00518 while (fname && isspace ((unsigned char) at (tos, fname)))
00519 fname--;
00520 while (fname
00521 && !isspace ((unsigned char) at (tos,fname))
00522 && at (tos,fname) != '*')
00523 fname--;
00524
00525 fname++;
00526
00527
00528
00529 for (len = fname; 0 < len; len--)
00530 {
00531 if (!isspace ((unsigned char) at (tos, len - 1)))
00532 break;
00533 }
00534 for (idx = 0; idx < len; idx++)
00535 catchar (&out, at (tos, idx));
00536
00537 cattext (&out, "\n");
00538
00539
00540
00541 for (len = openp; 0 < len; len--)
00542 {
00543 if (!isspace ((unsigned char) at (tos, len - 1)))
00544 break;
00545 }
00546 for (idx = fname; idx < len; idx++)
00547 catchar (&out, at (tos, idx));
00548
00549 cattext (&out, " PARAMS (");
00550
00551 for (idx = openp; at (tos, idx) && at (tos, idx) != ';'; idx++)
00552 catchar (&out, at (tos, idx));
00553
00554 cattext (&out, ");\n\n");
00555 }
00556 overwrite_string (tos, &out);
00557 pc++;
00558
00559 }
00560
00561
00562
00563
00564 static void
00565 translatecomments ()
00566 {
00567 unsigned int idx = 0;
00568 string_type out;
00569 init_string (&out);
00570
00571 while (at (tos, idx))
00572 {
00573 if (at (tos, idx) == '{' && at (tos, idx + 1) == '*')
00574 {
00575 cattext (&out, "/*");
00576 idx += 2;
00577 }
00578 else if (at (tos, idx) == '*' && at (tos, idx + 1) == '}')
00579 {
00580 cattext (&out, "*/");
00581 idx += 2;
00582 }
00583 else
00584 {
00585 catchar (&out, at (tos, idx));
00586 idx++;
00587 }
00588 }
00589
00590 overwrite_string (tos, &out);
00591
00592 pc++;
00593 }
00594
00595
00596 static void
00597 outputdots ()
00598 {
00599 unsigned int idx = 0;
00600 string_type out;
00601 init_string (&out);
00602
00603 while (at (tos, idx))
00604 {
00605 if (at (tos, idx) == '\n' && at (tos, idx + 1) == '.')
00606 {
00607 char c;
00608 idx += 2;
00609
00610 while ((c = at (tos, idx)) && c != '\n')
00611 {
00612 if (c == '{' && at (tos, idx + 1) == '*')
00613 {
00614 cattext (&out, "/*");
00615 idx += 2;
00616 }
00617 else if (c == '*' && at (tos, idx + 1) == '}')
00618 {
00619 cattext (&out, "*/");
00620 idx += 2;
00621 }
00622 else
00623 {
00624 catchar (&out, c);
00625 idx++;
00626 }
00627 }
00628 catchar (&out, '\n');
00629 }
00630 else
00631 {
00632 idx++;
00633 }
00634 }
00635
00636 overwrite_string (tos, &out);
00637 pc++;
00638 }
00639
00640
00641 static void
00642 courierize ()
00643 {
00644 string_type out;
00645 unsigned int idx = 0;
00646 int command = 0;
00647
00648 init_string (&out);
00649
00650 while (at (tos, idx))
00651 {
00652 if (at (tos, idx) == '\n'
00653 && (at (tos, idx +1 ) == '.'
00654 || at (tos, idx + 1) == '|'))
00655 {
00656 cattext (&out, "\n@example\n");
00657 do
00658 {
00659 idx += 2;
00660
00661 while (at (tos, idx) && at (tos, idx) != '\n')
00662 {
00663 if (command > 1)
00664 {
00665
00666
00667 if (at (tos, idx) == '{')
00668 ++command;
00669 else if (at (tos, idx) == '}')
00670 --command;
00671 }
00672 else if (command != 0)
00673 {
00674 if (at (tos, idx) == '{')
00675 ++command;
00676 else if (!islower ((unsigned char) at (tos, idx)))
00677 --command;
00678 }
00679 else if (at (tos, idx) == '@'
00680 && islower ((unsigned char) at (tos, idx + 1)))
00681 {
00682 ++command;
00683 }
00684 else if (at (tos, idx) == '{' && at (tos, idx + 1) == '*')
00685 {
00686 cattext (&out, "/*");
00687 idx += 2;
00688 continue;
00689 }
00690 else if (at (tos, idx) == '*' && at (tos, idx + 1) == '}')
00691 {
00692 cattext (&out, "*/");
00693 idx += 2;
00694 continue;
00695 }
00696 else if (at (tos, idx) == '{'
00697 || at (tos, idx) == '}')
00698 {
00699 catchar (&out, '@');
00700 }
00701
00702 catchar (&out, at (tos, idx));
00703 idx++;
00704 }
00705 catchar (&out, '\n');
00706 }
00707 while (at (tos, idx) == '\n'
00708 && ((at (tos, idx + 1) == '.')
00709 || (at (tos, idx + 1) == '|')))
00710 ;
00711 cattext (&out, "@end example");
00712 }
00713 else
00714 {
00715 catchar (&out, at (tos, idx));
00716 idx++;
00717 }
00718 }
00719
00720 overwrite_string (tos, &out);
00721 pc++;
00722 }
00723
00724
00725
00726
00727
00728 static void
00729 bulletize ()
00730 {
00731 unsigned int idx = 0;
00732 int on = 0;
00733 string_type out;
00734 init_string (&out);
00735
00736 while (at (tos, idx))
00737 {
00738 if (at (tos, idx) == '@'
00739 && at (tos, idx + 1) == '*')
00740 {
00741 cattext (&out, "*");
00742 idx += 2;
00743 }
00744 else if (at (tos, idx) == '\n'
00745 && at (tos, idx + 1) == 'o'
00746 && isspace ((unsigned char) at (tos, idx + 2)))
00747 {
00748 if (!on)
00749 {
00750 cattext (&out, "\n@itemize @bullet\n");
00751 on = 1;
00752
00753 }
00754 cattext (&out, "\n@item\n");
00755 idx += 3;
00756 }
00757 else
00758 {
00759 catchar (&out, at (tos, idx));
00760 if (on && at (tos, idx) == '\n'
00761 && at (tos, idx + 1) == '\n'
00762 && at (tos, idx + 2) != 'o')
00763 {
00764 cattext (&out, "@end itemize");
00765 on = 0;
00766 }
00767 idx++;
00768
00769 }
00770 }
00771 if (on)
00772 {
00773 cattext (&out, "@end itemize\n");
00774 }
00775
00776 delete_string (tos);
00777 *tos = out;
00778 pc++;
00779 }
00780
00781
00782
00783 static void
00784 do_fancy_stuff ()
00785 {
00786 unsigned int idx = 0;
00787 string_type out;
00788 init_string (&out);
00789 while (at (tos, idx))
00790 {
00791 if (at (tos, idx) == '<'
00792 && at (tos, idx + 1) == '<'
00793 && !isspace ((unsigned char) at (tos, idx + 2)))
00794 {
00795
00796 idx += 2;
00797 cattext (&out, "@code{");
00798 while (at (tos, idx)
00799 && at (tos, idx) != '>' )
00800 {
00801 catchar (&out, at (tos, idx));
00802 idx++;
00803
00804 }
00805 cattext (&out, "}");
00806 idx += 2;
00807 }
00808 else
00809 {
00810 catchar (&out, at (tos, idx));
00811 idx++;
00812 }
00813 }
00814 delete_string (tos);
00815 *tos = out;
00816 pc++;
00817
00818 }
00819
00820
00821
00822 static int
00823 iscommand (ptr, idx)
00824 string_type *ptr;
00825 unsigned int idx;
00826 {
00827 unsigned int len = 0;
00828 while (at (ptr, idx))
00829 {
00830 if (isupper ((unsigned char) at (ptr, idx))
00831 || at (ptr, idx) == ' ' || at (ptr, idx) == '_')
00832 {
00833 len++;
00834 idx++;
00835 }
00836 else if (at (ptr, idx) == '\n')
00837 {
00838 if (len > 3)
00839 return 1;
00840 return 0;
00841 }
00842 else
00843 return 0;
00844 }
00845 return 0;
00846 }
00847
00848 static int
00849 copy_past_newline (ptr, idx, dst)
00850 string_type *ptr;
00851 unsigned int idx;
00852 string_type *dst;
00853 {
00854 int column = 0;
00855
00856 while (at (ptr, idx) && at (ptr, idx) != '\n')
00857 {
00858 if (at (ptr, idx) == '\t')
00859 {
00860
00861
00862 do
00863 catchar (dst, ' ');
00864 while (++column & 7);
00865 }
00866 else
00867 {
00868 catchar (dst, at (ptr, idx));
00869 column++;
00870 }
00871 idx++;
00872
00873 }
00874 catchar (dst, at (ptr, idx));
00875 idx++;
00876 return idx;
00877
00878 }
00879
00880 static void
00881 icopy_past_newline ()
00882 {
00883 tos++;
00884 check_range ();
00885 init_string (tos);
00886 idx = copy_past_newline (ptr, idx, tos);
00887 pc++;
00888 }
00889
00890
00891
00892
00893 static void
00894 kill_bogus_lines ()
00895 {
00896 int sl;
00897
00898 int idx = 0;
00899 int c;
00900 int dot = 0;
00901
00902 string_type out;
00903 init_string (&out);
00904
00905 while (at (tos, idx) == '\n')
00906 {
00907 idx++;
00908 }
00909 c = idx;
00910
00911
00912
00913 if (at (tos, idx) == '.')
00914 catchar (&out, '\n');
00915
00916
00917 while (at (tos, idx))
00918 {
00919 idx++;
00920 }
00921
00922
00923 idx--;
00924
00925 while (idx && isspace ((unsigned char) at (tos, idx)))
00926 idx--;
00927 idx++;
00928
00929
00930
00931 sl = 1;
00932
00933 while (c < idx)
00934 {
00935 if (at (tos, c) == '\n'
00936 && at (tos, c + 1) == '\n'
00937 && at (tos, c + 2) == '.')
00938 {
00939
00940 c++;
00941 }
00942 else if (at (tos, c) == '.' && sl)
00943 {
00944
00945 dot = 2;
00946 }
00947 else if (at (tos, c) == '\n'
00948 && at (tos, c + 1) == '\n'
00949 && dot)
00950 {
00951 c++;
00952
00953 }
00954
00955 catchar (&out, at (tos, c));
00956 if (at (tos, c) == '\n')
00957 {
00958 sl = 1;
00959
00960 if (dot == 2)
00961 dot = 1;
00962 else
00963 dot = 0;
00964 }
00965 else
00966 sl = 0;
00967
00968 c++;
00969
00970 }
00971
00972
00973 catchar (&out, '\n');
00974 pc++;
00975 delete_string (tos);
00976 *tos = out;
00977
00978 }
00979
00980 static void
00981 indent ()
00982 {
00983 string_type out;
00984 int tab = 0;
00985 int idx = 0;
00986 int ol = 0;
00987 init_string (&out);
00988 while (at (tos, idx))
00989 {
00990 switch (at (tos, idx))
00991 {
00992 case '\n':
00993 cattext (&out, "\n");
00994 idx++;
00995 if (tab && at (tos, idx))
00996 {
00997 cattext (&out, " ");
00998 }
00999 ol = 0;
01000 break;
01001 case '(':
01002 tab++;
01003 if (ol == 0)
01004 cattext (&out, " ");
01005 idx++;
01006 cattext (&out, "(");
01007 ol = 1;
01008 break;
01009 case ')':
01010 tab--;
01011 cattext (&out, ")");
01012 idx++;
01013 ol = 1;
01014
01015 break;
01016 default:
01017 catchar (&out, at (tos, idx));
01018 ol = 1;
01019
01020 idx++;
01021 break;
01022 }
01023 }
01024
01025 pc++;
01026 delete_string (tos);
01027 *tos = out;
01028
01029 }
01030
01031 static void
01032 get_stuff_in_command ()
01033 {
01034 tos++;
01035 check_range ();
01036 init_string (tos);
01037
01038 while (at (ptr, idx))
01039 {
01040 if (iscommand (ptr, idx))
01041 break;
01042 idx = copy_past_newline (ptr, idx, tos);
01043 }
01044 pc++;
01045 }
01046
01047 static void
01048 swap ()
01049 {
01050 string_type t;
01051
01052 t = tos[0];
01053 tos[0] = tos[-1];
01054 tos[-1] = t;
01055 pc++;
01056 }
01057
01058 static void
01059 other_dup ()
01060 {
01061 tos++;
01062 check_range ();
01063 init_string (tos);
01064 catstr (tos, tos - 1);
01065 pc++;
01066 }
01067
01068 static void
01069 drop ()
01070 {
01071 tos--;
01072 check_range ();
01073 pc++;
01074 }
01075
01076 static void
01077 idrop ()
01078 {
01079 isp--;
01080 icheck_range ();
01081 pc++;
01082 }
01083
01084 static void
01085 icatstr ()
01086 {
01087 tos--;
01088 check_range ();
01089 catstr (tos, tos + 1);
01090 delete_string (tos + 1);
01091 pc++;
01092 }
01093
01094 static void
01095 skip_past_newline ()
01096 {
01097 while (at (ptr, idx)
01098 && at (ptr, idx) != '\n')
01099 idx++;
01100 idx++;
01101 pc++;
01102 }
01103
01104 static void
01105 internalmode ()
01106 {
01107 internal_mode = *(isp);
01108 isp--;
01109 icheck_range ();
01110 pc++;
01111 }
01112
01113 static void
01114 maybecatstr ()
01115 {
01116 if (internal_wanted == internal_mode)
01117 {
01118 catstr (tos - 1, tos);
01119 }
01120 delete_string (tos);
01121 tos--;
01122 check_range ();
01123 pc++;
01124 }
01125
01126 char *
01127 nextword (string, word)
01128 char *string;
01129 char **word;
01130 {
01131 char *word_start;
01132 int idx;
01133 char *dst;
01134 char *src;
01135
01136 int length = 0;
01137
01138 while (isspace ((unsigned char) *string) || *string == '-')
01139 {
01140 if (*string == '-')
01141 {
01142 while (*string && *string != '\n')
01143 string++;
01144
01145 }
01146 else
01147 {
01148 string++;
01149 }
01150 }
01151 if (!*string)
01152 return 0;
01153
01154 word_start = string;
01155 if (*string == '"')
01156 {
01157 do
01158 {
01159 string++;
01160 length++;
01161 if (*string == '\\')
01162 {
01163 string += 2;
01164 length += 2;
01165 }
01166 }
01167 while (*string != '"');
01168 }
01169 else
01170 {
01171 while (!isspace ((unsigned char) *string))
01172 {
01173 string++;
01174 length++;
01175
01176 }
01177 }
01178
01179 *word = malloc (length + 1);
01180
01181 dst = *word;
01182 src = word_start;
01183
01184 for (idx = 0; idx < length; idx++)
01185 {
01186 if (src[idx] == '\\')
01187 switch (src[idx + 1])
01188 {
01189 case 'n':
01190 *dst++ = '\n';
01191 idx++;
01192 break;
01193 case '"':
01194 case '\\':
01195 *dst++ = src[idx + 1];
01196 idx++;
01197 break;
01198 default:
01199 *dst++ = '\\';
01200 break;
01201 }
01202 else
01203 *dst++ = src[idx];
01204 }
01205 *dst++ = 0;
01206
01207 if (*string)
01208 return string + 1;
01209 else
01210 return 0;
01211 }
01212
01213 dict_type *root;
01214
01215 dict_type *
01216 lookup_word (word)
01217 char *word;
01218 {
01219 dict_type *ptr = root;
01220 while (ptr)
01221 {
01222 if (strcmp (ptr->word, word) == 0)
01223 return ptr;
01224 ptr = ptr->next;
01225 }
01226 if (warning)
01227 fprintf (stderr, "Can't find %s\n", word);
01228 return 0;
01229 }
01230
01231 static void
01232 perform ()
01233 {
01234 tos = stack;
01235
01236 while (at (ptr, idx))
01237 {
01238
01239 if (iscommand (ptr, idx))
01240 {
01241 char *next;
01242 dict_type *word;
01243
01244 (void) nextword (addr (ptr, idx), &next);
01245
01246 word = lookup_word (next);
01247
01248 if (word)
01249 {
01250 exec (word);
01251 }
01252 else
01253 {
01254 if (warning)
01255 fprintf (stderr, "warning, %s is not recognised\n", next);
01256 skip_past_newline ();
01257 }
01258
01259 }
01260 else
01261 skip_past_newline ();
01262 }
01263 }
01264
01265 dict_type *
01266 newentry (word)
01267 char *word;
01268 {
01269 dict_type *new = (dict_type *) malloc (sizeof (dict_type));
01270 new->word = word;
01271 new->next = root;
01272 root = new;
01273 new->code = (stinst_type *) malloc (sizeof (stinst_type));
01274 new->code_length = 1;
01275 new->code_end = 0;
01276 return new;
01277 }
01278
01279 unsigned int
01280 add_to_definition (entry, word)
01281 dict_type *entry;
01282 stinst_type word;
01283 {
01284 if (entry->code_end == entry->code_length)
01285 {
01286 entry->code_length += 2;
01287 entry->code =
01288 (stinst_type *) realloc ((char *) (entry->code),
01289 entry->code_length * sizeof (word_type));
01290 }
01291 entry->code[entry->code_end] = word;
01292
01293 return entry->code_end++;
01294 }
01295
01296 void
01297 add_intrinsic (name, func)
01298 char *name;
01299 void (*func) ();
01300 {
01301 dict_type *new = newentry (name);
01302 add_to_definition (new, func);
01303 add_to_definition (new, 0);
01304 }
01305
01306 void
01307 add_var (name)
01308 char *name;
01309 {
01310 dict_type *new = newentry (name);
01311 add_to_definition (new, push_number);
01312 add_to_definition (new, (stinst_type) (&(new->var)));
01313 add_to_definition (new, 0);
01314 }
01315
01316 void
01317 compile (string)
01318 char *string;
01319 {
01320
01321 char *word;
01322 string = nextword (string, &word);
01323 while (string && *string && word[0])
01324 {
01325 if (strcmp (word, "var") == 0)
01326 {
01327 string = nextword (string, &word);
01328
01329 add_var (word);
01330 string = nextword (string, &word);
01331 }
01332 else if (word[0] == ':')
01333 {
01334 dict_type *ptr;
01335
01336 string = nextword (string, &word);
01337
01338 ptr = newentry (word);
01339 string = nextword (string, &word);
01340 while (word[0] != ';')
01341 {
01342 switch (word[0])
01343 {
01344 case '"':
01345
01346
01347 add_to_definition (ptr, push_text);
01348 add_to_definition (ptr, (stinst_type) (word + 1));
01349 break;
01350 case '0':
01351 case '1':
01352 case '2':
01353 case '3':
01354 case '4':
01355 case '5':
01356 case '6':
01357 case '7':
01358 case '8':
01359 case '9':
01360
01361
01362 add_to_definition (ptr, push_number);
01363 add_to_definition (ptr, (stinst_type) atol (word));
01364 break;
01365 default:
01366 add_to_definition (ptr, call);
01367 add_to_definition (ptr, (stinst_type) lookup_word (word));
01368 }
01369
01370 string = nextword (string, &word);
01371 }
01372 add_to_definition (ptr, 0);
01373 string = nextword (string, &word);
01374 }
01375 else
01376 {
01377 fprintf (stderr, "syntax error at %s\n", string - 1);
01378 }
01379 }
01380 }
01381
01382 static void
01383 bang ()
01384 {
01385 *(long *) ((isp[0])) = isp[-1];
01386 isp -= 2;
01387 icheck_range ();
01388 pc++;
01389 }
01390
01391 static void
01392 atsign ()
01393 {
01394 isp[0] = *(long *) (isp[0]);
01395 pc++;
01396 }
01397
01398 static void
01399 hello ()
01400 {
01401 printf ("hello\n");
01402 pc++;
01403 }
01404
01405 static void
01406 stdout_ ()
01407 {
01408 isp++;
01409 icheck_range ();
01410 *isp = 1;
01411 pc++;
01412 }
01413
01414 static void
01415 stderr_ ()
01416 {
01417 isp++;
01418 icheck_range ();
01419 *isp = 2;
01420 pc++;
01421 }
01422
01423 static void
01424 print ()
01425 {
01426 if (*isp == 1)
01427 write_buffer (tos, stdout);
01428 else if (*isp == 2)
01429 write_buffer (tos, stderr);
01430 else
01431 fprintf (stderr, "print: illegal print destination `%ld'\n", *isp);
01432 isp--;
01433 tos--;
01434 icheck_range ();
01435 check_range ();
01436 pc++;
01437 }
01438
01439 static void
01440 read_in (str, file)
01441 string_type *str;
01442 FILE *file;
01443 {
01444 char buff[10000];
01445 unsigned int r;
01446 do
01447 {
01448 r = fread (buff, 1, sizeof (buff), file);
01449 catbuf (str, buff, r);
01450 }
01451 while (r);
01452 buff[0] = 0;
01453
01454 catbuf (str, buff, 1);
01455 }
01456
01457 static void
01458 usage ()
01459 {
01460 fprintf (stderr, "usage: -[d|i|g] <file >file\n");
01461 exit (33);
01462 }
01463
01464
01465
01466
01467
01468
01469 static void
01470 chew_exit ()
01471 {
01472 exit (0);
01473 }
01474
01475 int
01476 main (ac, av)
01477 int ac;
01478 char *av[];
01479 {
01480 unsigned int i;
01481 string_type buffer;
01482 string_type pptr;
01483
01484 init_string (&buffer);
01485 init_string (&pptr);
01486 init_string (stack + 0);
01487 tos = stack + 1;
01488 ptr = &pptr;
01489
01490 add_intrinsic ("push_text", push_text);
01491 add_intrinsic ("!", bang);
01492 add_intrinsic ("@", atsign);
01493 add_intrinsic ("hello", hello);
01494 add_intrinsic ("stdout", stdout_);
01495 add_intrinsic ("stderr", stderr_);
01496 add_intrinsic ("print", print);
01497 add_intrinsic ("skip_past_newline", skip_past_newline);
01498 add_intrinsic ("catstr", icatstr);
01499 add_intrinsic ("copy_past_newline", icopy_past_newline);
01500 add_intrinsic ("dup", other_dup);
01501 add_intrinsic ("drop", drop);
01502 add_intrinsic ("idrop", idrop);
01503 add_intrinsic ("remchar", remchar);
01504 add_intrinsic ("get_stuff_in_command", get_stuff_in_command);
01505 add_intrinsic ("do_fancy_stuff", do_fancy_stuff);
01506 add_intrinsic ("bulletize", bulletize);
01507 add_intrinsic ("courierize", courierize);
01508
01509
01510
01511 add_intrinsic ("exit", chew_exit);
01512 add_intrinsic ("swap", swap);
01513 add_intrinsic ("outputdots", outputdots);
01514 add_intrinsic ("paramstuff", paramstuff);
01515 add_intrinsic ("maybecatstr", maybecatstr);
01516 add_intrinsic ("translatecomments", translatecomments);
01517 add_intrinsic ("kill_bogus_lines", kill_bogus_lines);
01518 add_intrinsic ("indent", indent);
01519 add_intrinsic ("internalmode", internalmode);
01520 add_intrinsic ("print_stack_level", print_stack_level);
01521 add_intrinsic ("strip_trailing_newlines", strip_trailing_newlines);
01522
01523
01524 catchar (&buffer, '\n');
01525
01526 read_in (&buffer, stdin);
01527 remove_noncomments (&buffer, ptr);
01528 for (i = 1; i < (unsigned int) ac; i++)
01529 {
01530 if (av[i][0] == '-')
01531 {
01532 if (av[i][1] == 'f')
01533 {
01534 string_type b;
01535 FILE *f;
01536 init_string (&b);
01537
01538 f = fopen (av[i + 1], "r");
01539 if (!f)
01540 {
01541 fprintf (stderr, "Can't open the input file %s\n",
01542 av[i + 1]);
01543 return 33;
01544 }
01545
01546 read_in (&b, f);
01547 compile (b.ptr);
01548 perform ();
01549 }
01550 else if (av[i][1] == 'i')
01551 {
01552 internal_wanted = 1;
01553 }
01554 else if (av[i][1] == 'w')
01555 {
01556 warning = 1;
01557 }
01558 else
01559 usage ();
01560 }
01561 }
01562 write_buffer (stack + 0, stdout);
01563 if (tos != stack)
01564 {
01565 fprintf (stderr, "finishing with current stack level %d\n",
01566 tos - stack);
01567 return 1;
01568 }
01569 return 0;
01570 }