Add GLSL lexer/parser support for uniform arrays 87/251687/1
authorLukasz Kostyra <l.kostyra@samsung.com>
Fri, 15 Jan 2021 12:09:12 +0000 (13:09 +0100)
committerLukasz Kostyra <l.kostyra@samsung.com>
Mon, 18 Jan 2021 11:37:12 +0000 (12:37 +0100)
Using uniform arrays caused syntax error. GLSL lexer/parser now
understands these statements.

Change-Id: Ia5345594ab356fa3977447fe6f3434a06371f946

GLESv2/yagl_glsl_lexer.l
GLESv2/yagl_glsl_parser.y

index de5d5116d4e44bcec535f55433a0cc1bbdb07df4..9190c7b3d761826d9c6902b1d58afac2e4de5813 100644 (file)
@@ -534,16 +534,34 @@ STRING [^ \r\t\v\f\n()\[\]{},;?:/%*&|^!+\-=<>\.]+
     return TOK_STRING;
 }
 
-<UNIFORM>{WS}*; {
+<UNIFORM>{WS}+ {
+    struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+    yagl_glsl_state_new_pending(state, yytext);
+}
+
+<UNIFORM>; {
     struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
     BEGIN(INITIAL);
-    yagl_glsl_state_new_str_token(state, yylval, yytext);
+    yagl_glsl_state_new_character_token(state, yylval, *yytext);
     return TOK_EOI;
 }
 
-<UNIFORM>{WS}+ {
+<UNIFORM>\[ {
     struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
-    yagl_glsl_state_new_pending(state, yytext);
+    yagl_glsl_state_new_character_token(state, yylval, *yytext);
+    return TOK_ARR_PAREN_OPEN;
+}
+
+<UNIFORM>\] {
+    struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+    yagl_glsl_state_new_character_token(state, yylval, *yytext);
+    return TOK_ARR_PAREN_CLOSE;
+}
+
+<UNIFORM>[0-9]* {
+    struct yagl_glsl_state *state = yagl_glsl_lexer_get_extra(yyscanner);
+    yagl_glsl_state_new_integer_token(state, yylval, strtol(yytext, NULL, 10));
+    return TOK_INTEGER;
 }
 
 <UNIFORM>{PRECISION_QUAL} {
index 538f3405788ccc4eaf84813033d3d6352dbd8855..61dbbe275b5e40313d8c1551a0d6afa192539311 100644 (file)
@@ -47,7 +47,9 @@ static int yagl_glsl_lex(union YYSTYPE *val, struct yagl_glsl_state *state)
 }
 
 %token <str> TOK_EOL
-%token <str> TOK_EOI
+%token <character> TOK_EOI
+%token <character> TOK_ARR_PAREN_OPEN
+%token <character> TOK_ARR_PAREN_CLOSE
 %token <str> TOK_VERSION
 %token <str> TOK_DEFINE
 %token <str> TOK_UNDEF
@@ -652,6 +654,98 @@ expression
         yagl_glsl_state_append_output(state, $1.value);
     }
 }
