b32573e0224dc8f68c2580e217614551da2d2bba
[mesa.git] / src / mesa / slang / slang_compile_operation.h
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5.2
4 *
5 * Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 #ifndef SLANG_COMPILE_OPERATION_H
26 #define SLANG_COMPILE_OPERATION_H
27
28
29 #include "main/compiler.h"
30 #include "main/glheader.h"
31 #include "slang_compile_variable.h"
32 #include "slang_utility.h"
33
34 /**
35 * Types of slang operations.
36 * These are the types of the AST (abstract syntax tree) nodes.
37 * [foo] indicates a sub-tree or reference to another type of node
38 */
39 typedef enum slang_operation_type_
40 {
41 SLANG_OPER_NONE,
42 SLANG_OPER_BLOCK_NO_NEW_SCOPE, /* "{" sequence "}" */
43 SLANG_OPER_BLOCK_NEW_SCOPE, /* "{" sequence "}" */
44 SLANG_OPER_VARIABLE_DECL, /* [type] [var] or [var] = [expr] */
45 SLANG_OPER_ASM,
46 SLANG_OPER_BREAK, /* "break" statement */
47 SLANG_OPER_CONTINUE, /* "continue" statement */
48 SLANG_OPER_DISCARD, /* "discard" (kill fragment) statement */
49 SLANG_OPER_RETURN, /* "return" [expr] */
50 SLANG_OPER_RETURN_INLINED, /* "return" [expr] from inlined function */
51 SLANG_OPER_LABEL, /* a jump target */
52 SLANG_OPER_EXPRESSION, /* [expr] */
53 SLANG_OPER_IF, /* "if" [0] then [1] else [2] */
54 SLANG_OPER_WHILE, /* "while" [cond] [body] */
55 SLANG_OPER_DO, /* "do" [body] "while" [cond] */
56 SLANG_OPER_FOR, /* "for" [init] [while] [incr] [body] */
57 SLANG_OPER_VOID, /* nop */
58 SLANG_OPER_LITERAL_BOOL, /* "true" or "false" */
59 SLANG_OPER_LITERAL_INT, /* integer literal */
60 SLANG_OPER_LITERAL_FLOAT, /* float literal */
61 SLANG_OPER_IDENTIFIER, /* var name, func name, etc */
62 SLANG_OPER_SEQUENCE, /* [expr] "," [expr] "," etc */
63 SLANG_OPER_ASSIGN, /* [var] "=" [expr] */
64 SLANG_OPER_ADDASSIGN, /* [var] "+=" [expr] */
65 SLANG_OPER_SUBASSIGN, /* [var] "-=" [expr] */
66 SLANG_OPER_MULASSIGN, /* [var] "*=" [expr] */
67 SLANG_OPER_DIVASSIGN, /* [var] "/=" [expr] */
68 /*SLANG_OPER_MODASSIGN, */
69 /*SLANG_OPER_LSHASSIGN, */
70 /*SLANG_OPER_RSHASSIGN, */
71 /*SLANG_OPER_ORASSIGN, */
72 /*SLANG_OPER_XORASSIGN, */
73 /*SLANG_OPER_ANDASSIGN, */
74 SLANG_OPER_SELECT, /* [expr] "?" [expr] ":" [expr] */
75 SLANG_OPER_LOGICALOR, /* [expr] "||" [expr] */
76 SLANG_OPER_LOGICALXOR, /* [expr] "^^" [expr] */
77 SLANG_OPER_LOGICALAND, /* [expr] "&&" [expr] */
78 /*SLANG_OPER_BITOR, */
79 /*SLANG_OPER_BITXOR, */
80 /*SLANG_OPER_BITAND, */
81 SLANG_OPER_EQUAL, /* [expr] "==" [expr] */
82 SLANG_OPER_NOTEQUAL, /* [expr] "!=" [expr] */
83 SLANG_OPER_LESS, /* [expr] "<" [expr] */
84 SLANG_OPER_GREATER, /* [expr] ">" [expr] */
85 SLANG_OPER_LESSEQUAL, /* [expr] "<=" [expr] */
86 SLANG_OPER_GREATEREQUAL, /* [expr] ">=" [expr] */
87 /*SLANG_OPER_LSHIFT, */
88 /*SLANG_OPER_RSHIFT, */
89 SLANG_OPER_ADD, /* [expr] "+" [expr] */
90 SLANG_OPER_SUBTRACT, /* [expr] "-" [expr] */
91 SLANG_OPER_MULTIPLY, /* [expr] "*" [expr] */
92 SLANG_OPER_DIVIDE, /* [expr] "/" [expr] */
93 /*SLANG_OPER_MODULUS, */
94 SLANG_OPER_PREINCREMENT, /* "++" [var] */
95 SLANG_OPER_PREDECREMENT, /* "--" [var] */
96 SLANG_OPER_PLUS, /* "-" [expr] */
97 SLANG_OPER_MINUS, /* "+" [expr] */
98 /*SLANG_OPER_COMPLEMENT, */
99 SLANG_OPER_NOT, /* "!" [expr] */
100 SLANG_OPER_SUBSCRIPT, /* [expr] "[" [expr] "]" */
101 SLANG_OPER_CALL, /* [func name] [param] [param] [...] */
102 SLANG_OPER_NON_INLINED_CALL, /* a real function call */
103 SLANG_OPER_METHOD, /* method call, such as v.length() */
104 SLANG_OPER_FIELD, /* i.e.: ".next" or ".xzy" or ".xxx" etc */
105 SLANG_OPER_POSTINCREMENT, /* [var] "++" */
106 SLANG_OPER_POSTDECREMENT /* [var] "--" */
107 } slang_operation_type;
108
109
110 /**
111 * A slang_operation is basically a compiled instruction (such as assignment,
112 * a while-loop, a conditional, a multiply, a function call, etc).
113 * The AST (abstract syntax tree) is built from these nodes.
114 * NOTE: This structure could have been implemented as a union of simpler
115 * structs which would correspond to the operation types above.
116 */
117 typedef struct slang_operation_
118 {
119 slang_operation_type type;
120 struct slang_operation_ *children;
121 GLuint num_children;
122 GLfloat literal[4]; /**< Used for float, int and bool values */
123 GLuint literal_size; /**< 1, 2, 3, or 4 */
124 slang_atom a_id; /**< type: asm, identifier, call, field */
125 slang_atom a_obj; /**< object in a method call */
126 slang_variable_scope *locals; /**< local vars for scope */
127 struct slang_function_ *fun; /**< If type == SLANG_OPER_CALL */
128 struct slang_variable_ *var; /**< If type == slang_oper_identier */
129 struct slang_label_ *label; /**< If type == SLANG_OPER_LABEL */
130 /** If type==SLANG_OPER_CALL and we're calling an array constructor,
131 * for which there's no real function, we need to have a flag to
132 * indicate such. num_children indicates number of elements.
133 */
134 GLboolean array_constructor;
135 } slang_operation;
136
137
138 extern GLboolean
139 slang_operation_construct(slang_operation *);
140
141 extern void
142 slang_operation_destruct(slang_operation *);
143
144 extern void
145 slang_replace_scope(slang_operation *oper,
146 slang_variable_scope *oldScope,
147 slang_variable_scope *newScope);
148
149 extern GLboolean
150 slang_operation_copy(slang_operation *, const slang_operation *);
151
152 extern slang_operation *
153 slang_operation_new(GLuint count);
154
155 extern void
156 slang_operation_delete(slang_operation *oper);
157
158 extern void
159 slang_operation_free_children(slang_operation *oper);
160
161 extern slang_operation *
162 slang_operation_grow(GLuint *numChildren, slang_operation **children);
163
164 extern slang_operation *
165 slang_operation_insert(GLuint *numChildren, slang_operation **children,
166 GLuint pos);
167
168 extern slang_operation *
169 slang_operation_insert_child(slang_operation *oper, GLuint pos);
170
171 extern void
172 _slang_operation_swap(slang_operation *oper0, slang_operation *oper1);
173
174
175 extern void
176 slang_operation_add_children(slang_operation *oper, GLuint num_children);
177
178
179 /** Return number of children of given node */
180 static INLINE GLuint
181 slang_oper_num_children(const slang_operation *oper)
182 {
183 return oper->num_children;
184 }
185
186 /** Return child of given operation node */
187 static INLINE slang_operation *
188 slang_oper_child(slang_operation *oper, GLuint child)
189 {
190 assert(child < oper->num_children);
191 return &oper->children[child];
192 }
193
194
195 /** Return child of given operation node, const version */
196 static INLINE const slang_operation *
197 slang_oper_child_const(const slang_operation *oper, GLuint child)
198 {
199 assert(child < oper->num_children);
200 return &oper->children[child];
201 }
202
203
204 /** Init oper to a boolean literal. */
205 static INLINE void
206 slang_operation_literal_bool(slang_operation *oper, GLboolean value)
207 {
208 oper->type = SLANG_OPER_LITERAL_BOOL;
209 oper->literal[0] =
210 oper->literal[1] =
211 oper->literal[2] =
212 oper->literal[3] = (float) value;
213 oper->literal_size = 1;
214 }
215
216
217 /** Init oper to an int literal. */
218 static INLINE void
219 slang_operation_literal_int(slang_operation *oper, GLint value)
220 {
221 oper->type = SLANG_OPER_LITERAL_INT;
222 oper->literal[0] =
223 oper->literal[1] =
224 oper->literal[2] =
225 oper->literal[3] = (float) value;
226 oper->literal_size = 1;
227 }
228
229
230 #endif /* SLANG_COMPILE_OPERATION_H */