mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 11:10:10 +01:00
Initial commit. lol
This commit is contained in:
commit
a87ac255cf
26 changed files with 6342 additions and 0 deletions
1
.dir-locals.el
Normal file
1
.dir-locals.el
Normal file
|
|
@ -0,0 +1 @@
|
|||
((c-mode . ((c-basic-offset . 3))))
|
||||
40
Makefile
Normal file
40
Makefile
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
CSRCS = symbol_table.c hash_table.c glsl_types.c
|
||||
CCSRCS = glsl_parser.tab.cc glsl_lexer.cc glsl_parser_extras.cc
|
||||
# ast_to_hir.cc ir.cc hir_field_selection.cc
|
||||
OBJS = $(CSRCS:.c=.o) $(CCSRCS:.cc=.o)
|
||||
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
WARN = -Wall -Wextra -Wunsafe-loop-optimizations -Wstack-protector \
|
||||
-Wunreachable-code
|
||||
CPPFLAGS = -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE
|
||||
CFLAGS = -O0 -ggdb3 -fstack-protector $(CPPFLAGS) $(WARN) -std=c89 -ansi -pedantic
|
||||
CXXFLAGS = -O0 -ggdb3 -fstack-protector $(CPPFLAGS) $(WARN)
|
||||
LDLAGS = -ggdb3
|
||||
|
||||
glsl: $(OBJS)
|
||||
$(CXX) $(LDLAGS) $(OBJS) -o glsl
|
||||
|
||||
glsl_parser.tab.cc glsl_parser.tab.h: glsl_parser.y
|
||||
bison --report-file=glsl_parser.output -v -d \
|
||||
--output=glsl_parser.tab.cc \
|
||||
--name-prefix=_mesa_glsl_ $< && \
|
||||
mv glsl_parser.tab.hh glsl_parser.tab.h
|
||||
|
||||
glsl_lexer.cc: glsl_lexer.l
|
||||
flex --outfile="glsl_lexer.cc" $<
|
||||
|
||||
glsl_parser_tab.o: glsl_parser.tab.cc
|
||||
glsl_types.o: glsl_types.c glsl_types.h builtin_types.h
|
||||
glsl_lexer.o: glsl_lexer.cc glsl_parser.tab.h glsl_parser_extras.h ast.h
|
||||
glsl_parser.o: glsl_parser_extras.h ast.h
|
||||
ast_to_hir.o: ast_to_hir.cc symbol_table.h glsl_parser_extras.h ast.h glsl_types.h ir.h
|
||||
|
||||
builtin_types.h: builtin_types.sh
|
||||
./builtin_types.sh > builtin_types.h
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) glsl
|
||||
rm -f glsl_lexer.cc glsl_parser.tab.{cc,h,hh} glsl_parser.output
|
||||
rm -f builtin_types.h
|
||||
rm -f *~
|
||||
511
ast.h
Normal file
511
ast.h
Normal file
|
|
@ -0,0 +1,511 @@
|
|||
/*
|
||||
* Copyright © 2009 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef AST_H
|
||||
#define AST_H
|
||||
|
||||
#include "main/simple_list.h"
|
||||
#include "glsl_parser_extras.h"
|
||||
|
||||
struct ir_instruction;
|
||||
struct _mesa_glsl_parse_state;
|
||||
|
||||
struct YYLTYPE;
|
||||
|
||||
#define _mesa_ast_print(n) \
|
||||
((ast_node *) n)->print()
|
||||
|
||||
#define _mesa_ast_to_hir(n, instr, s) \
|
||||
((struct ast_node *) n)->vtbl->to_hir((struct ast_node *) n, instr, s)
|
||||
|
||||
#define _mesa_ast_function_call_to_hir(n, p, s) \
|
||||
((struct ast_node *) n)->vtbl->function_call_to_hir( \
|
||||
(struct ast_node *) n, \
|
||||
(struct ast_node *) p, \
|
||||
s)
|
||||
|
||||
class ast_node : public simple_node {
|
||||
public:
|
||||
virtual ~ast_node();
|
||||
virtual void print(void) const;
|
||||
|
||||
/**
|
||||
* Retrieve the source location of an AST node
|
||||
*
|
||||
* This function is primarily used to get the source position of an AST node
|
||||
* into a form that can be passed to \c _mesa_glsl_error.
|
||||
*
|
||||
* \sa _mesa_glsl_error, ast_node::set_location
|
||||
*/
|
||||
struct YYLTYPE get_location(void) const
|
||||
{
|
||||
struct YYLTYPE locp;
|
||||
|
||||
locp.source = this->location.source;
|
||||
locp.first_line = this->location.line;
|
||||
locp.first_column = this->location.column;
|
||||
locp.last_line = locp.first_line;
|
||||
locp.last_column = locp.first_column;
|
||||
|
||||
return locp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the source location of an AST node from a parser location
|
||||
*
|
||||
* \sa ast_node::get_location
|
||||
*/
|
||||
void set_location(const struct YYLTYPE *locp)
|
||||
{
|
||||
this->location.source = locp->source;
|
||||
this->location.line = locp->first_line;
|
||||
this->location.column = locp->first_column;
|
||||
}
|
||||
|
||||
|
||||
int type;
|
||||
|
||||
struct {
|
||||
unsigned source;
|
||||
unsigned line;
|
||||
unsigned column;
|
||||
} location;
|
||||
|
||||
protected:
|
||||
ast_node(void);
|
||||
};
|
||||
|
||||
|
||||
enum ast_operators {
|
||||
ast_assign,
|
||||
ast_plus, /**< Unary + operator. */
|
||||
ast_neg,
|
||||
ast_add,
|
||||
ast_sub,
|
||||
ast_mul,
|
||||
ast_div,
|
||||
ast_mod,
|
||||
ast_lshift,
|
||||
ast_rshift,
|
||||
ast_less,
|
||||
ast_greater,
|
||||
ast_lequal,
|
||||
ast_gequal,
|
||||
ast_equal,
|
||||
ast_nequal,
|
||||
ast_bit_and,
|
||||
ast_bit_xor,
|
||||
ast_bit_or,
|
||||
ast_bit_not,
|
||||
ast_logic_and,
|
||||
ast_logic_xor,
|
||||
ast_logic_or,
|
||||
ast_logic_not,
|
||||
|
||||
ast_mul_assign,
|
||||
ast_div_assign,
|
||||
ast_mod_assign,
|
||||
ast_add_assign,
|
||||
ast_sub_assign,
|
||||
ast_ls_assign,
|
||||
ast_rs_assign,
|
||||
ast_and_assign,
|
||||
ast_xor_assign,
|
||||
ast_or_assign,
|
||||
|
||||
ast_conditional,
|
||||
|
||||
ast_pre_inc,
|
||||
ast_pre_dec,
|
||||
ast_post_inc,
|
||||
ast_post_dec,
|
||||
ast_field_selection,
|
||||
ast_array_index,
|
||||
|
||||
ast_function_call,
|
||||
|
||||
ast_identifier,
|
||||
ast_int_constant,
|
||||
ast_uint_constant,
|
||||
ast_float_constant,
|
||||
ast_bool_constant,
|
||||
|
||||
ast_sequence
|
||||
};
|
||||
|
||||
class ast_expression : public ast_node {
|
||||
public:
|
||||
ast_expression(int oper, ast_expression *,
|
||||
ast_expression *, ast_expression *);
|
||||
|
||||
virtual void print(void) const;
|
||||
|
||||
enum ast_operators oper;
|
||||
|
||||
ast_expression *subexpressions[3];
|
||||
|
||||
union {
|
||||
char *identifier;
|
||||
int int_constant;
|
||||
float float_constant;
|
||||
unsigned uint_constant;
|
||||
int bool_constant;
|
||||
} primary_expression;
|
||||
|
||||
|
||||
/**
|
||||
* List of expressions for an \c ast_sequence.
|
||||
*/
|
||||
struct simple_node expressions;
|
||||
};
|
||||
|
||||
/**
|
||||
* Number of possible operators for an ast_expression
|
||||
*
|
||||
* This is done as a define instead of as an additional value in the enum so
|
||||
* that the compiler won't generate spurious messages like "warning:
|
||||
* enumeration value ‘ast_num_operators’ not handled in switch"
|
||||
*/
|
||||
#define AST_NUM_OPERATORS (ast_sequence + 1)
|
||||
|
||||
|
||||
class ast_compound_statement : public ast_node {
|
||||
public:
|
||||
ast_compound_statement(int new_scope, ast_node *statements);
|
||||
virtual void print(void) const;
|
||||
|
||||
int new_scope;
|
||||
struct simple_node statements;
|
||||
};
|
||||
|
||||
class ast_declaration : public ast_node {
|
||||
public:
|
||||
ast_declaration(char *identifier, int is_array, ast_expression *array_size,
|
||||
ast_expression *initializer);
|
||||
virtual void print(void) const;
|
||||
|
||||
char *identifier;
|
||||
|
||||
int is_array;
|
||||
ast_expression *array_size;
|
||||
|
||||
ast_expression *initializer;
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
ast_precision_high = 0, /**< Default precision. */
|
||||
ast_precision_medium,
|
||||
ast_precision_low
|
||||
};
|
||||
|
||||
struct ast_type_qualifier {
|
||||
unsigned invariant:1;
|
||||
unsigned constant:1;
|
||||
unsigned attribute:1;
|
||||
unsigned varying:1;
|
||||
unsigned in:1;
|
||||
unsigned out:1;
|
||||
unsigned centroid:1;
|
||||
unsigned uniform:1;
|
||||
unsigned smooth:1;
|
||||
unsigned flat:1;
|
||||
unsigned noperspective:1;
|
||||
};
|
||||
|
||||
class ast_struct_specifier : public ast_node {
|
||||
public:
|
||||
ast_struct_specifier(char *identifier, ast_node *declarator_list);
|
||||
virtual void print(void) const;
|
||||
|
||||
char *name;
|
||||
struct simple_node declarations;
|
||||
};
|
||||
|
||||
|
||||
enum ast_types {
|
||||
ast_void,
|
||||
ast_float,
|
||||
ast_int,
|
||||
ast_uint,
|
||||
ast_bool,
|
||||
ast_vec2,
|
||||
ast_vec3,
|
||||
ast_vec4,
|
||||
ast_bvec2,
|
||||
ast_bvec3,
|
||||
ast_bvec4,
|
||||
ast_ivec2,
|
||||
ast_ivec3,
|
||||
ast_ivec4,
|
||||
ast_uvec2,
|
||||
ast_uvec3,
|
||||
ast_uvec4,
|
||||
ast_mat2,
|
||||
ast_mat2x3,
|
||||
ast_mat2x4,
|
||||
ast_mat3x2,
|
||||
ast_mat3,
|
||||
ast_mat3x4,
|
||||
ast_mat4x2,
|
||||
ast_mat4x3,
|
||||
ast_mat4,
|
||||
ast_sampler1d,
|
||||
ast_sampler2d,
|
||||
ast_sampler3d,
|
||||
ast_samplercube,
|
||||
ast_sampler1dshadow,
|
||||
ast_sampler2dshadow,
|
||||
ast_samplercubeshadow,
|
||||
ast_sampler1darray,
|
||||
ast_sampler2darray,
|
||||
ast_sampler1darrayshadow,
|
||||
ast_sampler2darrayshadow,
|
||||
ast_isampler1d,
|
||||
ast_isampler2d,
|
||||
ast_isampler3d,
|
||||
ast_isamplercube,
|
||||
ast_isampler1darray,
|
||||
ast_isampler2darray,
|
||||
ast_usampler1d,
|
||||
ast_usampler2d,
|
||||
ast_usampler3d,
|
||||
ast_usamplercube,
|
||||
ast_usampler1darray,
|
||||
ast_usampler2darray,
|
||||
|
||||
ast_struct,
|
||||
ast_type_name
|
||||
};
|
||||
|
||||
|
||||
class ast_type_specifier : public ast_node {
|
||||
public:
|
||||
ast_type_specifier(int specifier);
|
||||
|
||||
virtual void print(void) const;
|
||||
|
||||
enum ast_types type_specifier;
|
||||
|
||||
char *type_name;
|
||||
ast_struct_specifier *structure;
|
||||
|
||||
int is_array;
|
||||
ast_expression *array_size;
|
||||
|
||||
unsigned precision:2;
|
||||
};
|
||||
|
||||
|
||||
class ast_fully_specified_type : public ast_node {
|
||||
public:
|
||||
virtual void print(void) const;
|
||||
|
||||
ast_type_qualifier qualifier;
|
||||
ast_type_specifier *specifier;
|
||||
};
|
||||
|
||||
|
||||
class ast_declarator_list : public ast_node {
|
||||
public:
|
||||
ast_declarator_list(ast_fully_specified_type *);
|
||||
virtual void print(void) const;
|
||||
|
||||
ast_fully_specified_type *type;
|
||||
struct simple_node declarations;
|
||||
|
||||
/**
|
||||
* Special flag for vertex shader "invariant" declarations.
|
||||
*
|
||||
* Vertex shaders can contain "invariant" variable redeclarations that do
|
||||
* not include a type. For example, "invariant gl_Position;". This flag
|
||||
* is used to note these cases when no type is specified.
|
||||
*/
|
||||
int invariant;
|
||||
};
|
||||
|
||||
|
||||
class ast_parameter_declarator : public ast_node {
|
||||
public:
|
||||
virtual void print(void) const;
|
||||
|
||||
ast_fully_specified_type *type;
|
||||
char *identifier;
|
||||
int is_array;
|
||||
ast_expression *array_size;
|
||||
};
|
||||
|
||||
|
||||
class ast_function : public ast_node {
|
||||
public:
|
||||
ast_function(void);
|
||||
|
||||
virtual void print(void) const;
|
||||
|
||||
ast_fully_specified_type *return_type;
|
||||
char *identifier;
|
||||
|
||||
struct simple_node parameters;
|
||||
};
|
||||
|
||||
|
||||
class ast_declaration_statement : public ast_node {
|
||||
public:
|
||||
ast_declaration_statement(void);
|
||||
|
||||
enum {
|
||||
ast_function,
|
||||
ast_declaration,
|
||||
ast_precision
|
||||
} mode;
|
||||
|
||||
union {
|
||||
class ast_function *function;
|
||||
ast_declarator_list *declarator;
|
||||
ast_type_specifier *type;
|
||||
ast_node *node;
|
||||
} declaration;
|
||||
};
|
||||
|
||||
|
||||
class ast_expression_statement : public ast_node {
|
||||
public:
|
||||
ast_expression_statement(ast_expression *);
|
||||
virtual void print(void) const;
|
||||
|
||||
ast_expression *expression;
|
||||
};
|
||||
|
||||
|
||||
class ast_case_label : public ast_node {
|
||||
public:
|
||||
|
||||
/**
|
||||
* An expression of NULL means 'default'.
|
||||
*/
|
||||
ast_expression *expression;
|
||||
};
|
||||
|
||||
class ast_selection_statement : public ast_node {
|
||||
public:
|
||||
ast_selection_statement(ast_expression *condition,
|
||||
ast_node *then_statement,
|
||||
ast_node *else_statement);
|
||||
virtual void print(void) const;
|
||||
|
||||
ast_expression *condition;
|
||||
ast_node *then_statement;
|
||||
ast_node *else_statement;
|
||||
};
|
||||
|
||||
|
||||
class ast_switch_statement : public ast_node {
|
||||
public:
|
||||
ast_expression *expression;
|
||||
struct simple_node statements;
|
||||
};
|
||||
|
||||
class ast_iteration_statement : public ast_node {
|
||||
public:
|
||||
ast_iteration_statement(int mode, ast_node *init, ast_node *condition,
|
||||
ast_expression *rest_expression, ast_node *body);
|
||||
|
||||
virtual void print(void) const;
|
||||
|
||||
enum ast_iteration_modes {
|
||||
ast_for,
|
||||
ast_while,
|
||||
ast_do_while
|
||||
} mode;
|
||||
|
||||
|
||||
ast_node *init_statement;
|
||||
ast_node *condition;
|
||||
ast_expression *rest_expression;
|
||||
|
||||
ast_node *body;
|
||||
};
|
||||
|
||||
|
||||
class ast_jump_statement : public ast_node {
|
||||
public:
|
||||
ast_jump_statement(int mode, ast_expression *return_value);
|
||||
virtual void print(void) const;
|
||||
|
||||
enum ast_jump_modes {
|
||||
ast_continue,
|
||||
ast_break,
|
||||
ast_return,
|
||||
ast_discard
|
||||
} mode;
|
||||
|
||||
ast_expression *opt_return_value;
|
||||
};
|
||||
|
||||
|
||||
class ast_function_definition : public ast_node {
|
||||
public:
|
||||
virtual void print(void) const;
|
||||
|
||||
ast_function *prototype;
|
||||
ast_compound_statement *body;
|
||||
};
|
||||
|
||||
|
||||
extern struct ir_instruction *
|
||||
ast_expression_to_hir(const ast_node *ast,
|
||||
struct simple_node *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
extern struct ir_instruction *
|
||||
ast_expression_statement_to_hir(const struct ast_node *ast,
|
||||
struct simple_node *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
extern struct ir_instruction *
|
||||
ast_compound_statement_to_hir(const struct ast_node *ast,
|
||||
struct simple_node *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
extern struct ir_instruction *
|
||||
ast_function_definition_to_hir(const struct ast_node *ast,
|
||||
struct simple_node *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
extern struct ir_instruction *
|
||||
ast_declarator_list_to_hir(const struct ast_node *ast,
|
||||
struct simple_node *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
extern struct ir_instruction *
|
||||
ast_parameter_declarator_to_hir(const struct ast_node *ast,
|
||||
struct simple_node *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
extern struct ir_instruction *
|
||||
_mesa_ast_field_selection_to_hir(const struct ast_expression *expr,
|
||||
struct simple_node *instructions,
|
||||
struct _mesa_glsl_parse_state *state);
|
||||
|
||||
#endif /* AST_H */
|
||||
1172
ast_to_hir.cc
Normal file
1172
ast_to_hir.cc
Normal file
File diff suppressed because it is too large
Load diff
328
builtin_types.sh
Executable file
328
builtin_types.sh
Executable file
|
|
@ -0,0 +1,328 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Copyright © 2009 Intel Corporation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice (including the next
|
||||
# paragraph) shall be included in all copies or substantial portions of the
|
||||
# Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
# gen_integral_type <name> <base_type> <vector elements> <matrix rows>
|
||||
function gen_integral_type
|
||||
{
|
||||
printf ' { %17s, 0, 0, 0, 0, %u, %u, "%s", 0, {NULL} },\n' $2 $3 $4 $1
|
||||
index=$((index + 1))
|
||||
}
|
||||
|
||||
# gen_struct_type <name>
|
||||
function gen_struct_type
|
||||
{
|
||||
elements=$(printf "%s_fields" $1)
|
||||
printf ' {\n GLSL_TYPE_STRUCT, 0, 0, 0, 0, 0, 0, "%s",\n Elements(%s),\n {(void *) %s}\n },\n' \
|
||||
$1 $elements $elements
|
||||
}
|
||||
|
||||
# gen_sampler_type <name> <dimensions> <shadow> <array> <type>
|
||||
function gen_sampler_type
|
||||
{
|
||||
name=$(printf "sampler%s" $1)
|
||||
|
||||
if [ $4 -eq 1 ]; then
|
||||
name=$(printf "%sArray" $name)
|
||||
fi
|
||||
|
||||
if [ $3 -eq 1 ]; then
|
||||
name=$(printf "%sShadow" $name)
|
||||
fi
|
||||
|
||||
if [ $5 == GLSL_TYPE_INT ]; then
|
||||
name=$(printf "i%s" $name)
|
||||
elif [ $5 == GLSL_TYPE_UINT ]; then
|
||||
name=$(printf "u%s" $name)
|
||||
fi
|
||||
|
||||
printf ' { GLSL_TYPE_SAMPLER, %21s, %u, %u, %15s, 0, 0,\n "%s", 0, {NULL} },\n' \
|
||||
$2 $3 $4 $5 $name
|
||||
}
|
||||
|
||||
function gen_header
|
||||
{
|
||||
if [ x$1 == x ]; then
|
||||
name="builtin_types"
|
||||
else
|
||||
name="builtin_${1}_types"
|
||||
fi
|
||||
|
||||
printf "\nstatic const struct glsl_type %s[] = {\n" $name
|
||||
}
|
||||
|
||||
function gen_footer
|
||||
{
|
||||
printf "};\n"
|
||||
}
|
||||
|
||||
function gen_struct_field_header
|
||||
{
|
||||
printf "\nstatic const struct glsl_struct_field %s_fields[] = {\n" $1
|
||||
}
|
||||
|
||||
function gen_struct_field_footer
|
||||
{
|
||||
printf "};\n"
|
||||
}
|
||||
|
||||
function gen_struct_field
|
||||
{
|
||||
printf ' { & %s[%2u], "%s" },\n' $1 $2 "$3"
|
||||
}
|
||||
|
||||
cat <<EOF
|
||||
/* THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT! See builtin_types.sh. */
|
||||
/*
|
||||
* Copyright © 2009 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef Elements
|
||||
#define Elements(x) (sizeof(x)/sizeof(*(x)))
|
||||
#endif
|
||||
|
||||
static const struct glsl_type error_type = {
|
||||
GLSL_TYPE_ERROR, 0, 0, 0, 0, 0, 0, "", 0, {NULL}
|
||||
};
|
||||
|
||||
const struct glsl_type *const glsl_error_type = & error_type;
|
||||
|
||||
EOF
|
||||
|
||||
echo '/** \name Core built-in types'
|
||||
echo ' *'
|
||||
echo ' * These types exist in all versions of GLSL.'
|
||||
echo ' */'
|
||||
echo '/*@{*/'
|
||||
gen_header "core"
|
||||
|
||||
index=0;
|
||||
bool_index=$index
|
||||
gen_integral_type "bool" "GLSL_TYPE_BOOL" 0 0
|
||||
for i in 2 3 4; do
|
||||
gen_integral_type "bvec$i" "GLSL_TYPE_BOOL" $i 0
|
||||
done
|
||||
|
||||
int_index=$index
|
||||
gen_integral_type "int" "GLSL_TYPE_INT" 0 0
|
||||
for i in 2 3 4; do
|
||||
gen_integral_type "ivec$i" "GLSL_TYPE_INT" $i 0
|
||||
done
|
||||
|
||||
float_index=$index
|
||||
gen_integral_type "float" "GLSL_TYPE_FLOAT" 0 0
|
||||
for i in 2 3 4; do
|
||||
gen_integral_type "vec$i" "GLSL_TYPE_FLOAT" $i 0
|
||||
done
|
||||
|
||||
for i in 2 3 4; do
|
||||
gen_integral_type "mat$i" "GLSL_TYPE_FLOAT" $i $i
|
||||
done
|
||||
|
||||
for i in "1D" "2D"; do
|
||||
gen_sampler_type $i "GLSL_SAMPLER_DIM_$i" 0 0 "GLSL_TYPE_FLOAT"
|
||||
gen_sampler_type $i "GLSL_SAMPLER_DIM_$i" 1 0 "GLSL_TYPE_FLOAT"
|
||||
done
|
||||
|
||||
gen_sampler_type "3D" "GLSL_SAMPLER_DIM_3D" 0 0 "GLSL_TYPE_FLOAT"
|
||||
gen_sampler_type "Cube" "GLSL_SAMPLER_DIM_CUBE" 0 0 "GLSL_TYPE_FLOAT"
|
||||
gen_sampler_type "2DRect" "GLSL_SAMPLER_DIM_RECT" 0 0 "GLSL_TYPE_FLOAT"
|
||||
gen_sampler_type "2DRect" "GLSL_SAMPLER_DIM_RECT" 1 0 "GLSL_TYPE_FLOAT"
|
||||
|
||||
gen_footer
|
||||
|
||||
echo
|
||||
echo 'const struct glsl_type *const glsl_bool_type = & builtin_core_types['$bool_index'];'
|
||||
echo 'const struct glsl_type *const glsl_int_type = & builtin_core_types['$int_index'];'
|
||||
echo 'const struct glsl_type *const glsl_float_type = & builtin_core_types['$float_index'];'
|
||||
echo '/*@}*/'
|
||||
|
||||
echo
|
||||
echo '/** \name GLSL structures that have not been deprecated.'
|
||||
echo ' */'
|
||||
echo '/*@{*/'
|
||||
gen_struct_field_header gl_DepthRangeParameters
|
||||
gen_struct_field builtin_core_types 8 "near"
|
||||
gen_struct_field builtin_core_types 8 "far"
|
||||
gen_struct_field builtin_core_types 8 "diff"
|
||||
gen_struct_field_footer
|
||||
|
||||
gen_header "structure"
|
||||
gen_struct_type gl_DepthRangeParameters
|
||||
gen_footer
|
||||
echo '/*@}*/'
|
||||
|
||||
echo
|
||||
echo '/** \name GLSL 1.00 / 1.10 structures that are deprecated in GLSL 1.30'
|
||||
echo ' */'
|
||||
echo '/*@{*/'
|
||||
gen_struct_field_header gl_PointParameters
|
||||
gen_struct_field builtin_core_types 8 "size"
|
||||
gen_struct_field builtin_core_types 8 "sizeMin"
|
||||
gen_struct_field builtin_core_types 8 "sizeMax"
|
||||
gen_struct_field builtin_core_types 8 "fadeThresholdSize"
|
||||
gen_struct_field builtin_core_types 8 "distanceConstantAttenuation"
|
||||
gen_struct_field builtin_core_types 8 "distanceLinearAttenuation"
|
||||
gen_struct_field builtin_core_types 8 "distanceQuadraticAttenuation"
|
||||
gen_struct_field_footer
|
||||
|
||||
gen_struct_field_header gl_MaterialParameters
|
||||
gen_struct_field builtin_core_types 11 "emission"
|
||||
gen_struct_field builtin_core_types 11 "ambient"
|
||||
gen_struct_field builtin_core_types 11 "diffuse"
|
||||
gen_struct_field builtin_core_types 11 "specular"
|
||||
gen_struct_field builtin_core_types 8 "shininess"
|
||||
gen_struct_field_footer
|
||||
|
||||
gen_struct_field_header gl_LightSourceParameters
|
||||
gen_struct_field builtin_core_types 11 "ambient"
|
||||
gen_struct_field builtin_core_types 11 "diffuse"
|
||||
gen_struct_field builtin_core_types 11 "specular"
|
||||
gen_struct_field builtin_core_types 11 "position"
|
||||
gen_struct_field builtin_core_types 11 "halfVector"
|
||||
gen_struct_field builtin_core_types 10 "spotDirection"
|
||||
gen_struct_field builtin_core_types 8 "spotExponent"
|
||||
gen_struct_field builtin_core_types 8 "spotCutoff"
|
||||
gen_struct_field builtin_core_types 8 "spotCosCutoff"
|
||||
gen_struct_field builtin_core_types 8 "constantAttenuation"
|
||||
gen_struct_field builtin_core_types 8 "linearAttenuation"
|
||||
gen_struct_field builtin_core_types 8 "quadraticAttenuation"
|
||||
gen_struct_field_footer
|
||||
|
||||
gen_struct_field_header gl_LightModelParameters
|
||||
gen_struct_field builtin_core_types 11 "ambient"
|
||||
gen_struct_field_footer
|
||||
|
||||
gen_struct_field_header gl_LightModelProducts
|
||||
gen_struct_field builtin_core_types 11 "sceneColor"
|
||||
gen_struct_field_footer
|
||||
|
||||
gen_struct_field_header gl_LightProducts
|
||||
gen_struct_field builtin_core_types 11 "ambient"
|
||||
gen_struct_field builtin_core_types 11 "diffuse"
|
||||
gen_struct_field builtin_core_types 11 "specular"
|
||||
gen_struct_field_footer
|
||||
|
||||
gen_struct_field_header gl_FogParameters
|
||||
gen_struct_field builtin_core_types 11 "color"
|
||||
gen_struct_field builtin_core_types 8 "density"
|
||||
gen_struct_field builtin_core_types 8 "start"
|
||||
gen_struct_field builtin_core_types 8 "end"
|
||||
gen_struct_field builtin_core_types 8 "scalre"
|
||||
gen_struct_field_footer
|
||||
|
||||
gen_header "110_deprecated_structure"
|
||||
gen_struct_type gl_PointParameters
|
||||
gen_struct_type gl_MaterialParameters
|
||||
gen_struct_type gl_LightSourceParameters
|
||||
gen_struct_type gl_LightModelParameters
|
||||
gen_struct_type gl_LightModelProducts
|
||||
gen_struct_type gl_LightProducts
|
||||
gen_struct_type gl_FogParameters
|
||||
gen_footer
|
||||
echo '/*@}*/'
|
||||
|
||||
|
||||
echo
|
||||
echo '/** \name Types added in GLSL 1.20'
|
||||
echo ' */'
|
||||
echo '/*@{*/'
|
||||
gen_header "120"
|
||||
for i in 2 3 4; do
|
||||
for j in 2 3 4; do
|
||||
if [ $i -ne $j ]; then
|
||||
gen_integral_type "mat${i}x${j}" "GLSL_TYPE_FLOAT" $i $j
|
||||
fi
|
||||
done
|
||||
done
|
||||
gen_footer
|
||||
echo '/*@}*/'
|
||||
|
||||
echo
|
||||
echo '/** \name Types added in GLSL 1.30'
|
||||
echo ' */'
|
||||
echo '/*@{*/'
|
||||
gen_header "130"
|
||||
index=0;
|
||||
uint_index=$index
|
||||
gen_integral_type "uint" "GLSL_TYPE_UINT" 0 0
|
||||
for i in 2 3 4; do
|
||||
gen_integral_type "uvec$i" "GLSL_TYPE_UINT" $i 0
|
||||
done
|
||||
|
||||
echo
|
||||
echo " /* 1D and 2D texture arrays */"
|
||||
for i in "1D" "2D"; do
|
||||
gen_sampler_type $i "GLSL_SAMPLER_DIM_$i" 0 1 "GLSL_TYPE_FLOAT"
|
||||
gen_sampler_type $i "GLSL_SAMPLER_DIM_$i" 0 1 "GLSL_TYPE_INT"
|
||||
gen_sampler_type $i "GLSL_SAMPLER_DIM_$i" 0 1 "GLSL_TYPE_UINT"
|
||||
gen_sampler_type $i "GLSL_SAMPLER_DIM_$i" 1 1 "GLSL_TYPE_FLOAT"
|
||||
done
|
||||
|
||||
echo
|
||||
echo " /* cube shadow samplers */"
|
||||
gen_sampler_type "Cube" "GLSL_SAMPLER_DIM_CUBE" 1 0 "GLSL_TYPE_FLOAT"
|
||||
|
||||
echo
|
||||
echo " /* signed and unsigned integer samplers */"
|
||||
for i in "1D" "2D" "3D"; do
|
||||
gen_sampler_type $i "GLSL_SAMPLER_DIM_$i" 0 0 "GLSL_TYPE_INT"
|
||||
gen_sampler_type $i "GLSL_SAMPLER_DIM_$i" 0 0 "GLSL_TYPE_UINT"
|
||||
done
|
||||
|
||||
gen_sampler_type "Cube" "GLSL_SAMPLER_DIM_CUBE" 0 0 "GLSL_TYPE_INT"
|
||||
gen_sampler_type "Cube" "GLSL_SAMPLER_DIM_CUBE" 0 0 "GLSL_TYPE_UINT"
|
||||
|
||||
gen_footer
|
||||
echo ''
|
||||
echo 'const struct glsl_type *const glsl_uint_type = & builtin_130_types['$uint_index'];'
|
||||
echo '/*@}*/'
|
||||
|
||||
echo
|
||||
echo '/** \name Sampler types added by GL_EXT_texture_buffer_object'
|
||||
echo ' */'
|
||||
echo '/*@{*/'
|
||||
gen_header "EXT_texture_buffer_object"
|
||||
gen_sampler_type "Buffer" "GLSL_SAMPLER_DIM_BUF" 0 0 "GLSL_TYPE_FLOAT"
|
||||
gen_sampler_type "Buffer" "GLSL_SAMPLER_DIM_BUF" 0 0 "GLSL_TYPE_INT"
|
||||
gen_sampler_type "Buffer" "GLSL_SAMPLER_DIM_BUF" 0 0 "GLSL_TYPE_UINT"
|
||||
gen_footer
|
||||
echo '/*@}*/'
|
||||
273
glsl_lexer.l
Normal file
273
glsl_lexer.l
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
%{
|
||||
/*
|
||||
* Copyright © 2008, 2009 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "ast.h"
|
||||
#include "glsl_parser_extras.h"
|
||||
#include "glsl_parser.tab.h"
|
||||
#include "symbol_table.h"
|
||||
|
||||
#define YY_USER_ACTION \
|
||||
do { \
|
||||
yylloc->source = 0; \
|
||||
yylloc->first_column = yycolumn + 1; \
|
||||
yylloc->first_line = yylineno + 1; \
|
||||
yycolumn += yyleng; \
|
||||
} while(0);
|
||||
|
||||
%}
|
||||
|
||||
%option bison-bridge bison-locations reentrant noyywrap
|
||||
%option never-interactive
|
||||
%option prefix="_mesa_glsl_"
|
||||
%option extra-type="struct _mesa_glsl_parse_state *"
|
||||
%option stack
|
||||
|
||||
%x PP COMMENT
|
||||
|
||||
%%
|
||||
|
||||
"/*" { yy_push_state(COMMENT, yyscanner); }
|
||||
<COMMENT>[^*\n]*
|
||||
<COMMENT>[^*\n]*\n { yylineno++; yycolumn = 0; }
|
||||
<COMMENT>"*"+[^*/\n]*
|
||||
<COMMENT>"*"+[^*/\n]*\n { yylineno++; yycolumn = 0; }
|
||||
<COMMENT>"*"+"/" { yy_pop_state(yyscanner); }
|
||||
|
||||
\/\/.*\n { yylineno++; yycolumn = 0; }
|
||||
[ \r\t]+ ;
|
||||
|
||||
/* Preprocessor tokens. */
|
||||
^[ \t]*#[ \t]*$ ;
|
||||
^[ \t]*#[ \t]*version { BEGIN PP; return VERSION; }
|
||||
^[ \t]*#[ \t]*extension { BEGIN PP; return EXTENSION; }
|
||||
^[ \t]*#[ \t]*line { BEGIN PP; return LINE; }
|
||||
^[ \t]*#[ \t]*pragma { BEGIN PP; return PRAGMA; }
|
||||
<PP>: return COLON;
|
||||
<PP>[_a-zA-Z][_a-zA-Z0-9]* {
|
||||
yylval->identifier = strdup(yytext);
|
||||
return IDENTIFIER;
|
||||
}
|
||||
<PP>[1-9][0-9]* {
|
||||
yylval->n = strtol(yytext, NULL, 10);
|
||||
return INTCONSTANT;
|
||||
}
|
||||
<PP>\n { BEGIN 0; yylineno++; yycolumn = 0; return EOL; }
|
||||
|
||||
\n { yylineno++; yycolumn = 0; }
|
||||
|
||||
attribute return ATTRIBUTE;
|
||||
const return CONST;
|
||||
bool return BOOL;
|
||||
float return FLOAT;
|
||||
int return INT;
|
||||
|
||||
break return BREAK;
|
||||
continue return CONTINUE;
|
||||
do return DO;
|
||||
while return WHILE;
|
||||
else return ELSE;
|
||||
for return FOR;
|
||||
if return IF;
|
||||
discard return DISCARD;
|
||||
return return RETURN;
|
||||
|
||||
bvec2 return BVEC2;
|
||||
bvec3 return BVEC3;
|
||||
bvec4 return BVEC4;
|
||||
ivec2 return IVEC2;
|
||||
ivec3 return IVEC3;
|
||||
ivec4 return IVEC4;
|
||||
vec2 return VEC2;
|
||||
vec3 return VEC3;
|
||||
vec4 return VEC4;
|
||||
mat2 return MAT2;
|
||||
mat3 return MAT3;
|
||||
mat4 return MAT4;
|
||||
mat2x2 return MAT2X2;
|
||||
mat2x3 return MAT2X3;
|
||||
mat2x4 return MAT2X4;
|
||||
mat3x2 return MAT3X2;
|
||||
mat3x3 return MAT3X3;
|
||||
mat3x4 return MAT3X4;
|
||||
mat4x2 return MAT4X2;
|
||||
mat4x3 return MAT4X3;
|
||||
mat4x4 return MAT4X4;
|
||||
|
||||
in return IN;
|
||||
out return OUT;
|
||||
inout return INOUT;
|
||||
uniform return UNIFORM;
|
||||
varying return VARYING;
|
||||
centroid return CENTROID;
|
||||
invariant return INVARIANT;
|
||||
|
||||
sampler1D return SAMPLER1D;
|
||||
sampler2D return SAMPLER2D;
|
||||
sampler3D return SAMPLER3D;
|
||||
samplerCube return SAMPLERCUBE;
|
||||
sampler1DShadow return SAMPLER1DSHADOW;
|
||||
sampler2DShadow return SAMPLER2DSHADOW;
|
||||
|
||||
struct return STRUCT;
|
||||
void return VOID;
|
||||
|
||||
\+\+ return INC_OP;
|
||||
-- return DEC_OP;
|
||||
\<= return LE_OP;
|
||||
>= return GE_OP;
|
||||
== return EQ_OP;
|
||||
!= return NE_OP;
|
||||
&& return AND_OP;
|
||||
\|\| return OR_OP;
|
||||
"^^" return XOR_OP;
|
||||
|
||||
\*= return MUL_ASSIGN;
|
||||
\/= return DIV_ASSIGN;
|
||||
\+= return ADD_ASSIGN;
|
||||
\%= return MOD_ASSIGN;
|
||||
\<\<= return LEFT_ASSIGN;
|
||||
>>= return RIGHT_ASSIGN;
|
||||
&= return AND_ASSIGN;
|
||||
^= return XOR_ASSIGN;
|
||||
\|= return OR_ASSIGN;
|
||||
-= return SUB_ASSIGN;
|
||||
|
||||
[1-9][0-9]* {
|
||||
yylval->n = strtol(yytext, NULL, 10);
|
||||
return INTCONSTANT;
|
||||
}
|
||||
0[xX][0-9a-fA-F]+ {
|
||||
yylval->n = strtol(yytext + 2, NULL, 16);
|
||||
return INTCONSTANT;
|
||||
}
|
||||
0[0-7]* {
|
||||
yylval->n = strtol(yytext + 2, NULL, 8);
|
||||
return INTCONSTANT;
|
||||
}
|
||||
|
||||
[0-9]+\.[0-9]+([eE][+-]?[0-9]+)?[fF]? {
|
||||
yylval->real = strtod(yytext, NULL);
|
||||
return FLOATCONSTANT;
|
||||
}
|
||||
\.[0-9]+([eE][+-]?[0-9]+)?[fF]? {
|
||||
yylval->real = strtod(yytext, NULL);
|
||||
return FLOATCONSTANT;
|
||||
}
|
||||
[0-9]+\.([eE][+-]?[0-9]+)?[fF]? {
|
||||
yylval->real = strtod(yytext, NULL);
|
||||
return FLOATCONSTANT;
|
||||
}
|
||||
[0-9]+[eE][+-]?[0-9]+[fF]? {
|
||||
yylval->real = strtod(yytext, NULL);
|
||||
return FLOATCONSTANT;
|
||||
}
|
||||
|
||||
true {
|
||||
yylval->n = 1;
|
||||
return BOOLCONSTANT;
|
||||
}
|
||||
false {
|
||||
yylval->n = 0;
|
||||
return BOOLCONSTANT;
|
||||
}
|
||||
|
||||
|
||||
/* Reserved words in GLSL 1.10. */
|
||||
asm return ASM;
|
||||
class return CLASS;
|
||||
union return UNION;
|
||||
enum return ENUM;
|
||||
typedef return TYPEDEF;
|
||||
template return TEMPLATE;
|
||||
this return THIS;
|
||||
packed return PACKED;
|
||||
goto return GOTO;
|
||||
switch return SWITCH;
|
||||
default return DEFAULT;
|
||||
inline return INLINE;
|
||||
noinline return NOINLINE;
|
||||
volatile return VOLATILE;
|
||||
public return PUBLIC;
|
||||
static return STATIC;
|
||||
extern return EXTERN;
|
||||
external return EXTERNAL;
|
||||
interface return INTERFACE;
|
||||
long return LONG;
|
||||
short return SHORT;
|
||||
double return DOUBLE;
|
||||
half return HALF;
|
||||
fixed return FIXED;
|
||||
unsigned return UNSIGNED;
|
||||
input return INPUT;
|
||||
output return OUTPUT;
|
||||
hvec2 return HVEC2;
|
||||
hvec3 return HVEC3;
|
||||
hvec4 return HVEC4;
|
||||
dvec2 return DVEC2;
|
||||
dvec3 return DVEC3;
|
||||
dvec4 return DVEC4;
|
||||
fvec2 return FVEC2;
|
||||
fvec3 return FVEC3;
|
||||
fvec4 return FVEC4;
|
||||
sampler2DRect return SAMPLER2DRECT;
|
||||
sampler3DRect return SAMPLER3DRECT;
|
||||
sampler2DRectShadow return SAMPLER2DRECTSHADOW;
|
||||
sizeof return SIZEOF;
|
||||
cast return CAST;
|
||||
namespace return NAMESPACE;
|
||||
using return USING;
|
||||
|
||||
/* Additional reserved words in GLSL 1.20. */
|
||||
lowp return LOWP;
|
||||
mediump return MEDIUMP;
|
||||
highp return HIGHP;
|
||||
precision return PRECISION;
|
||||
|
||||
[_a-zA-Z][_a-zA-Z0-9]* {
|
||||
yylval->identifier = strdup(yytext);
|
||||
|
||||
if (_mesa_symbol_table_find_symbol(yyextra->symbols,
|
||||
0,
|
||||
yylval->identifier))
|
||||
return TYPE_NAME;
|
||||
else
|
||||
return IDENTIFIER;
|
||||
}
|
||||
|
||||
. { return yytext[0]; }
|
||||
|
||||
%%
|
||||
|
||||
void
|
||||
_mesa_glsl_lexer_ctor(struct _mesa_glsl_parse_state *state,
|
||||
const char *string, size_t len)
|
||||
{
|
||||
yylex_init_extra(state, & state->scanner);
|
||||
yy_scan_bytes(string, len, state->scanner);
|
||||
}
|
||||
|
||||
void
|
||||
_mesa_glsl_lexer_dtor(struct _mesa_glsl_parse_state *state)
|
||||
{
|
||||
yylex_destroy(state->scanner);
|
||||
}
|
||||
1228
glsl_parser.y
Normal file
1228
glsl_parser.y
Normal file
File diff suppressed because it is too large
Load diff
771
glsl_parser_extras.cc
Normal file
771
glsl_parser_extras.cc
Normal file
|
|
@ -0,0 +1,771 @@
|
|||
/*
|
||||
* Copyright © 2008, 2009 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ast.h"
|
||||
#include "glsl_parser_extras.h"
|
||||
#include "glsl_parser.tab.h"
|
||||
#include "symbol_table.h"
|
||||
|
||||
void
|
||||
_mesa_glsl_error(YYLTYPE *locp, void *state, const char *fmt, ...)
|
||||
{
|
||||
char buf[1024];
|
||||
int len;
|
||||
va_list ap;
|
||||
|
||||
(void) state;
|
||||
len = snprintf(buf, sizeof(buf), "%u:%u(%u): error: ",
|
||||
locp->source, locp->first_line, locp->first_column);
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf + len, sizeof(buf) - len, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
printf("%s\n", buf);
|
||||
}
|
||||
|
||||
|
||||
ast_node::~ast_node()
|
||||
{
|
||||
/* empty */
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q)
|
||||
{
|
||||
if (q->constant)
|
||||
printf("const ");
|
||||
|
||||
if (q->invariant)
|
||||
printf("invariant ");
|
||||
|
||||
if (q->attribute)
|
||||
printf("attribute ");
|
||||
|
||||
if (q->varying)
|
||||
printf("varying ");
|
||||
|
||||
if (q->in && q->out)
|
||||
printf("inout ");
|
||||
else {
|
||||
if (q->in)
|
||||
printf("in ");
|
||||
|
||||
if (q->out)
|
||||
printf("out ");
|
||||
}
|
||||
|
||||
if (q->centroid)
|
||||
printf("centroid ");
|
||||
if (q->uniform)
|
||||
printf("uniform ");
|
||||
if (q->smooth)
|
||||
printf("smooth ");
|
||||
if (q->flat)
|
||||
printf("flat ");
|
||||
if (q->noperspective)
|
||||
printf("noperspective ");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ast_node::print(void) const
|
||||
{
|
||||
printf("node_%d ", type);
|
||||
}
|
||||
|
||||
|
||||
ast_node::ast_node(void)
|
||||
{
|
||||
// make_empty_list(& ast->node);
|
||||
}
|
||||
|
||||
void
|
||||
ast_type_specifier::print(void) const
|
||||
{
|
||||
switch (type_specifier) {
|
||||
case ast_void: printf("void "); break;
|
||||
case ast_float: printf("float "); break;
|
||||
case ast_int: printf("int "); break;
|
||||
case ast_uint: printf("uint "); break;
|
||||
case ast_bool: printf("bool "); break;
|
||||
case ast_vec2: printf("vec2 "); break;
|
||||
case ast_vec3: printf("vec3 "); break;
|
||||
case ast_vec4: printf("vec4 "); break;
|
||||
case ast_bvec2: printf("bvec2 "); break;
|
||||
case ast_bvec3: printf("bvec3 "); break;
|
||||
case ast_bvec4: printf("bvec4 "); break;
|
||||
case ast_ivec2: printf("ivec2 "); break;
|
||||
case ast_ivec3: printf("ivec3 "); break;
|
||||
case ast_ivec4: printf("ivec4 "); break;
|
||||
case ast_uvec2: printf("uvec2 "); break;
|
||||
case ast_uvec3: printf("uvec3 "); break;
|
||||
case ast_uvec4: printf("uvec4 "); break;
|
||||
case ast_mat2: printf("mat2 "); break;
|
||||
case ast_mat2x3: printf("mat2x3 "); break;
|
||||
case ast_mat2x4: printf("mat2x4 "); break;
|
||||
case ast_mat3x2: printf("mat3x2 "); break;
|
||||
case ast_mat3: printf("mat3 "); break;
|
||||
case ast_mat3x4: printf("mat3x4 "); break;
|
||||
case ast_mat4x2: printf("mat4x2 "); break;
|
||||
case ast_mat4x3: printf("mat4x3 "); break;
|
||||
case ast_mat4: printf("mat4 "); break;
|
||||
case ast_sampler1d: printf("sampler1d "); break;
|
||||
case ast_sampler2d: printf("sampler2d "); break;
|
||||
case ast_sampler3d: printf("sampler3d "); break;
|
||||
case ast_samplercube: printf("samplercube "); break;
|
||||
case ast_sampler1dshadow: printf("sampler1dshadow "); break;
|
||||
case ast_sampler2dshadow: printf("sampler2dshadow "); break;
|
||||
case ast_samplercubeshadow: printf("samplercubeshadow "); break;
|
||||
case ast_sampler1darray: printf("sampler1darray "); break;
|
||||
case ast_sampler2darray: printf("sampler2darray "); break;
|
||||
case ast_sampler1darrayshadow: printf("sampler1darrayshadow "); break;
|
||||
case ast_sampler2darrayshadow: printf("sampler2darrayshadow "); break;
|
||||
case ast_isampler1d: printf("isampler1d "); break;
|
||||
case ast_isampler2d: printf("isampler2d "); break;
|
||||
case ast_isampler3d: printf("isampler3d "); break;
|
||||
case ast_isamplercube: printf("isamplercube "); break;
|
||||
case ast_isampler1darray: printf("isampler1darray "); break;
|
||||
case ast_isampler2darray: printf("isampler2darray "); break;
|
||||
case ast_usampler1d: printf("usampler1d "); break;
|
||||
case ast_usampler2d: printf("usampler2d "); break;
|
||||
case ast_usampler3d: printf("usampler3d "); break;
|
||||
case ast_usamplercube: printf("usamplercube "); break;
|
||||
case ast_usampler1darray: printf("usampler1darray "); break;
|
||||
case ast_usampler2darray: printf("usampler2darray "); break;
|
||||
|
||||
case ast_struct:
|
||||
structure->print();
|
||||
break;
|
||||
|
||||
case ast_type_name: printf("%s ", type_name); break;
|
||||
}
|
||||
|
||||
if (is_array) {
|
||||
printf("[ ");
|
||||
|
||||
if (array_size) {
|
||||
array_size->print();
|
||||
}
|
||||
|
||||
printf("] ");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ast_opt_array_size_print(bool is_array, const ast_expression *array_size)
|
||||
{
|
||||
if (is_array) {
|
||||
printf("[ ");
|
||||
|
||||
if (array_size)
|
||||
array_size->print();
|
||||
|
||||
printf("] ");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ast_type_specifier::ast_type_specifier(int specifier)
|
||||
{
|
||||
type_specifier = ast_types(specifier);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ast_compound_statement::print(void) const
|
||||
{
|
||||
const struct simple_node *ptr;
|
||||
|
||||
printf("{\n");
|
||||
|
||||
foreach(ptr, & statements) {
|
||||
_mesa_ast_print(ptr);
|
||||
}
|
||||
|
||||
printf("}\n");
|
||||
}
|
||||
|
||||
|
||||
ast_compound_statement::ast_compound_statement(int new_scope,
|
||||
ast_node *statements)
|
||||
{
|
||||
this->new_scope = new_scope;
|
||||
make_empty_list(& this->statements);
|
||||
|
||||
if (statements != NULL) {
|
||||
/* This seems odd, but it works. The simple_list is,
|
||||
* basically, a circular list. insert_at_tail adds
|
||||
* the specified node to the list before the current
|
||||
* head.
|
||||
*/
|
||||
insert_at_tail((struct simple_node *) statements,
|
||||
& this->statements);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ast_expression::print(void) const
|
||||
{
|
||||
static const char *const operators[] = {
|
||||
"=",
|
||||
"+",
|
||||
"-",
|
||||
"+",
|
||||
"-",
|
||||
"*",
|
||||
"/",
|
||||
"%",
|
||||
"<<",
|
||||
">>",
|
||||
"<",
|
||||
">",
|
||||
"<=",
|
||||
">=",
|
||||
"==",
|
||||
"!=",
|
||||
"&",
|
||||
"^",
|
||||
"|",
|
||||
"~",
|
||||
"&&",
|
||||
"^^",
|
||||
"!",
|
||||
|
||||
"*=",
|
||||
"/=",
|
||||
"%=",
|
||||
"+=",
|
||||
"-=",
|
||||
"<<=",
|
||||
">>=",
|
||||
"&=",
|
||||
"^=",
|
||||
"|=",
|
||||
|
||||
"?:",
|
||||
"++",
|
||||
"--",
|
||||
"++",
|
||||
"--",
|
||||
".",
|
||||
};
|
||||
|
||||
|
||||
switch (oper) {
|
||||
case ast_assign:
|
||||
case ast_add:
|
||||
case ast_sub:
|
||||
case ast_mul:
|
||||
case ast_div:
|
||||
case ast_mod:
|
||||
case ast_lshift:
|
||||
case ast_rshift:
|
||||
case ast_less:
|
||||
case ast_greater:
|
||||
case ast_lequal:
|
||||
case ast_gequal:
|
||||
case ast_equal:
|
||||
case ast_nequal:
|
||||
case ast_bit_and:
|
||||
case ast_bit_xor:
|
||||
case ast_bit_or:
|
||||
case ast_logic_and:
|
||||
case ast_logic_xor:
|
||||
case ast_logic_or:
|
||||
case ast_mul_assign:
|
||||
case ast_div_assign:
|
||||
case ast_mod_assign:
|
||||
case ast_add_assign:
|
||||
case ast_sub_assign:
|
||||
case ast_ls_assign:
|
||||
case ast_rs_assign:
|
||||
case ast_and_assign:
|
||||
case ast_xor_assign:
|
||||
case ast_or_assign:
|
||||
subexpressions[0]->print();
|
||||
printf("%s ", operators[oper]);
|
||||
subexpressions[1]->print();
|
||||
break;
|
||||
|
||||
case ast_field_selection:
|
||||
subexpressions[0]->print();
|
||||
printf(". %s ", primary_expression.identifier);
|
||||
break;
|
||||
|
||||
case ast_plus:
|
||||
case ast_neg:
|
||||
case ast_bit_not:
|
||||
case ast_logic_not:
|
||||
case ast_pre_inc:
|
||||
case ast_pre_dec:
|
||||
printf("%s ", operators[oper]);
|
||||
subexpressions[0]->print();
|
||||
break;
|
||||
|
||||
case ast_post_inc:
|
||||
case ast_post_dec:
|
||||
subexpressions[0]->print();
|
||||
printf("%s ", operators[oper]);
|
||||
break;
|
||||
|
||||
case ast_conditional:
|
||||
subexpressions[0]->print();
|
||||
printf("? ");
|
||||
subexpressions[1]->print();
|
||||
printf(": ");
|
||||
subexpressions[1]->print();
|
||||
break;
|
||||
|
||||
case ast_array_index:
|
||||
subexpressions[0]->print();
|
||||
printf("[ ");
|
||||
subexpressions[1]->print();
|
||||
printf("] ");
|
||||
break;
|
||||
|
||||
case ast_function_call: {
|
||||
ast_expression *parameters = subexpressions[1];
|
||||
|
||||
subexpressions[0]->print();
|
||||
printf("( ");
|
||||
|
||||
if (parameters != NULL) {
|
||||
struct simple_node *ptr;
|
||||
|
||||
parameters->print();
|
||||
foreach (ptr, (struct simple_node *) parameters) {
|
||||
printf(", ");
|
||||
_mesa_ast_print(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
printf(") ");
|
||||
break;
|
||||
}
|
||||
|
||||
case ast_identifier:
|
||||
printf("%s ", primary_expression.identifier);
|
||||
break;
|
||||
|
||||
case ast_int_constant:
|
||||
printf("%d ", primary_expression.int_constant);
|
||||
break;
|
||||
|
||||
case ast_uint_constant:
|
||||
printf("%u ", primary_expression.uint_constant);
|
||||
break;
|
||||
|
||||
case ast_float_constant:
|
||||
printf("%f ", primary_expression.float_constant);
|
||||
break;
|
||||
|
||||
case ast_bool_constant:
|
||||
printf("%s ",
|
||||
primary_expression.bool_constant
|
||||
? "true" : "false");
|
||||
break;
|
||||
|
||||
case ast_sequence: {
|
||||
struct simple_node *ptr;
|
||||
struct simple_node *const head = first_elem(& expressions);
|
||||
|
||||
printf("( ");
|
||||
foreach (ptr, & expressions) {
|
||||
if (ptr != head)
|
||||
printf(", ");
|
||||
|
||||
_mesa_ast_print(ptr);
|
||||
}
|
||||
printf(") ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ast_expression::ast_expression(int oper,
|
||||
ast_expression *ex0,
|
||||
ast_expression *ex1,
|
||||
ast_expression *ex2)
|
||||
{
|
||||
this->oper = ast_operators(oper);
|
||||
this->subexpressions[0] = ex0;
|
||||
this->subexpressions[1] = ex1;
|
||||
this->subexpressions[2] = ex2;
|
||||
make_empty_list(& expressions);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ast_expression_statement::print(void) const
|
||||
{
|
||||
if (expression)
|
||||
expression->print();
|
||||
|
||||
printf("; ");
|
||||
}
|
||||
|
||||
|
||||
ast_expression_statement::ast_expression_statement(ast_expression *ex) :
|
||||
expression(ex)
|
||||
{
|
||||
/* empty */
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ast_function::print(void) const
|
||||
{
|
||||
struct simple_node *ptr;
|
||||
|
||||
return_type->print();
|
||||
printf(" %s (", identifier);
|
||||
|
||||
foreach(ptr, & parameters) {
|
||||
_mesa_ast_print(ptr);
|
||||
}
|
||||
|
||||
printf(")");
|
||||
}
|
||||
|
||||
|
||||
ast_function::ast_function(void)
|
||||
{
|
||||
make_empty_list(& parameters);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ast_fully_specified_type::print(void) const
|
||||
{
|
||||
_mesa_ast_type_qualifier_print(& qualifier);
|
||||
specifier->print();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ast_parameter_declarator::print(void) const
|
||||
{
|
||||
type->print();
|
||||
if (identifier)
|
||||
printf("%s ", identifier);
|
||||
ast_opt_array_size_print(is_array, array_size);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ast_function_definition::print(void) const
|
||||
{
|
||||
prototype->print();
|
||||
body->print();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ast_declaration::print(void) const
|
||||
{
|
||||
printf("%s ", identifier);
|
||||
ast_opt_array_size_print(is_array, array_size);
|
||||
|
||||
if (initializer) {
|
||||
printf("= ");
|
||||
initializer->print();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ast_declaration::ast_declaration(char *identifier, int is_array,
|
||||
ast_expression *array_size,
|
||||
ast_expression *initializer)
|
||||
{
|
||||
this->identifier = identifier;
|
||||
this->is_array = is_array;
|
||||
this->array_size = array_size;
|
||||
this->initializer = initializer;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ast_declarator_list::print(void) const
|
||||
{
|
||||
struct simple_node *head;
|
||||
struct simple_node *ptr;
|
||||
|
||||
assert(type || invariant);
|
||||
|
||||
if (type)
|
||||
type->print();
|
||||
else
|
||||
printf("invariant ");
|
||||
|
||||
head = first_elem(& declarations);
|
||||
foreach (ptr, & declarations) {
|
||||
if (ptr != head)
|
||||
printf(", ");
|
||||
|
||||
_mesa_ast_print(ptr);
|
||||
}
|
||||
|
||||
printf("; ");
|
||||
}
|
||||
|
||||
|
||||
ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type)
|
||||
{
|
||||
this->type = type;
|
||||
make_empty_list(& this->declarations);
|
||||
}
|
||||
|
||||
void
|
||||
ast_jump_statement::print(void) const
|
||||
{
|
||||
switch (mode) {
|
||||
case ast_continue:
|
||||
printf("continue; ");
|
||||
break;
|
||||
case ast_break:
|
||||
printf("break; ");
|
||||
break;
|
||||
case ast_return:
|
||||
printf("return ");
|
||||
if (opt_return_value)
|
||||
opt_return_value->print();
|
||||
|
||||
printf("; ");
|
||||
break;
|
||||
case ast_discard:
|
||||
printf("discard; ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ast_jump_statement::ast_jump_statement(int mode, ast_expression *return_value)
|
||||
{
|
||||
this->mode = ast_jump_modes(mode);
|
||||
|
||||
if (mode == ast_return)
|
||||
opt_return_value = return_value;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ast_selection_statement::print(void) const
|
||||
{
|
||||
printf("if ( ");
|
||||
condition->print();
|
||||
printf(") ");
|
||||
|
||||
then_statement->print();
|
||||
|
||||
if (else_statement) {
|
||||
printf("else ");
|
||||
else_statement->print();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
ast_selection_statement::ast_selection_statement(ast_expression *condition,
|
||||
ast_node *then_statement,
|
||||
ast_node *else_statement)
|
||||
{
|
||||
this->condition = condition;
|
||||
this->then_statement = then_statement;
|
||||
this->else_statement = else_statement;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ast_iteration_statement::print(void) const
|
||||
{
|
||||
switch (mode) {
|
||||
case ast_for:
|
||||
printf("for( ");
|
||||
if (init_statement)
|
||||
init_statement->print();
|
||||
printf("; ");
|
||||
|
||||
if (condition)
|
||||
condition->print();
|
||||
printf("; ");
|
||||
|
||||
if (rest_expression)
|
||||
rest_expression->print();
|
||||
printf(") ");
|
||||
|
||||
body->print();
|
||||
break;
|
||||
|
||||
case ast_while:
|
||||
printf("while ( ");
|
||||
if (condition)
|
||||
condition->print();
|
||||
printf(") ");
|
||||
body->print();
|
||||
break;
|
||||
|
||||
case ast_do_while:
|
||||
printf("do ");
|
||||
body->print();
|
||||
printf("while ( ");
|
||||
if (condition)
|
||||
condition->print();
|
||||
printf("); ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ast_iteration_statement::ast_iteration_statement(int mode,
|
||||
ast_node *init,
|
||||
ast_node *condition,
|
||||
ast_expression *rest_expression,
|
||||
ast_node *body)
|
||||
{
|
||||
this->mode = ast_iteration_modes(mode);
|
||||
this->init_statement = init;
|
||||
this->condition = condition;
|
||||
this->rest_expression = rest_expression;
|
||||
this->body = body;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ast_struct_specifier::print(void) const
|
||||
{
|
||||
struct simple_node *ptr;
|
||||
|
||||
printf("struct %s { ", name);
|
||||
foreach (ptr, & declarations) {
|
||||
_mesa_ast_print(ptr);
|
||||
}
|
||||
printf("} ");
|
||||
}
|
||||
|
||||
|
||||
ast_struct_specifier::ast_struct_specifier(char *identifier,
|
||||
ast_node *declarator_list)
|
||||
{
|
||||
name = identifier;
|
||||
|
||||
/* This seems odd, but it works. The simple_list is,
|
||||
* basically, a circular list. insert_at_tail adds
|
||||
* the specified node to the list before the current
|
||||
* head.
|
||||
*/
|
||||
insert_at_tail((struct simple_node *) declarator_list,
|
||||
& declarations);
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
load_text_file(const char *file_name, size_t *size)
|
||||
{
|
||||
char *text = NULL;
|
||||
struct stat st;
|
||||
ssize_t total_read = 0;
|
||||
int fd = open(file_name, O_RDONLY);
|
||||
|
||||
*size = 0;
|
||||
if (fd < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fstat(fd, & st) == 0) {
|
||||
text = (char *) malloc(st.st_size + 1);
|
||||
if (text != NULL) {
|
||||
do {
|
||||
ssize_t bytes = read(fd, text + total_read,
|
||||
st.st_size - total_read);
|
||||
if (bytes < 0) {
|
||||
free(text);
|
||||
text = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bytes == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
total_read += bytes;
|
||||
} while (total_read < st.st_size);
|
||||
|
||||
text[total_read] = '\0';
|
||||
*size = total_read;
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
struct _mesa_glsl_parse_state state;
|
||||
char *shader;
|
||||
size_t shader_len;
|
||||
struct simple_node *ptr;
|
||||
struct simple_node instructions;
|
||||
|
||||
(void) argc;
|
||||
shader = load_text_file(argv[1], & shader_len);
|
||||
|
||||
state.scanner = NULL;
|
||||
make_empty_list(& state.translation_unit);
|
||||
state.symbols = _mesa_symbol_table_ctor();
|
||||
|
||||
_mesa_glsl_lexer_ctor(& state, shader, shader_len);
|
||||
_mesa_glsl_parse(& state);
|
||||
_mesa_glsl_lexer_dtor(& state);
|
||||
|
||||
foreach (ptr, & state.translation_unit) {
|
||||
_mesa_ast_print(ptr);
|
||||
}
|
||||
|
||||
#if 0
|
||||
make_empty_list(& instructions);
|
||||
foreach (ptr, & state.translation_unit) {
|
||||
_mesa_ast_to_hir(ptr, &instructions, &state);
|
||||
}
|
||||
#endif
|
||||
|
||||
_mesa_symbol_table_dtor(state.symbols);
|
||||
|
||||
return 0;
|
||||
}
|
||||
68
glsl_parser_extras.h
Normal file
68
glsl_parser_extras.h
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright © 2010 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GLSL_PARSER_EXTRAS_H
|
||||
#define GLSL_PARSER_EXTRAS_H
|
||||
|
||||
#include "main/simple_list.h"
|
||||
|
||||
enum _mesa_glsl_parser_targets {
|
||||
vertex_shader,
|
||||
geometry_shader,
|
||||
fragment_shader
|
||||
};
|
||||
|
||||
struct _mesa_glsl_parse_state {
|
||||
void *scanner;
|
||||
struct simple_node translation_unit;
|
||||
struct _mesa_symbol_table *symbols;
|
||||
|
||||
unsigned language_version;
|
||||
enum _mesa_glsl_parser_targets target;
|
||||
};
|
||||
|
||||
typedef struct YYLTYPE {
|
||||
int first_line;
|
||||
int first_column;
|
||||
int last_line;
|
||||
int last_column;
|
||||
unsigned source;
|
||||
} YYLTYPE;
|
||||
# define YYLTYPE_IS_DECLARED 1
|
||||
# define YYLTYPE_IS_TRIVIAL 1
|
||||
|
||||
extern void _mesa_glsl_error(YYLTYPE *locp, void *state, const char *fmt, ...);
|
||||
|
||||
extern void _mesa_glsl_lexer_ctor(struct _mesa_glsl_parse_state *state,
|
||||
const char *string, size_t len);
|
||||
|
||||
extern void _mesa_glsl_lexer_dtor(struct _mesa_glsl_parse_state *state);
|
||||
|
||||
union YYSTYPE;
|
||||
extern int _mesa_glsl_lex(union YYSTYPE *yylval, YYLTYPE *yylloc,
|
||||
void *scanner);
|
||||
|
||||
extern int _mesa_glsl_parse(struct _mesa_glsl_parse_state *);
|
||||
|
||||
#endif /* GLSL_PARSER_EXTRAS_H */
|
||||
159
glsl_types.c
Normal file
159
glsl_types.c
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Copyright © 2009 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "symbol_table.h"
|
||||
#include "glsl_parser_extras.h"
|
||||
#include "glsl_types.h"
|
||||
#include "builtin_types.h"
|
||||
|
||||
|
||||
struct glsl_type *
|
||||
_mesa_glsl_array_type_ctor(struct glsl_type *base, unsigned length,
|
||||
const char *name)
|
||||
{
|
||||
struct glsl_type *type = calloc(1, sizeof(*type));
|
||||
|
||||
type->base_type = GLSL_TYPE_ARRAY;
|
||||
type->name = name;
|
||||
type->length = length;
|
||||
type->fields.array = base;
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
add_types_to_symbol_table(struct _mesa_symbol_table *symtab,
|
||||
const struct glsl_type *types,
|
||||
unsigned num_types)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < num_types; i++) {
|
||||
_mesa_symbol_table_add_symbol(symtab, 0, types[i].name,
|
||||
(void *) & types[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
generate_110_types(struct _mesa_symbol_table *symtab)
|
||||
{
|
||||
add_types_to_symbol_table(symtab, builtin_core_types,
|
||||
Elements(builtin_core_types));
|
||||
add_types_to_symbol_table(symtab, builtin_structure_types,
|
||||
Elements(builtin_structure_types));
|
||||
add_types_to_symbol_table(symtab, builtin_110_deprecated_structure_types,
|
||||
Elements(builtin_110_deprecated_structure_types));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
generate_120_types(struct _mesa_symbol_table *symtab)
|
||||
{
|
||||
generate_110_types(symtab);
|
||||
|
||||
add_types_to_symbol_table(symtab, builtin_120_types,
|
||||
Elements(builtin_120_types));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
generate_130_types(struct _mesa_symbol_table *symtab)
|
||||
{
|
||||
generate_120_types(symtab);
|
||||
|
||||
add_types_to_symbol_table(symtab, builtin_130_types,
|
||||
Elements(builtin_130_types));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state)
|
||||
{
|
||||
switch (state->language_version) {
|
||||
case 110:
|
||||
generate_110_types(state->symbols);
|
||||
break;
|
||||
case 120:
|
||||
generate_120_types(state->symbols);
|
||||
break;
|
||||
case 130:
|
||||
generate_130_types(state->symbols);
|
||||
break;
|
||||
default:
|
||||
/* error */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const struct glsl_type *
|
||||
_mesa_glsl_get_vector_type(unsigned base_type, unsigned vector_length)
|
||||
{
|
||||
switch (base_type) {
|
||||
case GLSL_TYPE_UINT:
|
||||
switch (vector_length) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
return glsl_uint_type + (vector_length - 1);
|
||||
default:
|
||||
return glsl_error_type;
|
||||
}
|
||||
case GLSL_TYPE_INT:
|
||||
switch (vector_length) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
return glsl_int_type + (vector_length - 1);
|
||||
default:
|
||||
return glsl_error_type;
|
||||
}
|
||||
case GLSL_TYPE_FLOAT:
|
||||
switch (vector_length) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
return glsl_float_type + (vector_length - 1);
|
||||
default:
|
||||
return glsl_error_type;
|
||||
}
|
||||
case GLSL_TYPE_BOOL:
|
||||
switch (vector_length) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
return glsl_bool_type + (vector_length - 1);
|
||||
default:
|
||||
return glsl_error_type;
|
||||
}
|
||||
default:
|
||||
return glsl_error_type;
|
||||
}
|
||||
}
|
||||
141
glsl_types.h
Normal file
141
glsl_types.h
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Copyright © 2009 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef GLSL_TYPES_H
|
||||
#define GLSL_TYPES_H
|
||||
|
||||
#define GLSL_TYPE_UINT 0
|
||||
#define GLSL_TYPE_INT 1
|
||||
#define GLSL_TYPE_FLOAT 2
|
||||
#define GLSL_TYPE_BOOL 3
|
||||
#define GLSL_TYPE_SAMPLER 4
|
||||
#define GLSL_TYPE_STRUCT 5
|
||||
#define GLSL_TYPE_ARRAY 6
|
||||
#define GLSL_TYPE_FUNCTION 7
|
||||
#define GLSL_TYPE_VOID 8
|
||||
#define GLSL_TYPE_ERROR 9
|
||||
|
||||
#define is_numeric_base_type(b) \
|
||||
(((b) >= GLSL_TYPE_UINT) && ((b) <= GLSL_TYPE_FLOAT))
|
||||
|
||||
#define is_integer_base_type(b) \
|
||||
(((b) == GLSL_TYPE_UINT) || ((b) == GLSL_TYPE_INT))
|
||||
|
||||
#define is_error_type(t) ((t)->base_type == GLSL_TYPE_ERROR)
|
||||
|
||||
#define GLSL_SAMPLER_DIM_1D 0
|
||||
#define GLSL_SAMPLER_DIM_2D 1
|
||||
#define GLSL_SAMPLER_DIM_3D 2
|
||||
#define GLSL_SAMPLER_DIM_CUBE 3
|
||||
#define GLSL_SAMPLER_DIM_RECT 4
|
||||
#define GLSL_SAMPLER_DIM_BUF 5
|
||||
|
||||
|
||||
struct glsl_type {
|
||||
unsigned base_type:4;
|
||||
|
||||
unsigned sampler_dimensionality:3;
|
||||
unsigned sampler_shadow:1;
|
||||
unsigned sampler_array:1;
|
||||
unsigned sampler_type:2; /**< Type of data returned using this sampler.
|
||||
* only \c GLSL_TYPE_FLOAT, \c GLSL_TYPE_INT,
|
||||
* and \c GLSL_TYPE_UINT are valid.
|
||||
*/
|
||||
|
||||
unsigned vector_elements:3; /**< 0, 2, 3, or 4 vector elements. */
|
||||
unsigned matrix_rows:3; /**< 0, 2, 3, or 4 matrix rows. */
|
||||
|
||||
/**
|
||||
* Name of the data type
|
||||
*
|
||||
* This may be \c NULL for anonymous structures, for arrays, or for
|
||||
* function types.
|
||||
*/
|
||||
const char *name;
|
||||
|
||||
/**
|
||||
* For \c GLSL_TYPE_ARRAY, this is the length of the array. For
|
||||
* \c GLSL_TYPE_STRUCT, it is the number of elements in the structure and
|
||||
* the number of values pointed to by \c fields.structure (below).
|
||||
*
|
||||
* For \c GLSL_TYPE_FUNCTION, it is the number of parameters to the
|
||||
* function. The return value from a function is implicitly the first
|
||||
* parameter. The types of the parameters are stored in
|
||||
* \c fields.parameters (below).
|
||||
*/
|
||||
unsigned length;
|
||||
|
||||
/**
|
||||
* Subtype of composite data types.
|
||||
*/
|
||||
union {
|
||||
const struct glsl_type *array; /**< Type of array elements. */
|
||||
const struct glsl_type *parameters; /**< Parameters to function. */
|
||||
const struct glsl_struct_field *structure;/**< List of struct fields. */
|
||||
} fields;
|
||||
};
|
||||
|
||||
#define is_glsl_type_scalar(t) \
|
||||
(((t)->vector_elements == 0) \
|
||||
&& ((t)->base_type >= GLSL_TYPE_UINT) \
|
||||
&& ((t)->base_type <= GLSL_TYPE_BOOL))
|
||||
|
||||
#define is_glsl_type_vector(t) \
|
||||
(((t)->vector_elements > 0) \
|
||||
&& ((t)->matrix_rows == 0) \
|
||||
&& ((t)->base_type >= GLSL_TYPE_UINT) \
|
||||
&& ((t)->base_type <= GLSL_TYPE_BOOL))
|
||||
|
||||
#define is_glsl_type_matrix(t) \
|
||||
(((t)->matrix_rows > 0) \
|
||||
&& ((t)->base_type == GLSL_TYPE_FLOAT)) /* GLSL only has float matrices. */
|
||||
|
||||
struct glsl_struct_field {
|
||||
const struct glsl_type *type;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct _mesa_glsl_parse_state;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void
|
||||
_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state);
|
||||
|
||||
extern const struct glsl_type *
|
||||
_mesa_glsl_get_vector_type(unsigned base_type, unsigned vector_length);
|
||||
|
||||
extern const struct glsl_type *const glsl_error_type;
|
||||
extern const struct glsl_type *const glsl_int_type;
|
||||
extern const struct glsl_type *const glsl_uint_type;
|
||||
extern const struct glsl_type *const glsl_float_type;
|
||||
extern const struct glsl_type *const glsl_bool_type;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GLSL_TYPES_H */
|
||||
159
hash_table.c
Normal file
159
hash_table.c
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Copyright © 2008 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file hash_table.c
|
||||
* \brief Implementation of a generic, opaque hash table data type.
|
||||
*
|
||||
* \author Ian Romanick <ian.d.romanick@intel.com>
|
||||
*/
|
||||
|
||||
#include "main/imports.h"
|
||||
#include "main/simple_list.h"
|
||||
#include "hash_table.h"
|
||||
|
||||
struct node {
|
||||
struct node *next;
|
||||
struct node *prev;
|
||||
};
|
||||
|
||||
struct hash_table {
|
||||
hash_func_t hash;
|
||||
hash_compare_func_t compare;
|
||||
|
||||
unsigned num_buckets;
|
||||
struct node buckets[1];
|
||||
};
|
||||
|
||||
|
||||
struct hash_node {
|
||||
struct node link;
|
||||
const void *key;
|
||||
void *data;
|
||||
};
|
||||
|
||||
|
||||
struct hash_table *
|
||||
hash_table_ctor(unsigned num_buckets, hash_func_t hash,
|
||||
hash_compare_func_t compare)
|
||||
{
|
||||
struct hash_table *ht;
|
||||
unsigned i;
|
||||
|
||||
|
||||
if (num_buckets < 16) {
|
||||
num_buckets = 16;
|
||||
}
|
||||
|
||||
ht = _mesa_malloc(sizeof(*ht) + ((num_buckets - 1)
|
||||
* sizeof(ht->buckets[0])));
|
||||
if (ht != NULL) {
|
||||
ht->hash = hash;
|
||||
ht->compare = compare;
|
||||
ht->num_buckets = num_buckets;
|
||||
|
||||
for (i = 0; i < num_buckets; i++) {
|
||||
make_empty_list(& ht->buckets[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return ht;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hash_table_dtor(struct hash_table *ht)
|
||||
{
|
||||
hash_table_clear(ht);
|
||||
_mesa_free(ht);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hash_table_clear(struct hash_table *ht)
|
||||
{
|
||||
struct node *node;
|
||||
struct node *temp;
|
||||
unsigned i;
|
||||
|
||||
|
||||
for (i = 0; i < ht->num_buckets; i++) {
|
||||
foreach_s(node, temp, & ht->buckets[i]) {
|
||||
remove_from_list(node);
|
||||
_mesa_free(node);
|
||||
}
|
||||
|
||||
assert(is_empty_list(& ht->buckets[i]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
hash_table_find(struct hash_table *ht, const void *key)
|
||||
{
|
||||
const unsigned hash_value = (*ht->hash)(key);
|
||||
const unsigned bucket = hash_value % ht->num_buckets;
|
||||
struct node *node;
|
||||
|
||||
foreach(node, & ht->buckets[bucket]) {
|
||||
struct hash_node *hn = (struct hash_node *) node;
|
||||
|
||||
if ((*ht->compare)(hn->key, key) == 0) {
|
||||
return hn->data;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hash_table_insert(struct hash_table *ht, void *data, const void *key)
|
||||
{
|
||||
const unsigned hash_value = (*ht->hash)(key);
|
||||
const unsigned bucket = hash_value % ht->num_buckets;
|
||||
struct hash_node *node;
|
||||
|
||||
node = _mesa_calloc(sizeof(*node));
|
||||
|
||||
node->data = data;
|
||||
node->key = key;
|
||||
|
||||
insert_at_head(& ht->buckets[bucket], & node->link);
|
||||
}
|
||||
|
||||
|
||||
unsigned
|
||||
hash_table_string_hash(const void *key)
|
||||
{
|
||||
const char *str = (const char *) key;
|
||||
unsigned hash = 5381;
|
||||
|
||||
|
||||
while (*str != '\0') {
|
||||
hash = (hash * 33) + *str;
|
||||
str++;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
117
hash_table.h
Normal file
117
hash_table.h
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright © 2008 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file hash_table.h
|
||||
* \brief Implementation of a generic, opaque hash table data type.
|
||||
*
|
||||
* \author Ian Romanick <ian.d.romanick@intel.com>
|
||||
*/
|
||||
|
||||
#ifndef HASH_TABLE_H
|
||||
#define HASH_TABLE_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
struct hash_table;
|
||||
|
||||
typedef unsigned (*hash_func_t)(const void *key);
|
||||
typedef int (*hash_compare_func_t)(const void *key1, const void *key2);
|
||||
|
||||
/**
|
||||
* Hash table constructor
|
||||
*
|
||||
* Creates a hash table with the specified number of buckets. The supplied
|
||||
* \c hash and \c compare routines are used when adding elements to the table
|
||||
* and when searching for elements in the table.
|
||||
*
|
||||
* \param num_buckets Number of buckets (bins) in the hash table.
|
||||
* \param hash Function used to compute hash value of input keys.
|
||||
* \param compare Function used to compare keys.
|
||||
*/
|
||||
extern struct hash_table *hash_table_ctor(unsigned num_buckets,
|
||||
hash_func_t hash, hash_compare_func_t compare);
|
||||
|
||||
|
||||
/**
|
||||
* Release all memory associated with a hash table
|
||||
*
|
||||
* \warning
|
||||
* This function cannot release memory occupied either by keys or data.
|
||||
*/
|
||||
extern void hash_table_dtor(struct hash_table *ht);
|
||||
|
||||
|
||||
/**
|
||||
* Flush all entries from a hash table
|
||||
*
|
||||
* \param ht Table to be cleared of its entries.
|
||||
*/
|
||||
extern void hash_table_clear(struct hash_table *ht);
|
||||
|
||||
|
||||
/**
|
||||
* Search a hash table for a specific element
|
||||
*
|
||||
* \param ht Table to be searched
|
||||
* \param key Key of the desired element
|
||||
*
|
||||
* \return
|
||||
* The \c data value supplied to \c hash_table_insert when the element with
|
||||
* the matching key was added. If no matching key exists in the table,
|
||||
* \c NULL is returned.
|
||||
*/
|
||||
extern void *hash_table_find(struct hash_table *ht, const void *key);
|
||||
|
||||
|
||||
/**
|
||||
* Add an element to a hash table
|
||||
*/
|
||||
extern void hash_table_insert(struct hash_table *ht, void *data,
|
||||
const void *key);
|
||||
|
||||
|
||||
/**
|
||||
* Compute hash value of a string
|
||||
*
|
||||
* Computes the hash value of a string using the DJB2 algorithm developed by
|
||||
* Professor Daniel J. Bernstein. It was published on comp.lang.c once upon
|
||||
* a time. I was unable to find the original posting in the archives.
|
||||
*
|
||||
* \param key Pointer to a NUL terminated string to be hashed.
|
||||
*
|
||||
* \sa hash_table_string_compare
|
||||
*/
|
||||
extern unsigned hash_table_string_hash(const void *key);
|
||||
|
||||
|
||||
/**
|
||||
* Compare two strings used as keys
|
||||
*
|
||||
* This is just a macro wrapper around \c strcmp.
|
||||
*
|
||||
* \sa hash_table_string_hash
|
||||
*/
|
||||
#define hash_table_string_compare ((hash_compare_func_t) strcmp)
|
||||
|
||||
#endif /* HASH_TABLE_H */
|
||||
187
hir_field_selection.cc
Normal file
187
hir_field_selection.cc
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* Copyright © 2010 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "main/imports.h"
|
||||
#include "symbol_table.h"
|
||||
#include "glsl_parser_extras.h"
|
||||
#include "ast.h"
|
||||
#include "glsl_types.h"
|
||||
#include "ir.h"
|
||||
|
||||
#define X 1
|
||||
#define R 5
|
||||
#define S 9
|
||||
#define I 13
|
||||
|
||||
static bool
|
||||
generate_swizzle(const char *str, struct ir_swizzle_mask *swiz,
|
||||
unsigned vector_length)
|
||||
{
|
||||
/* For each possible swizzle character, this table encodes the value in
|
||||
* \c idx_map that represents the 0th element of the vector. For invalid
|
||||
* swizzle characters (e.g., 'k'), a special value is used that will allow
|
||||
* detection of errors.
|
||||
*/
|
||||
unsigned char base_idx[26] = {
|
||||
/* a b c d e f g h i j k l m */
|
||||
R, R, I, I, I, I, R, I, I, I, I, I, I,
|
||||
/* n o p q r s t u v w x y z */
|
||||
I, I, S, S, R, S, S, I, I, X, X, X, X
|
||||
};
|
||||
|
||||
/* Each valid swizzle character has an entry in the previous table. This
|
||||
* table encodes the base index encoded in the previous table plus the actual
|
||||
* index of the swizzle character. When processing swizzles, the first
|
||||
* character in the string is indexed in the previous table. Each character
|
||||
* in the string is indexed in this table, and the value found there has the
|
||||
* value form the first table subtracted. The result must be on the range
|
||||
* [0,3].
|
||||
*
|
||||
* For example, the string "wzyx" will get X from the first table. Each of
|
||||
* the charcaters will get X+3, X+2, X+1, and X+0 from this table. After
|
||||
* subtraction, the swizzle values are { 3, 2, 1, 0 }.
|
||||
*
|
||||
* The string "wzrg" will get X from the first table. Each of the characters
|
||||
* will get X+3, X+2, R+0, and R+1 from this table. After subtraction, the
|
||||
* swizzle values are { 3, 2, 4, 5 }. Since 4 and 5 are outside the range
|
||||
* [0,3], the error is detected.
|
||||
*/
|
||||
unsigned char idx_map[26] = {
|
||||
/* a b c d e f g h i j k l m */
|
||||
R+3, R+2, 0, 0, 0, 0, R+1, 0, 0, 0, 0, 0, 0,
|
||||
/* n o p q r s t u v w x y z */
|
||||
0, 0, S+2, S+3, R+0, S+0, S+1, 0, 0, X+3, X+0, X+1, X+2
|
||||
};
|
||||
|
||||
int swiz_idx[4] = { 0, 0, 0, 0 };
|
||||
unsigned base;
|
||||
unsigned dup_mask = 0;
|
||||
unsigned seen_mask = 0;
|
||||
unsigned i;
|
||||
|
||||
|
||||
/* Validate the first character in the swizzle string and look up the base
|
||||
* index value as described above.
|
||||
*/
|
||||
if ((str[0] < 'a') || (str[0] > 'z'))
|
||||
return FALSE;
|
||||
|
||||
base = base_idx[str[0] - 'a'];
|
||||
|
||||
|
||||
for (i = 0; (i < 4) && (str[i] != '\0'); i++) {
|
||||
unsigned bit;
|
||||
|
||||
/* Validate the next character, and, as described above, convert it to a
|
||||
* swizzle index.
|
||||
*/
|
||||
if ((str[i] < 'a') || (str[i] > 'z'))
|
||||
return FALSE;
|
||||
|
||||
swiz_idx[i] = idx_map[str[0] - 'a'] - base;
|
||||
if ((swiz_idx[i] < 0) || (swiz_idx[i] >= (int) vector_length))
|
||||
return FALSE;
|
||||
|
||||
|
||||
/* Track a bit-mask of the swizzle index values that have been seen. If
|
||||
* a value is seen more than once, set the "duplicate" flag.
|
||||
*/
|
||||
bit = (1U << swiz_idx[i]);
|
||||
dup_mask |= seen_mask & bit;
|
||||
seen_mask |= bit;
|
||||
}
|
||||
|
||||
if (str[i] != '\0')
|
||||
return FALSE;
|
||||
|
||||
swiz->x = swiz_idx[0];
|
||||
swiz->y = swiz_idx[1];
|
||||
swiz->z = swiz_idx[2];
|
||||
swiz->w = swiz_idx[3];
|
||||
swiz->num_components = i;
|
||||
swiz->has_duplicates = (dup_mask != 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
struct ir_instruction *
|
||||
_mesa_ast_field_selection_to_hir(const ast_expression *expr,
|
||||
simple_node *instructions,
|
||||
struct _mesa_glsl_parse_state *state)
|
||||
{
|
||||
ir_instruction *op;
|
||||
ir_dereference *deref;
|
||||
YYLTYPE loc;
|
||||
|
||||
|
||||
op = _mesa_ast_to_hir(expr->subexpressions[0], instructions, state);
|
||||
deref = new ir_dereference(op);
|
||||
|
||||
/* Initially assume that the resulting type of the field selection is an
|
||||
* error. This make the error paths below a bit easier to follow.
|
||||
*/
|
||||
deref->type = glsl_error_type;
|
||||
|
||||
/* If processing the thing being dereferenced generated an error, bail out
|
||||
* now. Doing so prevents spurious error messages from being logged below.
|
||||
*/
|
||||
if (is_error_type(op->type))
|
||||
return (struct ir_instruction *) deref;
|
||||
|
||||
/* There are two kinds of field selection. There is the selection of a
|
||||
* specific field from a structure, and there is the selection of a
|
||||
* swizzle / mask from a vector. Which is which is determined entirely
|
||||
* by the base type of the thing to which the field selection operator is
|
||||
* being applied.
|
||||
*/
|
||||
_mesa_ast_get_location(expr, & loc);
|
||||
if (is_glsl_type_vector(op->type)) {
|
||||
if (generate_swizzle(expr->primary_expression.identifier,
|
||||
& deref->selector.swizzle,
|
||||
op->type->vector_elements)) {
|
||||
/* Based on the number of elements in the swizzle and the base type
|
||||
* (i.e., float, int, unsigned, or bool) of the vector being swizzled,
|
||||
* generate the type of the resulting value.
|
||||
*/
|
||||
deref->type =
|
||||
_mesa_glsl_get_vector_type(op->type->base_type,
|
||||
deref->selector.swizzle.num_components);
|
||||
} else {
|
||||
/* FINISHME: Logging of error messages should be moved into
|
||||
* FINISHME: generate_swizzle. This allows the generation of more
|
||||
* FINISHME: specific error messages.
|
||||
*/
|
||||
_mesa_glsl_error(& loc, state, "Invalid swizzle / mask `%s'",
|
||||
expr->primary_expression.identifier);
|
||||
}
|
||||
} else if (op->type->base_type == GLSL_TYPE_STRUCT) {
|
||||
/* FINISHME: Handle field selection from structures. */
|
||||
} else {
|
||||
_mesa_glsl_error(& loc, state, "Cannot access field `%s' of "
|
||||
"non-structure / non-vector.",
|
||||
expr->primary_expression.identifier);
|
||||
}
|
||||
|
||||
return (struct ir_instruction *) deref;
|
||||
}
|
||||
41
hir_function.c
Normal file
41
hir_function.c
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
struct ir_instruction *
|
||||
_mesa_ast_constructor_to_hir(const struct ast_node *n,
|
||||
const struct ast_node *parameters,
|
||||
struct _mesa_glsl_parse_state *state)
|
||||
{
|
||||
const struct ast_type_specifier *type = (struct ast_type_specifier *) n;
|
||||
|
||||
|
||||
/* There are effectively three kinds of constructors. Each has its own set
|
||||
* of rules.
|
||||
*
|
||||
* * Built-in scalar, vector, and matrix types: For each of these the only
|
||||
* matching requirement is that the number of values supplied is
|
||||
* sufficient to initialize all of the fields of the type.
|
||||
* * Array types: The number of initializers must match the size of the
|
||||
* array, if a size is specified. Each of the initializers must
|
||||
* exactly match the base type of the array.
|
||||
* * Structure types: These initializers must exactly match the fields of
|
||||
* the structure in order. This is the most restrictive type.
|
||||
*
|
||||
* In all cases the built-in promotions from integer to floating-point types
|
||||
* are applied.
|
||||
*/
|
||||
|
||||
if (type->is_array) {
|
||||
/* FINISHME */
|
||||
} else if ((type->type_specifier == ast_struct)
|
||||
|| (type->type_specifier == ast_type_name)) {
|
||||
/* FINISHME */
|
||||
} else {
|
||||
const struct glsl_type *ctor_type;
|
||||
|
||||
/* Look-up the type, by name, in the symbol table.
|
||||
*/
|
||||
|
||||
|
||||
/* Generate a series of assignments of constructor parameters to fields
|
||||
* of the object being initialized.
|
||||
*/
|
||||
}
|
||||
}
|
||||
116
ir.cc
Normal file
116
ir.cc
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright © 2010 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "main/imports.h"
|
||||
#include "main/simple_list.h"
|
||||
#include "ir.h"
|
||||
#include "glsl_types.h"
|
||||
|
||||
ir_instruction::ir_instruction(int mode)
|
||||
{
|
||||
this->mode = mode;
|
||||
make_empty_list(this);
|
||||
}
|
||||
|
||||
|
||||
ir_assignment::ir_assignment(ir_instruction *lhs, ir_instruction *rhs,
|
||||
ir_expression *condition)
|
||||
: ir_instruction(ir_op_assign)
|
||||
{
|
||||
this->lhs = (ir_dereference *) lhs;
|
||||
this->rhs = rhs;
|
||||
this->condition = condition;
|
||||
}
|
||||
|
||||
|
||||
ir_expression::ir_expression(int op, const struct glsl_type *type,
|
||||
ir_instruction *op0, ir_instruction *op1)
|
||||
: ir_instruction(ir_op_expression)
|
||||
{
|
||||
this->type = type;
|
||||
this->operation = ir_expression_operation(op);
|
||||
this->operands[0] = op0;
|
||||
this->operands[1] = op1;
|
||||
}
|
||||
|
||||
|
||||
ir_label::ir_label(const char *label)
|
||||
: ir_instruction(ir_op_label), label(label)
|
||||
{
|
||||
/* empty */
|
||||
}
|
||||
|
||||
|
||||
ir_constant::ir_constant(const struct glsl_type *type, const void *data)
|
||||
: ir_instruction(ir_op_constant)
|
||||
{
|
||||
const unsigned elements =
|
||||
((type->vector_elements == 0) ? 1 : type->vector_elements)
|
||||
* ((type->matrix_rows == 0) ? 1 : type->matrix_rows);
|
||||
unsigned size = 0;
|
||||
|
||||
this->type = type;
|
||||
switch (type->base_type) {
|
||||
case GLSL_TYPE_UINT: size = sizeof(this->value.u[0]); break;
|
||||
case GLSL_TYPE_INT: size = sizeof(this->value.i[0]); break;
|
||||
case GLSL_TYPE_FLOAT: size = sizeof(this->value.f[0]); break;
|
||||
case GLSL_TYPE_BOOL: size = sizeof(this->value.b[0]); break;
|
||||
default:
|
||||
/* FINISHME: What to do? Exceptions are not the answer.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(& this->value, data, size * elements);
|
||||
}
|
||||
|
||||
|
||||
ir_dereference::ir_dereference(ir_instruction *var)
|
||||
: ir_instruction(ir_op_dereference)
|
||||
{
|
||||
this->mode = ir_reference_variable;
|
||||
this->var = var;
|
||||
this->type = (var != NULL) ? var->type : glsl_error_type;
|
||||
}
|
||||
|
||||
|
||||
ir_variable::ir_variable(const struct glsl_type *type, const char *name)
|
||||
: ir_instruction(ir_op_var_decl)
|
||||
{
|
||||
this->type = type;
|
||||
this->name = name;
|
||||
}
|
||||
|
||||
|
||||
ir_function_signature::ir_function_signature(void)
|
||||
: ir_instruction(ir_op_func_sig)
|
||||
{
|
||||
make_empty_list(& parameters);
|
||||
}
|
||||
|
||||
|
||||
ir_function::ir_function(void)
|
||||
: ir_instruction(ir_op_func)
|
||||
{
|
||||
make_empty_list(& signatures);
|
||||
}
|
||||
302
ir.h
Normal file
302
ir.h
Normal file
|
|
@ -0,0 +1,302 @@
|
|||
/*
|
||||
* Copyright © 2010 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
struct ir_program {
|
||||
void *bong_hits;
|
||||
};
|
||||
|
||||
|
||||
enum ir_opcodes {
|
||||
ir_op_var_decl,
|
||||
ir_op_assign,
|
||||
ir_op_expression,
|
||||
ir_op_dereference,
|
||||
ir_op_jump,
|
||||
ir_op_label,
|
||||
ir_op_constant,
|
||||
ir_op_func_sig,
|
||||
ir_op_func
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class of all IR instructions
|
||||
*/
|
||||
class ir_instruction : public simple_node {
|
||||
public:
|
||||
unsigned mode;
|
||||
const struct glsl_type *type;
|
||||
|
||||
protected:
|
||||
ir_instruction(int mode);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Dummy constructor to catch bad constructors in derived classes.
|
||||
*
|
||||
* Every derived must use the constructor that sets the instructions
|
||||
* mode. Having the \c void constructor private prevents derived classes
|
||||
* from accidentally doing the wrong thing.
|
||||
*/
|
||||
ir_instruction(void);
|
||||
};
|
||||
|
||||
|
||||
enum ir_variable_mode {
|
||||
ir_var_auto = 0,
|
||||
ir_var_uniform,
|
||||
ir_var_in,
|
||||
ir_var_out,
|
||||
ir_var_inout
|
||||
};
|
||||
|
||||
enum ir_varaible_interpolation {
|
||||
ir_var_smooth = 0,
|
||||
ir_var_flat,
|
||||
ir_var_noperspective
|
||||
};
|
||||
|
||||
class ir_variable : public ir_instruction {
|
||||
public:
|
||||
ir_variable(const struct glsl_type *, const char *);
|
||||
|
||||
const char *name;
|
||||
|
||||
unsigned read_only:1;
|
||||
unsigned centroid:1;
|
||||
unsigned invariant:1;
|
||||
|
||||
unsigned mode:3;
|
||||
unsigned interpolation:2;
|
||||
};
|
||||
|
||||
|
||||
class ir_label : public ir_instruction {
|
||||
public:
|
||||
ir_label(const char *label);
|
||||
|
||||
const char *label;
|
||||
};
|
||||
|
||||
|
||||
/*@{*/
|
||||
class ir_function_signature : public ir_instruction {
|
||||
public:
|
||||
ir_function_signature(void);
|
||||
|
||||
/**
|
||||
* Function return type.
|
||||
*
|
||||
* \note This discards the optional precision qualifier.
|
||||
*/
|
||||
const struct glsl_type *return_type;
|
||||
|
||||
/**
|
||||
* List of function parameters stored as ir_variable objects.
|
||||
*/
|
||||
struct simple_node parameters;
|
||||
|
||||
/**
|
||||
* Pointer to the label that begins the function definition.
|
||||
*/
|
||||
ir_label *definition;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Header for tracking functions in the symbol table
|
||||
*/
|
||||
class ir_function : public ir_instruction {
|
||||
public:
|
||||
ir_function(void);
|
||||
|
||||
/**
|
||||
* Name of the function.
|
||||
*/
|
||||
const char *name;
|
||||
|
||||
struct simple_node signatures;
|
||||
};
|
||||
/*@}*/
|
||||
|
||||
class ir_expression;
|
||||
class ir_dereference;
|
||||
|
||||
class ir_assignment : public ir_instruction {
|
||||
public:
|
||||
ir_assignment(ir_instruction *lhs, ir_instruction *rhs,
|
||||
ir_expression *condition);
|
||||
|
||||
/**
|
||||
* Left-hand side of the assignment.
|
||||
*/
|
||||
ir_dereference *lhs;
|
||||
|
||||
/**
|
||||
* Value being assigned
|
||||
*
|
||||
* This should be either \c ir_op_expression or \c ir_op_deference.
|
||||
*/
|
||||
ir_instruction *rhs;
|
||||
|
||||
/**
|
||||
* Optional condition for the assignment.
|
||||
*/
|
||||
ir_expression *condition;
|
||||
};
|
||||
|
||||
|
||||
enum ir_expression_operation {
|
||||
ir_unop_bit_not,
|
||||
ir_unop_logic_not,
|
||||
ir_unop_neg,
|
||||
ir_unop_abs,
|
||||
ir_unop_rcp,
|
||||
ir_unop_rsq,
|
||||
ir_unop_exp,
|
||||
ir_unop_log,
|
||||
ir_unop_f2i, /**< Float-to-integer conversion. */
|
||||
ir_unop_i2f, /**< Integer-to-float conversion. */
|
||||
|
||||
/**
|
||||
* \name Unary floating-point rounding operations.
|
||||
*/
|
||||
/*@{*/
|
||||
ir_unop_trunc,
|
||||
ir_unop_ceil,
|
||||
ir_unop_floor,
|
||||
/*@}*/
|
||||
|
||||
ir_binop_add,
|
||||
ir_binop_sub,
|
||||
ir_binop_mul,
|
||||
ir_binop_div,
|
||||
ir_binop_mod,
|
||||
|
||||
/**
|
||||
* \name Binary comparison operators
|
||||
*/
|
||||
/*@{*/
|
||||
ir_binop_less,
|
||||
ir_binop_greater,
|
||||
ir_binop_lequal,
|
||||
ir_binop_gequal,
|
||||
ir_binop_equal,
|
||||
ir_binop_nequal,
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
* \name Bit-wise binary operations.
|
||||
*/
|
||||
/*@{*/
|
||||
ir_binop_lshift,
|
||||
ir_binop_rshift,
|
||||
ir_binop_bit_and,
|
||||
ir_binop_bit_xor,
|
||||
ir_binop_bit_or,
|
||||
/*@}*/
|
||||
|
||||
ir_binop_logic_and,
|
||||
ir_binop_logic_xor,
|
||||
ir_binop_logic_or,
|
||||
ir_binop_logic_not,
|
||||
|
||||
ir_binop_dot,
|
||||
ir_binop_min,
|
||||
ir_binop_max,
|
||||
|
||||
ir_binop_pow
|
||||
};
|
||||
|
||||
class ir_expression : public ir_instruction {
|
||||
public:
|
||||
ir_expression(int op, const struct glsl_type *type,
|
||||
ir_instruction *, ir_instruction *);
|
||||
|
||||
ir_expression_operation operation;
|
||||
ir_instruction *operands[2];
|
||||
};
|
||||
|
||||
|
||||
struct ir_swizzle_mask {
|
||||
unsigned x:2;
|
||||
unsigned y:2;
|
||||
unsigned z:2;
|
||||
unsigned w:2;
|
||||
|
||||
/**
|
||||
* Number of components in the swizzle.
|
||||
*/
|
||||
unsigned num_components:2;
|
||||
|
||||
/**
|
||||
* Does the swizzle contain duplicate components?
|
||||
*
|
||||
* L-value swizzles cannot contain duplicate components.
|
||||
*/
|
||||
unsigned has_duplicates:1;
|
||||
};
|
||||
|
||||
class ir_dereference : public ir_instruction {
|
||||
public:
|
||||
ir_dereference(struct ir_instruction *);
|
||||
|
||||
enum {
|
||||
ir_reference_variable,
|
||||
ir_reference_array,
|
||||
ir_reference_record
|
||||
} mode;
|
||||
|
||||
/**
|
||||
* Object being dereferenced.
|
||||
*
|
||||
* Must be either an \c ir_variable or an \c ir_deference.
|
||||
*/
|
||||
ir_instruction *var;
|
||||
|
||||
union {
|
||||
ir_expression *array_index;
|
||||
const char *field;
|
||||
struct ir_swizzle_mask swizzle;
|
||||
} selector;
|
||||
};
|
||||
|
||||
|
||||
class ir_constant : public ir_instruction {
|
||||
public:
|
||||
ir_constant(const struct glsl_type *type, const void *data);
|
||||
|
||||
/**
|
||||
* Value of the constant.
|
||||
*
|
||||
* The field used to back the values supplied by the constant is determined
|
||||
* by the type associated with the \c ir_instruction. Constants may be
|
||||
* scalars, vectors, or matrices.
|
||||
*/
|
||||
union {
|
||||
unsigned u[16];
|
||||
int i[16];
|
||||
float f[16];
|
||||
bool b[16];
|
||||
} value;
|
||||
};
|
||||
|
||||
6
main/imports.h
Normal file
6
main/imports.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define _mesa_malloc(x) malloc(x)
|
||||
#define _mesa_free(x) free(x)
|
||||
#define _mesa_calloc(x) calloc(1,x)
|
||||
235
main/simple_list.h
Normal file
235
main/simple_list.h
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
/**
|
||||
* \file simple_list.h
|
||||
* Simple macros for type-safe, intrusive lists.
|
||||
*
|
||||
* Intended to work with a list sentinal which is created as an empty
|
||||
* list. Insert & delete are O(1).
|
||||
*
|
||||
* \author
|
||||
* (C) 1997, Keith Whitwell
|
||||
*/
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 3.5
|
||||
*
|
||||
* Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _SIMPLE_LIST_H
|
||||
#define _SIMPLE_LIST_H
|
||||
|
||||
struct simple_node {
|
||||
struct simple_node *next;
|
||||
struct simple_node *prev;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove an element from list.
|
||||
*
|
||||
* \param elem element to remove.
|
||||
*/
|
||||
#define remove_from_list(elem) \
|
||||
do { \
|
||||
(elem)->next->prev = (elem)->prev; \
|
||||
(elem)->prev->next = (elem)->next; \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Insert an element to the list head.
|
||||
*
|
||||
* \param list list.
|
||||
* \param elem element to insert.
|
||||
*/
|
||||
#define insert_at_head(list, elem) \
|
||||
do { \
|
||||
(elem)->prev = list; \
|
||||
(elem)->next = (list)->next; \
|
||||
(list)->next->prev = elem; \
|
||||
(list)->next = elem; \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* Insert an element to the list tail.
|
||||
*
|
||||
* \param list list.
|
||||
* \param elem element to insert.
|
||||
*/
|
||||
#define insert_at_tail(list, elem) \
|
||||
do { \
|
||||
(elem)->next = list; \
|
||||
(elem)->prev = (list)->prev; \
|
||||
(list)->prev->next = elem; \
|
||||
(list)->prev = elem; \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* Move an element to the list head.
|
||||
*
|
||||
* \param list list.
|
||||
* \param elem element to move.
|
||||
*/
|
||||
#define move_to_head(list, elem) \
|
||||
do { \
|
||||
remove_from_list(elem); \
|
||||
insert_at_head(list, elem); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Move an element to the list tail.
|
||||
*
|
||||
* \param list list.
|
||||
* \param elem element to move.
|
||||
*/
|
||||
#define move_to_tail(list, elem) \
|
||||
do { \
|
||||
remove_from_list(elem); \
|
||||
insert_at_tail(list, elem); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Consatinate a cyclic list to a list
|
||||
*
|
||||
* Appends the sequence of nodes starting with \c tail to the list \c head.
|
||||
* A "cyclic list" is a list that does not have a sentinal node. This means
|
||||
* that the data pointed to by \c tail is an actual node, not a dataless
|
||||
* sentinal. Note that if \c tail constist of a single node, this macro
|
||||
* behaves identically to \c insert_at_tail
|
||||
*
|
||||
* \param head Head of the list to be appended to. This may or may not
|
||||
* be a cyclic list.
|
||||
* \param tail Head of the cyclic list to be appended to \c head.
|
||||
* \param temp Temporary \c simple_list used by the macro
|
||||
*
|
||||
* \sa insert_at_tail
|
||||
*/
|
||||
#define concat_list_and_cycle(head, tail, temp) \
|
||||
do { \
|
||||
(head)->prev->next = (tail); \
|
||||
(tail)->prev->next = (head); \
|
||||
(temp) = (head)->prev; \
|
||||
(head)->prev = (tail)->prev; \
|
||||
(tail)->prev = (temp); \
|
||||
} while (0)
|
||||
|
||||
#define concat_list(head, next_list) \
|
||||
do { \
|
||||
(next_list)->next->prev = (head)->prev; \
|
||||
(next_list)->prev->next = (head); \
|
||||
(head)->prev->next = (next_list)->next; \
|
||||
(head)->prev = (next_list)->prev; \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Make a empty list empty.
|
||||
*
|
||||
* \param sentinal list (sentinal element).
|
||||
*/
|
||||
#define make_empty_list(sentinal) \
|
||||
do { \
|
||||
(sentinal)->next = sentinal; \
|
||||
(sentinal)->prev = sentinal; \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Get list first element.
|
||||
*
|
||||
* \param list list.
|
||||
*
|
||||
* \return pointer to first element.
|
||||
*/
|
||||
#define first_elem(list) ((list)->next)
|
||||
|
||||
/**
|
||||
* Get list last element.
|
||||
*
|
||||
* \param list list.
|
||||
*
|
||||
* \return pointer to last element.
|
||||
*/
|
||||
#define last_elem(list) ((list)->prev)
|
||||
|
||||
/**
|
||||
* Get next element.
|
||||
*
|
||||
* \param elem element.
|
||||
*
|
||||
* \return pointer to next element.
|
||||
*/
|
||||
#define next_elem(elem) ((elem)->next)
|
||||
|
||||
/**
|
||||
* Get previous element.
|
||||
*
|
||||
* \param elem element.
|
||||
*
|
||||
* \return pointer to previous element.
|
||||
*/
|
||||
#define prev_elem(elem) ((elem)->prev)
|
||||
|
||||
/**
|
||||
* Test whether element is at end of the list.
|
||||
*
|
||||
* \param list list.
|
||||
* \param elem element.
|
||||
*
|
||||
* \return non-zero if element is at end of list, or zero otherwise.
|
||||
*/
|
||||
#define at_end(list, elem) ((elem) == (list))
|
||||
|
||||
/**
|
||||
* Test if a list is empty.
|
||||
*
|
||||
* \param list list.
|
||||
*
|
||||
* \return non-zero if list empty, or zero otherwise.
|
||||
*/
|
||||
#define is_empty_list(list) ((list)->next == (list))
|
||||
|
||||
/**
|
||||
* Walk through the elements of a list.
|
||||
*
|
||||
* \param ptr pointer to the current element.
|
||||
* \param list list.
|
||||
*
|
||||
* \note It should be followed by a { } block or a single statement, as in a \c
|
||||
* for loop.
|
||||
*/
|
||||
#define foreach(ptr, list) \
|
||||
for( ptr=(list)->next ; ptr!=list ; ptr=(ptr)->next )
|
||||
|
||||
/**
|
||||
* Walk through the elements of a list.
|
||||
*
|
||||
* Same as #foreach but lets you unlink the current value during a list
|
||||
* traversal. Useful for freeing a list, element by element.
|
||||
*
|
||||
* \param ptr pointer to the current element.
|
||||
* \param t temporary pointer.
|
||||
* \param list list.
|
||||
*
|
||||
* \note It should be followed by a { } block or a single statement, as in a \c
|
||||
* for loop.
|
||||
*/
|
||||
#define foreach_s(ptr, t, list) \
|
||||
for(ptr=(list)->next,t=(ptr)->next; list != ptr; ptr=t, t=(t)->next)
|
||||
|
||||
#endif
|
||||
377
symbol_table.c
Normal file
377
symbol_table.c
Normal file
|
|
@ -0,0 +1,377 @@
|
|||
/*
|
||||
* Copyright © 2008 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "main/imports.h"
|
||||
#include "symbol_table.h"
|
||||
#include "hash_table.h"
|
||||
|
||||
struct symbol {
|
||||
/**
|
||||
* Link to the next symbol in the table with the same name
|
||||
*
|
||||
* The linked list of symbols with the same name is ordered by scope
|
||||
* from inner-most to outer-most.
|
||||
*/
|
||||
struct symbol *next_with_same_name;
|
||||
|
||||
|
||||
/**
|
||||
* Link to the next symbol in the table with the same scope
|
||||
*
|
||||
* The linked list of symbols with the same scope is unordered. Symbols
|
||||
* in this list my have unique names.
|
||||
*/
|
||||
struct symbol *next_with_same_scope;
|
||||
|
||||
|
||||
/**
|
||||
* Header information for the list of symbols with the same name.
|
||||
*/
|
||||
struct symbol_header *hdr;
|
||||
|
||||
|
||||
/**
|
||||
* Name space of the symbol
|
||||
*
|
||||
* Name space are arbitrary user assigned integers. No two symbols can
|
||||
* exist in the same name space at the same scope level.
|
||||
*/
|
||||
int name_space;
|
||||
|
||||
|
||||
/**
|
||||
* Arbitrary user supplied data.
|
||||
*/
|
||||
void *data;
|
||||
|
||||
/** Scope depth where this symbol was defined. */
|
||||
unsigned depth;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
struct symbol_header {
|
||||
/** Linkage in list of all headers in a given symbol table. */
|
||||
struct symbol_header *next;
|
||||
|
||||
/** Symbol name. */
|
||||
const char *name;
|
||||
|
||||
/** Linked list of symbols with the same name. */
|
||||
struct symbol *symbols;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Element of the scope stack.
|
||||
*/
|
||||
struct scope_level {
|
||||
/** Link to next (inner) scope level. */
|
||||
struct scope_level *next;
|
||||
|
||||
/** Linked list of symbols with the same scope. */
|
||||
struct symbol *symbols;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
struct _mesa_symbol_table {
|
||||
/** Hash table containing all symbols in the symbol table. */
|
||||
struct hash_table *ht;
|
||||
|
||||
/** Top of scope stack. */
|
||||
struct scope_level *current_scope;
|
||||
|
||||
/** List of all symbol headers in the table. */
|
||||
struct symbol_header *hdr;
|
||||
|
||||
/** Current scope depth. */
|
||||
unsigned depth;
|
||||
};
|
||||
|
||||
|
||||
struct _mesa_symbol_table_iterator {
|
||||
/**
|
||||
* Name space of symbols returned by this iterator.
|
||||
*/
|
||||
int name_space;
|
||||
|
||||
|
||||
/**
|
||||
* Currently iterated symbol
|
||||
*
|
||||
* The next call to \c _mesa_symbol_table_iterator_get will return this
|
||||
* value. It will also update this value to the value that should be
|
||||
* returned by the next call.
|
||||
*/
|
||||
struct symbol *curr;
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
check_symbol_table(struct _mesa_symbol_table *table)
|
||||
{
|
||||
#if 1
|
||||
struct scope_level *scope;
|
||||
|
||||
for (scope = table->current_scope; scope != NULL; scope = scope->next) {
|
||||
struct symbol *sym;
|
||||
|
||||
for (sym = scope->symbols
|
||||
; sym != NULL
|
||||
; sym = sym->next_with_same_name) {
|
||||
const struct symbol_header *const hdr = sym->hdr;
|
||||
struct symbol *sym2;
|
||||
|
||||
for (sym2 = hdr->symbols
|
||||
; sym2 != NULL
|
||||
; sym2 = sym2->next_with_same_name) {
|
||||
assert(sym2->hdr == hdr);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
_mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table)
|
||||
{
|
||||
struct scope_level *const scope = table->current_scope;
|
||||
struct symbol *sym = scope->symbols;
|
||||
|
||||
table->current_scope = scope->next;
|
||||
table->depth--;
|
||||
|
||||
free(scope);
|
||||
|
||||
while (sym != NULL) {
|
||||
struct symbol *const next = sym->next_with_same_scope;
|
||||
struct symbol_header *const hdr = sym->hdr;
|
||||
|
||||
assert(hdr->symbols == sym);
|
||||
|
||||
hdr->symbols = sym->next_with_same_name;
|
||||
|
||||
free(sym);
|
||||
|
||||
sym = next;
|
||||
}
|
||||
|
||||
check_symbol_table(table);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_mesa_symbol_table_push_scope(struct _mesa_symbol_table *table)
|
||||
{
|
||||
struct scope_level *const scope = calloc(1, sizeof(*scope));
|
||||
|
||||
scope->next = table->current_scope;
|
||||
table->current_scope = scope;
|
||||
table->depth++;
|
||||
}
|
||||
|
||||
|
||||
static struct symbol_header *
|
||||
find_symbol(struct _mesa_symbol_table *table, const char *name)
|
||||
{
|
||||
return (struct symbol_header *) hash_table_find(table->ht, name);
|
||||
}
|
||||
|
||||
|
||||
struct _mesa_symbol_table_iterator *
|
||||
_mesa_symbol_table_iterator_ctor(struct _mesa_symbol_table *table,
|
||||
int name_space, const char *name)
|
||||
{
|
||||
struct _mesa_symbol_table_iterator *iter = calloc(1, sizeof(*iter));
|
||||
struct symbol_header *const hdr = find_symbol(table, name);
|
||||
|
||||
iter->name_space = name_space;
|
||||
|
||||
if (hdr != NULL) {
|
||||
struct symbol *sym;
|
||||
|
||||
for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
|
||||
assert(sym->hdr == hdr);
|
||||
|
||||
if ((name_space == -1) || (sym->name_space == name_space)) {
|
||||
iter->curr = sym;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_mesa_symbol_table_iterator_dtor(struct _mesa_symbol_table_iterator *iter)
|
||||
{
|
||||
free(iter);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
_mesa_symbol_table_iterator_get(struct _mesa_symbol_table_iterator *iter)
|
||||
{
|
||||
return (iter->curr == NULL) ? NULL : iter->curr->data;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_mesa_symbol_table_iterator_next(struct _mesa_symbol_table_iterator *iter)
|
||||
{
|
||||
struct symbol_header *hdr;
|
||||
|
||||
if (iter->curr == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
hdr = iter->curr->hdr;
|
||||
iter->curr = iter->curr->next_with_same_name;
|
||||
|
||||
while (iter->curr != NULL) {
|
||||
assert(iter->curr->hdr == hdr);
|
||||
|
||||
if ((iter->name_space == -1)
|
||||
|| (iter->curr->name_space == iter->name_space)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
iter->curr = iter->curr->next_with_same_name;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
_mesa_symbol_table_find_symbol(struct _mesa_symbol_table *table,
|
||||
int name_space, const char *name)
|
||||
{
|
||||
struct symbol_header *const hdr = find_symbol(table, name);
|
||||
|
||||
if (hdr != NULL) {
|
||||
struct symbol *sym;
|
||||
|
||||
|
||||
for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
|
||||
assert(sym->hdr == hdr);
|
||||
|
||||
if ((name_space == -1) || (sym->name_space == name_space)) {
|
||||
return sym->data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_mesa_symbol_table_add_symbol(struct _mesa_symbol_table *table,
|
||||
int name_space, const char *name,
|
||||
void *declaration)
|
||||
{
|
||||
struct symbol_header *hdr;
|
||||
struct symbol *sym;
|
||||
|
||||
check_symbol_table(table);
|
||||
|
||||
hdr = find_symbol(table, name);
|
||||
|
||||
check_symbol_table(table);
|
||||
|
||||
if (hdr == NULL) {
|
||||
hdr = calloc(1, sizeof(*hdr));
|
||||
hdr->name = name;
|
||||
|
||||
hash_table_insert(table->ht, hdr, name);
|
||||
hdr->next = table->hdr;
|
||||
table->hdr = hdr;
|
||||
}
|
||||
|
||||
check_symbol_table(table);
|
||||
|
||||
/* If the symbol already exists at this scope, it cannot be added to the
|
||||
* table.
|
||||
*/
|
||||
if (hdr->symbols && (hdr->symbols->depth == table->depth))
|
||||
return -1;
|
||||
|
||||
sym = calloc(1, sizeof(*sym));
|
||||
sym->next_with_same_name = hdr->symbols;
|
||||
sym->next_with_same_scope = table->current_scope->symbols;
|
||||
sym->hdr = hdr;
|
||||
sym->name_space = name_space;
|
||||
sym->data = declaration;
|
||||
sym->depth = table->depth;
|
||||
|
||||
assert(sym->hdr == hdr);
|
||||
|
||||
hdr->symbols = sym;
|
||||
table->current_scope->symbols = sym;
|
||||
|
||||
check_symbol_table(table);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct _mesa_symbol_table *
|
||||
_mesa_symbol_table_ctor(void)
|
||||
{
|
||||
struct _mesa_symbol_table *table = calloc(1, sizeof(*table));
|
||||
|
||||
if (table != NULL) {
|
||||
table->ht = hash_table_ctor(32, hash_table_string_hash,
|
||||
hash_table_string_compare);
|
||||
|
||||
_mesa_symbol_table_push_scope(table);
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_mesa_symbol_table_dtor(struct _mesa_symbol_table *table)
|
||||
{
|
||||
struct symbol_header *hdr;
|
||||
struct symbol_header *next;
|
||||
|
||||
while (table->current_scope != NULL) {
|
||||
_mesa_symbol_table_pop_scope(table);
|
||||
}
|
||||
|
||||
for (hdr = table->hdr; hdr != NULL; hdr = next) {
|
||||
next = hdr->next;
|
||||
_mesa_free(hdr);
|
||||
}
|
||||
|
||||
hash_table_dtor(table->ht);
|
||||
free(table);
|
||||
}
|
||||
63
symbol_table.h
Normal file
63
symbol_table.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright © 2008 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MESA_SYMBOL_TABLE_H
|
||||
#define MESA_SYMBOL_TABLE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct _mesa_symbol_table;
|
||||
struct _mesa_symbol_table_iterator;
|
||||
|
||||
extern void _mesa_symbol_table_push_scope(struct _mesa_symbol_table *table);
|
||||
|
||||
extern void _mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table);
|
||||
|
||||
extern int _mesa_symbol_table_add_symbol(struct _mesa_symbol_table *symtab,
|
||||
int name_space, const char *name, void *declaration);
|
||||
|
||||
extern void *_mesa_symbol_table_find_symbol(
|
||||
struct _mesa_symbol_table *symtab, int name_space, const char *name);
|
||||
|
||||
extern struct _mesa_symbol_table *_mesa_symbol_table_ctor(void);
|
||||
|
||||
extern void _mesa_symbol_table_dtor(struct _mesa_symbol_table *);
|
||||
|
||||
extern struct _mesa_symbol_table_iterator *_mesa_symbol_table_iterator_ctor(
|
||||
struct _mesa_symbol_table *table, int name_space, const char *name);
|
||||
|
||||
extern void _mesa_symbol_table_iterator_dtor(
|
||||
struct _mesa_symbol_table_iterator *);
|
||||
|
||||
extern void *_mesa_symbol_table_iterator_get(
|
||||
struct _mesa_symbol_table_iterator *iter);
|
||||
|
||||
extern int _mesa_symbol_table_iterator_next(
|
||||
struct _mesa_symbol_table_iterator *iter);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MESA_SYMBOL_TABLE_H */
|
||||
9
tests/parameters-01.txt
Normal file
9
tests/parameters-01.txt
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
void a()
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
void a()
|
||||
{
|
||||
;
|
||||
}
|
||||
9
tests/parameters-02.txt
Normal file
9
tests/parameters-02.txt
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
void a()
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
void a(float x)
|
||||
{
|
||||
;
|
||||
}
|
||||
9
tests/parameters-03.txt
Normal file
9
tests/parameters-03.txt
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/* FAIL - x is redeclared in the function body at the same scope as the
|
||||
* parameter
|
||||
*/
|
||||
void a(float x, float y)
|
||||
{
|
||||
float x;
|
||||
|
||||
x = y;
|
||||
}
|
||||
10
tests/swiz-01.glsl
Normal file
10
tests/swiz-01.glsl
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#version 120
|
||||
|
||||
void main()
|
||||
{
|
||||
float a;
|
||||
vec4 b;
|
||||
|
||||
b.x = 6.0;
|
||||
a = b.x;
|
||||
}
|
||||
10
tests/swiz-02.glsl
Normal file
10
tests/swiz-02.glsl
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#version 120
|
||||
|
||||
void main()
|
||||
{
|
||||
float a;
|
||||
vec4 b;
|
||||
|
||||
b.x = 6.0;
|
||||
a = b.xy;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue