nvfx: expose GLSL
[mesa/mesa-lb.git] / src / glsl / pp / sl_pp_expression.c
blobec904787dd77dfedf90ad8b46a00235ce1337e11
1 /**************************************************************************
2 *
3 * Copyright 2009 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
28 #include <stdlib.h>
29 #include <string.h>
30 #include "sl_pp_expression.h"
31 #include "sl_pp_public.h"
34 struct parse_context {
35 struct sl_pp_context *context;
36 const struct sl_pp_token_info *input;
39 static int
40 _parse_or(struct parse_context *ctx,
41 int *result);
43 static int
44 _parse_primary(struct parse_context *ctx,
45 int *result)
47 if (ctx->input->token == SL_PP_UINT) {
48 *result = atoi(sl_pp_context_cstr(ctx->context, ctx->input->data._uint));
49 ctx->input++;
50 } else {
51 if (ctx->input->token != SL_PP_LPAREN) {
52 strcpy(ctx->context->error_msg, "expected `('");
53 return -1;
55 ctx->input++;
56 if (_parse_or(ctx, result)) {
57 return -1;
59 if (ctx->input->token != SL_PP_RPAREN) {
60 strcpy(ctx->context->error_msg, "expected `)'");
61 return -1;
63 ctx->input++;
65 return 0;
68 static int
69 _parse_unary(struct parse_context *ctx,
70 int *result)
72 if (!_parse_primary(ctx, result)) {
73 return 0;
76 switch (ctx->input->token) {
77 case SL_PP_PLUS:
78 ctx->input++;
79 if (_parse_unary(ctx, result)) {
80 return -1;
82 *result = +*result;
83 break;
85 case SL_PP_MINUS:
86 ctx->input++;
87 if (_parse_unary(ctx, result)) {
88 return -1;
90 *result = -*result;
91 break;
93 case SL_PP_NOT:
94 ctx->input++;
95 if (_parse_unary(ctx, result)) {
96 return -1;
98 *result = !*result;
99 break;
101 case SL_PP_BITNOT:
102 ctx->input++;
103 if (_parse_unary(ctx, result)) {
104 return -1;
106 *result = ~*result;
107 break;
109 default:
110 return -1;
113 return 0;
116 static int
117 _parse_multiplicative(struct parse_context *ctx,
118 int *result)
120 if (_parse_unary(ctx, result)) {
121 return -1;
123 for (;;) {
124 int right;
126 switch (ctx->input->token) {
127 case SL_PP_STAR:
128 ctx->input++;
129 if (_parse_unary(ctx, &right)) {
130 return -1;
132 *result = *result * right;
133 break;
135 case SL_PP_SLASH:
136 ctx->input++;
137 if (_parse_unary(ctx, &right)) {
138 return -1;
140 *result = *result / right;
141 break;
143 case SL_PP_MODULO:
144 ctx->input++;
145 if (_parse_unary(ctx, &right)) {
146 return -1;
148 *result = *result % right;
149 break;
151 default:
152 return 0;
157 static int
158 _parse_additive(struct parse_context *ctx,
159 int *result)
161 if (_parse_multiplicative(ctx, result)) {
162 return -1;
164 for (;;) {
165 int right;
167 switch (ctx->input->token) {
168 case SL_PP_PLUS:
169 ctx->input++;
170 if (_parse_multiplicative(ctx, &right)) {
171 return -1;
173 *result = *result + right;
174 break;
176 case SL_PP_MINUS:
177 ctx->input++;
178 if (_parse_multiplicative(ctx, &right)) {
179 return -1;
181 *result = *result - right;
182 break;
184 default:
185 return 0;
190 static int
191 _parse_shift(struct parse_context *ctx,
192 int *result)
194 if (_parse_additive(ctx, result)) {
195 return -1;
197 for (;;) {
198 int right;
200 switch (ctx->input->token) {
201 case SL_PP_LSHIFT:
202 ctx->input++;
203 if (_parse_additive(ctx, &right)) {
204 return -1;
206 *result = *result << right;
207 break;
209 case SL_PP_RSHIFT:
210 ctx->input++;
211 if (_parse_additive(ctx, &right)) {
212 return -1;
214 *result = *result >> right;
215 break;
217 default:
218 return 0;
223 static int
224 _parse_relational(struct parse_context *ctx,
225 int *result)
227 if (_parse_shift(ctx, result)) {
228 return -1;
230 for (;;) {
231 int right;
233 switch (ctx->input->token) {
234 case SL_PP_LESSEQUAL:
235 ctx->input++;
236 if (_parse_shift(ctx, &right)) {
237 return -1;
239 *result = *result <= right;
240 break;
242 case SL_PP_GREATEREQUAL:
243 ctx->input++;
244 if (_parse_shift(ctx, &right)) {
245 return -1;
247 *result = *result >= right;
248 break;
250 case SL_PP_LESS:
251 ctx->input++;
252 if (_parse_shift(ctx, &right)) {
253 return -1;
255 *result = *result < right;
256 break;
258 case SL_PP_GREATER:
259 ctx->input++;
260 if (_parse_shift(ctx, &right)) {
261 return -1;
263 *result = *result > right;
264 break;
266 default:
267 return 0;
272 static int
273 _parse_equality(struct parse_context *ctx,
274 int *result)
276 if (_parse_relational(ctx, result)) {
277 return -1;
279 for (;;) {
280 int right;
282 switch (ctx->input->token) {
283 case SL_PP_EQUAL:
284 ctx->input++;
285 if (_parse_relational(ctx, &right)) {
286 return -1;
288 *result = *result == right;
289 break;
291 case SL_PP_NOTEQUAL:
292 ctx->input++;
293 if (_parse_relational(ctx, &right)) {
294 return -1;
296 *result = *result != right;
297 break;
299 default:
300 return 0;
305 static int
306 _parse_bitand(struct parse_context *ctx,
307 int *result)
309 if (_parse_equality(ctx, result)) {
310 return -1;
312 while (ctx->input->token == SL_PP_BITAND) {
313 int right;
315 ctx->input++;
316 if (_parse_equality(ctx, &right)) {
317 return -1;
319 *result = *result & right;
321 return 0;
324 static int
325 _parse_xor(struct parse_context *ctx,
326 int *result)
328 if (_parse_bitand(ctx, result)) {
329 return -1;
331 while (ctx->input->token == SL_PP_XOR) {
332 int right;
334 ctx->input++;
335 if (_parse_bitand(ctx, &right)) {
336 return -1;
338 *result = *result ^ right;
340 return 0;
343 static int
344 _parse_bitor(struct parse_context *ctx,
345 int *result)
347 if (_parse_xor(ctx, result)) {
348 return -1;
350 while (ctx->input->token == SL_PP_BITOR) {
351 int right;
353 ctx->input++;
354 if (_parse_xor(ctx, &right)) {
355 return -1;
357 *result = *result | right;
359 return 0;
362 static int
363 _parse_and(struct parse_context *ctx,
364 int *result)
366 if (_parse_bitor(ctx, result)) {
367 return -1;
369 while (ctx->input->token == SL_PP_AND) {
370 int right;
372 ctx->input++;
373 if (_parse_bitor(ctx, &right)) {
374 return -1;
376 *result = *result && right;
378 return 0;
381 static int
382 _parse_or(struct parse_context *ctx,
383 int *result)
385 if (_parse_and(ctx, result)) {
386 return -1;
388 while (ctx->input->token == SL_PP_OR) {
389 int right;
391 ctx->input++;
392 if (_parse_and(ctx, &right)) {
393 return -1;
395 *result = *result || right;
397 return 0;
401 sl_pp_execute_expression(struct sl_pp_context *context,
402 const struct sl_pp_token_info *input,
403 int *result)
405 struct parse_context ctx;
407 ctx.context = context;
408 ctx.input = input;
410 return _parse_or(&ctx, result);