+| TOK_UNIFORM TOK_PRECISION_QUAL TOK_STRING TOK_STRING TOK_ARR_PAREN_OPEN TOK_INTEGER TOK_ARR_PAREN_CLOSE TOK_EOI
+{
+    char s[100];
+
+    yagl_glsl_state_flush_pending(state, $1.index);
+    yagl_glsl_state_append_output(state, $1.value);
+
+    // precision qualifier should only be flushed here, GLSL non-ES does not support it
+    yagl_glsl_state_flush_pending(state, $2.index);
+
+    yagl_glsl_state_flush_pending(state, $3.index);
+    yagl_glsl_state_append_output(state, $3.value);
+    yagl_glsl_state_flush_pending(state, $4.index);
+    yagl_glsl_state_append_output(state, $4.value);
+    yagl_glsl_state_flush_pending(state, $5.index);
+    yagl_glsl_state_append_output_char(state, $5.c);
+    yagl_glsl_state_flush_pending(state, $6.index);
+    sprintf(s, "%d", $6.value);
+    yagl_glsl_state_append_output(state, s);
+    yagl_glsl_state_flush_pending(state, $7.index);
+    yagl_glsl_state_append_output_char(state, $7.c);
+    yagl_glsl_state_flush_pending(state, $8.index);
+    yagl_glsl_state_append_output_char(state, $8.c);
+
+    // TODO this should also take into account TOK_INTEGER, because it could be an array of samplers
+    if (yagl_glsl_state_pp_is_condition_met(state)) {
+        // locally try to resolve the define based on current knowledge
+        // it won't matter if our type is not a macro but an actual sampler type
+        char* type_resolved = NULL;
+        int int_resolved = 0;
+        yagl_glsl_state_pp_resolve_define(state, $3.value, &type_resolved, &int_resolved);
+
+        if (type_resolved != NULL) {
+            if (strcmp(type_resolved, "samplerExternalOES") == 0) {
+                if (!state->have_samplerexternaloes) {
+                    yagl_glsl_state_append_header(state, "#define samplerExternalOES sampler2D\n");
+                    state->have_samplerexternaloes = 1;
+                }
+
+                yagl_glsl_state_add_sampler_ExternalOES(state, $4.value);
+            } else if (strcmp(type_resolved, "sampler2D") == 0) {
+                yagl_glsl_state_add_sampler_2D(state, $4.value);
+            }
+
+            free(type_resolved);
+        }
+    }
+}
+| TOK_UNIFORM TOK_STRING TOK_STRING TOK_ARR_PAREN_OPEN TOK_INTEGER TOK_ARR_PAREN_CLOSE TOK_EOI
+{
+    char s[100];
+
+    yagl_glsl_state_flush_pending(state, $1.index);
+    yagl_glsl_state_append_output(state, $1.value);
+    yagl_glsl_state_flush_pending(state, $2.index);
+    yagl_glsl_state_append_output(state, $2.value);
+    yagl_glsl_state_flush_pending(state, $3.index);
+    yagl_glsl_state_append_output(state, $3.value);
+    yagl_glsl_state_flush_pending(state, $4.index);
+    yagl_glsl_state_append_output_char(state, $4.c);
+    yagl_glsl_state_flush_pending(state, $5.index);
+    sprintf(s, "%d", $5.value);
+    yagl_glsl_state_append_output(state, s);
+    yagl_glsl_state_flush_pending(state, $6.index);
+    yagl_glsl_state_append_output_char(state, $6.c);
+    yagl_glsl_state_flush_pending(state, $7.index);
+    yagl_glsl_state_append_output_char(state, $7.c);
+
+    // TODO this should also take into account TOK_INTEGER, because it is an array of samplers (not a single sampler)
+    if (yagl_glsl_state_pp_is_condition_met(state)) {
+        // locally try to resolve the define based on current knowledge
+        // it won't matter if our type is not a macro but an actual sampler type
+        char* type_resolved = NULL;
+        int int_resolved = 0;
+        yagl_glsl_state_pp_resolve_define(state, $2.value, &type_resolved, &int_resolved);
+
+        if (type_resolved != NULL) {
+            if (strcmp(type_resolved, "samplerExternalOES") == 0) {
+                if (!state->have_samplerexternaloes) {
+                    yagl_glsl_state_append_header(state, "#define samplerExternalOES sampler2D\n");
+                    state->have_samplerexternaloes = 1;
+                }
+
+                yagl_glsl_state_add_sampler_ExternalOES(state, $3.value);
+            } else if (strcmp(type_resolved, "sampler2D") == 0) {
+                yagl_glsl_state_add_sampler_2D(state, $3.value);
+            }
+
+            free(type_resolved);
+        }
+    }
+}
 | TOK_UNIFORM TOK_PRECISION_QUAL TOK_STRING TOK_STRING TOK_EOI
 {
     yagl_glsl_state_flush_pending(state, $1.index);
@@ -665,7 +759,7 @@ expression
     yagl_glsl_state_flush_pending(state, $4.index);
     yagl_glsl_state_append_output(state, $4.value);
     yagl_glsl_state_flush_pending(state, $5.index);
-    yagl_glsl_state_append_output(state, $5.value);
+    yagl_glsl_state_append_output_char(state, $5.c);
 
     if (yagl_glsl_state_pp_is_condition_met(state)) {
         // locally try to resolve the define based on current knowledge
@@ -699,7 +793,7 @@ expression
     yagl_glsl_state_flush_pending(state, $3.index);
     yagl_glsl_state_append_output(state, $3.value);
     yagl_glsl_state_flush_pending(state, $4.index);
-    yagl_glsl_state_append_output(state, $4.value);
+    yagl_glsl_state_append_output_char(state, $4.c);
 
     if (yagl_glsl_state_pp_is_condition_met(state)) {
         // locally try to resolve the define based on current knowledge