]> git.xonotic.org Git - xonotic/gmqcc.git/blob - gmqcc.h
initial commit
[xonotic/gmqcc.git] / gmqcc.h
1 /*
2  * Compiler error system, this handles the error printing, and managing
3  * such as after so many errors just stop the compilation, and other
4  * intereting like colors for the console.
5  */
6 #ifndef DPQCC_HDR
7 #define DPQCC_HDR
8 #include <stdio.h>
9
10 /* The types supported by the language */
11 #define TYPE_VOID     0
12 #define TYPE_STRING   1
13 #define TYPE_FLOAT    2
14 #define TYPE_VECTOR   3
15 #define TYPE_ENTITY   4
16 #define TYPE_FIELD    5
17 #define TYPE_FUNCTION 6
18 #define TYPE_POINTER  7
19
20 /*
21  * there are 3 accessible memory zones -
22  * globals
23  *     array of 32bit ints/floats, mixed, LE,
24  * entities
25  *     structure is up to the engine but the fields are a linear array
26  *     of mixed ints/floats, there are globals referring to the offsets
27  *     of these in the entity struct so there are ADDRESS and STOREP and
28  *     LOAD instructions that use globals containing field offsets.
29  * strings
30  *     a static array in the progs.dat, with file parsing creating
31  *     additional constants, and some engine fields are mapped by 
32  *     address as well to unique string offsets
33  */
34  
35 /* 
36  * Instructions 
37  * These are the external instructions supported by the interperter
38  * this is what things compile to (from the C code). This is not internal
39  * instructions for support like int, and such (which are translated)
40  */
41 #define INSTR_DONE      0
42 // math
43 #define INSTR_MUL_F     1 /* multiplication float         */
44 #define INSTR_MUL_V     2 /* multiplication vector        */
45 #define INSTR_MUL_FV    3 /* multiplication float->vector */
46 #define INSTR_MUL_VF    4 /* multiplication vector->float */
47 #define INSTR_DIV_F     5
48 #define INSTR_ADD_F     6
49 #define INSTR_ADD_V     7
50 #define INSTR_SUB_F     8
51 #define INSTR_SUB_V     9
52 // compare
53 #define INSTR_EQ_F      10
54 #define INSTR_EQ_V      11
55 #define INSTR_EQ_S      12
56 #define INSTR_EQ_E      13
57 #define INSTR_EQ_FNC    14
58 #define INSTR_NE_F      15
59 #define INSTR_NE_V      16
60 #define INSTR_NE_S      17
61 #define INSTR_NE_E      18
62 #define INSTR_NE_FNC    19
63 // multi compare
64 #define INSTR_LE        20
65 #define INSTR_GE        21
66 #define INSTR_LT        22
67 #define INSTR_GT        23
68 // load and store
69 #define INSTR_LOAD_F    24
70 #define INSTR_LOAD_V    25
71 #define INSTR_LOAD_S    26
72 #define INSTR_LOAD_ENT  27
73 #define INSTR_LOAD_FLD  28
74 #define INSTR_LOAD_FNC  29
75 #define INSTR_STORE_F   31
76 #define INSTR_STORE_V   32
77 #define INSTR_STORE_S   33
78 #define INSTR_STORE_ENT 34
79 #define INSTR_STORE_FLD 35
80 #define INSTR_STORE_FNC 36
81 // others
82 #define INSTR_ADDRESS   30
83 #define INSTR_RETURN    37
84 #define INSTR_NOT_F     38
85 #define INSTR_NOT_V     39
86 #define INSTR_NOT_S     40
87 #define INSTR_NOT_ENT   41
88 #define INSTR_NOT_FNC   42
89 #define INSTR_IF        43
90 #define INSTR_IFNOT     44
91 #define INSTR_CALL0     45
92 #define INSTR_CALL1     46
93 #define INSTR_CALL2     47
94 #define INSTR_CALL3     48
95 #define INSTR_CALL4     49
96 #define INSTR_CALL5     50
97 #define INSTR_CALL6     51
98 #define INSTR_CALL7     52
99 #define INSTR_CALL8     53
100 #define INSTR_STATE     54
101 #define INSTR_GOTO      55
102 #define INSTR_AND       56
103 #define INSTR_OR        57
104 #define INSTR_BITAND    59
105 #define INSTR_BITOR     60
106
107 #define mem_a(x) malloc(x)
108 #define mem_d(x) free  (x)
109
110 /*
111  * This is the smallest lexer I've ever wrote: and I must say, it's quite
112  * more nicer than those large bulky complex parsers that most people write
113  * which has some sort of a complex state.
114  */
115 struct lex_file {
116         /*
117          * This is a simple state for lexing, no need to be complex for qc
118          * code.  It's trivial stuff.
119          */
120         FILE *file;
121         char  peek[5]; /* extend for depthier peeks */
122         int   last;
123         int   current;
124         int   length;
125         int   size;
126         char  lastok[8192]; /* No token shall ever be bigger than this! */
127 };
128
129 /*
130  * It's important that this table never exceed 32 keywords, the ascii
131  * table starts at 33 (which we need)
132  */
133 #define TOKEN_DO       0
134 #define TOKEN_ELSE     1
135 #define TOKEN_IF       2
136 #define TOKEN_WHILE    3
137 #define TOKEN_BREAK    4
138 #define TOKEN_CONTINUE 5
139 #define TOKEN_RETURN   6
140 #define TOKEN_GOTO     7
141 #define TOKEN_FOR      8
142
143 /*
144  * Lexer state constants, these are numbers for where exactly in
145  * the lexing the lexer is at. Or where it decided to stop if a lexer
146  * error occurs.
147  */
148 #define LEX_COMMENT  128 /* higher than ascii */
149 #define LEX_CHRLIT   129
150 #define LEX_STRLIT   130
151 #define LEX_IDENT    131
152 #define LEX_DO       132
153 #define LEX_ELSE     133
154 #define LEX_IF       134
155 #define LEX_WHILE    135
156 #define LEX_INCLUDE  136
157 #define LEX_DEFINE   137
158
159 int              lex_token(struct lex_file *);
160 void             lex_reset(struct lex_file *);
161 int              lex_debug(struct lex_file *);
162 int              lex_close(struct lex_file *);
163 struct lex_file *lex_open (const char *);
164
165 /* errors */
166 #define ERROR_LEX      (SHRT_MAX+0)
167 #define ERROR_PARSE    (SHRT_MAX+1)
168 #define ERROR_INTERNAL (SHRT_MAX+2)
169 int error(int, const char *, ...);
170
171 /* parse.c */
172 int parse(struct lex_file *);
173
174 #endif