home *** CD-ROM | disk | FTP | other *** search
/ Dream 57 / Amiga_Dream_57.iso / Amiga / Programmation / c / QuakeC / qtools0.2-src.lha / src / libqbuild / qcc.h < prev    next >
Encoding:
C/C++ Source or Header  |  1998-07-13  |  14.0 KB  |  491 lines

  1. #ifndef    QCC_H
  2. #define    QCC_H
  3.  
  4. /*
  5.  * ============================================================================
  6.  * 
  7.  * TODO:
  8.  * 
  9.  * "stopped at 10 errors"
  10.  * 
  11.  * other pointer types for models and clients?
  12.  * 
  13.  * compact string heap?
  14.  * 
  15.  * allways initialize all variables to something safe
  16.  * 
  17.  * the def->type->type arrangement is really silly.
  18.  * 
  19.  * return type checking
  20.  * 
  21.  * parm count type checking
  22.  * 
  23.  * immediate overflow checking
  24.  * 
  25.  * pass the first two parms in call->b and call->c
  26.  * 
  27.  * ============================================================================
  28.  */
  29.  
  30. /*
  31.  * ============================================================================
  32.  * 
  33.  * comments
  34.  * --------
  35.  * // comments discard text until the end of line
  36.  * / *  * / comments discard all enclosed text (spaced out on this line because this documentation is in a regular C comment block, and typing them in normally causes a parse error)
  37.  * 
  38.  * code structure
  39.  * --------------
  40.  * A definition is:
  41.  * <type> <name> [ = <immediate>] {, <name> [ = <immediate>] };
  42.  * 
  43.  * 
  44.  * types
  45.  * -----
  46.  * simple types: void, float, vector, string, or entity
  47.  * float                width, height;
  48.  * string               name;
  49.  * entity               self, other;
  50.  * 
  51.  * vector types:
  52.  * vector               org;    // also creates org_x, org_y, and org_z float defs
  53.  * 
  54.  * 
  55.  * A function type is specified as:     simpletype ( type name {,type name} )
  56.  * The names are ignored except when the function is initialized.       
  57.  * void()               think;
  58.  * entity()     FindTarget;
  59.  * void(vector destination, float speed, void() callback)       SUB_CalcMove;
  60.  * void(...)    dprint;         // variable argument builtin
  61.  * 
  62.  * A field type is specified as:  .type
  63.  * .vector              origin;
  64.  * .string              netname;
  65.  * .void()              think, touch, use;
  66.  * 
  67.  * 
  68.  * names
  69.  * -----
  70.  * Names are a maximum of 64 characters, must begin with A-Z,a-z, or _, and can continue with those characters or 0-9.
  71.  * 
  72.  * There are two levels of scoping: global, and function.  The parameter list of a function and any vars declared inside a function with the "local" statement are only visible within that function, 
  73.  * 
  74.  * 
  75.  * immediates
  76.  * ----------
  77.  * Float immediates must begin with 0-9 or minus sign.  .5 is illegal.
  78.  * 
  79.  * A parsing ambiguity is present with negative constants. "a-5" will be parsed as "a", then "-5", causing an error.  Seperate the - from the digits with a space "a - 5" to get the proper behavior.
  80.  * 12
  81.  * 1.6
  82.  * 0.5
  83.  * -100
  84.  * 
  85.  * Vector immediates are three float immediates enclosed in single quotes.
  86.  * '0 0 0'
  87.  * '20.5 -10 0.00001'
  88.  * 
  89.  * String immediates are characters enclosed in double quotes.  The string cannot contain explicit newlines, but the escape character \n can embed one.  The \" escape can be used to include a quote in the string.
  90.  * "maps/jrwiz1.bsp"
  91.  * "sound/nin/pain.wav"
  92.  * "ouch!\n"
  93.  * 
  94.  * Code immediates are statements enclosed in {} braces.
  95.  * statement:
  96.  * { <multiple statements> }
  97.  * <expression>;
  98.  * local <type> <name> [ = <immediate>] {, <name> [ = <immediate>] };
  99.  * return <expression>;
  100.  * if ( <expression> ) <statement> [ else <statement> ];
  101.  * while ( <expression> ) <statement>;
  102.  * do <statement> while ( <expression> );
  103.  * <function name> ( <function parms> );
  104.  * 
  105.  * expression:
  106.  * combiations of names and these operators with standard C precedence:
  107.  * "&&", "||", "<=", ">=","==", "!=", "!", "*", "/", "-", "+", "=", ".", "<", ">", "&", "|"
  108.  * Parenthesis can be used to alter order of operation.
  109.  * The & and | operations perform integral bit ops on floats
  110.  * 
  111.  * A built in function immediate is a number sign followed by an integer.
  112.  * #1
  113.  * #12
  114.  * 
  115.  * 
  116.  * compilation
  117.  * -----------
  118.  * Source files are processed sequentially without dumping any state, so if a defs file is the first one processed, the definitions will be available to all other files.
  119.  * 
  120.  * The language is strongly typed and there are no casts.
  121.  * 
  122.  * Anything that is initialized is assumed to be constant, and will have immediates folded into it.  If you change the value, your program will malfunction.  All uninitialized globals will be saved to savegame files.
  123.  * 
  124.  * Functions cannot have more than eight parameters.
  125.  * 
  126.  * Error recovery during compilation is minimal.  It will skip to the next global definition, so you will never see more than one error at a time in a given function.  All compilation aborts after ten error messages.
  127.  * 
  128.  * Names can be defined multiple times until they are defined with an initialization, allowing functions to be prototyped before their definition.
  129.  * 
  130.  * void()       MyFunction;                     // the prototype
  131.  * 
  132.  * void()       MyFunction =            // the initialization
  133.  * {
  134.  * dprint ("we're here\n");
  135.  * };
  136.  * 
  137.  * 
  138.  * entities and fields
  139.  * -------------------
  140.  * 
  141.  * 
  142.  * execution
  143.  * ---------
  144.  * Code execution is initiated by C code in quake from two main places:  the timed think routines for periodic control, and the touch function when two objects impact each other.
  145.  * 
  146.  * There are three global variables that are set before beginning code execution:
  147.  * entity       world;          // the server's world object, which holds all global
  148.  * // state for the server, like the deathmatch flags
  149.  * // and the body ques.
  150.  * entity       self;           // the entity the function is executing for
  151.  * entity       other;          // the other object in an impact, not used for thinks
  152.  * float        time;           // the current game time.  Note that because the
  153.  * // entities in the world are simulated sequentially,
  154.  * // time is NOT strictly increasing.  An impact late
  155.  * // in one entity's time slice may set time higher
  156.  * // than the think function of the next entity. 
  157.  * // The difference is limited to 0.1 seconds.
  158.  * Execution is also caused by a few uncommon events, like the addition of a new client to an existing server.
  159.  * 
  160.  * There is a runnaway counter that stops a program if 100000 statements are executed, assuming it is in an infinite loop.
  161.  * 
  162.  * It is acceptable to change the system set global variables.  This is usually done to pose as another entity by changing self and calling a function.
  163.  * 
  164.  * The interpretation is fairly efficient, but it is still over an order of magnitude slower than compiled C code.  All time consuming operations should be made into built in functions.
  165.  * 
  166.  * A profile counter is kept for each function, and incremented for each interpreted instruction inside that function.  The "profile" console command in Quake will dump out the top 10 functions, then clear all the counters.  The "profile all" command will dump sorted stats for every function that has been executed.
  167.  * 
  168.  * 
  169.  * afunc ( 4, bfunc(1,2,3));
  170.  * will fail because there is a shared parameter marshaling area, which will cause the 1 from bfunc to overwrite the 4 allready placed in parm0.  When a function is called, it copies the parms from the globals into it's privately scoped variables, so there is no collision when calling another function.
  171.  * 
  172.  * total = factorial(3) + factorial(4);
  173.  * Will fail because the return value from functions is held in a single global area.  If this really gets on your nerves, tell me and I can work around it at a slight performance and space penalty by allocating a new register for the function call and copying it out.
  174.  * 
  175.  * 
  176.  * built in functions
  177.  * ------------------
  178.  * void(string text)    dprint;
  179.  * Prints the string to the server console.
  180.  * 
  181.  * void(entity client, string text)     cprint;
  182.  * Prints a message to a specific client.
  183.  * 
  184.  * void(string text)    bprint;
  185.  * Broadcast prints a message to all clients on the current server.
  186.  * 
  187.  * entity()     spawn;
  188.  * Returns a totally empty entity.  You can manually set everything up, or just set the origin and call one of the existing entity setup functions.
  189.  * 
  190.  * entity(entity start, .string field, string match) find;
  191.  * Searches the server entity list beginning at start, looking for an entity that has entity.field = match.  To start at the beginning of the list, pass world.  World is returned when the end of the list is reached.
  192.  * 
  193.  * <FIXME: define all the other functions...>
  194.  * 
  195.  * 
  196.  * gotchas
  197.  * -------
  198.  * 
  199.  * The && and || operators DO NOT EARLY OUT like C!
  200.  * 
  201.  * Don't confuse single quoted vectors with double quoted strings
  202.  * 
  203.  * The function declaration syntax takes a little getting used to.
  204.  * 
  205.  * Don't forget the ; after the trailing brace of a function initialization.
  206.  * 
  207.  * Don't forget the "local" before defining local variables.
  208.  * 
  209.  * There are no ++ / -- operators, or operate/assign operators.
  210.  * 
  211.  * ============================================================================
  212.  */
  213.  
  214. #define    MAX_ERRORS        10
  215. #define    MAX_NAME        64                /* chars long */
  216. #define    MAX_REGS        16384
  217.  
  218. #define    MAX_FRAMES        256
  219.  
  220. #define    MAX_STRINGS        500000
  221. #define    MAX_GLOBALS        16384
  222. #define    MAX_FIELDS        1024
  223. #define    MAX_STATEMENTS        65536
  224. #define    MAX_FUNCTIONS        8192
  225.  
  226. #define    MAX_SOUNDS        1024
  227. #define    MAX_MODELS        1024
  228. #define    MAX_FILES        1024
  229. #define    MAX_DATA_PATH        64
  230.  
  231. #define    MAX_PARMS    8
  232.  
  233. #define    TOP_PRIORITY    6
  234. #define    NOT_PRIORITY    4
  235.  
  236. /*============================================================================ */
  237.  
  238. typedef int func_t;
  239. typedef int string_t;
  240.  
  241. typedef enum {
  242.   ev_void, ev_string, ev_float, ev_vector, ev_entity, ev_field, ev_function, ev_pointer
  243. } __packed etype_t;
  244.  
  245. #define    OFS_NULL        0
  246. #define    OFS_RETURN        1
  247. #define    OFS_PARM0        4                /* leave 3 ofs for each parm to hold vectors */
  248. #define    OFS_PARM1        7
  249. #define    OFS_PARM2        10
  250. #define    OFS_PARM3        13
  251. #define    OFS_PARM4        16
  252. #define    OFS_PARM5        19
  253. #define    OFS_PARM6        22
  254. #define    OFS_PARM7        25
  255. #define    RESERVED_OFS        28
  256.  
  257. enum {
  258.   OP_DONE,
  259.   OP_MUL_F,
  260.   OP_MUL_V,
  261.   OP_MUL_FV,
  262.   OP_MUL_VF,
  263.   OP_DIV_F,
  264.   OP_ADD_F,
  265.   OP_ADD_V,
  266.   OP_SUB_F,
  267.   OP_SUB_V,
  268.  
  269.   OP_EQ_F,
  270.   OP_EQ_V,
  271.   OP_EQ_S,
  272.   OP_EQ_E,
  273.   OP_EQ_FNC,
  274.  
  275.   OP_NE_F,
  276.   OP_NE_V,
  277.   OP_NE_S,
  278.   OP_NE_E,
  279.   OP_NE_FNC,
  280.  
  281.   OP_LE,
  282.   OP_GE,
  283.   OP_LT,
  284.   OP_GT,
  285.  
  286.   OP_LOAD_F,
  287.   OP_LOAD_V,
  288.   OP_LOAD_S,
  289.   OP_LOAD_ENT,
  290.   OP_LOAD_FLD,
  291.   OP_LOAD_FNC,
  292.  
  293.   OP_ADDRESS,
  294.  
  295.   OP_STORE_F,
  296.   OP_STORE_V,
  297.   OP_STORE_S,
  298.   OP_STORE_ENT,
  299.   OP_STORE_FLD,
  300.   OP_STORE_FNC,
  301.  
  302.   OP_STOREP_F,
  303.   OP_STOREP_V,
  304.   OP_STOREP_S,
  305.   OP_STOREP_ENT,
  306.   OP_STOREP_FLD,
  307.   OP_STOREP_FNC,
  308.  
  309.   OP_RETURN,
  310.   OP_NOT_F,
  311.   OP_NOT_V,
  312.   OP_NOT_S,
  313.   OP_NOT_ENT,
  314.   OP_NOT_FNC,
  315.   OP_IF,
  316.   OP_IFNOT,
  317.   OP_CALL0,
  318.   OP_CALL1,
  319.   OP_CALL2,
  320.   OP_CALL3,
  321.   OP_CALL4,
  322.   OP_CALL5,
  323.   OP_CALL6,
  324.   OP_CALL7,
  325.   OP_CALL8,
  326.   OP_STATE,
  327.   OP_GOTO,
  328.   OP_AND,
  329.   OP_OR,
  330.  
  331.   OP_BITAND,
  332.   OP_BITOR
  333. } __packed;
  334.  
  335. typedef struct statement_s {
  336.   unsigned short int op;
  337.   short int a, b, c;
  338. } __packed dstatement_t;
  339.  
  340. typedef struct {
  341.   unsigned short int type;                    /* if DEF_SAVEGLOBGAL bit is set */
  342.   /* the variable needs to be saved in savegames */
  343.  
  344.   unsigned short int ofs;
  345.   int s_name;
  346. } __packed ddef_t;
  347.  
  348. #define    DEF_SAVEGLOBGAL    (1<<15)
  349.  
  350. typedef struct {
  351.   int first_statement;                        /* negative numbers are builtins */
  352.  
  353.   int parm_start;
  354.   int locals;                            /* total ints of parms + locals */
  355.  
  356.   int profile;                            /* runtime */
  357.  
  358.   int s_name;
  359.   int s_file;                            /* source file defined in */
  360.  
  361.   int numparms;
  362.   unsigned char parm_size[MAX_PARMS];
  363. } __packed dfunction_t;
  364.  
  365. #define    PROG_VERSION    6
  366. typedef struct {
  367.   int version;
  368.   int crc;                            /* check of header file */
  369.  
  370.   int ofs_statements;
  371.   int numstatements;                        /* statement 0 is an error */
  372.  
  373.   int ofs_globaldefs;
  374.   int numglobaldefs;
  375.  
  376.   int ofs_fielddefs;
  377.   int numfielddefs;
  378.  
  379.   int ofs_functions;
  380.   int numfunctions;                        /* function 0 is an empty */
  381.  
  382.   int ofs_strings;
  383.   int numstrings;                        /* first string is a null string */
  384.  
  385.   int ofs_globals;
  386.   int numglobals;
  387.  
  388.   int entityfields;
  389. } __packed dprograms_t;
  390.  
  391. /*============================================================================= */
  392.  
  393. /* offsets are allways multiplied by 4 before using */
  394. typedef int gofs_t;                        /* offset in global data block */
  395.  
  396. typedef struct function_s function_t;
  397.  
  398. typedef struct type_s {
  399.   etype_t type;
  400.   struct def_s *def;                        /* a def that points to this type */
  401.  
  402.   struct type_s *next;
  403.   /* function types are more complex */
  404.   struct type_s *aux_type;                    /* return type or field type */
  405.  
  406.   int num_parms;                        /* -1 = variable args */
  407.  
  408.   struct type_s *parm_types[MAX_PARMS];                /* only [num_parms] allocated */
  409.  
  410. } __packed type_t;
  411.  
  412. typedef struct def_s {
  413.   type_t *type;
  414.   char *name;
  415.   struct def_s *next, *prev;
  416.  
  417.   struct def_s *search_next;                    /* for finding faster */
  418.  
  419.   gofs_t ofs;
  420.   struct def_s *scope;                        /* function the var was defined in, or NULL */
  421.  
  422.   int initialized;                        /* 1 when a declaration included "= immediate" */
  423.  
  424. } __packed def_t;
  425.  
  426. /*============================================================================= */
  427.  
  428. typedef union eval_s {
  429.   string_t string;
  430.   float _float;
  431.   float vector[3];
  432.   func_t function;
  433.   int _int;
  434.   union eval_s *ptr;
  435. } __packed eval_t;
  436.  
  437. struct function_s {
  438.   int builtin;                            /* if non 0, call an internal function */
  439.  
  440.   int code;                            /* first statement */
  441.  
  442.   char *file;                            /* source file with definition */
  443.  
  444.   int file_line;
  445.   struct def_s *def;
  446.   int parm_ofs[MAX_PARMS];                    /* allways contiguous, right? */
  447.  
  448. } __packed;
  449.  
  450. /* */
  451. /* output generated by prog parsing */
  452. /* */
  453. typedef struct {
  454.   char *memory;
  455.   int max_memory;
  456.   int current_memory;
  457.   type_t *types;
  458.  
  459.   def_t *def_head;                        /* unused head of linked list */
  460.   def_t *def_tail;                        /* add new defs after this and move it */
  461.   def_t *search;                        /* search chain through defs */
  462.  
  463.   int size_fields;
  464. } __packed pr_info_t;
  465.  
  466. typedef struct {
  467.   char *name;
  468.   char *opname;
  469.   float priority;
  470.   bool right_associative;
  471.   def_t *type_a, *type_b, *type_c;
  472. } __packed opcode_t;
  473.  
  474. /*============================================================================ */
  475.  
  476. typedef enum {
  477.   tt_eof,                            /* end of file reached */
  478.   tt_name,                            /* an alphanumeric name token */
  479.   tt_punct,                            /* code punctuation */
  480.   tt_immediate                            /* string, float, vector */
  481. } __packed token_type_t;
  482.  
  483. #define    G_FLOAT(o) (pr_globals[o])
  484. #define    G_INT(o) (*(int *)&pr_globals[o])
  485. #define    G_VECTOR(o) (&pr_globals[o])
  486. #define    G_STRING(o) (strings + *(string_t *)&pr_globals[o])
  487. #define    G_FUNCTION(o) (*(func_t *)&pr_globals[o])
  488.  
  489. /*============================================================================= */
  490. #endif
  491.