diff options
Diffstat (limited to 'mesalib/src/mesa/shader/slang/library/slang_shader.syn')
-rw-r--r-- | mesalib/src/mesa/shader/slang/library/slang_shader.syn | 1716 |
1 files changed, 1716 insertions, 0 deletions
diff --git a/mesalib/src/mesa/shader/slang/library/slang_shader.syn b/mesalib/src/mesa/shader/slang/library/slang_shader.syn new file mode 100644 index 000000000..cc5c70a02 --- /dev/null +++ b/mesalib/src/mesa/shader/slang/library/slang_shader.syn @@ -0,0 +1,1716 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 2004-2006 Brian Paul All Rights Reserved. + * Copyright (C) 2008 VMware, Inc. 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. + */ + +/* + * \file slang_shader.syn + * slang vertex/fragment shader syntax + * \author Michal Krol + */ + +/* + * usage: + * syn2c slang_shader.syn > slang_shader_syn.h + * + * when modifying or extending this file, several things must be taken into + * consideration: + * + * - when adding new operators that were marked as reserved in the + * initial specification, one must only uncomment particular lines of + * code that refer to operators being added; + * + * - when adding new shader targets, one must reserve a new value for + * shader_type register and use it in .if constructs for symbols that + * are exclusive for that shader; + * + * - some symbols mimic output of other symbols - the best example is + * the "for" construct: expression "for (foo(); ; bar())" is seen as + * "for (foo(); true; bar())" by the output processor - hence, special + * care must be taken when rearranging output of essential symbols; + * + * - order of single-quoted tokens does matter in alternatives - so do not + * parse "<" operator before "<<" and "<<" before "<<="; + * + * - all double-quoted tokens are internally preprocessed to eliminate + * problems with parsing strings that are prefixes of other strings, + * like "sampler1D" and "sampler1DShadow"; + */ + +.syntax translation_unit; + +/* revision number - increment after each change affecting emitted output */ +.emtcode REVISION 5 + +/* external declaration (or precision or invariant stmt) */ +.emtcode EXTERNAL_NULL 0 +.emtcode EXTERNAL_FUNCTION_DEFINITION 1 +.emtcode EXTERNAL_DECLARATION 2 +.emtcode DEFAULT_PRECISION 3 +.emtcode INVARIANT_STMT 4 + +/* precision */ +.emtcode PRECISION_DEFAULT 0 +.emtcode PRECISION_LOW 1 +.emtcode PRECISION_MEDIUM 2 +.emtcode PRECISION_HIGH 3 + +/* declaration */ +.emtcode DECLARATION_FUNCTION_PROTOTYPE 1 +.emtcode DECLARATION_INIT_DECLARATOR_LIST 2 + +/* function type */ +.emtcode FUNCTION_ORDINARY 0 +.emtcode FUNCTION_CONSTRUCTOR 1 +.emtcode FUNCTION_OPERATOR 2 + +/* function call type */ +.emtcode FUNCTION_CALL_NONARRAY 0 +.emtcode FUNCTION_CALL_ARRAY 1 + +/* operator type */ +.emtcode OPERATOR_ADDASSIGN 1 +.emtcode OPERATOR_SUBASSIGN 2 +.emtcode OPERATOR_MULASSIGN 3 +.emtcode OPERATOR_DIVASSIGN 4 +/*.emtcode OPERATOR_MODASSIGN 5*/ +/*.emtcode OPERATOR_LSHASSIGN 6*/ +/*.emtcode OPERATOR_RSHASSIGN 7*/ +/*.emtcode OPERATOR_ORASSIGN 8*/ +/*.emtcode OPERATOR_XORASSIGN 9*/ +/*.emtcode OPERATOR_ANDASSIGN 10*/ +.emtcode OPERATOR_LOGICALXOR 11 +/*.emtcode OPERATOR_BITOR 12*/ +/*.emtcode OPERATOR_BITXOR 13*/ +/*.emtcode OPERATOR_BITAND 14*/ +.emtcode OPERATOR_LESS 15 +.emtcode OPERATOR_GREATER 16 +.emtcode OPERATOR_LESSEQUAL 17 +.emtcode OPERATOR_GREATEREQUAL 18 +/*.emtcode OPERATOR_LSHIFT 19*/ +/*.emtcode OPERATOR_RSHIFT 20*/ +.emtcode OPERATOR_MULTIPLY 21 +.emtcode OPERATOR_DIVIDE 22 +/*.emtcode OPERATOR_MODULUS 23*/ +.emtcode OPERATOR_INCREMENT 24 +.emtcode OPERATOR_DECREMENT 25 +.emtcode OPERATOR_PLUS 26 +.emtcode OPERATOR_MINUS 27 +/*.emtcode OPERATOR_COMPLEMENT 28*/ +.emtcode OPERATOR_NOT 29 + +/* init declarator list */ +.emtcode DECLARATOR_NONE 0 +.emtcode DECLARATOR_NEXT 1 + +/* variable declaration */ +.emtcode VARIABLE_NONE 0 +.emtcode VARIABLE_IDENTIFIER 1 +.emtcode VARIABLE_INITIALIZER 2 +.emtcode VARIABLE_ARRAY_EXPLICIT 3 +.emtcode VARIABLE_ARRAY_UNKNOWN 4 + +/* type qualifier */ +.emtcode TYPE_QUALIFIER_NONE 0 +.emtcode TYPE_QUALIFIER_CONST 1 +.emtcode TYPE_QUALIFIER_ATTRIBUTE 2 +.emtcode TYPE_QUALIFIER_VARYING 3 +.emtcode TYPE_QUALIFIER_UNIFORM 4 +.emtcode TYPE_QUALIFIER_FIXEDOUTPUT 5 +.emtcode TYPE_QUALIFIER_FIXEDINPUT 6 + +/* invariant qualifier */ +.emtcode TYPE_VARIANT 90 +.emtcode TYPE_INVARIANT 91 + +/* centroid qualifier */ +.emtcode TYPE_CENTER 95 +.emtcode TYPE_CENTROID 96 + +/* type specifier */ +.emtcode TYPE_SPECIFIER_VOID 0 +.emtcode TYPE_SPECIFIER_BOOL 1 +.emtcode TYPE_SPECIFIER_BVEC2 2 +.emtcode TYPE_SPECIFIER_BVEC3 3 +.emtcode TYPE_SPECIFIER_BVEC4 4 +.emtcode TYPE_SPECIFIER_INT 5 +.emtcode TYPE_SPECIFIER_IVEC2 6 +.emtcode TYPE_SPECIFIER_IVEC3 7 +.emtcode TYPE_SPECIFIER_IVEC4 8 +.emtcode TYPE_SPECIFIER_FLOAT 9 +.emtcode TYPE_SPECIFIER_VEC2 10 +.emtcode TYPE_SPECIFIER_VEC3 11 +.emtcode TYPE_SPECIFIER_VEC4 12 +.emtcode TYPE_SPECIFIER_MAT2 13 +.emtcode TYPE_SPECIFIER_MAT3 14 +.emtcode TYPE_SPECIFIER_MAT4 15 +.emtcode TYPE_SPECIFIER_SAMPLER1D 16 +.emtcode TYPE_SPECIFIER_SAMPLER2D 17 +.emtcode TYPE_SPECIFIER_SAMPLER3D 18 +.emtcode TYPE_SPECIFIER_SAMPLERCUBE 19 +.emtcode TYPE_SPECIFIER_SAMPLER1DSHADOW 20 +.emtcode TYPE_SPECIFIER_SAMPLER2DSHADOW 21 +.emtcode TYPE_SPECIFIER_SAMPLER2DRECT 22 +.emtcode TYPE_SPECIFIER_SAMPLER2DRECTSHADOW 23 +.emtcode TYPE_SPECIFIER_STRUCT 24 +.emtcode TYPE_SPECIFIER_TYPENAME 25 + +/* OpenGL 2.1 */ +.emtcode TYPE_SPECIFIER_MAT23 26 +.emtcode TYPE_SPECIFIER_MAT32 27 +.emtcode TYPE_SPECIFIER_MAT24 28 +.emtcode TYPE_SPECIFIER_MAT42 29 +.emtcode TYPE_SPECIFIER_MAT34 30 +.emtcode TYPE_SPECIFIER_MAT43 31 + +/* type specifier array */ +.emtcode TYPE_SPECIFIER_NONARRAY 0 +.emtcode TYPE_SPECIFIER_ARRAY 1 + +/* structure field */ +.emtcode FIELD_NONE 0 +.emtcode FIELD_NEXT 1 +.emtcode FIELD_ARRAY 2 + +/* operation */ +.emtcode OP_END 0 +.emtcode OP_BLOCK_BEGIN_NO_NEW_SCOPE 1 +.emtcode OP_BLOCK_BEGIN_NEW_SCOPE 2 +.emtcode OP_DECLARE 3 +.emtcode OP_ASM 4 +.emtcode OP_BREAK 5 +.emtcode OP_CONTINUE 6 +.emtcode OP_DISCARD 7 +.emtcode OP_RETURN 8 +.emtcode OP_EXPRESSION 9 +.emtcode OP_IF 10 +.emtcode OP_WHILE 11 +.emtcode OP_DO 12 +.emtcode OP_FOR 13 +.emtcode OP_PUSH_VOID 14 +.emtcode OP_PUSH_BOOL 15 +.emtcode OP_PUSH_INT 16 +.emtcode OP_PUSH_FLOAT 17 +.emtcode OP_PUSH_IDENTIFIER 18 +.emtcode OP_SEQUENCE 19 +.emtcode OP_ASSIGN 20 +.emtcode OP_ADDASSIGN 21 +.emtcode OP_SUBASSIGN 22 +.emtcode OP_MULASSIGN 23 +.emtcode OP_DIVASSIGN 24 +/*.emtcode OP_MODASSIGN 25*/ +/*.emtcode OP_LSHASSIGN 26*/ +/*.emtcode OP_RSHASSIGN 27*/ +/*.emtcode OP_ORASSIGN 28*/ +/*.emtcode OP_XORASSIGN 29*/ +/*.emtcode OP_ANDASSIGN 30*/ +.emtcode OP_SELECT 31 +.emtcode OP_LOGICALOR 32 +.emtcode OP_LOGICALXOR 33 +.emtcode OP_LOGICALAND 34 +/*.emtcode OP_BITOR 35*/ +/*.emtcode OP_BITXOR 36*/ +/*.emtcode OP_BITAND 37*/ +.emtcode OP_EQUAL 38 +.emtcode OP_NOTEQUAL 39 +.emtcode OP_LESS 40 +.emtcode OP_GREATER 41 +.emtcode OP_LESSEQUAL 42 +.emtcode OP_GREATEREQUAL 43 +/*.emtcode OP_LSHIFT 44*/ +/*.emtcode OP_RSHIFT 45*/ +.emtcode OP_ADD 46 +.emtcode OP_SUBTRACT 47 +.emtcode OP_MULTIPLY 48 +.emtcode OP_DIVIDE 49 +/*.emtcode OP_MODULUS 50*/ +.emtcode OP_PREINCREMENT 51 +.emtcode OP_PREDECREMENT 52 +.emtcode OP_PLUS 53 +.emtcode OP_MINUS 54 +/*.emtcode OP_COMPLEMENT 55*/ +.emtcode OP_NOT 56 +.emtcode OP_SUBSCRIPT 57 +.emtcode OP_CALL 58 +.emtcode OP_FIELD 59 +.emtcode OP_POSTINCREMENT 60 +.emtcode OP_POSTDECREMENT 61 +.emtcode OP_PRECISION 62 +.emtcode OP_METHOD 63 + +/* parameter qualifier */ +.emtcode PARAM_QUALIFIER_IN 0 +.emtcode PARAM_QUALIFIER_OUT 1 +.emtcode PARAM_QUALIFIER_INOUT 2 + +/* function parameter */ +.emtcode PARAMETER_NONE 0 +.emtcode PARAMETER_NEXT 1 + +/* function parameter array presence */ +.emtcode PARAMETER_ARRAY_NOT_PRESENT 0 +.emtcode PARAMETER_ARRAY_PRESENT 1 + +/* INVALID_EXTERNAL_DECLARATION seems to be reported when there's */ +/* any syntax errors... */ +.errtext INVALID_EXTERNAL_DECLARATION "2001: Syntax error." +.errtext INVALID_OPERATOR_OVERRIDE "2002: Invalid operator override." +.errtext LBRACE_EXPECTED "2003: '{' expected but '$err_token$' found." +.errtext LPAREN_EXPECTED "2004: '(' expected but '$err_token$' found." +.errtext RPAREN_EXPECTED "2005: ')' expected but '$err_token$' found." +.errtext INVALID_PRECISION "2006: Invalid precision specifier '$err_token$'." +.errtext INVALID_PRECISION_TYPE "2007: Invalid precision type '$err_token$'." + + +/* + * tells whether the shader that is being parsed is a built-in shader or not + * 0 - normal behaviour + * 1 - accepts constructor and operator definitions and __asm statements + * the implementation will set it to 1 when compiling internal built-in shaders + */ +.regbyte parsing_builtin 0 + +/* + * holds the type of the shader being parsed; possible values are + * listed below. + * FRAGMENT_SHADER 1 + * VERTEX_SHADER 2 + * shader type is set by the caller before parsing + */ +.regbyte shader_type 0 + +/* + * <variable_identifier> ::= <identifier> + */ +variable_identifier + identifier .emit OP_PUSH_IDENTIFIER; + +/* + * <primary_expression> ::= <variable_identifier> + * | <intconstant> + * | <floatconstant> + * | <boolconstant> + * | "(" <expression> ")" + */ +primary_expression + floatconstant .or boolconstant .or intconstant .or variable_identifier .or primary_expression_1; +primary_expression_1 + lparen .and expression .and rparen; + +/* + * <postfix_expression> ::= <primary_expression> + * | <postfix_expression> "[" <integer_expression> "]" + * | <function_call> + * | <postfix_expression> "." <field_selection> + * | <postfix_expression> "++" + * | <postfix_expression> "--" + */ +postfix_expression + postfix_expression_1 .and .loop postfix_expression_2; +postfix_expression_1 + function_call .or primary_expression; +postfix_expression_2 + postfix_expression_3 .or postfix_expression_4 .or + plusplus .emit OP_POSTINCREMENT .or + minusminus .emit OP_POSTDECREMENT; +postfix_expression_3 + lbracket .and integer_expression .and rbracket .emit OP_SUBSCRIPT; +postfix_expression_4 + dot .and field_selection .emit OP_FIELD; + +/* + * <integer_expression> ::= <expression> + */ +integer_expression + expression; + +/* + * <function_call> ::= <function_call_generic> + */ +function_call + function_call_or_method; + +/* + * <function_call_or_method> ::= <regular_function_call> + * | <postfix_expression> "." <function_call_generic> + */ +function_call_or_method + regular_function_call .or method_call; + +/* + * <method_call> ::= <identifier> "." <function_call_generic> + */ +method_call + identifier .emit OP_METHOD .and dot .and function_call_generic .and .true .emit OP_END; + +/* + * <regular_function_call> ::= <function_call_generic> + */ +regular_function_call + function_call_generic .emit OP_CALL .and .true .emit OP_END; + +/* + * <function_call_generic> ::= <function_call_header_with_parameters> ")" + * | <function_call_header_no_parameters> ")" + */ +function_call_generic + function_call_generic_1 .or function_call_generic_2; +function_call_generic_1 + function_call_header_with_parameters .and rparen .error RPAREN_EXPECTED; +function_call_generic_2 + function_call_header_no_parameters .and rparen .error RPAREN_EXPECTED; + +/* + * <function_call_header_no_parameters>::= <function_call_header> "void" + * | <function_call_header> + */ +function_call_header_no_parameters + function_call_header .and function_call_header_no_parameters_1; +function_call_header_no_parameters_1 + "void" .or .true; + +/* + * <function_call_header_with_parameters> ::= <function_call_header> <assignment_expression> + * | <function_call_header_with_parameters> "," <assignment_expression> + */ +function_call_header_with_parameters + function_call_header .and assignment_expression .and .true .emit OP_END .and + .loop function_call_header_with_parameters_1; +function_call_header_with_parameters_1 + comma .and assignment_expression .and .true .emit OP_END; + +/* + * <function_call_header> ::= <function_identifier> "(" + */ +function_call_header + function_identifier .and lparen; + +/* + * <function_identifier> ::= <constructor_identifier> + * | <identifier> + * | <type_specifier> + * + * note: <constructor_identifier> and <type_specifier> have been deleted + */ +function_identifier + identifier .and function_identifier_opt_array; +function_identifier_opt_array + function_identifier_array .emit FUNCTION_CALL_ARRAY .or + .true .emit FUNCTION_CALL_NONARRAY; +function_identifier_array + lbracket .and constant_expression .and rbracket; + +/* + * <unary_expression> ::= <postfix_expression> + * | "++" <unary_expression> + * | "--" <unary_expression> + * | <unary_operator> <unary_expression> + * + * <unary_operator> ::= "+" + * | "-" + * | "!" + * | "~" // reserved + */ +unary_expression + postfix_expression .or unary_expression_1 .or unary_expression_2 .or unary_expression_3 .or + unary_expression_4 .or unary_expression_5/* .or unary_expression_6*/; +unary_expression_1 + plusplus .and unary_expression .and .true .emit OP_PREINCREMENT; +unary_expression_2 + minusminus .and unary_expression .and .true .emit OP_PREDECREMENT; +unary_expression_3 + plus .and unary_expression .and .true .emit OP_PLUS; +unary_expression_4 + minus .and unary_expression .and .true .emit OP_MINUS; +unary_expression_5 + bang .and unary_expression .and .true .emit OP_NOT; +/*unary_expression_6 + tilde .and unary_expression .and .true .emit OP_COMPLEMENT;*/ + +/* + * <multiplicative_expression> ::= <unary_expression> + * | <multiplicative_expression> "*" <unary_expression> + * | <multiplicative_expression> "/" <unary_expression> + * | <multiplicative_expression> "%" <unary_expression> // reserved + */ +multiplicative_expression + unary_expression .and .loop multiplicative_expression_1; +multiplicative_expression_1 + multiplicative_expression_2 .or multiplicative_expression_3/* .or multiplicative_expression_4*/; +multiplicative_expression_2 + star .and unary_expression .and .true .emit OP_MULTIPLY; +multiplicative_expression_3 + slash .and unary_expression .and .true .emit OP_DIVIDE; +/*multiplicative_expression_4 + percent .and unary_expression .and .true .emit OP_MODULUS;*/ + +/* + * <additive_expression> ::= <multiplicative_expression> + * | <additive_expression> "+" <multiplicative_expression> + * | <additive_expression> "-" <multiplicative_expression> + */ +additive_expression + multiplicative_expression .and .loop additive_expression_1; +additive_expression_1 + additive_expression_2 .or additive_expression_3; +additive_expression_2 + plus .and multiplicative_expression .and .true .emit OP_ADD; +additive_expression_3 + minus .and multiplicative_expression .and .true .emit OP_SUBTRACT; + +/* + * <shift_expression> ::= <additive_expression> + * | <shift_expression> "<<" <additive_expression> // reserved + * | <shift_expression> ">>" <additive_expression> // reserved + */ +shift_expression + additive_expression/* .and .loop shift_expression_1*/; +/*shift_expression_1 + shift_expression_2 .or shift_expression_3;*/ +/*shift_expression_2 + lessless .and additive_expression .and .true .emit OP_LSHIFT;*/ +/*shift_expression_3 + greatergreater .and additive_expression .and .true .emit OP_RSHIFT;*/ + +/* + * <relational_expression> ::= <shift_expression> + * | <relational_expression> "<" <shift_expression> + * | <relational_expression> ">" <shift_expression> + * | <relational_expression> "<=" <shift_expression> + * | <relational_expression> ">=" <shift_expression> + */ +relational_expression + shift_expression .and .loop relational_expression_1; +relational_expression_1 + relational_expression_2 .or relational_expression_3 .or relational_expression_4 .or + relational_expression_5; +relational_expression_2 + lessequals .and shift_expression .and .true .emit OP_LESSEQUAL; +relational_expression_3 + greaterequals .and shift_expression .and .true .emit OP_GREATEREQUAL; +relational_expression_4 + less .and shift_expression .and .true .emit OP_LESS; +relational_expression_5 + greater .and shift_expression .and .true .emit OP_GREATER; + +/* + * <equality_expression> ::= <relational_expression> + * | <equality_expression> "==" <relational_expression> + * | <equality_expression> "!=" <relational_expression> + */ +equality_expression + relational_expression .and .loop equality_expression_1; +equality_expression_1 + equality_expression_2 .or equality_expression_3; +equality_expression_2 + equalsequals .and relational_expression .and .true .emit OP_EQUAL; +equality_expression_3 + bangequals .and relational_expression .and .true .emit OP_NOTEQUAL; + +/* + * <and_expression> ::= <equality_expression> + * | <and_expression> "&" <equality_expression> // reserved + */ +and_expression + equality_expression/* .and .loop and_expression_1*/; +/*and_expression_1 + ampersand .and equality_expression .and .true .emit OP_BITAND;*/ + +/* + * <exclusive_or_expression> ::= <and_expression> + * | <exclusive_or_expression> "^" <and_expression> // reserved + */ +exclusive_or_expression + and_expression/* .and .loop exclusive_or_expression_1*/; +/*exclusive_or_expression_1 + caret .and and_expression .and .true .emit OP_BITXOR;*/ + +/* + * <inclusive_or_expression> ::= <exclusive_or_expression> + * | <inclusive_or_expression> "|" <exclusive_or_expression> // reserved + */ +inclusive_or_expression + exclusive_or_expression/* .and .loop inclusive_or_expression_1*/; +/*inclusive_or_expression_1 + bar .and exclusive_or_expression .and .true .emit OP_BITOR;*/ + +/* + * <logical_and_expression> ::= <inclusive_or_expression> + * | <logical_and_expression> "&&" <inclusive_or_expression> + */ +logical_and_expression + inclusive_or_expression .and .loop logical_and_expression_1; +logical_and_expression_1 + ampersandampersand .and inclusive_or_expression .and .true .emit OP_LOGICALAND; + +/* + * <logical_xor_expression> ::= <logical_and_expression> + * | <logical_xor_expression> "^^" <logical_and_expression> + */ +logical_xor_expression + logical_and_expression .and .loop logical_xor_expression_1; +logical_xor_expression_1 + caretcaret .and logical_and_expression .and .true .emit OP_LOGICALXOR; + +/* + * <logical_or_expression> ::= <logical_xor_expression> + * | <logical_or_expression> "||" <logical_xor_expression> + */ +logical_or_expression + logical_xor_expression .and .loop logical_or_expression_1; +logical_or_expression_1 + barbar .and logical_xor_expression .and .true .emit OP_LOGICALOR; + +/* + * <conditional_expression> ::= <logical_or_expression> + * | <logical_or_expression> "?" <expression> ":" <conditional_expression> + */ +conditional_expression + logical_or_expression .and .loop conditional_expression_1; +conditional_expression_1 + question .and expression .and colon .and conditional_expression .and .true .emit OP_SELECT; + +/* + * <assignment_expression> ::= <conditional_expression> + * | <unary_expression> <assignment_operator> <assignment_expression> + * + * <assignment_operator> ::= "=" + * | "*=" + * | "/=" + * | "+=" + * | "-=" + * | "%=" // reserved + * | "<<=" // reserved + * | ">>=" // reserved + * | "&=" // reserved + * | "^=" // reserved + * | "|=" // reserved + */ +assignment_expression + assignment_expression_1 .or assignment_expression_2 .or assignment_expression_3 .or + assignment_expression_4 .or assignment_expression_5/* .or assignment_expression_6 .or + assignment_expression_7 .or assignment_expression_8 .or assignment_expression_9 .or + assignment_expression_10 .or assignment_expression_11*/ .or conditional_expression; +assignment_expression_1 + unary_expression .and equals .and assignment_expression .and .true .emit OP_ASSIGN; +assignment_expression_2 + unary_expression .and starequals .and assignment_expression .and .true .emit OP_MULASSIGN; +assignment_expression_3 + unary_expression .and slashequals .and assignment_expression .and .true .emit OP_DIVASSIGN; +assignment_expression_4 + unary_expression .and plusequals .and assignment_expression .and .true .emit OP_ADDASSIGN; +assignment_expression_5 + unary_expression .and minusequals .and assignment_expression .and .true .emit OP_SUBASSIGN; +/*assignment_expression_6 + unary_expression .and percentequals .and assignment_expression .and .true .emit OP_MODASSIGN;*/ +/*assignment_expression_7 + unary_expression .and lesslessequals .and assignment_expression .and .true .emit OP_LSHASSIGN;*/ +/*assignment_expression_8 + unary_expression .and greatergreaterequals .and assignment_expression .and + .true .emit OP_RSHASSIGN;*/ +/*assignment_expression_9 + unary_expression .and ampersandequals .and assignment_expression .and .true .emit OP_ANDASSIGN;*/ +/*assignment_expression_10 + unary_expression .and caretequals .and assignment_expression .and .true .emit OP_XORASSIGN;*/ +/*assignment_expression_11 + unary_expression .and barequals .and assignment_expression .and .true .emit OP_ORASSIGN;*/ + +/* + * <expression> ::= <assignment_expression> + * | <expression> "," <assignment_expression> + */ +expression + assignment_expression .and .loop expression_1; +expression_1 + comma .and assignment_expression .and .true .emit OP_SEQUENCE; + +/* + * <constant_expression> ::= <conditional_expression> + */ +constant_expression + conditional_expression .and .true .emit OP_END; + +/* + * <declaration> ::= <function_prototype> ";" + * | <init_declarator_list> ";" + */ +declaration + declaration_1 .or declaration_2; +declaration_1 + function_prototype .emit DECLARATION_FUNCTION_PROTOTYPE .and semicolon; +declaration_2 + init_declarator_list .emit DECLARATION_INIT_DECLARATOR_LIST .and semicolon; + +/* + * <function_prototype> ::= <function_header> "void" ")" + * | <function_declarator> ")" + */ +function_prototype + function_prototype_1 .or function_prototype_2; +function_prototype_1 + function_header .and "void" .and rparen .error RPAREN_EXPECTED .emit PARAMETER_NONE; +function_prototype_2 + function_declarator .and rparen .error RPAREN_EXPECTED .emit PARAMETER_NONE; + +/* + * <function_declarator> ::= <function_header> + * | <function_header_with_parameters> + */ +function_declarator + function_header_with_parameters .or function_header; + +/* + * <function_header_with_parameters> ::= <function_header> <parameter_declaration> + * | <function_header_with_parameters> "," + * <parameter_declaration> + */ +function_header_with_parameters + function_header .and parameter_declaration .and .loop function_header_with_parameters_1; +function_header_with_parameters_1 + comma .and parameter_declaration; + +/* + * <function_header> ::= <fully_specified_type> <identifier> "(" + */ +function_header + function_header_nospace .or function_header_space; +function_header_space + fully_specified_type_space .and space .and function_decl_identifier .and lparen; +function_header_nospace + fully_specified_type_nospace .and function_decl_identifier .and lparen; + +/* + * <function_decl_identifier> ::= "__constructor" + * | <__operator> + * | <identifier> + * + * note: this is an extension to the standard language specification. + * normally slang disallows operator and constructor prototypes and definitions + */ +function_decl_identifier + .if (parsing_builtin != 0) __operator .emit FUNCTION_OPERATOR .or + .if (parsing_builtin != 0) "__constructor" .emit FUNCTION_CONSTRUCTOR .or + identifier .emit FUNCTION_ORDINARY; + +/* + * <__operator> ::= "__operator" <overriden_op> + * + * note: this is an extension to the standard language specification. + * normally slang disallows operator prototypes and definitions + */ +__operator + "__operator" .and overriden_operator .error INVALID_OPERATOR_OVERRIDE; + +/* + * <overriden_op> ::= "=" + * | "+=" + * | "-=" + * | "*=" + * | "/=" + * | "%=" // reserved + * | "<<=" // reserved + * | ">>=" // reserved + * | "&=" // reserved + * | "^=" // reserved + * | "|=" // reserved + * | "^^" + * | "|" // reserved + * | "^" // reserved + * | "&" // reserved + * | "==" + * | "!=" + * | "<" + * | ">" + * | "<=" + * | ">=" + * | "<<" // reserved + * | ">>" // reserved + * | "*" + * | "/" + * | "%" // reserved + * | "++" + * | "--" + * | "+" + * | "-" + * | "~" // reserved + * | "!" + * + * note: this is an extension to the standard language specification. + * normally slang disallows operator prototypes and definitions + */ +overriden_operator + plusplus .emit OPERATOR_INCREMENT .or + plusequals .emit OPERATOR_ADDASSIGN .or + plus .emit OPERATOR_PLUS .or + minusminus .emit OPERATOR_DECREMENT .or + minusequals .emit OPERATOR_SUBASSIGN .or + minus .emit OPERATOR_MINUS .or + bang .emit OPERATOR_NOT .or + starequals .emit OPERATOR_MULASSIGN .or + star .emit OPERATOR_MULTIPLY .or + slashequals .emit OPERATOR_DIVASSIGN .or + slash .emit OPERATOR_DIVIDE .or + lessequals .emit OPERATOR_LESSEQUAL .or + /*lesslessequals .emit OPERATOR_LSHASSIGN .or*/ + /*lessless .emit OPERATOR_LSHIFT .or*/ + less .emit OPERATOR_LESS .or + greaterequals .emit OPERATOR_GREATEREQUAL .or + /*greatergreaterequals .emit OPERATOR_RSHASSIGN .or*/ + /*greatergreater .emit OPERATOR_RSHIFT .or*/ + greater .emit OPERATOR_GREATER .or + /*percentequals .emit OPERATOR_MODASSIGN .or*/ + /*percent .emit OPERATOR_MODULUS .or*/ + /*ampersandequals .emit OPERATOR_ANDASSIGN */ + /*ampersand .emit OPERATOR_BITAND .or*/ + /*barequals .emit OPERATOR_ORASSIGN .or*/ + /*bar .emit OPERATOR_BITOR .or*/ + /*tilde .emit OPERATOR_COMPLEMENT .or*/ + /*caretequals .emit OPERATOR_XORASSIGN .or*/ + caretcaret .emit OPERATOR_LOGICALXOR /*.or + caret .emit OPERATOR_BITXOR*/; + +/* + * <parameter_declarator> ::= <type_specifier> <identifier> + * | <type_specifier> <identifier> "[" <constant_expression> "]" + */ +parameter_declarator + parameter_declarator_nospace .or parameter_declarator_space; +parameter_declarator_nospace + type_specifier_nospace .and identifier .and parameter_declarator_1; +parameter_declarator_space + type_specifier_space .and space .and identifier .and parameter_declarator_1; +parameter_declarator_1 + parameter_declarator_2 .emit PARAMETER_ARRAY_PRESENT .or + .true .emit PARAMETER_ARRAY_NOT_PRESENT; +parameter_declarator_2 + lbracket .and constant_expression .and rbracket; + +/* + * <parameter_declaration> ::= <type_qualifier> <parameter_qualifier> + * <precision> <parameter_declarator> + * | <type_qualifier> <parameter_qualifier> + * <precision> <parameter_type_specifier> + * | <type_qualifier> <parameter_qualifier> + * <parameter_declarator> + * | <type_qualifier> <parameter_qualifier> + * <parameter_type_specifier> + * | <parameter_qualifier> <precision> + * <parameter_declarator> + * | <parameter_qualifier> <precision> + * <parameter_type_specifier> + * | <parameter_qualifier> <parameter_declarator> + * | <parameter_qualifier> <parameter_type_specifier> + */ +parameter_declaration + parameter_declaration_1 .emit PARAMETER_NEXT; +parameter_declaration_1 + parameter_declaration_2 .or parameter_declaration_3; +parameter_declaration_2 + type_qualifier .and space .and parameter_qualifier .and parameter_declaration_4; +parameter_declaration_3 + parameter_qualifier .emit TYPE_QUALIFIER_NONE .and parameter_declaration_4; +parameter_declaration_4 + parameter_declaration_optprec .and parameter_declaration_rest; +parameter_declaration_optprec + parameter_declaration_prec .or .true .emit PRECISION_DEFAULT; +parameter_declaration_prec + precision .and space; +parameter_declaration_rest + parameter_declarator .or parameter_type_specifier; + +/* + * <parameter_qualifier> ::= "in" + * | "out" + * | "inout" + * | "" + */ +parameter_qualifier + parameter_qualifier_1 .or .true .emit PARAM_QUALIFIER_IN; +parameter_qualifier_1 + parameter_qualifier_2 .and space; +parameter_qualifier_2 + "in" .emit PARAM_QUALIFIER_IN .or + "out" .emit PARAM_QUALIFIER_OUT .or + "inout" .emit PARAM_QUALIFIER_INOUT; + +/* + * <parameter_type_specifier> ::= <type_specifier> + * | <type_specifier> "[" <constant_expression> "]" + */ +parameter_type_specifier + parameter_type_specifier_1 .and .true .emit '\0' .and parameter_type_specifier_2; +parameter_type_specifier_1 + type_specifier_nospace .or type_specifier_space; +parameter_type_specifier_2 + parameter_type_specifier_3 .emit PARAMETER_ARRAY_PRESENT .or + .true .emit PARAMETER_ARRAY_NOT_PRESENT; +parameter_type_specifier_3 + lbracket .and constant_expression .and rbracket; + +/* + * <init_declarator_list> ::= <single_declaration> + * | <init_declarator_list> "," <identifier> + * | <init_declarator_list> "," <identifier> "[" "]" + * | <init_declarator_list> "," <identifier> "[" <constant_expression> "]" + * | <init_declarator_list> "," <identifier> "=" <initializer> + */ +init_declarator_list + single_declaration .and .loop init_declarator_list_1 .emit DECLARATOR_NEXT .and + .true .emit DECLARATOR_NONE; +init_declarator_list_1 + comma .and identifier .emit VARIABLE_IDENTIFIER .and init_declarator_list_2; +init_declarator_list_2 + init_declarator_list_3 .or init_declarator_list_4 .or .true .emit VARIABLE_NONE; +init_declarator_list_3 + equals .and initializer .emit VARIABLE_INITIALIZER; +init_declarator_list_4 + lbracket .and init_declarator_list_5 .and rbracket; +init_declarator_list_5 + constant_expression .emit VARIABLE_ARRAY_EXPLICIT .or .true .emit VARIABLE_ARRAY_UNKNOWN; + +/* + * <single_declaration> ::= <fully_specified_type> + * | <fully_specified_type> <identifier> + * | <fully_specified_type> <identifier> "[" "]" + * | <fully_specified_type> <identifier> "[" <constant_expression> "]" + * | <fully_specified_type> <identifier> "=" <initializer> + */ +single_declaration + single_declaration_nospace .or single_declaration_space; +single_declaration_space + fully_specified_type_space .and single_declaration_space_1; +single_declaration_nospace + fully_specified_type_nospace .and single_declaration_nospace_1; +single_declaration_space_1 + single_declaration_space_2 .emit VARIABLE_IDENTIFIER .or .true .emit VARIABLE_NONE; +single_declaration_nospace_1 + single_declaration_nospace_2 .emit VARIABLE_IDENTIFIER .or .true .emit VARIABLE_NONE; +single_declaration_space_2 + space .and identifier .and single_declaration_3; +single_declaration_nospace_2 + identifier .and single_declaration_3; +single_declaration_3 + single_declaration_4 .or single_declaration_5 .or .true .emit VARIABLE_NONE; +single_declaration_4 + equals .and initializer .emit VARIABLE_INITIALIZER; +single_declaration_5 + lbracket .and single_declaration_6 .and rbracket; +single_declaration_6 + constant_expression .emit VARIABLE_ARRAY_EXPLICIT .or .true .emit VARIABLE_ARRAY_UNKNOWN; + +/* + * <fully_specified_type> ::= <opt_invariant> <opt_centroid> <opt_qualifer> <opt_precision> <type_specifier> + * + * Example: "invariant varying highp vec3" + */ +fully_specified_type_space + fully_specified_type_optinvariant .and fully_specified_type_optcentroid .and fully_specified_type_optqual .and fully_specified_type_optprec .and type_specifier_space; +fully_specified_type_nospace + fully_specified_type_optinvariant .and fully_specified_type_optcentroid .and fully_specified_type_optqual .and fully_specified_type_optprec .and type_specifier_nospace; +fully_specified_type_optinvariant + fully_specified_type_invariant .or .true .emit TYPE_VARIANT; +fully_specified_type_invariant + invariant_qualifier .and space; +fully_specified_type_optcentroid + fully_specified_type_centroid .or .true .emit TYPE_CENTER; +fully_specified_type_centroid + centroid_qualifier .and space; +fully_specified_type_optqual + fully_specified_type_qual .or .true .emit TYPE_QUALIFIER_NONE; +fully_specified_type_qual + type_qualifier .and space; +fully_specified_type_optprec + fully_specified_type_prec .or .true .emit PRECISION_DEFAULT; +fully_specified_type_prec + precision .and space; + +/* + * <invariant_qualifier> ::= "invariant" + */ +invariant_qualifier + "invariant" .emit TYPE_INVARIANT; + +centroid_qualifier + "centroid" .emit TYPE_CENTROID; + + +/* + * <type_qualifier> ::= "const" + * | "attribute" // Vertex only. + * | "varying" + * | "uniform" + * | "__fixed_output" + * | "__fixed_input" + * + * note: this is an extension to the standard language specification, + * normally slang disallows __fixed_output and __fixed_input type qualifiers + */ +type_qualifier + "const" .emit TYPE_QUALIFIER_CONST .or + .if (shader_type == 2) "attribute" .emit TYPE_QUALIFIER_ATTRIBUTE .or + "varying" .emit TYPE_QUALIFIER_VARYING .or + "uniform" .emit TYPE_QUALIFIER_UNIFORM .or + .if (parsing_builtin != 0) "__fixed_output" .emit TYPE_QUALIFIER_FIXEDOUTPUT .or + .if (parsing_builtin != 0) "__fixed_input" .emit TYPE_QUALIFIER_FIXEDINPUT; + +/* + * <type_specifier_nonarray> ::= "void" + * | "float" + * | "int" + * | "bool" + * | "vec2" + * | "vec3" + * | "vec4" + * | "bvec2" + * | "bvec3" + * | "bvec4" + * | "ivec2" + * | "ivec3" + * | "ivec4" + * | "mat2" + * | "mat3" + * | "mat4" + * | "mat2x3" + * | "mat3x2" + * | "mat2x4" + * | "mat4x2" + * | "mat3x4" + * | "mat4x3" + * | "sampler1D" + * | "sampler2D" + * | "sampler3D" + * | "samplerCube" + * | "sampler1DShadow" + * | "sampler2DShadow" + * | "sampler2DRect" + * | "sampler2DRectShadow" + * | <struct_specifier> + * | <type_name> + */ +type_specifier_nonarray_space + "void" .emit TYPE_SPECIFIER_VOID .or + "float" .emit TYPE_SPECIFIER_FLOAT .or + "int" .emit TYPE_SPECIFIER_INT .or + "bool" .emit TYPE_SPECIFIER_BOOL .or + "vec2" .emit TYPE_SPECIFIER_VEC2 .or + "vec3" .emit TYPE_SPECIFIER_VEC3 .or + "vec4" .emit TYPE_SPECIFIER_VEC4 .or + "bvec2" .emit TYPE_SPECIFIER_BVEC2 .or + "bvec3" .emit TYPE_SPECIFIER_BVEC3 .or + "bvec4" .emit TYPE_SPECIFIER_BVEC4 .or + "ivec2" .emit TYPE_SPECIFIER_IVEC2 .or + "ivec3" .emit TYPE_SPECIFIER_IVEC3 .or + "ivec4" .emit TYPE_SPECIFIER_IVEC4 .or + "mat2" .emit TYPE_SPECIFIER_MAT2 .or + "mat3" .emit TYPE_SPECIFIER_MAT3 .or + "mat4" .emit TYPE_SPECIFIER_MAT4 .or + "mat2x3" .emit TYPE_SPECIFIER_MAT23 .or + "mat3x2" .emit TYPE_SPECIFIER_MAT32 .or + "mat2x4" .emit TYPE_SPECIFIER_MAT24 .or + "mat4x2" .emit TYPE_SPECIFIER_MAT42 .or + "mat3x4" .emit TYPE_SPECIFIER_MAT34 .or + "mat4x3" .emit TYPE_SPECIFIER_MAT43 .or + "sampler1D" .emit TYPE_SPECIFIER_SAMPLER1D .or + "sampler2D" .emit TYPE_SPECIFIER_SAMPLER2D .or + "sampler3D" .emit TYPE_SPECIFIER_SAMPLER3D .or + "samplerCube" .emit TYPE_SPECIFIER_SAMPLERCUBE .or + "sampler1DShadow" .emit TYPE_SPECIFIER_SAMPLER1DSHADOW .or + "sampler2DShadow" .emit TYPE_SPECIFIER_SAMPLER2DSHADOW .or + "sampler2DRect" .emit TYPE_SPECIFIER_SAMPLER2DRECT .or + "sampler2DRectShadow" .emit TYPE_SPECIFIER_SAMPLER2DRECTSHADOW .or + type_name .emit TYPE_SPECIFIER_TYPENAME; +type_specifier_nonarray_nospace + struct_specifier .emit TYPE_SPECIFIER_STRUCT; +type_specifier_nonarray + type_specifier_nonarray_nospace .or type_specifier_nonarray_space; + +/* + * <type_specifier> ::= <type_specifier_nonarray> + * | <type_specifier_nonarray> "[" <constant_expression> "]" + */ +type_specifier_space + type_specifier_nonarray_space .and .true .emit TYPE_SPECIFIER_NONARRAY; +type_specifier_nospace + type_specifier_nospace_array .or type_specifier_nospace_1; +type_specifier_nospace_1 + type_specifier_nonarray_nospace .and .true .emit TYPE_SPECIFIER_NONARRAY; +type_specifier_nospace_array + type_specifier_nonarray .and lbracket .emit TYPE_SPECIFIER_ARRAY .and constant_expression .and rbracket; + +/* + * <struct_specifier> ::= "struct" <identifier> "{" <struct_declaration_list> "}" + * | "struct" "{" <struct_declaration_list> "}" + */ +struct_specifier + "struct" .and struct_specifier_1 .and optional_space .and lbrace .error LBRACE_EXPECTED .and + struct_declaration_list .and rbrace .emit FIELD_NONE; +struct_specifier_1 + struct_specifier_2 .or .true .emit '\0'; +struct_specifier_2 + space .and identifier; + +/* + * <struct_declaration_list> ::= <struct_declaration> + * | <struct_declaration_list> <struct_declaration> + */ +struct_declaration_list + struct_declaration .and .loop struct_declaration .emit FIELD_NEXT; + +/* + * <struct_declaration> ::= <type_specifier> <struct_declarator_list> ";" + */ +struct_declaration + struct_declaration_nospace .or struct_declaration_space; +struct_declaration_space + type_specifier_space .and space .and struct_declarator_list .and semicolon .emit FIELD_NONE; +struct_declaration_nospace + type_specifier_nospace .and struct_declarator_list .and semicolon .emit FIELD_NONE; + +/* + * <struct_declarator_list> ::= <struct_declarator> + * | <struct_declarator_list> "," <struct_declarator> + */ +struct_declarator_list + struct_declarator .and .loop struct_declarator_list_1 .emit FIELD_NEXT; +struct_declarator_list_1 + comma .and struct_declarator; + +/* + * <struct_declarator> ::= <identifier> + * | <identifier> "[" <constant_expression> "]" + */ +struct_declarator + identifier .and struct_declarator_1; +struct_declarator_1 + struct_declarator_2 .emit FIELD_ARRAY .or .true .emit FIELD_NONE; +struct_declarator_2 + lbracket .and constant_expression .and rbracket; + +/* + * <initializer> ::= <assignment_expression> + */ +initializer + assignment_expression .and .true .emit OP_END; + +/* + * <declaration_statement> ::= <declaration> + */ +declaration_statement + declaration; + +/* + * <statement> ::= <compound_statement> + * | <simple_statement> + */ +statement + compound_statement .or simple_statement; +statement_space + compound_statement .or statement_space_1; +statement_space_1 + space .and simple_statement; + +/* + * <simple_statement> ::= <__asm_statement> + * | <selection_statement> + * | <iteration_statement> + * | <jump_statement> + * | <expression_statement> + * | <declaration_statement> + * + * note: this is an extension to the standard language specification. + * normally slang disallows use of __asm statements + */ +simple_statement + .if (parsing_builtin != 0) __asm_statement .emit OP_ASM .or + selection_statement .or + iteration_statement .or + precision_stmt .emit OP_PRECISION .or + jump_statement .or + expression_statement .emit OP_EXPRESSION .or + declaration_statement .emit OP_DECLARE; + +/* + * <compound_statement> ::= "{" "}" + * | "{" <statement_list> "}" + */ +compound_statement + compound_statement_1 .emit OP_BLOCK_BEGIN_NEW_SCOPE .and .true .emit OP_END; +compound_statement_1 + compound_statement_2 .or compound_statement_3; +compound_statement_2 + lbrace .and rbrace; +compound_statement_3 + lbrace .and statement_list .and rbrace; + +/* + * <compound_statement_no_new_scope> ::= "{" "}" + * | "{" <statement_list> "}" + */ +compound_statement_no_new_scope + compound_statement_no_new_scope_1 .emit OP_BLOCK_BEGIN_NO_NEW_SCOPE .and .true .emit OP_END; +compound_statement_no_new_scope_1 + compound_statement_no_new_scope_2 .or compound_statement_no_new_scope_3; +compound_statement_no_new_scope_2 + lbrace .and rbrace; +compound_statement_no_new_scope_3 + lbrace .and statement_list .and rbrace; + + +/* + * <statement_list> ::= <statement> + * | <statement_list> <statement> + */ +statement_list + statement .and .loop statement; + +/* + * <expression_statement> ::= ";" + * | <expression> ";" + */ +expression_statement + expression_statement_1 .or expression_statement_2; +expression_statement_1 + semicolon .emit OP_PUSH_VOID .emit OP_END; +expression_statement_2 + expression .and semicolon .emit OP_END; + +/* + * <selection_statement> ::= "if" "(" <expression> ")" <selection_rest_statement> + */ +selection_statement + "if" .emit OP_IF .and lparen .error LPAREN_EXPECTED .and expression .and + rparen .error RPAREN_EXPECTED .emit OP_END .and selection_rest_statement; + +/* + * <selection_rest_statement> ::= <statement> "else" <statement> + * | <statement> + */ +selection_rest_statement + statement .and selection_rest_statement_1; +selection_rest_statement_1 + selection_rest_statement_2 .or .true .emit OP_EXPRESSION .emit OP_PUSH_VOID .emit OP_END; +selection_rest_statement_2 + "else" .and optional_space .and statement; + +/* + * <condition> ::= <expression> + * | <fully_specified_type> <identifier> "=" <initializer> + * + * note: if <condition_1> is executed, the emit format must + * match <declaration> emit format + */ +condition + condition_1 .emit OP_DECLARE .emit DECLARATION_INIT_DECLARATOR_LIST .or + condition_3 .emit OP_EXPRESSION; +condition_1 + condition_1_nospace .or condition_1_space; +condition_1_nospace + fully_specified_type_nospace .and condition_2; +condition_1_space + fully_specified_type_space .and space .and condition_2; +condition_2 + identifier .emit VARIABLE_IDENTIFIER .and equals .emit VARIABLE_INITIALIZER .and + initializer .and .true .emit DECLARATOR_NONE; +condition_3 + expression .and .true .emit OP_END; + +/* + * <iteration_statement> ::= "while" "(" <condition> ")" <statement> + * | "do" <statement> "while" "(" <expression> ")" ";" + * | "for" "(" <for_init_statement> <for_rest_statement> ")" <statement> + */ +iteration_statement + iteration_statement_1 .or iteration_statement_2 .or iteration_statement_3; +iteration_statement_1 + "while" .emit OP_WHILE .and lparen .error LPAREN_EXPECTED .and condition .and + rparen .error RPAREN_EXPECTED .and statement; +iteration_statement_2 + "do" .emit OP_DO .and statement_space .and "while" .and lparen .error LPAREN_EXPECTED .and + expression .and rparen .error RPAREN_EXPECTED .emit OP_END .and semicolon; +iteration_statement_3 + "for" .emit OP_FOR .and lparen .error LPAREN_EXPECTED .and for_init_statement .and + for_rest_statement .and rparen .error RPAREN_EXPECTED .and statement; + +/* + * <for_init_statement> ::= <expression_statement> + * | <declaration_statement> + */ +for_init_statement + expression_statement .emit OP_EXPRESSION .or declaration_statement .emit OP_DECLARE; + +/* + * <conditionopt> ::= <condition> + * | "" + * + * note: <conditionopt> is used only by "for" statement. + * if <condition> is ommitted, parser simulates default behaviour, + * that is simulates "true" expression + */ +conditionopt + condition .or + .true .emit OP_EXPRESSION .emit OP_PUSH_BOOL .emit 2 .emit '1' .emit '\0' .emit OP_END; + +/* + * <for_rest_statement> ::= <conditionopt> ";" + * | <conditionopt> ";" <expression> + */ +for_rest_statement + conditionopt .and semicolon .and for_rest_statement_1; +for_rest_statement_1 + for_rest_statement_2 .or .true .emit OP_PUSH_VOID .emit OP_END; +for_rest_statement_2 + expression .and .true .emit OP_END; + +/* + * <jump_statement> ::= "continue" ";" + * | "break" ";" + * | "return" ";" + * | "return" <expression> ";" + * | "discard" ";" // Fragment shader only. + */ +jump_statement + jump_statement_1 .or jump_statement_2 .or jump_statement_3 .or jump_statement_4 .or + .if (shader_type == 1) jump_statement_5; +jump_statement_1 + "continue" .and semicolon .emit OP_CONTINUE; +jump_statement_2 + "break" .and semicolon .emit OP_BREAK; +jump_statement_3 + "return" .emit OP_RETURN .and optional_space .and expression .and semicolon .emit OP_END; +jump_statement_4 + "return" .emit OP_RETURN .and semicolon .emit OP_PUSH_VOID .emit OP_END; +jump_statement_5 + "discard" .and semicolon .emit OP_DISCARD; + +/* + * <__asm_statement> ::= "__asm" <identifier> <asm_arguments> ";" + * + * note: this is an extension to the standard language specification. + * normally slang disallows __asm statements + */ +__asm_statement + "__asm" .and space .and identifier .and space .and asm_arguments .and semicolon .emit OP_END; + +/* + * <asm_arguments> ::= <asm_argument> + * | <asm_arguments> "," <asm_argument> + * + * note: this is an extension to the standard language specification. + * normally slang disallows __asm statements + */ +asm_arguments + asm_argument .and .true .emit OP_END .and .loop asm_arguments_1; +asm_arguments_1 + comma .and asm_argument .and .true .emit OP_END; + +/* + * <asm_argument> ::= <variable_identifier> + * | <floatconstant> + * + * note: this is an extension to the standard language specification. + * normally slang disallows __asm statements + */ +asm_argument + var_with_field .or + variable_identifier .or + floatconstant; + +var_with_field + variable_identifier .and dot .and field_selection .emit OP_FIELD; + + +/* + * <translation_unit> ::= <external_declaration> + * | <translation_unit> <external_declaration> + */ +translation_unit + optional_space .emit REVISION .and external_declaration .error INVALID_EXTERNAL_DECLARATION .and + .loop external_declaration .and optional_space .and + '\0' .error INVALID_EXTERNAL_DECLARATION .emit EXTERNAL_NULL; + + +/* + * <external_declaration> ::= <function_definition> + * | <declaration> + */ +external_declaration + precision_stmt .emit DEFAULT_PRECISION .or + function_definition .emit EXTERNAL_FUNCTION_DEFINITION .or + invariant_stmt .emit INVARIANT_STMT .or + declaration .emit EXTERNAL_DECLARATION; + + +/* + * <precision_stmt> ::= "precision" <precision> <prectype> + */ +precision_stmt + "precision" .and space .and precision .error INVALID_PRECISION .and space .and prectype .error INVALID_PRECISION_TYPE .and semicolon; + +/* + * <precision> ::= "lowp" + * | "mediump" + * | "highp" + */ +precision + "lowp" .emit PRECISION_LOW .or + "mediump" .emit PRECISION_MEDIUM .or + "highp" .emit PRECISION_HIGH; + +/* + * <prectype> ::= "int" + * | "float" + * | "a sampler type" + */ +prectype + "int" .emit TYPE_SPECIFIER_INT .or + "float" .emit TYPE_SPECIFIER_FLOAT .or + "sampler1D" .emit TYPE_SPECIFIER_SAMPLER1D .or + "sampler2D" .emit TYPE_SPECIFIER_SAMPLER2D .or + "sampler3D" .emit TYPE_SPECIFIER_SAMPLER3D .or + "samplerCube" .emit TYPE_SPECIFIER_SAMPLERCUBE .or + "sampler1DShadow" .emit TYPE_SPECIFIER_SAMPLER1DSHADOW .or + "sampler2DShadow" .emit TYPE_SPECIFIER_SAMPLER2DSHADOW .or + "sampler2DRect" .emit TYPE_SPECIFIER_SAMPLER2DRECT .or + "sampler2DRectShadow" .emit TYPE_SPECIFIER_SAMPLER2DRECTSHADOW; + + +/* + * <invariant_stmt> ::= "invariant" identifier; + */ +invariant_stmt + "invariant" .and space .and identifier .and semicolon; + + +/* + * <function_definition> :: <function_prototype> <compound_statement_no_new_scope> + */ +function_definition + function_prototype .and compound_statement_no_new_scope; + + + +/* + * helper rules, not part of the official language syntax + */ + +digit_oct + '0'-'7'; + +digit_dec + '0'-'9'; + +digit_hex + '0'-'9' .or 'A'-'F' .or 'a'-'f'; + +id_character_first + 'a'-'z' .or 'A'-'Z' .or '_'; + +id_character_next + id_character_first .or digit_dec; + +identifier + id_character_first .emit * .and .loop id_character_next .emit * .and .true .emit '\0'; + +float + float_1 .or float_2 .or float_3; +float_1 + float_fractional_constant .and float_optional_exponent_part .and optional_f_suffix; +float_2 + float_digit_sequence .and .true .emit '\0' .and float_exponent_part .and optional_f_suffix; +float_3 + float_digit_sequence .and .true .emit '\0' .and 'f' .emit '\0'; + +float_fractional_constant + float_fractional_constant_1 .or float_fractional_constant_2 .or float_fractional_constant_3; +float_fractional_constant_1 + float_digit_sequence .and '.' .and float_digit_sequence; +float_fractional_constant_2 + float_digit_sequence .and '.' .and .true .emit '\0'; +float_fractional_constant_3 + '.' .emit '\0' .and float_digit_sequence; + +float_optional_exponent_part + float_exponent_part .or .true .emit '\0'; + +float_digit_sequence + digit_dec .emit * .and .loop digit_dec .emit * .and .true .emit '\0'; + +float_exponent_part + float_exponent_part_1 .or float_exponent_part_2; +float_exponent_part_1 + 'e' .and float_optional_sign .and float_digit_sequence; +float_exponent_part_2 + 'E' .and float_optional_sign .and float_digit_sequence; + +float_optional_sign + float_sign .or .true; + +float_sign + '+' .or '-' .emit '-'; + +optional_f_suffix + 'f' .or .true; + + +integer + integer_hex .or integer_oct .or integer_dec; + +integer_hex + '0' .and integer_hex_1 .emit 0x10 .and digit_hex .emit * .and .loop digit_hex .emit * .and + .true .emit '\0'; +integer_hex_1 + 'x' .or 'X'; + +integer_oct + '0' .emit 8 .emit * .and .loop digit_oct .emit * .and .true .emit '\0'; + +integer_dec + digit_dec .emit 10 .emit * .and .loop digit_dec .emit * .and .true .emit '\0'; + +boolean + "true" .emit 2 .emit '1' .emit '\0' .or + "false" .emit 2 .emit '0' .emit '\0'; + +type_name + identifier; + +field_selection + identifier; + +floatconstant + float .emit OP_PUSH_FLOAT; + +intconstant + integer .emit OP_PUSH_INT; + +boolconstant + boolean .emit OP_PUSH_BOOL; + +optional_space + .loop single_space; + +space + single_space .and .loop single_space; + +single_space + white_char .or c_style_comment_block .or cpp_style_comment_block; + +white_char + ' ' .or '\t' .or new_line .or '\v' .or '\f'; + +new_line + cr_lf .or lf_cr .or '\n' .or '\r'; + +cr_lf + '\r' .and '\n'; + +lf_cr + '\n' .and '\r'; + +c_style_comment_block + '/' .and '*' .and c_style_comment_rest; + +c_style_comment_rest + .loop c_style_comment_char_no_star .and c_style_comment_rest_1; +c_style_comment_rest_1 + c_style_comment_end .or c_style_comment_rest_2; +c_style_comment_rest_2 + '*' .and c_style_comment_rest; + +c_style_comment_char_no_star + '\x2B'-'\xFF' .or '\x01'-'\x29'; + +c_style_comment_end + '*' .and '/'; + +cpp_style_comment_block + '/' .and '/' .and cpp_style_comment_block_1; +cpp_style_comment_block_1 + cpp_style_comment_block_2 .or cpp_style_comment_block_3; +cpp_style_comment_block_2 + .loop cpp_style_comment_char .and new_line; +cpp_style_comment_block_3 + .loop cpp_style_comment_char; + +cpp_style_comment_char + '\x0E'-'\xFF' .or '\x01'-'\x09' .or '\x0B'-'\x0C'; + +/* lexical rules */ + +/*ampersand + optional_space .and '&' .and optional_space;*/ + +ampersandampersand + optional_space .and '&' .and '&' .and optional_space; + +/*ampersandequals + optional_space .and '&' .and '=' .and optional_space;*/ + +/*bar + optional_space .and '|' .and optional_space;*/ + +barbar + optional_space .and '|' .and '|' .and optional_space; + +/*barequals + optional_space .and '|' .and '=' .and optional_space;*/ + +bang + optional_space .and '!' .and optional_space; + +bangequals + optional_space .and '!' .and '=' .and optional_space; + +/*caret + optional_space .and '^' .and optional_space;*/ + +caretcaret + optional_space .and '^' .and '^' .and optional_space; + +/*caretequals + optional_space .and '^' .and '=' .and optional_space;*/ + +colon + optional_space .and ':' .and optional_space; + +comma + optional_space .and ',' .and optional_space; + +dot + optional_space .and '.' .and optional_space; + +equals + optional_space .and '=' .and optional_space; + +equalsequals + optional_space .and '=' .and '=' .and optional_space; + +greater + optional_space .and '>' .and optional_space; + +greaterequals + optional_space .and '>' .and '=' .and optional_space; + +/*greatergreater + optional_space .and '>' .and '>' .and optional_space;*/ + +/*greatergreaterequals + optional_space .and '>' .and '>' .and '=' .and optional_space;*/ + +lbrace + optional_space .and '{' .and optional_space; + +lbracket + optional_space .and '[' .and optional_space; + +less + optional_space .and '<' .and optional_space; + +lessequals + optional_space .and '<' .and '=' .and optional_space; + +/*lessless + optional_space .and '<' .and '<' .and optional_space;*/ + +/*lesslessequals + optional_space .and '<' .and '<' .and '=' .and optional_space;*/ + +lparen + optional_space .and '(' .and optional_space; + +minus + optional_space .and '-' .and optional_space; + +minusequals + optional_space .and '-' .and '=' .and optional_space; + +minusminus + optional_space .and '-' .and '-' .and optional_space; + +/*percent + optional_space .and '%' .and optional_space;*/ + +/*percentequals + optional_space .and '%' .and '=' .and optional_space;*/ + +plus + optional_space .and '+' .and optional_space; + +plusequals + optional_space .and '+' .and '=' .and optional_space; + +plusplus + optional_space .and '+' .and '+' .and optional_space; + +question + optional_space .and '?' .and optional_space; + +rbrace + optional_space .and '}' .and optional_space; + +rbracket + optional_space .and ']' .and optional_space; + +rparen + optional_space .and ')' .and optional_space; + +semicolon + optional_space .and ';' .and optional_space; + +slash + optional_space .and '/' .and optional_space; + +slashequals + optional_space .and '/' .and '=' .and optional_space; + +star + optional_space .and '*' .and optional_space; + +starequals + optional_space .and '*' .and '=' .and optional_space; + +/*tilde + optional_space .and '~' .and optional_space;*/ + +/* string rules - these are used internally by the parser when parsing quoted strings */ + +.string string_lexer; + +string_lexer + lex_first_identifier_character .and .loop lex_next_identifier_character; + +lex_first_identifier_character + 'a'-'z' .or 'A'-'Z' .or '_'; + +lex_next_identifier_character + 'a'-'z' .or 'A'-'Z' .or '0'-'9' .or '_'; + +/* error rules - these are used by error messages */ + +err_token + '~' .or '`' .or '!' .or '@' .or '#' .or '$' .or '%' .or '^' .or '&' .or '*' .or '(' .or ')' .or + '-' .or '+' .or '=' .or '|' .or '\\' .or '[' .or ']' .or '{' .or '}' .or ':' .or ';' .or '"' .or + '\'' .or '<' .or ',' .or '>' .or '.' .or '/' .or '?' .or err_identifier; + +err_identifier + id_character_first .and .loop id_character_next; + |