Browse Source

Initial commit. lol

tags/mesa-7.9-rc1
Ian Romanick 15 years ago
commit
a87ac255cf
26 changed files with 6342 additions and 0 deletions
  1. 1
    0
      .dir-locals.el
  2. 40
    0
      Makefile
  3. 511
    0
      ast.h
  4. 1172
    0
      ast_to_hir.cc
  5. 328
    0
      builtin_types.sh
  6. 273
    0
      glsl_lexer.l
  7. 1228
    0
      glsl_parser.y
  8. 771
    0
      glsl_parser_extras.cc
  9. 68
    0
      glsl_parser_extras.h
  10. 159
    0
      glsl_types.c
  11. 141
    0
      glsl_types.h
  12. 159
    0
      hash_table.c
  13. 117
    0
      hash_table.h
  14. 187
    0
      hir_field_selection.cc
  15. 41
    0
      hir_function.c
  16. 116
    0
      ir.cc
  17. 302
    0
      ir.h
  18. 6
    0
      main/imports.h
  19. 235
    0
      main/simple_list.h
  20. 377
    0
      symbol_table.c
  21. 63
    0
      symbol_table.h
  22. 9
    0
      tests/parameters-01.txt
  23. 9
    0
      tests/parameters-02.txt
  24. 9
    0
      tests/parameters-03.txt
  25. 10
    0
      tests/swiz-01.glsl
  26. 10
    0
      tests/swiz-02.glsl

+ 1
- 0
.dir-locals.el View File

@@ -0,0 +1 @@
((c-mode . ((c-basic-offset . 3))))

+ 40
- 0
Makefile View 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
- 0
ast.h View 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
- 0
ast_to_hir.cc
File diff suppressed because it is too large
View File


+ 328
- 0
builtin_types.sh View 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
- 0
glsl_lexer.l View 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
- 0
glsl_parser.y
File diff suppressed because it is too large
View File


+ 771
- 0
glsl_parser_extras.cc View 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
- 0
glsl_parser_extras.h View 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
- 0
glsl_types.c View 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
- 0
glsl_types.h View 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
- 0
hash_table.c View 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
- 0
hash_table.h View 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
- 0
hir_field_selection.cc View 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
- 0
hir_function.c View 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
- 0
ir.cc View 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
- 0
ir.h View 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
- 0
main/imports.h View 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
- 0
main/simple_list.h View 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
- 0
symbol_table.c View 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
- 0
symbol_table.h View 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
- 0
tests/parameters-01.txt View File

@@ -0,0 +1,9 @@
void a()
{
;
}

void a()
{
;
}

+ 9
- 0
tests/parameters-02.txt View File

@@ -0,0 +1,9 @@
void a()
{
;
}

void a(float x)
{
;
}

+ 9
- 0
tests/parameters-03.txt View 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
- 0
tests/swiz-01.glsl View File

@@ -0,0 +1,10 @@
#version 120

void main()
{
float a;
vec4 b;

b.x = 6.0;
a = b.x;
}

+ 10
- 0
tests/swiz-02.glsl View File

@@ -0,0 +1,10 @@
#version 120

void main()
{
float a;
vec4 b;

b.x = 6.0;
a = b.xy;
}

Loading…
Cancel
Save