2 * Copyright © 2008, 2009 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
29 #include <sys/types.h>
35 #include "glsl_parser_extras.h"
36 #include "glsl_parser.h"
37 #include "ir_print_visitor.h"
40 _mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state,
49 len = snprintf(buf, sizeof(buf), "%u:%u(%u): error: ",
50 locp->source, locp->first_line, locp->first_column);
53 vsnprintf(buf + len, sizeof(buf) - len, fmt, ap);
67 _mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q)
100 printf("noperspective ");
105 ast_node::print(void) const
107 printf("node_%d ", type);
111 ast_node::ast_node(void)
113 make_empty_list(this);
118 ast_opt_array_size_print(bool is_array, const ast_expression *array_size)
132 ast_compound_statement::print(void) const
134 const struct simple_node *ptr;
138 foreach(ptr, & statements) {
139 ((ast_node *)ptr)->print();
146 ast_compound_statement::ast_compound_statement(int new_scope,
147 ast_node *statements)
149 this->new_scope = new_scope;
150 make_empty_list(& this->statements);
152 if (statements != NULL) {
153 /* This seems odd, but it works. The simple_list is,
154 * basically, a circular list. insert_at_tail adds
155 * the specified node to the list before the current
158 insert_at_tail((struct simple_node *) statements,
165 ast_expression::print(void) const
179 subexpressions[0]->print();
180 printf("%s ", operator_string(oper));
181 subexpressions[1]->print();
184 case ast_field_selection:
185 subexpressions[0]->print();
186 printf(". %s ", primary_expression.identifier);
195 printf("%s ", operator_string(oper));
196 subexpressions[0]->print();
201 subexpressions[0]->print();
202 printf("%s ", operator_string(oper));
205 case ast_conditional:
206 subexpressions[0]->print();
208 subexpressions[1]->print();
210 subexpressions[1]->print();
213 case ast_array_index:
214 subexpressions[0]->print();
216 subexpressions[1]->print();
220 case ast_function_call: {
221 ast_expression *parameters = subexpressions[1];
223 subexpressions[0]->print();
226 if (parameters != NULL) {
227 struct simple_node *ptr;
230 foreach (ptr, (struct simple_node *) parameters) {
232 ((ast_node *)ptr)->print();
241 printf("%s ", primary_expression.identifier);
244 case ast_int_constant:
245 printf("%d ", primary_expression.int_constant);
248 case ast_uint_constant:
249 printf("%u ", primary_expression.uint_constant);
252 case ast_float_constant:
253 printf("%f ", primary_expression.float_constant);
256 case ast_bool_constant:
258 primary_expression.bool_constant
263 struct simple_node *ptr;
264 struct simple_node *const head = first_elem(& expressions);
267 foreach (ptr, & expressions) {
271 ((ast_node *)ptr)->print();
283 ast_expression::ast_expression(int oper,
288 this->oper = ast_operators(oper);
289 this->subexpressions[0] = ex0;
290 this->subexpressions[1] = ex1;
291 this->subexpressions[2] = ex2;
292 make_empty_list(& expressions);
297 ast_expression_statement::print(void) const
306 ast_expression_statement::ast_expression_statement(ast_expression *ex) :
314 ast_function::print(void) const
316 struct simple_node *ptr;
318 return_type->print();
319 printf(" %s (", identifier);
321 foreach(ptr, & parameters) {
322 ((ast_node *)ptr)->print();
329 ast_function::ast_function(void)
331 make_empty_list(& parameters);
336 ast_fully_specified_type::print(void) const
338 _mesa_ast_type_qualifier_print(& qualifier);
344 ast_parameter_declarator::print(void) const
348 printf("%s ", identifier);
349 ast_opt_array_size_print(is_array, array_size);
354 ast_function_definition::print(void) const
362 ast_declaration::print(void) const
364 printf("%s ", identifier);
365 ast_opt_array_size_print(is_array, array_size);
369 initializer->print();
374 ast_declaration::ast_declaration(char *identifier, int is_array,
375 ast_expression *array_size,
376 ast_expression *initializer)
378 this->identifier = identifier;
379 this->is_array = is_array;
380 this->array_size = array_size;
381 this->initializer = initializer;
386 ast_declarator_list::print(void) const
388 struct simple_node *head;
389 struct simple_node *ptr;
391 assert(type || invariant);
396 printf("invariant ");
398 head = first_elem(& declarations);
399 foreach (ptr, & declarations) {
403 ((ast_node *)ptr)->print();
410 ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type)
413 make_empty_list(& this->declarations);
417 ast_jump_statement::print(void) const
421 printf("continue; ");
428 if (opt_return_value)
429 opt_return_value->print();
440 ast_jump_statement::ast_jump_statement(int mode, ast_expression *return_value)
442 this->mode = ast_jump_modes(mode);
444 if (mode == ast_return)
445 opt_return_value = return_value;
450 ast_selection_statement::print(void) const
456 then_statement->print();
458 if (else_statement) {
460 else_statement->print();
466 ast_selection_statement::ast_selection_statement(ast_expression *condition,
467 ast_node *then_statement,
468 ast_node *else_statement)
470 this->condition = condition;
471 this->then_statement = then_statement;
472 this->else_statement = else_statement;
477 ast_iteration_statement::print(void) const
483 init_statement->print();
491 rest_expression->print();
517 ast_iteration_statement::ast_iteration_statement(int mode,
520 ast_expression *rest_expression,
523 this->mode = ast_iteration_modes(mode);
524 this->init_statement = init;
525 this->condition = condition;
526 this->rest_expression = rest_expression;
532 ast_struct_specifier::print(void) const
534 struct simple_node *ptr;
536 printf("struct %s { ", name);
537 foreach (ptr, & declarations) {
538 ((ast_node *)ptr)->print();
544 ast_struct_specifier::ast_struct_specifier(char *identifier,
545 ast_node *declarator_list)
549 /* This seems odd, but it works. The simple_list is,
550 * basically, a circular list. insert_at_tail adds
551 * the specified node to the list before the current
554 insert_at_tail((struct simple_node *) declarator_list,
560 load_text_file(const char *file_name, size_t *size)
564 ssize_t total_read = 0;
565 int fd = open(file_name, O_RDONLY);
572 if (fstat(fd, & st) == 0) {
573 text = (char *) malloc(st.st_size + 1);
576 ssize_t bytes = read(fd, text + total_read,
577 st.st_size - total_read);
589 } while (total_read < st.st_size);
591 text[total_read] = '\0';
603 main(int argc, char **argv)
605 struct _mesa_glsl_parse_state state;
608 struct simple_node *ptr;
609 exec_list instructions;
612 printf("Usage: %s [v|g|f] <shader_file>\n", argv[0]);
616 switch (argv[1][0]) {
618 state.target = vertex_shader;
621 state.target = geometry_shader;
624 state.target = fragment_shader;
627 printf("Usage: %s [v|g|f] <shader_file>\n", argv[0]);
631 shader = load_text_file(argv[2], & shader_len);
633 state.scanner = NULL;
634 make_empty_list(& state.translation_unit);
635 state.symbols = new glsl_symbol_table;
637 state.temp_index = 0;
639 _mesa_glsl_lexer_ctor(& state, shader, shader_len);
640 _mesa_glsl_parse(& state);
641 _mesa_glsl_lexer_dtor(& state);
643 foreach (ptr, & state.translation_unit) {
644 ((ast_node *)ptr)->print();
647 _mesa_ast_to_hir(&instructions, &state);
652 foreach_iter(exec_list_iterator, iter, instructions) {
655 ((ir_instruction *)iter.get())->accept(& v);
660 delete state.symbols;
662 return state.error != 0;