home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / t / toaster.zip / Compat / prelang.y < prev    next >
Text File  |  1991-12-31  |  21KB  |  723 lines

  1. %{
  2. # line 3 "prelang.y"
  3. /* The above line is to give proper line number references. Please mail me
  4.  * if your compiler complains about it.
  5.  */
  6. /*
  7.  * This is the grammar definition of LPC. The token table is built
  8.  * automatically by make_func. The lang.y is constructed from this file,
  9.  * the generated token list and post_lang.y. The reason of this is that there
  10.  * is no #include-statment that yacc recognizes.
  11.  */
  12. #include <string.h>
  13. #include <stdio.h>
  14. #include <memory.h>
  15. #if defined(sun)
  16. #include <alloca.h>
  17. #endif
  18.  
  19. #include "lint.h"
  20. #include "interpret.h"
  21. #include "object.h"
  22. #include "exec.h"
  23. #include "config.h"
  24. #include "instrs.h"
  25. #include "incralloc.h"
  26. #include "switch.h"
  27.  
  28. #if defined(__GNUC__) && !defined(lint) && !defined(DEBUG)
  29. #define INLINE inline
  30. #else
  31. #define INLINE
  32. #endif
  33.  
  34. #define YYMAXDEPTH    600
  35.  
  36. /* NUMPAREAS areas are saved with the program code after compilation.
  37.  */
  38. #define A_PROGRAM        0
  39. #define A_FUNCTIONS        1
  40. #define A_STRINGS        2
  41. #define A_VARIABLES        3
  42. #define A_LINENUMBERS        4
  43. #define A_INHERITS        5
  44. #define A_ARGUMENT_TYPES    6
  45. #define A_ARGUMENT_INDEX    7
  46. #define NUMPAREAS        8
  47. #define A_CASE_NUMBERS        8
  48. #define A_CASE_STRINGS        9
  49. #define A_CASE_LABELS           10
  50. #define NUMAREAS           11
  51.  
  52. #define BREAK_ON_STACK        0x40000
  53. #define BREAK_FROM_CASE        0x80000
  54.  
  55. /* make shure that this struct has a size that is a power of two */
  56. struct case_heap_entry { int key; short addr; short line; };
  57. #define CASE_HEAP_ENTRY_ALIGN(offset) offset &= -sizeof(struct case_heap_entry)
  58.  
  59. static struct mem_block mem_block[NUMAREAS];
  60.  
  61. /*
  62.  * Some good macros to have.
  63.  */
  64.  
  65. #define BASIC_TYPE(e,t) ((e) == TYPE_ANY ||\
  66.              (e) == (t) ||\
  67.              (t) == TYPE_ANY)
  68.  
  69. #define TYPE(e,t) (BASIC_TYPE((e) & TYPE_MOD_MASK, (t) & TYPE_MOD_MASK) ||\
  70.            (((e) & TYPE_MOD_POINTER) && ((t) & TYPE_MOD_POINTER) &&\
  71.             BASIC_TYPE((e) & (TYPE_MOD_MASK & ~TYPE_MOD_POINTER),\
  72.                    (t) & (TYPE_MOD_MASK & ~TYPE_MOD_POINTER))))
  73.  
  74. #define FUNCTION(n) ((struct function *)mem_block[A_FUNCTIONS].block + (n))
  75. #define VARIABLE(n) ((struct variable *)mem_block[A_VARIABLES].block + (n))
  76.  
  77. #define align(x) (((x) + 3) & ~3)
  78.  
  79. /*
  80.  * If the type of the function is given, then strict types are
  81.  * checked and required.
  82.  */
  83. static int exact_types;
  84. extern int pragma_strict_types;    /* Maintained by lex.c */
  85. extern int pragma_save_types;    /* Also maintained by lex.c */
  86. int approved_object;        /* How I hate all these global variables */
  87.  
  88. extern int total_num_prog_blocks, total_prog_block_size;
  89.  
  90. extern int num_parse_error;
  91. extern int d_flag;
  92. static int heart_beat;        /* Number of the heart beat function */
  93.  
  94. static int current_break_address;
  95. static int current_continue_address;
  96. static int current_case_number_heap;
  97. static int current_case_string_heap;
  98. #define SOME_NUMERIC_CASE_LABELS 0x40000
  99. #define NO_STRING_CASE_LABELS    0x80000
  100. static int zero_case_label;
  101. static int current_type;
  102.  
  103. static int last_push_indexed;
  104. static int last_push_local;
  105. static int last_push_identifier;
  106.  
  107. static struct program NULL_program; /* marion - clean neat empty struct */
  108.  
  109. static char *get_two_types PROT((int type1, int type2));
  110. void free_all_local_names(),
  111.     add_local_name PROT((char *, int)), smart_log PROT((char *, int, char *));
  112. extern int yylex();
  113. static int verify_declared PROT((char *));
  114. static void copy_variables();
  115. void type_error PROT((char *, int));
  116.  
  117. char *xalloc(), *string_copy();
  118.  
  119. extern int current_line;
  120. /*
  121.  * 'inherit_file' is used as a flag. If it is set to a string
  122.  * after yyparse(), this string should be loaded as an object,
  123.  * and the original object must be loaded again.
  124.  */
  125. extern char *current_file, *inherit_file;
  126.  
  127. /*
  128.  * The names and types of arguments and auto variables.
  129.  */
  130. char *local_names[MAX_LOCAL];
  131. unsigned short type_of_locals[MAX_LOCAL];
  132. int current_number_of_locals = 0;
  133. int current_break_stack_need = 0  ,max_break_stack_need = 0;
  134.  
  135. /*
  136.  * The types of arguments when calling functions must be saved,
  137.  * to be used afterwards for checking. And because function calls
  138.  * can be done as an argument to a function calls,
  139.  * a stack of argument types is needed. This stack does not need to
  140.  * be freed between compilations, but will be reused.
  141.  */
  142. static struct mem_block type_of_arguments;
  143.  
  144. struct program *prog;    /* Is returned to the caller of yyparse */
  145.  
  146. /*
  147.  * Compare two types, and return true if they are compatible.
  148.  */
  149. int compatible_types(t1, t2)
  150.     int t1, t2;
  151. {
  152.     if (t1 == TYPE_UNKNOWN || t2 == TYPE_UNKNOWN)
  153.     return 0;
  154.     if (t1 == t2)
  155.     return 1;
  156.     if (t1 == TYPE_ANY || t2 == TYPE_ANY)
  157.     return 1;
  158.     if ((t1 & TYPE_MOD_POINTER) && (t2 & TYPE_MOD_POINTER)) {
  159.     if ((t1 & TYPE_MOD_MASK) == (TYPE_ANY|TYPE_MOD_POINTER) ||
  160.         (t2 & TYPE_MOD_MASK) == (TYPE_ANY|TYPE_MOD_POINTER))
  161.         return 1;
  162.     }
  163.     return 0;
  164. }
  165.  
  166. /*
  167.  * Add another argument type to the argument type stack
  168.  */
  169. static void add_arg_type(type)
  170.     unsigned short type;
  171. {
  172.     struct mem_block *mbp = &type_of_arguments;
  173.     while (mbp->current_size + sizeof type > mbp->max_size) {
  174.     mbp->max_size <<= 1;
  175.     mbp->block = realloc((char *)mbp->block, mbp->max_size);
  176.     }
  177.     memcpy(mbp->block + mbp->current_size, &type, sizeof type);
  178.     mbp->current_size += sizeof type;
  179. }
  180.  
  181. /*
  182.  * Pop the argument type stack 'n' elements.
  183.  */
  184. INLINE
  185. static void pop_arg_stack(n)
  186.     int n;
  187. {
  188.     type_of_arguments.current_size -= sizeof (unsigned short) * n;
  189. }
  190.  
  191. /*
  192.  * Get type of argument number 'arg', where there are
  193.  * 'n' arguments in total in this function call. Argument
  194.  * 0 is the first argument.
  195.  */
  196. INLINE
  197. int get_argument_type(arg, n)
  198.     int arg, n;
  199. {
  200.     return
  201.     ((unsigned short *)
  202.      (type_of_arguments.block + type_of_arguments.current_size))[arg - n];
  203. }
  204.  
  205. INLINE
  206. static void add_to_mem_block(n, data, size)
  207.     int n, size;
  208.     char *data;
  209. {
  210.     struct mem_block *mbp = &mem_block[n];
  211.     while (mbp->current_size + size > mbp->max_size) {
  212.     mbp->max_size <<= 1;
  213.     mbp->block = realloc((char *)mbp->block, mbp->max_size);
  214.     }
  215.     memcpy(mbp->block + mbp->current_size, data, size);
  216.     mbp->current_size += size;
  217. }
  218.  
  219. static void ins_byte(b)
  220.     char b;
  221. {
  222.     add_to_mem_block(A_PROGRAM, &b, 1);
  223. }
  224.  
  225. /*
  226.  * Store a 2 byte number. It is stored in such a way as to be sure
  227.  * that correct byte order is used, regardless of machine architecture.
  228.  * Also beware that some machines can't write a word to odd addresses.
  229.  */
  230. static void ins_short(l)
  231.     short l;
  232. {
  233.     add_to_mem_block(A_PROGRAM, (char *)&l + 0, 1);
  234.     add_to_mem_block(A_PROGRAM, (char *)&l + 1, 1);
  235. }
  236.  
  237. static void upd_short(offset, l)
  238.     int offset;
  239.     short l;
  240. {
  241.     mem_block[A_PROGRAM].block[offset + 0] = ((char *)&l)[0];
  242.     mem_block[A_PROGRAM].block[offset + 1] = ((char *)&l)[1];
  243. }
  244.  
  245. static short read_short(offset)
  246.     int offset;
  247. {
  248.     short l;
  249.  
  250.     ((char *)&l)[0] = mem_block[A_PROGRAM].block[offset + 0];
  251.     ((char *)&l)[1] = mem_block[A_PROGRAM].block[offset + 1];
  252.     return l;
  253. }
  254.  
  255. /*
  256.  * Store a 4 byte number. It is stored in such a way as to be sure
  257.  * that correct byte order is used, regardless of machine architecture.
  258.  */
  259. static void ins_long(l)
  260.     int l;
  261. {
  262.     add_to_mem_block(A_PROGRAM, (char *)&l+0, 1);
  263.     add_to_mem_block(A_PROGRAM, (char *)&l+1, 1);
  264.     add_to_mem_block(A_PROGRAM, (char *)&l+2, 1);
  265.     add_to_mem_block(A_PROGRAM, (char *)&l+3, 1);
  266. }
  267.  
  268. static void ins_f_byte(b)
  269.     unsigned int b;
  270. {
  271.     ins_byte((char)(b - F_OFFSET));
  272. }
  273.  
  274. /*
  275.  * Return the index of the function found, otherwise -1.
  276.  */
  277. static int defined_function(s)
  278.     char *s;
  279. {
  280.     int offset;
  281.     struct function *funp;
  282.  
  283.     for (offset = 0; offset < mem_block[A_FUNCTIONS].current_size;
  284.      offset += sizeof (struct function)) {
  285.     funp = (struct function *)&mem_block[A_FUNCTIONS].block[offset];
  286.     if (funp->flags & NAME_HIDDEN)
  287.         continue;
  288.         if (strcmp(funp->name, s) == 0)
  289.         return offset / sizeof (struct function);
  290.     }
  291.     return -1;
  292. }
  293.  
  294. /*
  295.  * A mechanism to remember addresses on a stack. The size of the stack is
  296.  * defined in config.h.
  297.  */
  298. static int comp_stackp;
  299. static int comp_stack[COMPILER_STACK_SIZE];
  300.  
  301. static void push_address() {
  302.     if (comp_stackp >= COMPILER_STACK_SIZE) {
  303.     yyerror("Compiler stack overflow");
  304.     comp_stackp++;
  305.     return;
  306.     }
  307.     comp_stack[comp_stackp++] = mem_block[A_PROGRAM].current_size;
  308. }
  309.  
  310. static void push_explicit(address)
  311.     int address;
  312. {
  313.     if (comp_stackp >= COMPILER_STACK_SIZE) {
  314.     yyerror("Compiler stack overflow");
  315.     comp_stackp++;
  316.     return;
  317.     }
  318.     comp_stack[comp_stackp++] = address;
  319. }
  320.  
  321. static int pop_address() {
  322.     if (comp_stackp == 0)
  323.     fatal("Compiler stack underflow.\n");
  324.     if (comp_stackp > COMPILER_STACK_SIZE) {
  325.     --comp_stackp;
  326.     return 0;
  327.     }
  328.     return comp_stack[--comp_stackp];
  329. }
  330.  
  331. /*
  332.  * Initialize the environment that the compiler needs.
  333.  */
  334. static void prolog() {
  335.     int i;
  336.  
  337.     if (type_of_arguments.block == 0) {
  338.     type_of_arguments.max_size = 100;
  339.     type_of_arguments.block = xalloc(type_of_arguments.max_size);
  340.     }
  341.     type_of_arguments.current_size = 0;
  342.     approved_object = 0;
  343.     last_push_indexed = -1;
  344.     last_push_local = -1;
  345.     last_push_identifier = -1;
  346.     prog = 0;        /* 0 means fail to load. */
  347.     heart_beat = -1;
  348.     comp_stackp = 0;    /* Local temp stack used by compiler */
  349.     current_continue_address = 0;
  350.     current_break_address = 0;
  351.     num_parse_error = 0;
  352.     free_all_local_names();    /* In case of earlier error */
  353.     /* Initialize memory blocks where the result of the compilation
  354.      * will be stored.
  355.      */
  356.     for (i=0; i < NUMAREAS; i++) {
  357.     mem_block[i].block = xalloc(START_BLOCK_SIZE);
  358.     mem_block[i].current_size = 0;
  359.     mem_block[i].max_size = START_BLOCK_SIZE;
  360.     }
  361. }
  362.  
  363. /*
  364.  * Patch a function definition of an inherited function, to what it really
  365.  * should be.
  366.  * The name of the function can be one of:
  367.  *    object::name
  368.  *    ::name
  369.  *    name
  370.  * Where 'object' is the name of the superclass.
  371.  */
  372. static void find_inherited(funp)
  373.     struct function *funp;
  374. {
  375.     int i;
  376.     struct inherit *ip;
  377.     int num_inherits, super_length;
  378.     char *real_name, *super_name = 0, *p;
  379.  
  380.     real_name = funp->name;
  381.     if (real_name[0] == ':')
  382.     real_name = real_name + 2;    /* There will be exactly two ':' */
  383.     else if (p = strchr(real_name, ':')) {
  384.     real_name = p+2;
  385.     super_name = funp->name;
  386.     super_length = real_name - super_name - 2;
  387.     }
  388.     num_inherits = mem_block[A_INHERITS].current_size /
  389.     sizeof (struct inherit);
  390.     ip = (struct inherit *)mem_block[A_INHERITS].block;
  391.     for (; num_inherits > 0; ip++, num_inherits--) {
  392.     if (super_name) {
  393.         int l = strlen(ip->prog->name);    /* Including .c */
  394.         if (l - 2 < super_length)
  395.         continue;
  396.         if (strncmp(super_name, ip->prog->name + l - 2 - super_length,
  397.             super_length) != 0)
  398.         continue;
  399.     }
  400.     for (i=0; i < ip->prog->num_functions; i++) {
  401.         if (strcmp(ip->prog->functions[i].name, real_name) != 0)
  402.         continue;
  403.         if (ip->prog->functions[i].flags & NAME_UNDEFINED)
  404.         continue;
  405.         funp->offset = ip - (struct inherit *)mem_block[A_INHERITS].block;
  406.         funp->flags = ip->prog->functions[i].flags | NAME_INHERITED;
  407.         funp->num_local = ip->prog->functions[i].num_local;
  408.         funp->num_arg = ip->prog->functions[i].num_arg;
  409.         funp->type = ip->prog->functions[i].type;
  410.         funp->function_index_offset = i;
  411.         return;
  412.     }
  413.     }
  414.     return;
  415. }
  416. /*
  417.  * The program has been compiled. Prepare a 'struct program' to be returned.
  418.  */
  419. void epilog() {
  420.     int size, i;
  421.     char *p;
  422.     struct function *funp;
  423.     static int current_id_number = 1;
  424.  
  425. #ifdef DEBUG
  426.     if (num_parse_error == 0 && type_of_arguments.current_size != 0)
  427.     fatal("Failed to deallocate argument type stack\n");
  428. #endif
  429.     /*
  430.      * If functions are undefined, replace them by definitions done
  431.      * by inheritance. All explicit "name::func" are already resolved.
  432.      */
  433.     for (i = 0; i < mem_block[A_FUNCTIONS].current_size; i += sizeof *funp) {
  434.     funp = (struct function *)(mem_block[A_FUNCTIONS].block + i);
  435.     if (!(funp->flags & NAME_UNDEFINED) || funp->name == 0)
  436.         continue;
  437.     find_inherited(funp);
  438.     }
  439.     if (num_parse_error > 0) {
  440.     prog = 0;
  441.     for (i=0; i<NUMAREAS; i++)
  442.         free(mem_block[i].block);
  443.     return;
  444.     }
  445.     size = align(sizeof (struct program));
  446.     for (i=0; i<NUMPAREAS; i++)
  447.     size += align(mem_block[i].current_size);
  448.     p = (char *)xalloc(size);
  449.     prog = (struct program *)p;
  450.     *prog = NULL_program;
  451.     prog->total_size = size;
  452.     prog->ref = 0;
  453.     prog->heart_beat = heart_beat;
  454.     prog->name = string_copy(current_file);
  455.     prog->id_number = current_id_number++;
  456.     total_prog_block_size += prog->total_size;
  457.     total_num_prog_blocks += 1;
  458.  
  459.     p += align(sizeof (struct program));
  460.     prog->program = p;
  461.     if (mem_block[A_PROGRAM].current_size)
  462.     memcpy(p, mem_block[A_PROGRAM].block,
  463.            mem_block[A_PROGRAM].current_size);
  464.     prog->program_size = mem_block[A_PROGRAM].current_size;
  465.  
  466.     p += align(mem_block[A_PROGRAM].current_size);
  467.     prog->line_numbers = (unsigned short *)p;
  468.     if (mem_block[A_LINENUMBERS].current_size)
  469.     memcpy(p, mem_block[A_LINENUMBERS].block,
  470.            mem_block[A_LINENUMBERS].current_size);
  471.  
  472.     p += align(mem_block[A_LINENUMBERS].current_size);
  473.     prog->functions = (struct function *)p;
  474.     prog->num_functions = mem_block[A_FUNCTIONS].current_size /
  475.     sizeof (struct function);
  476.     if (mem_block[A_FUNCTIONS].current_size)
  477.     memcpy(p, mem_block[A_FUNCTIONS].block,
  478.            mem_block[A_FUNCTIONS].current_size);
  479.  
  480.     p += align(mem_block[A_FUNCTIONS].current_size);
  481.     prog->strings = (char **)p;
  482.     prog->num_strings = mem_block[A_STRINGS].current_size /
  483.     sizeof (char *);
  484.     if (mem_block[A_STRINGS].current_size)
  485.     memcpy(p, mem_block[A_STRINGS].block,
  486.            mem_block[A_STRINGS].current_size);
  487.  
  488.     p += align(mem_block[A_STRINGS].current_size);
  489.     prog->variable_names = (struct variable *)p;
  490.     prog->num_variables = mem_block[A_VARIABLES].current_size /
  491.     sizeof (struct variable);
  492.     if (mem_block[A_VARIABLES].current_size)
  493.     memcpy(p, mem_block[A_VARIABLES].block,
  494.            mem_block[A_VARIABLES].current_size);
  495.  
  496.     p += align(mem_block[A_VARIABLES].current_size);
  497.     prog->inherit = (struct inherit *)p;
  498.     prog->num_inherited = mem_block[A_INHERITS].current_size /
  499.     sizeof (struct inherit);
  500.     if (prog->num_inherited)
  501.     memcpy(p, mem_block[A_INHERITS].block,
  502.            mem_block[A_INHERITS].current_size);
  503.     
  504.     prog->argument_types = 0;    /* For now. Will be fixed someday */
  505.  
  506.     prog->type_start = 0;
  507.     for (i=0; i<NUMAREAS; i++)
  508.         free((char *)mem_block[i].block);
  509.  
  510.     /*  marion
  511.     Do referencing here - avoid multiple referencing when an object
  512.     inherits more than one object and one of the inherited is already
  513.     loaded and not the last inherited
  514.     */
  515.     reference_prog (prog, "epilog");
  516.     for (i = 0; i < prog->num_inherited; i++) {
  517.     reference_prog (prog->inherit[i].prog, "inheritance");
  518.     }
  519. }
  520.  
  521. static int define_new_function(name, num_arg, num_local, offset, flags, type)
  522.     char *name;
  523.     int num_arg, num_local;
  524.     int offset, flags, type;
  525. {
  526.     int num;
  527.     struct function fun;
  528.     unsigned short argument_start_index;
  529.  
  530.     num = defined_function(name);
  531.     if (num >= 0) {
  532.     struct function *funp;
  533.  
  534.     /*
  535.      * The function was already defined. It may be one of several reasons:
  536.      *
  537.      * 1.    There has been a prototype.
  538.      * 2.    There was the same function defined by inheritance.
  539.      * 3.    This function has been called, but not yet defined.
  540.      * 4.    The function is double defined.
  541.      * 5.    A "late" prototype has been encountered.
  542.      */
  543.     funp = (struct function *)(mem_block[A_FUNCTIONS].block) + num;
  544.     if (!(funp->flags & NAME_UNDEFINED) &&
  545.         !(flags & NAME_PROTOTYPE) &&
  546.         !(funp->flags & NAME_INHERITED))
  547.     {
  548.         char buff[500];
  549.         sprintf(buff, "Redeclaration of function %s.", name);
  550.         yyerror(buff);
  551.         return num;
  552.     }
  553.     /*
  554.      * It was either an undefined but used funtion, or an inherited
  555.      * function. In both cases, we now consider this to be THE new
  556.      * definition. It might also have been a prototype to an already
  557.      * defined function.
  558.      *
  559.      * Check arguments only when types are supposed to be tested,
  560.      * and if this function really has been defined already.
  561.      */
  562.     if (exact_types && funp->type != TYPE_UNKNOWN) {
  563.         int i;
  564.         if (funp->num_arg != num_arg && !(funp->type & TYPE_MOD_VARARGS))
  565.         yyerror("Incorrect number of arguments.");
  566.         else if (!(funp->flags & NAME_STRICT_TYPES))
  567.         yyerror("Called function not compiled with type testing.\n");
  568.         else {
  569.         /* Now check that argument types wasn't changed. */
  570.         for (i=0; i < num_arg; i++) {
  571.         }
  572.         }
  573.     }
  574.     /* If it was yet another prototype, then simply return. */
  575.     if (flags & NAME_PROTOTYPE)
  576.         return num;
  577.     funp->num_arg = num_arg;
  578.     funp->num_local = num_local;
  579.     funp->flags = flags;
  580.     funp->offset = offset;
  581.     funp->function_index_offset = 0;
  582.     funp->type = type;
  583.     if (exact_types)
  584.         funp->flags |= NAME_STRICT_TYPES;
  585.     return num;
  586.     }
  587.     if (strcmp(name, "heart_beat") == 0)
  588.     heart_beat = mem_block[A_FUNCTIONS].current_size /
  589.         sizeof (struct function);
  590.     fun.name = make_shared_string(name);
  591.     fun.offset = offset;
  592.     fun.flags = flags;
  593.     fun.num_arg = num_arg;
  594.     fun.num_local = num_local;
  595.     fun.function_index_offset = 0;
  596.     fun.type = type;
  597.     if (exact_types)
  598.     fun.flags |= NAME_STRICT_TYPES;
  599.     num = mem_block[A_FUNCTIONS].current_size / sizeof fun;
  600.     /* Number of local variables will be updated later */
  601.     add_to_mem_block(A_FUNCTIONS, (char *)&fun, sizeof fun);
  602.  
  603.     if (exact_types == 0 || num_arg == 0) {
  604.     argument_start_index = INDEX_START_NONE;
  605.     } else {
  606.     int i;
  607.  
  608.     /*
  609.      * Save the start of argument types.
  610.      */
  611.     argument_start_index =
  612.         mem_block[A_ARGUMENT_TYPES].current_size /
  613.         sizeof (unsigned short);
  614.     for (i=0; i < num_arg; i++) {
  615.         add_to_mem_block(A_ARGUMENT_TYPES, &type_of_locals[i],
  616.                  sizeof type_of_locals[i]);
  617.     }
  618.     }
  619.     add_to_mem_block(A_ARGUMENT_INDEX, &argument_start_index,
  620.              sizeof argument_start_index);
  621.     return num;
  622. }
  623.  
  624. static void define_variable(name, type, flags)
  625.     char *name;
  626.     int type;
  627.     int flags;
  628. {
  629.     struct variable dummy;
  630.  
  631.     dummy.name = make_shared_string(name);
  632.     dummy.type = type;
  633.     dummy.flags = flags;
  634.     add_to_mem_block(A_VARIABLES, (char *)&dummy, sizeof dummy);
  635. }
  636.  
  637. short store_prog_string(str)
  638.     char *str;
  639. {
  640.     short i;
  641.     char **p;
  642.  
  643.     p = (char **) mem_block[A_STRINGS].block;
  644.     str = make_shared_string(str);
  645.     for (i=mem_block[A_STRINGS].current_size / sizeof str -1; i>=0; --i)
  646.     if (p[i] == str)  {
  647.         free_string(str); /* Needed as string is only free'ed once. */
  648.         return i;
  649.     }
  650.  
  651.     add_to_mem_block(A_STRINGS, &str, sizeof str);
  652.     return mem_block[A_STRINGS].current_size / sizeof str - 1;
  653. }
  654.  
  655. void add_to_case_heap(block_index,entry)
  656.     int block_index;
  657.     struct case_heap_entry *entry;
  658. {
  659.     char *heap_start;
  660.     int offset,parent;
  661.     int current_heap;
  662.  
  663.     if ( block_index == A_CASE_NUMBERS )
  664.         current_heap = current_case_number_heap;
  665.     else
  666.         current_heap = current_case_string_heap;
  667.     offset = mem_block[block_index].current_size - current_heap;
  668.     add_to_mem_block(block_index, (char*)entry, sizeof(*entry) );
  669.     heap_start = mem_block[block_index].block + current_heap;
  670.     for ( ; offset; offset = parent ) {
  671.         parent = ( offset - sizeof(struct case_heap_entry) ) >> 1 ;
  672.         CASE_HEAP_ENTRY_ALIGN(parent);
  673.         if ( ((struct case_heap_entry*)(heap_start+offset))->key <
  674.              ((struct case_heap_entry*)(heap_start+parent))->key )
  675.         {
  676.             *(struct case_heap_entry*)(heap_start+offset) =
  677.             *(struct case_heap_entry*)(heap_start+parent);
  678.             *(struct case_heap_entry*)(heap_start+parent) = *entry;
  679.         }
  680.     }
  681. }
  682.  
  683. %}
  684.  
  685. /*
  686.  * These values are used by the stack machine, and can not be directly
  687.  * called from LPC.
  688.  */
  689. %token F_JUMP F_JUMP_WHEN_ZERO F_JUMP_WHEN_NON_ZERO
  690. %token F_POP_VALUE F_DUP
  691. %token F_STORE F_CALL_FUNCTION_BY_ADDRESS
  692. %token F_PUSH_IDENTIFIER_LVALUE F_PUSH_LOCAL_VARIABLE_LVALUE
  693. %token F_PUSH_INDEXED_LVALUE F_INDIRECT F_INDEX_INSTR
  694. %token F_CONST0 F_CONST1
  695.  
  696. /*
  697.  * These are the predefined functions that can be accessed from LPC.
  698.  */
  699.  
  700. %token F_IF F_IDENTIFIER F_LAND F_LOR F_STATUS
  701. %token F_RETURN F_STRING
  702. %token F_INC F_DEC
  703. %token F_POST_INC F_POST_DEC F_COMMA
  704. %token F_NUMBER F_ASSIGN F_INT F_ADD F_SUBTRACT F_MULTIPLY
  705. %token F_DIVIDE F_LT F_GT F_EQ F_GE F_LE
  706. %token F_NE
  707. %token F_ADD_EQ F_SUB_EQ F_DIV_EQ F_MULT_EQ
  708. %token F_NEGATE
  709. %token F_SUBSCRIPT F_WHILE F_BREAK
  710. %token F_DO F_FOR F_SWITCH
  711. %token F_SSCANF F_PARSE_COMMAND F_STRING_DECL F_LOCAL_NAME
  712. %token F_ELSE F_DESCRIBE
  713. %token F_CONTINUE
  714. %token F_MOD F_MOD_EQ F_INHERIT F_COLON_COLON
  715. %token F_STATIC
  716. %token F_ARROW F_AGGREGATE
  717. %token F_COMPL F_AND F_AND_EQ F_OR F_OR_EQ F_XOR F_XOR_EQ
  718. %token F_LSH F_LSH_EQ F_RSH F_RSH_EQ
  719. %token F_CATCH
  720. %token F_OBJECT F_VOID F_MIXED F_PRIVATE F_NO_MASK F_NOT
  721. %token F_PROTECTED F_PUBLIC
  722. %token F_VARARGS
  723.