+int error(lex_file *, int, const char *, ...);
+
+/*===================================================================*/
+/*========================== parse.c ================================*/
+/*===================================================================*/
+int parse_gen(lex_file *);
+
+/*===================================================================*/
+/*========================== typedef.c ==============================*/
+/*===================================================================*/
+typedef struct typedef_node_t {
+ char *name;
+} typedef_node;
+
+void typedef_init();
+void typedef_clear();
+typedef_node *typedef_find(const char *);
+int typedef_add (lex_file *file, const char *, const char *);
+
+
+/*===================================================================*/
+/*=========================== util.c ================================*/
+/*===================================================================*/
+void *util_memory_a (unsigned int, unsigned int, const char *);
+void util_memory_d (void *, unsigned int, const char *);
+void util_meminfo ();
+
+bool util_strupper (const char *);
+bool util_strdigit (const char *);
+char *util_strdup (const char *);
+char *util_strrq (const char *);
+char *util_strrnl (const char *);
+char *util_strsws (const char *);
+char *util_strchp (const char *, const char *);
+void util_debug (const char *, const char *, ...);
+int util_getline (char **, size_t *, FILE *);
+void util_endianswap (void *, int, int);
+
+uint32_t util_crc32(const char *, int, register const short);
+
+#ifdef NOTRACK
+# define mem_a(x) malloc(x)
+# define mem_d(x) free (x)
+#else
+# define mem_a(x) util_memory_a((x), __LINE__, __FILE__)
+# define mem_d(x) util_memory_d((x), __LINE__, __FILE__)
+#endif
+
+/*
+ * TODO: make these safer to use. Currently this only works on
+ * x86 and x86_64, some systems will likely not like this. Such
+ * as BE systems.
+ */
+#define FLT2INT(Y) *((int32_t*)&(Y))
+#define INT2FLT(Y) *((float *)&(Y))
+
+/* Builds vector type (usefull for inside structures) */
+#define VECTOR_SNAP(X,Y) X ## Y
+#define VECTOR_FILL(X,Y) VECTOR_SNAP(X,Y)
+#define VECTOR_TYPE(T,N) \
+ T* N##_data = NULL; \
+ long N##_elements = 0; \
+ long N##_allocated = 0
+/* Builds vector add */
+#define VECTOR_CORE(T,N) \
+ int N##_add(T element) { \
+ void *temp = NULL; \
+ if (N##_elements == N##_allocated) { \
+ if (N##_allocated == 0) { \
+ N##_allocated = 12; \
+ } else { \
+ N##_allocated *= 2; \
+ } \
+ if (!(temp = mem_a(N##_allocated * sizeof(T)))) { \
+ mem_d(temp); \
+ return -1; \
+ } \
+ memcpy(temp, N##_data, (N##_elements * sizeof(T))); \
+ mem_d(N##_data); \
+ N##_data = (T*)temp; \
+ } \
+ N##_data[N##_elements] = element; \
+ return N##_elements++; \
+ } \
+ int N##_put(T* elements, size_t len) { \
+ len --; \
+ elements--; \
+ while (N##_add(*++elements) != -1 && len--); \
+ return N##_elements; \
+ } \
+ typedef char VECTOR_FILL(extra_semicolon_,__COUNTER__)
+#define VECTOR_PROT(T,N) \
+ extern T* N##_data ; \
+ extern long N##_elements ; \
+ extern long N##_allocated; \
+ int N##_add(T); \
+ int N##_put(T *, size_t)
+#define VECTOR_MAKE(T,N) \
+ VECTOR_TYPE(T,N); \
+ VECTOR_CORE(T,N)
+
+/*===================================================================*/
+/*=========================== code.c ================================*/
+/*===================================================================*/
+enum {
+ TYPE_VOID ,
+ TYPE_STRING ,
+ TYPE_FLOAT ,
+ TYPE_VECTOR ,
+ TYPE_ENTITY ,
+ TYPE_FIELD ,
+ TYPE_FUNCTION ,
+ TYPE_POINTER ,
+ /* TYPE_INTEGER , */
+ TYPE_VARIANT
+};
+
+/*
+ * Each paramater incerements by 3 since vector types hold
+ * 3 components (x,y,z).
+ */
+#define OFS_NULL 0
+#define OFS_RETURN 1
+#define OFS_PARM0 (OFS_RETURN+3)
+#define OFS_PARM1 (OFS_PARM0 +3)
+#define OFS_PARM2 (OFS_PARM1 +3)
+#define OFS_PARM3 (OFS_PARM2 +3)
+#define OFS_PARM4 (OFS_PARM3 +3)
+#define OFS_PARM5 (OFS_PARM4 +3)
+#define OFS_PARM6 (OFS_PARM5 +3)
+#define OFS_PARM7 (OFS_PARM6 +3)
+
+typedef struct {
+ uint16_t opcode;
+
+ /* operand 1 */
+ union {
+ int16_t s1; /* signed */
+ uint16_t u1; /* unsigned */
+ } o1;
+ /* operand 2 */
+ union {
+ int16_t s1; /* signed */
+ uint16_t u1; /* unsigned */
+ } o2;
+ /* operand 3 */
+ union {
+ int16_t s1; /* signed */
+ uint16_t u1; /* unsigned */
+ } o3;
+
+ /*
+ * This is the same as the structure in darkplaces
+ * {
+ * unsigned short op;
+ * short a,b,c;
+ * }
+ * But this one is more sane to work with, and the
+ * type sizes are guranteed.
+ */
+} prog_section_statement;
+
+typedef struct {
+ /* The types:
+ * 0 = ev_void
+ * 1 = ev_string
+ * 2 = ev_float
+ * 3 = ev_vector
+ * 4 = ev_entity
+ * 5 = ev_field
+ * 6 = ev_function
+ * 7 = ev_pointer -- engine only
+ * 8 = ev_bad -- engine only
+ */
+ uint16_t type;
+ uint16_t offset;
+ uint32_t name;
+} prog_section_both;
+typedef prog_section_both prog_section_def;
+typedef prog_section_both prog_section_field;
+
+typedef struct {
+ int32_t entry; /* in statement table for instructions */
+ uint32_t firstlocal; /* First local in local table */
+ uint32_t locals; /* Total ints of params + locals */
+ uint32_t profile; /* Always zero (engine uses this) */
+ uint32_t name; /* name of function in string table */
+ uint32_t file; /* file of the source file */
+ uint32_t nargs; /* number of arguments */
+ uint8_t argsize[8]; /* size of arguments (keep 8 always?) */
+} prog_section_function;
+
+/*
+ * Instructions
+ * These are the external instructions supported by the interperter
+ * this is what things compile to (from the C code).
+ */
+enum {
+ INSTR_DONE,
+ INSTR_MUL_F,
+ INSTR_MUL_V,
+ INSTR_MUL_FV,
+ INSTR_MUL_VF,
+ INSTR_DIV_F,
+ INSTR_ADD_F,
+ INSTR_ADD_V,
+ INSTR_SUB_F,
+ INSTR_SUB_V,
+ INSTR_EQ_F,
+ INSTR_EQ_V,
+ INSTR_EQ_S,
+ INSTR_EQ_E,
+ INSTR_EQ_FNC,
+ INSTR_NE_F,
+ INSTR_NE_V,
+ INSTR_NE_S,
+ INSTR_NE_E,
+ INSTR_NE_FNC,
+ INSTR_LE,
+ INSTR_GE,
+ INSTR_LT,
+ INSTR_GT,
+ INSTR_LOAD_F,
+ INSTR_LOAD_V,
+ INSTR_LOAD_S,
+ INSTR_LOAD_ENT,
+ INSTR_LOAD_FLD,
+ INSTR_LOAD_FNC,
+ INSTR_ADDRESS,
+ INSTR_STORE_F,
+ INSTR_STORE_V,
+ INSTR_STORE_S,
+ INSTR_STORE_ENT,
+ INSTR_STORE_FLD,
+ INSTR_STORE_FNC,
+ INSTR_STOREP_F,
+ INSTR_STOREP_V,
+ INSTR_STOREP_S,
+ INSTR_STOREP_ENT,
+ INSTR_STOREP_FLD,
+ INSTR_STOREP_FNC,
+ INSTR_RETURN,
+ INSTR_NOT_F,
+ INSTR_NOT_V,
+ INSTR_NOT_S,
+ INSTR_NOT_ENT,
+ INSTR_NOT_FNC,
+ INSTR_IF,
+ INSTR_IFNOT,
+ INSTR_CALL0,
+ INSTR_CALL1,
+ INSTR_CALL2,
+ INSTR_CALL3,
+ INSTR_CALL4,
+ INSTR_CALL5,
+ INSTR_CALL6,
+ INSTR_CALL7,
+ INSTR_CALL8,
+ INSTR_STATE,
+ INSTR_GOTO,
+ INSTR_AND,
+ INSTR_OR,
+ INSTR_BITAND,
+ INSTR_BITOR,
+
+ /*
+ * Virtual instructions used by the assembler
+ * keep at the end but before virtual instructions
+ * for the IR below.
+ */
+ AINSTR_END,
+
+ /*
+ * Virtual instructions used by the IR
+ * Keep at the end!
+ */
+ VINSTR_PHI,
+ VINSTR_JUMP,
+ VINSTR_COND
+};
+
+/*
+ * The symbols below are created by the following
+ * expanded macros:
+ *
+ * VECTOR_MAKE(prog_section_statement, code_statements);
+ * VECTOR_MAKE(prog_section_def, code_defs );
+ * VECTOR_MAKE(prog_section_field, code_fields );
+ * VECTOR_MAKE(prog_section_function, code_functions );
+ * VECTOR_MAKE(int, code_globals );
+ * VECTOR_MAKE(char, code_chars );
+ */
+VECTOR_PROT(prog_section_statement, code_statements);
+VECTOR_PROT(prog_section_statement, code_statements);
+VECTOR_PROT(prog_section_def, code_defs );
+VECTOR_PROT(prog_section_field, code_fields );
+VECTOR_PROT(prog_section_function, code_functions );
+VECTOR_PROT(int, code_globals );
+VECTOR_PROT(char, code_chars );