/* * A compiled program consists of several data blocks, all allocated * contiguos in memory to enhance the working set. At the compilation, * the blocks will be allocated separately, as the final size is * unknow. When compilation is done, the blocks will be copied into * the one big area. * * 1. The program itself. Consists of machine code instructions for a virtual * stack machine. * 2. Function headers. This struct exists once for each written function. * It tells where in the program the function is, how many arguments it * takes number of local variables etc. etc. * 3. Function pointers. For every function in the program (even inherited * ones) there is a function pointer. It contains information about where * the function struct is, and some flags for the function. * 4. Function index. This is an array of shorts that points into the array * of function pointers. It is sorted on the pointer to the name of the * function. There is one short for each function that is callable from * other objects. This area is not present while compiling. * 5. String table. All strings used in the program. They are all pointers * into the shared string area. Thus, they are easily found and deallocated * when the object is destructed. * 6. Table of variable names. They all point into the shared string table. * Types are also stored here. * 7. Line number information. This is used at errors, to find out the * line number of the error. * 8. List of inherited objects. * 9. A list of constants used by the program. Only arrays, mappings * and lists apply. * 10. Switch information. (stored in mappings) * 11. a list of 'fast lookup' lfun pointers. */ /* * When an new object inherits from another, all function definitions * are copied, and all variable definitions. * Flags below can't explicitly declared. Flags that can be declared, * are found with TYPE_ below. * * When an object is compiled with type testing NAME_STRICT_TYPES, all * types are saved of the arguments for that function during compilation. * If the #pragma save_types is specified, then the types are saved even * after compilation, to be used when the object is inherited. */ #define NAME_INHERITED 0x1 /* Defined by inheritance */ #define NAME_UNDEFINED 0x2 /* Not defined yet */ #define NAME_STRICT_TYPES 0x4 /* Compiled with type testing */ #define NAME_HIDDEN 0x8 /* Not visible for inheritance */ #define NAME_PROTOTYPE 0x10 /* Defined by a prototype only */ #define LF_CATCH_TELL 0 #define LF_HEART_BEAT 1 #define LF_INIT 2 #define LF_EXIT 3 extern char **lfuns; extern int num_lfuns; struct function { char *name; unsigned int offset; /* Address of function */ unsigned short num_local; /* Number of local variables */ unsigned short num_arg; /* Number of arguments needed. -1 arguments means function not defined in this object. Probably inherited */ }; struct function_p { /* Access like this: * prog->inherit[this->prog].prog->functions[this->fun] */ unsigned short prog; unsigned short fun; unsigned short flags; /* NAME_ . See above. */ unsigned short type; /* Return type of function. See below. */ }; #define FUNC(PROG,X) \ ((PROG)->inherit[(PROG)->function_ptrs[X].prog].prog->functions+ \ (PROG)->function_ptrs[X].fun) struct inherit { unsigned short inherit_level; struct program *prog; unsigned short function_index_offset; unsigned short variable_index_offset; }; struct variable { char *name; unsigned short type; /* Type of variable. See below. TYPE_ */ unsigned char flags; /* Facts found by the compiler. NAME_ */ unsigned char rttype; /* run-time type */ }; struct program { int ref; /* Reference count */ #ifdef DEBUG int extra_ref; /* Used to verify ref count */ #endif int id; unsigned short flags; struct program *next_hash; char *program; /* The binary instructions */ char *name; /* Name of file that defined prog */ signed char *line_numbers; /* Line number information */ struct function *functions; struct function_p *function_ptrs; unsigned short *funindex; char **strings; /* All strings uses by the program */ struct variable *variable_names; /* All variables defined */ struct inherit *inherit; /* List of inherited prgms */ int total_size; /* Sum of all data in this struct */ struct vector **switch_mappings; struct svalue *constants; short *lfuns; /* * The types of function arguments are saved where 'argument_types' * points. It can be a variable number of arguments, so allocation * is done dynamically. To know where first argument is found for * function 'n' (number of function), use 'type_start[n]'. * These two arrays will only be allocated if '#pragma save_types' has * been specified. This #pragma should be specified in files that are * commonly used for inheritance. There are several lines of code * that depends on the type length (16 bits) of 'type_start' (sorry !). */ unsigned short *argument_types; #define INDEX_START_NONE 65535 unsigned short *type_start; /* * And now some general size information. */ unsigned short num_constants; unsigned short num_switch_mappings; unsigned short program_size; /* size of this instruction code */ unsigned short num_functions; unsigned short num_funindex; unsigned short num_function_ptrs; unsigned short num_strings; unsigned short num_variables; unsigned short num_inherited; unsigned short num_line_numbers; unsigned short num_lfuns; }; extern struct program *current_prog; /* * Types available. The number '0' is valid as any type. These types * are only used by the compiler, when type checks are enabled. Compare with * the run-time types, named T_ interpret.h. */ #define TYPE_UNKNOWN 0 /* This type must be casted */ #define TYPE_ANY 1 /* Will match any type */ #define TYPE_VOID 2 #define TYPE_NUMBER 3 #define TYPE_STRING 4 #define TYPE_OBJECT 5 #define TYPE_MAPPING 6 #define TYPE_LIST 7 #define TYPE_FUNCTION 8 #define TYPE_FLOAT 9 #define TYPE_REGULAR_EXPRESSION 10 /* * These are or'ed in on top of the basic type. */ #define TYPE_MOD_STATIC 0x0100 /* Static function or variable */ #define TYPE_MOD_NO_MASK 0x0200 /* The nomask => not redefineable */ #define TYPE_MOD_POINTER 0x0400 /* Pointer to a basic type */ #define TYPE_MOD_PRIVATE 0x0800 /* Can't be inherited */ #define TYPE_MOD_PROTECTED 0x1000 #define TYPE_MOD_PUBLIC 0x2000 /* Force inherit through private */ #define TYPE_MOD_VARARGS 0x4000 /* may take less args */ #define TYPE_MOD_CONSTANT 0x8000 /* Used for optimization */ #define TYPE_MOD_SIDE_EFFECT 0x80 /* Used for optimization */ #define TYPE_MOD_INLINE 0x40 /* Used for optimization */ #define TYPE_MOD_VA_ARGS 0x20 /* may take more args */ #define TYPE_MOD_MASK (~(TYPE_MOD_STATIC | TYPE_MOD_NO_MASK |\ TYPE_MOD_PRIVATE | TYPE_MOD_PROTECTED |\ TYPE_MOD_PUBLIC | TYPE_MOD_VARARGS |\ TYPE_MOD_CONSTANT | TYPE_MOD_SIDE_EFFECT|\ TYPE_MOD_INLINE | TYPE_MOD_VA_ARGS)) struct keyword { char *word; short token; short min_args; /* Minimum number of arguments. */ short max_args; /* Maximum number of arguments. */ short ret_type; /* The return type used by the compiler. */ short arg_type1; /* Type of argument 1 */ short arg_type2; /* Type of argument 2 */ int arg_index; /* Index pointing to where to find arg type */ short Default; /* an efun to use as default for last argument */ func_t efunc; /* what do we call? */ opcode_t opfunc; /* who you gonna call? */ }; int defined_function(char *s); int islocal(char *str);