sksl support for buffer blocks
authorEthan Nicholas <ethannicholas@google.com>
Mon, 1 May 2017 20:57:07 +0000 (16:57 -0400)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Tue, 2 May 2017 17:39:45 +0000 (17:39 +0000)
Bug: skia:
Change-Id: Ic2cabaf2c7fb23cec7863f2b6152bbed133e0886
Reviewed-on: https://skia-review.googlesource.com/14947
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>

src/sksl/SkSLIRGenerator.cpp
src/sksl/SkSLParser.cpp
src/sksl/SkSLSPIRVCodeGenerator.cpp
src/sksl/SkSLToken.h
src/sksl/ir/SkSLModifiers.h
src/sksl/lex.sksl.c
src/sksl/sksl.flex
tests/SkSLErrorTest.cpp

index 523b7a0..b167d1e 100644 (file)
@@ -606,6 +606,7 @@ std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTInte
     std::shared_ptr<SymbolTable> old = fSymbolTable;
     AutoSymbolTable table(this);
     std::vector<Type::Field> fields;
+    bool haveRuntimeArray = false;
     for (size_t i = 0; i < intf.fDeclarations.size(); i++) {
         std::unique_ptr<VarDeclarations> decl = this->convertVarDeclarations(
                                                                          *intf.fDeclarations[i],
@@ -614,6 +615,11 @@ std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTInte
             return nullptr;
         }
         for (const auto& var : decl->fVars) {
+            if (haveRuntimeArray) {
+                fErrors.error(decl->fPosition,
+                              "only the last entry in an interface block may be a runtime-sized "
+                              "array");
+            }
             fields.push_back(Type::Field(var->fVar->fModifiers, var->fVar->fName,
                                          &var->fVar->fType));
             if (var->fValue) {
@@ -623,10 +629,15 @@ std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTInte
             if (var->fVar->fModifiers.fFlags & (Modifiers::kIn_Flag |
                                                 Modifiers::kOut_Flag |
                                                 Modifiers::kUniform_Flag |
+                                                Modifiers::kBuffer_Flag |
                                                 Modifiers::kConst_Flag)) {
                 fErrors.error(decl->fPosition,
                               "interface block fields may not have storage qualifiers");
             }
+            if (var->fVar->fType.kind() == Type::kArray_Kind &&
+                var->fVar->fType.columns() == -1) {
+                haveRuntimeArray = true;
+            }
         }
     }
     Type* type = new Type(intf.fPosition, intf.fTypeName, fields);
index ae9d990..0f5b974 100644 (file)
@@ -12,8 +12,8 @@
 #define register
 #include "disable_flex_warnings.h"
 #include "lex.sksl.c"
-static_assert(YY_FLEX_MAJOR_VERSION * 100 + YY_FLEX_MINOR_VERSION * 10 +
-              YY_FLEX_SUBMINOR_VERSION >= 261,
+static_assert(YY_FLEX_MAJOR_VERSION * 10000 + YY_FLEX_MINOR_VERSION * 100 +
+              YY_FLEX_SUBMINOR_VERSION >= 20601,
               "we require Flex 2.6.1 or better for security reasons");
 #undef register
 #ifdef __clang__
@@ -655,7 +655,7 @@ Layout Parser::layout() {
 }
 
 /* layout? (UNIFORM | CONST | IN | OUT | INOUT | LOWP | MEDIUMP | HIGHP | FLAT | NOPERSPECTIVE |
-            READONLY | WRITEONLY | COHERENT | VOLATILE | RESTRICT)* */
+            READONLY | WRITEONLY | COHERENT | VOLATILE | RESTRICT | BUFFER)* */
 Modifiers Parser::modifiers() {
     Layout layout = this->layout();
     int flags = 0;
@@ -723,6 +723,10 @@ Modifiers Parser::modifiers() {
                 this->nextToken();
                 flags |= Modifiers::kRestrict_Flag;
                 break;
+            case Token::BUFFER:
+                this->nextToken();
+                flags |= Modifiers::kBuffer_Flag;
+                break;
             case Token::HASSIDEEFFECTS:
                 this->nextToken();
                 flags |= Modifiers::kHasSideEffects_Flag;
index d2850e9..24f3d91 100644 (file)
@@ -1077,10 +1077,12 @@ SpvId SPIRVCodeGenerator::getType(const Type& type, const MemoryLayout& layout)
                                            (int32_t) layout.stride(type),
                                            fDecorationBuffer);
                 } else {
-                    ABORT("runtime-sized arrays are not yet supported");
                     this->writeInstruction(SpvOpTypeRuntimeArray, result,
                                            this->getType(type.componentType(), layout),
                                            fConstantBuffer);
+                    this->writeInstruction(SpvOpDecorate, result, SpvDecorationArrayStride,
+                                           (int32_t) layout.stride(type),
+                                           fDecorationBuffer);
                 }
                 break;
             }
@@ -2526,7 +2528,8 @@ void SPIRVCodeGenerator::writeLayout(const Layout& layout, SpvId target, int mem
 }
 
 SpvId SPIRVCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
-    MemoryLayout layout = intf.fVariable.fModifiers.fLayout.fPushConstant ?
+    MemoryLayout layout = intf.fVariable.fModifiers.fLayout.fPushConstant |
+                          (0 != (intf.fVariable.fModifiers.fFlags & Modifiers::kBuffer_Flag)) ?
                           MemoryLayout(MemoryLayout::k430_Standard) :
                           fDefaultLayout;
     SpvId result = this->nextId();
@@ -2541,7 +2544,11 @@ SpvId SPIRVCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
         type = new Type(type->fPosition, type->name(), fields);
     }
     SpvId typeId = this->getType(*type, layout);
-    this->writeInstruction(SpvOpDecorate, typeId, SpvDecorationBlock, fDecorationBuffer);
+    if (intf.fVariable.fModifiers.fFlags & Modifiers::kBuffer_Flag) {
+        this->writeInstruction(SpvOpDecorate, typeId, SpvDecorationBufferBlock, fDecorationBuffer);
+    } else {
+        this->writeInstruction(SpvOpDecorate, typeId, SpvDecorationBlock, fDecorationBuffer);
+    }
     SpvStorageClass_ storageClass = get_storage_class(intf.fVariable.fModifiers);
     SpvId ptrType = this->nextId();
     this->writeInstruction(SpvOpTypePointer, ptrType, storageClass, typeId, fConstantBuffer);
@@ -2577,7 +2584,8 @@ void SPIRVCodeGenerator::writeGlobalVars(Program::Kind kind, const VarDeclaratio
         if (!var->fReadCount && !var->fWriteCount &&
                 !(var->fModifiers.fFlags & (Modifiers::kIn_Flag |
                                             Modifiers::kOut_Flag |
-                                            Modifiers::kUniform_Flag))) {
+                                            Modifiers::kUniform_Flag |
+                                            Modifiers::kBuffer_Flag))) {
             // variable is dead and not an input / output var (the Vulkan debug layers complain if
             // we elide an interface var, even if it's dead)
             continue;
index 874c7eb..a5b1754 100644 (file)
@@ -104,6 +104,7 @@ struct Token {
         COHERENT,
         VOLATILE,
         RESTRICT,
+        BUFFER,
         HASSIDEEFFECTS,
         STRUCT,
         LAYOUT,
index 8aaf2ae..80ef5d7 100644 (file)
@@ -32,7 +32,8 @@ struct Modifiers {
         kCoherent_Flag       = 1 << 11,
         kVolatile_Flag       = 1 << 12,
         kRestrict_Flag       = 1 << 13,
-        kHasSideEffects_Flag = 1 << 14
+        kBuffer_Flag         = 1 << 14,
+        kHasSideEffects_Flag = 1 << 15
     };
 
     Modifiers()
@@ -81,6 +82,9 @@ struct Modifiers {
         if (fFlags & kRestrict_Flag) {
             result += "restrict ";
         }
+        if (fFlags & kBuffer_Flag) {
+            result += "buffer ";
+        }
         if (fFlags & kHasSideEffects_Flag) {
             result += "sk_has_side_effects ";
         }
index 3ad9034..bfb6c5e 100644 (file)
@@ -1,11 +1,5 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
 
-#line 2 "lex.sksl.c"
+#line 3 "lex.sksl.c"
 
 #define  YY_INT_ALIGNED short int
 
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MINOR_VERSION 6
-#define YY_FLEX_SUBMINOR_VERSION 3
+#define YY_FLEX_SUBMINOR_VERSION 1
 #if YY_FLEX_SUBMINOR_VERSION > 0
 #define FLEX_BETA
 #endif
 
-    #define yy_create_buffer sksl_create_buffer
-
-    #define yy_delete_buffer sksl_delete_buffer
-
-    #define yy_scan_buffer sksl_scan_buffer
-
-    #define yy_scan_string sksl_scan_string
-
-    #define yy_scan_bytes sksl_scan_bytes
-
-    #define yy_init_buffer sksl_init_buffer
-
-    #define yy_flush_buffer sksl_flush_buffer
-
-    #define yy_load_buffer_state sksl_load_buffer_state
-
-    #define yy_switch_to_buffer sksl_switch_to_buffer
-
-    #define yypush_buffer_state skslpush_buffer_state
-
-    #define yypop_buffer_state skslpop_buffer_state
-
-    #define yyensure_buffer_stack skslensure_buffer_stack
-
-    #define yylex sksllex
-
-    #define yyrestart skslrestart
-
-    #define yylex_init sksllex_init
-
-    #define yylex_init_extra sksllex_init_extra
-
-    #define yylex_destroy sksllex_destroy
-
-    #define yyget_debug skslget_debug
-
-    #define yyset_debug skslset_debug
-
-    #define yyget_extra skslget_extra
-
-    #define yyset_extra skslset_extra
-
-    #define yyget_in skslget_in
-
-    #define yyset_in skslset_in
-
-    #define yyget_out skslget_out
-
-    #define yyset_out skslset_out
-
-    #define yyget_leng skslget_leng
-
-    #define yyget_text skslget_text
-
-    #define yyget_lineno skslget_lineno
-
-    #define yyset_lineno skslset_lineno
-
-        #define yyget_column skslget_column
-
-        #define yyset_column skslset_column
-
-    #define yywrap skslwrap
-
-    #define yyalloc skslalloc
-
-    #define yyrealloc skslrealloc
-
-    #define yyfree skslfree
-
 /* First, we deal with  platform-specific or compiler-specific issues. */
 
 /* begin standard C headers. */
@@ -175,10 +99,12 @@ typedef unsigned int flex_uint32_t;
 /* Returned upon end-of-file. */
 #define YY_NULL 0
 
-/* Promotes a possibly negative, possibly signed char to an
- *   integer in range [0..255] for use as an array index.
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
  */
-#define YY_SC_TO_UI(c) ((YY_CHAR) (c))
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
 
 /* An opaque pointer. */
 #ifndef YY_TYPEDEF_YY_SCANNER_T
@@ -202,16 +128,20 @@ typedef void* yyscan_t;
  * definition of BEGIN.
  */
 #define BEGIN yyg->yy_start = 1 + 2 *
+
 /* Translate the current start state into a value that can be later handed
  * to BEGIN to return to the state.  The YYSTATE alias is for lex
  * compatibility.
  */
 #define YY_START ((yyg->yy_start - 1) / 2)
 #define YYSTATE YY_START
+
 /* Action number for EOF rule of a given start state. */
 #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
 /* Special action meaning "start processing a new file". */
 #define YY_NEW_FILE skslrestart(yyin ,yyscanner )
+
 #define YY_END_OF_BUFFER_CHAR 0
 
 /* Size of default input buffer. */
@@ -244,10 +174,10 @@ typedef size_t yy_size_t;
 #define EOB_ACT_CONTINUE_SCAN 0
 #define EOB_ACT_END_OF_FILE 1
 #define EOB_ACT_LAST_MATCH 2
-    
+
     /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
      *       access to the local variable yy_act. Since yyless() is a macro, it would break
-     *       existing scanners that call yyless() from OUTSIDE sksllex.
+     *       existing scanners that call yyless() from OUTSIDE sksllex. 
      *       One obvious solution it to make yy_act a global. I tried that, and saw
      *       a 5% performance hit in a non-yylineno scanner, because yy_act is
      *       normally declared as a register variable-- so it is not worth it.
@@ -280,6 +210,7 @@ typedef size_t yy_size_t;
                YY_DO_BEFORE_ACTION; /* set up yytext again */ \
                } \
        while ( 0 )
+
 #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
 
 #ifndef YY_STRUCT_YY_BUFFER_STATE
@@ -322,7 +253,7 @@ struct yy_buffer_state
 
     int yy_bs_lineno; /**< The line count. */
     int yy_bs_column; /**< The column count. */
-
+    
        /* Whether to try to fill the input buffer when we reach the
         * end of it.
         */
@@ -356,33 +287,36 @@ struct yy_buffer_state
 #define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
                           ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
                           : NULL)
+
 /* Same as previous macro, but useful when we know that the buffer stack is not
  * NULL or when we need an lvalue. For internal use only.
  */
 #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
 
-void skslrestart ( FILE *input_file , yyscan_t yyscanner );
-void sksl_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
-YY_BUFFER_STATE sksl_create_buffer ( FILE *file, int size , yyscan_t yyscanner );
-void sksl_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
-void sksl_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
-void skslpush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
-void skslpop_buffer_state ( yyscan_t yyscanner );
-
-static void skslensure_buffer_stack ( yyscan_t yyscanner );
-static void sksl_load_buffer_state ( yyscan_t yyscanner );
-static void sksl_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner );
+void skslrestart (FILE *input_file ,yyscan_t yyscanner );
+void sksl_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE sksl_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void sksl_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void sksl_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void skslpush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void skslpop_buffer_state (yyscan_t yyscanner );
+
+static void skslensure_buffer_stack (yyscan_t yyscanner );
+static void sksl_load_buffer_state (yyscan_t yyscanner );
+static void sksl_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
+
 #define YY_FLUSH_BUFFER sksl_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
 
-YY_BUFFER_STATE sksl_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner );
-YY_BUFFER_STATE sksl_scan_string ( const char *yy_str , yyscan_t yyscanner );
-YY_BUFFER_STATE sksl_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner );
+YY_BUFFER_STATE sksl_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE sksl_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE sksl_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
 
-void *skslalloc ( yy_size_t , yyscan_t yyscanner );
-void *skslrealloc ( void *, yy_size_t , yyscan_t yyscanner );
-void skslfree ( void * , yyscan_t yyscanner );
+void *skslalloc (yy_size_t ,yyscan_t yyscanner );
+void *skslrealloc (void *,yy_size_t ,yyscan_t yyscanner );
+void skslfree (void * ,yyscan_t yyscanner );
 
 #define yy_new_buffer sksl_create_buffer
+
 #define yy_set_interactive(is_interactive) \
        { \
        if ( ! YY_CURRENT_BUFFER ){ \
@@ -392,6 +326,7 @@ void skslfree ( void * , yyscan_t yyscanner );
        } \
        YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
        }
+
 #define yy_set_bol(at_bol) \
        { \
        if ( ! YY_CURRENT_BUFFER ){\
@@ -401,19 +336,21 @@ void skslfree ( void * , yyscan_t yyscanner );
        } \
        YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
        }
+
 #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
 
 /* Begin user sect3 */
-typedef flex_uint8_t YY_CHAR;
+
+typedef unsigned char YY_CHAR;
 
 typedef int yy_state_type;
 
 #define yytext_ptr yytext_r
 
-static yy_state_type yy_get_previous_state ( yyscan_t yyscanner );
-static yy_state_type yy_try_NUL_trans ( yy_state_type current_state  , yyscan_t yyscanner);
-static int yy_get_next_buffer ( yyscan_t yyscanner );
-static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner );
+static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state  ,yyscan_t yyscanner);
+static int yy_get_next_buffer (yyscan_t yyscanner );
+static void yynoreturn yy_fatal_error (yyconst char* msg ,yyscan_t yyscanner );
 
 /* Done after the current pattern has been matched and before the
  * corresponding action - sets up yytext.
@@ -424,8 +361,9 @@ static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner );
        yyg->yy_hold_char = *yy_cp; \
        *yy_cp = '\0'; \
        yyg->yy_c_buf_p = yy_cp;
-#define YY_NUM_RULES 93
-#define YY_END_OF_BUFFER 94
+
+#define YY_NUM_RULES 94
+#define YY_END_OF_BUFFER 95
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -433,40 +371,41 @@ struct yy_trans_info
        flex_int32_t yy_verify;
        flex_int32_t yy_nxt;
        };
-static const flex_int16_t yy_accept[271] =
+static yyconst flex_int16_t yy_accept[276] =
     {   0,
-        0,    0,   94,   92,   91,   91,   65,   92,   39,   55,
-       60,   41,   42,   53,   51,   48,   52,   47,   54,    4,
-        4,   67,   88,   72,   68,   71,   66,   45,   46,   59,
-       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,
-       39,   39,   39,   39,   39,   39,   39,   39,   43,   58,
-       44,   61,   91,   70,   40,   39,   79,   64,   84,   77,
-       49,   75,   50,   76,    1,    0,   89,   78,    2,    4,
-        0,    0,   56,   74,   69,   73,   57,   83,   63,   39,
-       39,   39,   39,   39,   12,   39,   39,   39,   39,   39,
-        8,   20,   39,   39,   39,   39,   39,   39,   39,   39,
-
-       39,   39,   39,   39,   39,   39,   39,   82,   62,   40,
-       87,    0,    0,    0,   89,    1,    0,    0,    3,    5,
-       80,   81,   86,   39,   39,   39,   39,   39,   39,   39,
-       39,   39,   10,   39,   39,   39,   39,   39,   39,   21,
-       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,
-       39,   39,   85,    0,    1,   90,    0,    0,    2,   39,
-       14,   39,   39,   39,   39,   39,    9,   39,   28,   39,
-       39,   39,   25,   39,   39,   39,   39,   39,   39,   39,
-       39,   39,    6,   39,   39,   39,   39,    0,    1,   16,
-       39,   24,   39,   39,   39,    7,   27,   22,   39,   39,
-
-       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,
-       11,   39,   39,   39,   39,   39,   37,   39,   39,   39,
-       39,   39,   19,   39,   36,   13,   39,   39,   39,   39,
-       39,   15,   18,   26,   39,   39,   39,   39,   39,   23,
-       39,   39,   32,   17,   39,   39,   30,   34,   39,   33,
-       39,   39,   38,   39,   31,   39,   39,   39,   39,   39,
-       39,   29,   39,   39,   39,   39,   39,   39,   35,    0
+        0,    0,   95,   93,   92,   92,   66,   93,   40,   56,
+       61,   42,   43,   54,   52,   49,   53,   48,   55,    4,
+        4,   68,   89,   73,   69,   72,   67,   46,   47,   60,
+       40,   40,   40,   40,   40,   40,   40,   40,   40,   40,
+       40,   40,   40,   40,   40,   40,   40,   40,   44,   59,
+       45,   62,   92,   71,   41,   40,   80,   65,   85,   78,
+       50,   76,   51,   77,    1,    0,   90,   79,    2,    4,
+        0,    0,   57,   75,   70,   74,   58,   84,   64,   40,
+       40,   40,   40,   40,   40,   12,   40,   40,   40,   40,
+       40,    8,   20,   40,   40,   40,   40,   40,   40,   40,
+
+       40,   40,   40,   40,   40,   40,   40,   40,   83,   63,
+       41,   88,    0,    0,    0,   90,    1,    0,    0,    3,
+        5,   81,   82,   87,   40,   40,   40,   40,   40,   40,
+       40,   40,   40,   40,   10,   40,   40,   40,   40,   40,
+       40,   21,   40,   40,   40,   40,   40,   40,   40,   40,
+       40,   40,   40,   40,   86,    0,    1,   91,    0,    0,
+        2,   40,   40,   14,   40,   40,   40,   40,   40,    9,
+       40,   28,   40,   40,   40,   25,   40,   40,   40,   40,
+       40,   40,   40,   40,   40,    6,   40,   40,   40,   40,
+        0,    1,   16,   40,   40,   24,   40,   40,   40,    7,
+
+       27,   22,   40,   40,   40,   40,   40,   40,   40,   40,
+       40,   40,   40,   40,   11,   40,   35,   40,   40,   40,
+       40,   38,   40,   40,   40,   40,   40,   19,   40,   37,
+       13,   40,   40,   40,   40,   40,   15,   18,   26,   40,
+       40,   40,   40,   40,   23,   40,   40,   32,   17,   40,
+       40,   30,   34,   40,   33,   40,   40,   39,   40,   31,
+       40,   40,   40,   40,   40,   40,   29,   40,   40,   40,
+       40,   40,   40,   36,    0
     } ;
 
-static const YY_CHAR yy_ec[256] =
+static yyconst YY_CHAR yy_ec[256] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
         1,    1,    2,    1,    1,    1,    1,    1,    1,    1,
@@ -498,7 +437,7 @@ static const YY_CHAR yy_ec[256] =
         1,    1,    1,    1,    1
     } ;
 
-static const YY_CHAR yy_meta[58] =
+static yyconst YY_CHAR yy_meta[58] =
     {   0,
         1,    1,    2,    1,    1,    3,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    4,    4,    1,    1,
@@ -508,75 +447,77 @@ static const YY_CHAR yy_meta[58] =
         3,    3,    3,    1,    1,    1,    1
     } ;
 
-static const flex_int16_t yy_base[277] =
+static yyconst flex_uint16_t yy_base[282] =
     {   0,
-        0,    0,  339,  340,   56,   58,  316,    0,    0,  315,
-       54,  340,  340,  314,   51,  340,   50,   48,   58,   53,
-       60,  340,  340,   60,  313,   61,  340,  340,  340,   63,
-      288,   56,   54,  292,   60,  293,   54,   63,  296,  286,
-      280,  282,  292,   62,  280,  282,  280,   65,  340,   74,
-      340,  340,  106,  340,    0,    0,  340,  301,  340,  340,
-      340,  340,  340,  340,   97,  311,    0,  340,   99,  104,
-      119,    0,  299,  340,  340,  340,  298,  340,  297,  283,
-      270,   97,  280,  268,    0,  267,  272,  281,  265,  273,
-        0,  265,  255,  256,  272,  260,  256,  268,   95,  272,
-
-      255,  261,  250,  259,  256,  257,  256,  340,  272,    0,
-      340,  132,  282,  276,    0,  130,  140,  110,  142,    0,
-      340,  340,  340,  260,  255,  254,  114,  257,  254,  251,
-      238,  236,    0,  245,  233,  237,  235,  240,  243,    0,
-      244,  242,  227,  225,  235,  223,  223,  235,  233,  237,
-      226,  218,  340,  146,  149,  340,  156,  154,  158,  225,
-        0,  218,  215,  223,  212,  229,    0,  224,    0,  213,
-      209,  207,    0,  206,  208,  214,  208,  205,  204,  218,
-      215,  214,    0,  202,  197,  209,  208,  160,  162,    0,
-      207,    0,  198,  199,  193,    0,    0,    0,  190,  195,
-
-      189,  188,  191,  194,  189,  184,  182,  191,  182,  188,
-        0,  182,  182,  175,  175,  188,    0,  176,  175,  180,
-      177,  184,    0,  186,    0,    0,  173,  173,  170,  164,
-      176,    0,    0,    0,  175,  165,  155,  159,  159,    0,
-      170,  163,    0,    0,  170,  159,    0,    0,  157,    0,
-      129,  121,    0,  121,    0,  114,  116,   95,  111,  103,
-       89,    0,   84,   82,   77,   73,   51,   20,    0,  340,
-      178,  181,  184,  189,  194,  196
+        0,    0,  344,  345,   56,   58,  321,    0,    0,  320,
+       54,  345,  345,  319,   51,  345,   50,   48,   58,   53,
+       60,  345,  345,   60,  318,   61,  345,  345,  345,   63,
+       41,   58,   59,  298,   60,  299,   57,   65,  302,  292,
+      286,  288,  298,   59,  286,  288,  286,   68,  345,   75,
+      345,  345,  109,  345,    0,    0,  345,  307,  345,  345,
+      345,  345,  345,  345,   98,  317,    0,  345,  100,  105,
+      120,    0,  305,  345,  345,  345,  304,  345,  303,  289,
+      287,  275,   70,  285,  273,    0,  272,  277,  286,  270,
+      278,    0,  270,  260,  261,  277,  265,  261,  273,   94,
+
+      277,  260,  266,  255,  264,  261,  262,  261,  345,  277,
+        0,  345,  131,  287,  281,    0,  129,  139,  110,  141,
+        0,  345,  345,  345,  265,  259,  259,  258,  113,  261,
+      258,  255,  242,  240,    0,  249,  237,  241,  239,  244,
+      247,    0,  248,  246,  231,  229,  239,  227,  227,  239,
+      237,  241,  230,  222,  345,  145,  148,  345,  155,  153,
+      157,  229,  233,    0,  221,  218,  226,  215,  232,    0,
+      227,    0,  216,  212,  210,    0,  209,  211,  217,  211,
+      208,  207,  221,  218,  217,    0,  205,  200,  212,  211,
+      159,  161,    0,  199,  209,    0,  200,  201,  195,    0,
+
+        0,    0,  192,  197,  191,  190,  193,  196,  191,  186,
+      184,  193,  184,  190,    0,  184,    0,  184,  177,  177,
+      190,    0,  178,  177,  182,  179,  186,    0,  188,    0,
+        0,  175,  175,  172,  166,  178,    0,    0,    0,  177,
+      167,  157,  161,  161,    0,  172,  165,    0,    0,  172,
+      161,    0,    0,  164,    0,  149,  153,    0,  161,    0,
+      142,  133,  104,  122,  115,  109,    0,  103,  100,   94,
+       88,   71,   20,    0,  345,  177,  180,  183,  188,  193,
+      195
     } ;
 
-static const flex_int16_t yy_def[277] =
+static yyconst flex_int16_t yy_def[282] =
     {   0,
-      270,    1,  270,  270,  270,  270,  270,  271,  272,  270,
-      270,  270,  270,  270,  270,  270,  270,  270,  270,  270,
-      270,  270,  270,  270,  270,  270,  270,  270,  270,  270,
-      272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
-      272,  272,  272,  272,  272,  272,  272,  272,  270,  270,
-      270,  270,  270,  270,  273,  272,  270,  270,  270,  270,
-      270,  270,  270,  270,  270,  274,  275,  270,  270,  270,
-      270,  276,  270,  270,  270,  270,  270,  270,  270,  272,
-      272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
-      272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
-
-      272,  272,  272,  272,  272,  272,  272,  270,  270,  273,
-      270,  270,  274,  274,  275,  270,  270,  270,  270,  276,
-      270,  270,  270,  272,  272,  272,  272,  272,  272,  272,
-      272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
-      272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
-      272,  272,  270,  270,  270,  270,  270,  270,  270,  272,
-      272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
-      272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
-      272,  272,  272,  272,  272,  272,  272,  270,  270,  272,
-      272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
-
-      272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
-      272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
-      272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
-      272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
-      272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
-      272,  272,  272,  272,  272,  272,  272,  272,  272,  272,
-      272,  272,  272,  272,  272,  272,  272,  272,  272,    0,
-      270,  270,  270,  270,  270,  270
+      275,    1,  275,  275,  275,  275,  275,  276,  277,  275,
+      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
+      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
+      277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
+      277,  277,  277,  277,  277,  277,  277,  277,  275,  275,
+      275,  275,  275,  275,  278,  277,  275,  275,  275,  275,
+      275,  275,  275,  275,  275,  279,  280,  275,  275,  275,
+      275,  281,  275,  275,  275,  275,  275,  275,  275,  277,
+      277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
+      277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
+
+      277,  277,  277,  277,  277,  277,  277,  277,  275,  275,
+      278,  275,  275,  279,  279,  280,  275,  275,  275,  275,
+      281,  275,  275,  275,  277,  277,  277,  277,  277,  277,
+      277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
+      277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
+      277,  277,  277,  277,  275,  275,  275,  275,  275,  275,
+      275,  277,  277,  277,  277,  277,  277,  277,  277,  277,
+      277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
+      277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
+      275,  275,  277,  277,  277,  277,  277,  277,  277,  277,
+
+      277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
+      277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
+      277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
+      277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
+      277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
+      277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
+      277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
+      277,  277,  277,  277,    0,  275,  275,  275,  275,  275,
+      275
     } ;
 
-static const flex_int16_t yy_nxt[398] =
+static yyconst flex_uint16_t yy_nxt[403] =
     {   0,
         4,    5,    6,    7,    8,    9,   10,   11,   12,   13,
        14,   15,   16,   17,   18,   19,   20,   21,   22,   23,
@@ -584,47 +525,48 @@ static const flex_int16_t yy_nxt[398] =
         9,   31,   32,   33,   34,   35,    9,   36,   37,    9,
        38,   39,   40,   41,   42,   43,   44,   45,   46,   47,
        48,    9,    9,   49,   50,   51,   52,   53,   53,   53,
-       53,   58,   61,   63,   65,   65,  269,   69,   66,   70,
+       53,   58,   61,   63,   65,   65,  274,   69,   66,   70,
        70,   64,   62,   67,   69,   59,   70,   70,   71,   68,
-       73,   74,   76,   77,   78,   71,   81,   71,   83,   91,
-       87,   79,   84,   93,   71,  108,   92,   85,  268,   82,
-
-       88,  100,  106,   89,   72,  267,   94,   53,   53,  101,
-      107,  266,  102,   65,   65,  116,  116,  265,   69,  264,
-       70,   70,  112,  263,  117,  142,  119,  119,  109,   71,
-      118,  112,  118,  117,  126,  119,  119,  262,   71,  127,
-      261,  143,  144,  154,  260,  154,  116,  116,  155,  155,
-      259,  158,  258,  158,  257,  157,  159,  159,  119,  119,
-      163,  164,  155,  155,  157,  155,  155,  188,  256,  188,
-      159,  159,  189,  189,  159,  159,  189,  189,  189,  189,
-       55,  255,   55,   56,   56,   56,  110,  110,  110,  113,
-      113,  113,  113,  113,  115,  254,  115,  115,  115,  120,
-
-      120,  253,  252,  251,  250,  249,  248,  247,  246,  245,
-      244,  243,  242,  241,  240,  239,  238,  237,  236,  235,
-      234,  233,  232,  231,  230,  229,  228,  227,  226,  225,
-      224,  223,  222,  221,  220,  219,  218,  217,  216,  215,
-      214,  213,  212,  211,  210,  209,  208,  207,  206,  205,
-      204,  203,  202,  201,  200,  199,  198,  197,  196,  195,
-      194,  193,  192,  191,  190,  187,  186,  185,  184,  183,
-      182,  181,  180,  179,  178,  177,  176,  175,  174,  173,
-      172,  171,  170,  169,  168,  167,  166,  165,  162,  161,
-      160,  156,  114,  153,  152,  151,  150,  149,  148,  147,
-
-      146,  145,  141,  140,  139,  138,  137,  136,  135,  134,
-      133,  132,  131,  130,  129,  128,  125,  124,  123,  122,
-      121,  114,  111,  105,  104,  103,   99,   98,   97,   96,
-       95,   90,   86,   80,   75,   60,   57,   54,  270,    3,
-      270,  270,  270,  270,  270,  270,  270,  270,  270,  270,
-      270,  270,  270,  270,  270,  270,  270,  270,  270,  270,
-      270,  270,  270,  270,  270,  270,  270,  270,  270,  270,
-      270,  270,  270,  270,  270,  270,  270,  270,  270,  270,
-      270,  270,  270,  270,  270,  270,  270,  270,  270,  270,
-      270,  270,  270,  270,  270,  270,  270
-
+       73,   74,   76,   77,   78,   71,   80,   71,   82,   81,
+       88,   79,   92,   84,   71,   94,  109,   85,  101,   93,
+
+       89,   83,   86,   90,   72,  107,  102,  128,   95,  103,
+       53,   53,  129,  108,   65,   65,  117,  117,  273,   69,
+      272,   70,   70,  113,  144,  118,  120,  120,  271,  110,
+       71,  119,  113,  119,  118,  270,  120,  120,  269,   71,
+      145,  146,  156,  268,  156,  117,  117,  157,  157,  267,
+      160,  266,  160,  265,  159,  161,  161,  120,  120,  166,
+      167,  157,  157,  159,  157,  157,  191,  264,  191,  161,
+      161,  192,  192,  161,  161,  192,  192,  192,  192,   55,
+      263,   55,   56,   56,   56,  111,  111,  111,  114,  114,
+      114,  114,  114,  116,  262,  116,  116,  116,  121,  121,
+
+      261,  260,  259,  258,  257,  256,  255,  254,  253,  252,
+      251,  250,  249,  248,  247,  246,  245,  244,  243,  242,
+      241,  240,  239,  238,  237,  236,  235,  234,  233,  232,
+      231,  230,  229,  228,  227,  226,  225,  224,  223,  222,
+      221,  220,  219,  218,  217,  216,  215,  214,  213,  212,
+      211,  210,  209,  208,  207,  206,  205,  204,  203,  202,
+      201,  200,  199,  198,  197,  196,  195,  194,  193,  190,
+      189,  188,  187,  186,  185,  184,  183,  182,  181,  180,
+      179,  178,  177,  176,  175,  174,  173,  172,  171,  170,
+      169,  168,  165,  164,  163,  162,  158,  115,  155,  154,
+
+      153,  152,  151,  150,  149,  148,  147,  143,  142,  141,
+      140,  139,  138,  137,  136,  135,  134,  133,  132,  131,
+      130,  127,  126,  125,  124,  123,  122,  115,  112,  106,
+      105,  104,  100,   99,   98,   97,   96,   91,   87,   75,
+       60,   57,   54,  275,    3,  275,  275,  275,  275,  275,
+      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
+      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
+      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
+      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
+      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
+
+      275,  275
     } ;
 
-static const flex_int16_t yy_chk[398] =
+static yyconst flex_int16_t yy_chk[403] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -632,54 +574,55 @@ static const flex_int16_t yy_chk[398] =
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    5,    5,    6,
-        6,   11,   15,   17,   18,   18,  268,   20,   19,   20,
+        6,   11,   15,   17,   18,   18,  273,   20,   19,   20,
        20,   17,   15,   19,   21,   11,   21,   21,   20,   19,
-       24,   24,   26,   26,   30,   21,   32,   20,   33,   37,
-       35,   30,   33,   38,   21,   50,   37,   33,  267,   32,
-
-       35,   44,   48,   35,   20,  266,   38,   53,   53,   44,
-       48,  265,   44,   65,   65,   69,   69,  264,   70,  263,
-       70,   70,   65,  261,   69,   99,  118,  118,   50,   70,
-       71,   65,   71,   69,   82,   71,   71,  260,   70,   82,
-      259,   99,   99,  112,  258,  112,  116,  116,  112,  112,
-      257,  117,  256,  117,  254,  116,  117,  117,  119,  119,
-      127,  127,  154,  154,  116,  155,  155,  157,  252,  157,
-      158,  158,  157,  157,  159,  159,  188,  188,  189,  189,
-      271,  251,  271,  272,  272,  272,  273,  273,  273,  274,
-      274,  274,  274,  274,  275,  249,  275,  275,  275,  276,
-
-      276,  246,  245,  242,  241,  239,  238,  237,  236,  235,
-      231,  230,  229,  228,  227,  224,  222,  221,  220,  219,
-      218,  216,  215,  214,  213,  212,  210,  209,  208,  207,
-      206,  205,  204,  203,  202,  201,  200,  199,  195,  194,
-      193,  191,  187,  186,  185,  184,  182,  181,  180,  179,
-      178,  177,  176,  175,  174,  172,  171,  170,  168,  166,
-      165,  164,  163,  162,  160,  152,  151,  150,  149,  148,
-      147,  146,  145,  144,  143,  142,  141,  139,  138,  137,
-      136,  135,  134,  132,  131,  130,  129,  128,  126,  125,
-      124,  114,  113,  109,  107,  106,  105,  104,  103,  102,
-
-      101,  100,   98,   97,   96,   95,   94,   93,   92,   90,
-       89,   88,   87,   86,   84,   83,   81,   80,   79,   77,
-       73,   66,   58,   47,   46,   45,   43,   42,   41,   40,
-       39,   36,   34,   31,   25,   14,   10,    7,    3,  270,
-      270,  270,  270,  270,  270,  270,  270,  270,  270,  270,
-      270,  270,  270,  270,  270,  270,  270,  270,  270,  270,
-      270,  270,  270,  270,  270,  270,  270,  270,  270,  270,
-      270,  270,  270,  270,  270,  270,  270,  270,  270,  270,
-      270,  270,  270,  270,  270,  270,  270,  270,  270,  270,
-      270,  270,  270,  270,  270,  270,  270
-
+       24,   24,   26,   26,   30,   21,   31,   20,   32,   31,
+       35,   30,   37,   33,   21,   38,   50,   33,   44,   37,
+
+       35,   32,   33,   35,   20,   48,   44,   83,   38,   44,
+       53,   53,   83,   48,   65,   65,   69,   69,  272,   70,
+      271,   70,   70,   65,  100,   69,  119,  119,  270,   50,
+       70,   71,   65,   71,   69,  269,   71,   71,  268,   70,
+      100,  100,  113,  266,  113,  117,  117,  113,  113,  265,
+      118,  264,  118,  263,  117,  118,  118,  120,  120,  129,
+      129,  156,  156,  117,  157,  157,  159,  262,  159,  160,
+      160,  159,  159,  161,  161,  191,  191,  192,  192,  276,
+      261,  276,  277,  277,  277,  278,  278,  278,  279,  279,
+      279,  279,  279,  280,  259,  280,  280,  280,  281,  281,
+
+      257,  256,  254,  251,  250,  247,  246,  244,  243,  242,
+      241,  240,  236,  235,  234,  233,  232,  229,  227,  226,
+      225,  224,  223,  221,  220,  219,  218,  216,  214,  213,
+      212,  211,  210,  209,  208,  207,  206,  205,  204,  203,
+      199,  198,  197,  195,  194,  190,  189,  188,  187,  185,
+      184,  183,  182,  181,  180,  179,  178,  177,  175,  174,
+      173,  171,  169,  168,  167,  166,  165,  163,  162,  154,
+      153,  152,  151,  150,  149,  148,  147,  146,  145,  144,
+      143,  141,  140,  139,  138,  137,  136,  134,  133,  132,
+      131,  130,  128,  127,  126,  125,  115,  114,  110,  108,
+
+      107,  106,  105,  104,  103,  102,  101,   99,   98,   97,
+       96,   95,   94,   93,   91,   90,   89,   88,   87,   85,
+       84,   82,   81,   80,   79,   77,   73,   66,   58,   47,
+       46,   45,   43,   42,   41,   40,   39,   36,   34,   25,
+       14,   10,    7,    3,  275,  275,  275,  275,  275,  275,
+      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
+      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
+      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
+      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
+      275,  275,  275,  275,  275,  275,  275,  275,  275,  275,
+
+      275,  275
     } ;
 
 /* Table of booleans, true if rule could match eol. */
-static const flex_int32_t yy_rule_can_match_eol[94] =
+static yyconst flex_int32_t yy_rule_can_match_eol[95] =
     {   0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,     };
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,     };
 
 /* The intent behind this definition is that it'll catch
  * any uses of REJECT which flex missed.
@@ -708,7 +651,7 @@ static const flex_int32_t yy_rule_can_match_eol[94] =
 
 */
 #define YY_NO_UNISTD_H 1
-#line 705 "lex.sksl.c"
+#line 655 "lex.sksl.c"
 
 #define INITIAL 0
 
@@ -758,44 +701,44 @@ struct yyguts_t
 
     }; /* end struct yyguts_t */
 
-static int yy_init_globals ( yyscan_t yyscanner );
+static int yy_init_globals (yyscan_t yyscanner );
 
 int sksllex_init (yyscan_t* scanner);
 
-int sksllex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner);
+int sksllex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
 
 /* Accessor methods to globals.
    These are made visible to non-reentrant scanners for convenience. */
 
-int sksllex_destroy ( yyscan_t yyscanner );
+int sksllex_destroy (yyscan_t yyscanner );
 
-int skslget_debug ( yyscan_t yyscanner );
+int skslget_debug (yyscan_t yyscanner );
 
-void skslset_debug ( int debug_flag , yyscan_t yyscanner );
+void skslset_debug (int debug_flag ,yyscan_t yyscanner );
 
-YY_EXTRA_TYPE skslget_extra ( yyscan_t yyscanner );
+YY_EXTRA_TYPE skslget_extra (yyscan_t yyscanner );
 
-void skslset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner );
+void skslset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
 
-FILE *skslget_in ( yyscan_t yyscanner );
+FILE *skslget_in (yyscan_t yyscanner );
 
-void skslset_in  ( FILE * _in_str , yyscan_t yyscanner );
+void skslset_in  (FILE * _in_str ,yyscan_t yyscanner );
 
-FILE *skslget_out ( yyscan_t yyscanner );
+FILE *skslget_out (yyscan_t yyscanner );
 
-void skslset_out  ( FILE * _out_str , yyscan_t yyscanner );
+void skslset_out  (FILE * _out_str ,yyscan_t yyscanner );
 
-                       int skslget_leng ( yyscan_t yyscanner );
+                       int skslget_leng (yyscan_t yyscanner );
 
-char *skslget_text ( yyscan_t yyscanner );
+char *skslget_text (yyscan_t yyscanner );
 
-int skslget_lineno ( yyscan_t yyscanner );
+int skslget_lineno (yyscan_t yyscanner );
 
-void skslset_lineno ( int _line_number , yyscan_t yyscanner );
+void skslset_lineno (int _line_number ,yyscan_t yyscanner );
 
-int skslget_column  ( yyscan_t yyscanner );
+int skslget_column  (yyscan_t yyscanner );
 
-void skslset_column ( int _column_no , yyscan_t yyscanner );
+void skslset_column (int _column_no ,yyscan_t yyscanner );
 
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -803,31 +746,32 @@ void skslset_column ( int _column_no , yyscan_t yyscanner );
 
 #ifndef YY_SKIP_YYWRAP
 #ifdef __cplusplus
-extern "C" int skslwrap ( yyscan_t yyscanner );
+extern "C" int skslwrap (yyscan_t yyscanner );
 #else
-extern int skslwrap ( yyscan_t yyscanner );
+extern int skslwrap (yyscan_t yyscanner );
 #endif
 #endif
 
 #ifndef YY_NO_UNPUT
     
-    static void yyunput ( int c, char *buf_ptr  , yyscan_t yyscanner);
+    static void yyunput (int c,char *buf_ptr  ,yyscan_t yyscanner);
     
 #endif
 
 #ifndef yytext_ptr
-static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner);
+static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
 #endif
 
 #ifdef YY_NEED_STRLEN
-static int yy_flex_strlen ( const char * , yyscan_t yyscanner);
+static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
 #endif
 
 #ifndef YY_NO_INPUT
+
 #ifdef __cplusplus
-static int yyinput ( yyscan_t yyscanner );
+static int yyinput (yyscan_t yyscanner );
 #else
-static int input ( yyscan_t yyscanner );
+static int input (yyscan_t yyscanner );
 #endif
 
 #endif
@@ -858,7 +802,7 @@ static int input ( yyscan_t yyscanner );
        if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
                { \
                int c = '*'; \
-               int n; \
+               size_t n; \
                for ( n = 0; n < max_size && \
                             (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
                        buf[n] = (char) c; \
@@ -871,7 +815,7 @@ static int input ( yyscan_t yyscanner );
        else \
                { \
                errno=0; \
-               while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \
+               while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
                        { \
                        if( errno != EINTR) \
                                { \
@@ -971,7 +915,7 @@ YY_DECL
 #line 30 "sksl.flex"
 
 
-#line 968 "lex.sksl.c"
+#line 919 "lex.sksl.c"
 
        while ( /*CONSTCOND*/1 )                /* loops until end-of-file is reached */
                {
@@ -998,13 +942,13 @@ yy_match:
                        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                                {
                                yy_current_state = (int) yy_def[yy_current_state];
-                               if ( yy_current_state >= 271 )
-                                       yy_c = yy_meta[yy_c];
+                               if ( yy_current_state >= 276 )
+                                       yy_c = yy_meta[(unsigned int) yy_c];
                                }
-                       yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+                       yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
                        ++yy_cp;
                        }
-               while ( yy_current_state != 270 );
+               while ( yy_current_state != 275 );
                yy_cp = yyg->yy_last_accepting_cpos;
                yy_current_state = yyg->yy_last_accepting_state;
 
@@ -1015,10 +959,10 @@ yy_find_action:
 
                if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
                        {
-                       int yyl;
+                       yy_size_t yyl;
                        for ( yyl = 0; yyl < yyleng; ++yyl )
                                if ( yytext[yyl] == '\n' )
-                                       
+                                          
     do{ yylineno++;
         yycolumn=0;
     }while(0)
@@ -1209,301 +1153,306 @@ YY_RULE_SETUP
 case 35:
 YY_RULE_SETUP
 #line 100 "sksl.flex"
-{ return SkSL::Token::HASSIDEEFFECTS; }
+{ return SkSL::Token::BUFFER; }
        YY_BREAK
 case 36:
 YY_RULE_SETUP
 #line 102 "sksl.flex"
-{ return SkSL::Token::STRUCT; }
+{ return SkSL::Token::HASSIDEEFFECTS; }
        YY_BREAK
 case 37:
 YY_RULE_SETUP
 #line 104 "sksl.flex"
-{ return SkSL::Token::LAYOUT; }
+{ return SkSL::Token::STRUCT; }
        YY_BREAK
 case 38:
 YY_RULE_SETUP
 #line 106 "sksl.flex"
-{ return SkSL::Token::PRECISION; }
+{ return SkSL::Token::LAYOUT; }
        YY_BREAK
 case 39:
 YY_RULE_SETUP
 #line 108 "sksl.flex"
-{ return SkSL::Token::IDENTIFIER; }
+{ return SkSL::Token::PRECISION; }
        YY_BREAK
 case 40:
 YY_RULE_SETUP
 #line 110 "sksl.flex"
-{ return SkSL::Token::DIRECTIVE; }
+{ return SkSL::Token::IDENTIFIER; }
        YY_BREAK
 case 41:
 YY_RULE_SETUP
 #line 112 "sksl.flex"
-{ return SkSL::Token::LPAREN; }
+{ return SkSL::Token::DIRECTIVE; }
        YY_BREAK
 case 42:
 YY_RULE_SETUP
 #line 114 "sksl.flex"
-{ return SkSL::Token::RPAREN; }
+{ return SkSL::Token::LPAREN; }
        YY_BREAK
 case 43:
 YY_RULE_SETUP
 #line 116 "sksl.flex"
-{ return SkSL::Token::LBRACE; }
+{ return SkSL::Token::RPAREN; }
        YY_BREAK
 case 44:
 YY_RULE_SETUP
 #line 118 "sksl.flex"
-{ return SkSL::Token::RBRACE; }
+{ return SkSL::Token::LBRACE; }
        YY_BREAK
 case 45:
 YY_RULE_SETUP
 #line 120 "sksl.flex"
-{ return SkSL::Token::LBRACKET; }
+{ return SkSL::Token::RBRACE; }
        YY_BREAK
 case 46:
 YY_RULE_SETUP
 #line 122 "sksl.flex"
-{ return SkSL::Token::RBRACKET; }
+{ return SkSL::Token::LBRACKET; }
        YY_BREAK
 case 47:
 YY_RULE_SETUP
 #line 124 "sksl.flex"
-{ return SkSL::Token::DOT; }
+{ return SkSL::Token::RBRACKET; }
        YY_BREAK
 case 48:
 YY_RULE_SETUP
 #line 126 "sksl.flex"
-{ return SkSL::Token::COMMA; }
+{ return SkSL::Token::DOT; }
        YY_BREAK
 case 49:
 YY_RULE_SETUP
 #line 128 "sksl.flex"
-{ return SkSL::Token::PLUSPLUS; }
+{ return SkSL::Token::COMMA; }
        YY_BREAK
 case 50:
 YY_RULE_SETUP
 #line 130 "sksl.flex"
-{ return SkSL::Token::MINUSMINUS; }
+{ return SkSL::Token::PLUSPLUS; }
        YY_BREAK
 case 51:
 YY_RULE_SETUP
 #line 132 "sksl.flex"
-{ return SkSL::Token::PLUS; }
+{ return SkSL::Token::MINUSMINUS; }
        YY_BREAK
 case 52:
 YY_RULE_SETUP
 #line 134 "sksl.flex"
-{ return SkSL::Token::MINUS; }
+{ return SkSL::Token::PLUS; }
        YY_BREAK
 case 53:
 YY_RULE_SETUP
 #line 136 "sksl.flex"
-{ return SkSL::Token::STAR; }
+{ return SkSL::Token::MINUS; }
        YY_BREAK
 case 54:
 YY_RULE_SETUP
 #line 138 "sksl.flex"
-{ return SkSL::Token::SLASH; }
+{ return SkSL::Token::STAR; }
        YY_BREAK
 case 55:
 YY_RULE_SETUP
 #line 140 "sksl.flex"
-{ return SkSL::Token::PERCENT; }
+{ return SkSL::Token::SLASH; }
        YY_BREAK
 case 56:
 YY_RULE_SETUP
 #line 142 "sksl.flex"
-{ return SkSL::Token::SHL; }
+{ return SkSL::Token::PERCENT; }
        YY_BREAK
 case 57:
 YY_RULE_SETUP
 #line 144 "sksl.flex"
-{ return SkSL::Token::SHR; }
+{ return SkSL::Token::SHL; }
        YY_BREAK
 case 58:
 YY_RULE_SETUP
 #line 146 "sksl.flex"
-{ return SkSL::Token::BITWISEOR; }
+{ return SkSL::Token::SHR; }
        YY_BREAK
 case 59:
 YY_RULE_SETUP
 #line 148 "sksl.flex"
-{ return SkSL::Token::BITWISEXOR; }
+{ return SkSL::Token::BITWISEOR; }
        YY_BREAK
 case 60:
 YY_RULE_SETUP
 #line 150 "sksl.flex"
-{ return SkSL::Token::BITWISEAND; }
+{ return SkSL::Token::BITWISEXOR; }
        YY_BREAK
 case 61:
 YY_RULE_SETUP
 #line 152 "sksl.flex"
-{ return SkSL::Token::BITWISENOT; }
+{ return SkSL::Token::BITWISEAND; }
        YY_BREAK
 case 62:
 YY_RULE_SETUP
 #line 154 "sksl.flex"
-{ return SkSL::Token::LOGICALOR; }
+{ return SkSL::Token::BITWISENOT; }
        YY_BREAK
 case 63:
 YY_RULE_SETUP
 #line 156 "sksl.flex"
-{ return SkSL::Token::LOGICALXOR; }
+{ return SkSL::Token::LOGICALOR; }
        YY_BREAK
 case 64:
 YY_RULE_SETUP
 #line 158 "sksl.flex"
-{ return SkSL::Token::LOGICALAND; }
+{ return SkSL::Token::LOGICALXOR; }
        YY_BREAK
 case 65:
 YY_RULE_SETUP
 #line 160 "sksl.flex"
-{ return SkSL::Token::LOGICALNOT; }
+{ return SkSL::Token::LOGICALAND; }
        YY_BREAK
 case 66:
 YY_RULE_SETUP
 #line 162 "sksl.flex"
-{ return SkSL::Token::QUESTION; }
+{ return SkSL::Token::LOGICALNOT; }
        YY_BREAK
 case 67:
 YY_RULE_SETUP
 #line 164 "sksl.flex"
-{ return SkSL::Token::COLON; }
+{ return SkSL::Token::QUESTION; }
        YY_BREAK
 case 68:
 YY_RULE_SETUP
 #line 166 "sksl.flex"
-{ return SkSL::Token::EQ; }
+{ return SkSL::Token::COLON; }
        YY_BREAK
 case 69:
 YY_RULE_SETUP
 #line 168 "sksl.flex"
-{ return SkSL::Token::EQEQ; }
+{ return SkSL::Token::EQ; }
        YY_BREAK
 case 70:
 YY_RULE_SETUP
 #line 170 "sksl.flex"
-{ return SkSL::Token::NEQ; }
+{ return SkSL::Token::EQEQ; }
        YY_BREAK
 case 71:
 YY_RULE_SETUP
 #line 172 "sksl.flex"
-{ return SkSL::Token::GT; }
+{ return SkSL::Token::NEQ; }
        YY_BREAK
 case 72:
 YY_RULE_SETUP
 #line 174 "sksl.flex"
-{ return SkSL::Token::LT; }
+{ return SkSL::Token::GT; }
        YY_BREAK
 case 73:
 YY_RULE_SETUP
 #line 176 "sksl.flex"
-{ return SkSL::Token::GTEQ; }
+{ return SkSL::Token::LT; }
        YY_BREAK
 case 74:
 YY_RULE_SETUP
 #line 178 "sksl.flex"
-{ return SkSL::Token::LTEQ; }
+{ return SkSL::Token::GTEQ; }
        YY_BREAK
 case 75:
 YY_RULE_SETUP
 #line 180 "sksl.flex"
-{ return SkSL::Token::PLUSEQ; }
+{ return SkSL::Token::LTEQ; }
        YY_BREAK
 case 76:
 YY_RULE_SETUP
 #line 182 "sksl.flex"
-{ return SkSL::Token::MINUSEQ; }
+{ return SkSL::Token::PLUSEQ; }
        YY_BREAK
 case 77:
 YY_RULE_SETUP
 #line 184 "sksl.flex"
-{ return SkSL::Token::STAREQ; }
+{ return SkSL::Token::MINUSEQ; }
        YY_BREAK
 case 78:
 YY_RULE_SETUP
 #line 186 "sksl.flex"
-{ return SkSL::Token::SLASHEQ; }
+{ return SkSL::Token::STAREQ; }
        YY_BREAK
 case 79:
 YY_RULE_SETUP
 #line 188 "sksl.flex"
-{ return SkSL::Token::PERCENTEQ; }
+{ return SkSL::Token::SLASHEQ; }
        YY_BREAK
 case 80:
 YY_RULE_SETUP
 #line 190 "sksl.flex"
-{ return SkSL::Token::SHLEQ; }
+{ return SkSL::Token::PERCENTEQ; }
        YY_BREAK
 case 81:
 YY_RULE_SETUP
 #line 192 "sksl.flex"
-{ return SkSL::Token::SHREQ; }
+{ return SkSL::Token::SHLEQ; }
        YY_BREAK
 case 82:
 YY_RULE_SETUP
 #line 194 "sksl.flex"
-{ return SkSL::Token::BITWISEOREQ; }
+{ return SkSL::Token::SHREQ; }
        YY_BREAK
 case 83:
 YY_RULE_SETUP
 #line 196 "sksl.flex"
-{ return SkSL::Token::BITWISEXOREQ; }
+{ return SkSL::Token::BITWISEOREQ; }
        YY_BREAK
 case 84:
 YY_RULE_SETUP
 #line 198 "sksl.flex"
-{ return SkSL::Token::BITWISEANDEQ; }
+{ return SkSL::Token::BITWISEXOREQ; }
        YY_BREAK
 case 85:
 YY_RULE_SETUP
 #line 200 "sksl.flex"
-{ return SkSL::Token::LOGICALOREQ; }
+{ return SkSL::Token::BITWISEANDEQ; }
        YY_BREAK
 case 86:
 YY_RULE_SETUP
 #line 202 "sksl.flex"
-{ return SkSL::Token::LOGICALXOREQ; }
+{ return SkSL::Token::LOGICALOREQ; }
        YY_BREAK
 case 87:
 YY_RULE_SETUP
 #line 204 "sksl.flex"
-{ return SkSL::Token::LOGICALANDEQ; }
+{ return SkSL::Token::LOGICALXOREQ; }
        YY_BREAK
 case 88:
 YY_RULE_SETUP
 #line 206 "sksl.flex"
-{ return SkSL::Token::SEMICOLON; }
+{ return SkSL::Token::LOGICALANDEQ; }
        YY_BREAK
 case 89:
 YY_RULE_SETUP
 #line 208 "sksl.flex"
-/* line comment */
+{ return SkSL::Token::SEMICOLON; }
        YY_BREAK
 case 90:
-/* rule 90 can match eol */
 YY_RULE_SETUP
 #line 210 "sksl.flex"
-/* block comment */
+/* line comment */
        YY_BREAK
 case 91:
 /* rule 91 can match eol */
 YY_RULE_SETUP
 #line 212 "sksl.flex"
-/* whitespace */
+/* block comment */
        YY_BREAK
 case 92:
+/* rule 92 can match eol */
 YY_RULE_SETUP
 #line 214 "sksl.flex"
-{ return SkSL::Token::INVALID_TOKEN; }
+/* whitespace */
        YY_BREAK
 case 93:
 YY_RULE_SETUP
 #line 216 "sksl.flex"
+{ return SkSL::Token::INVALID_TOKEN; }
+       YY_BREAK
+case 94:
+YY_RULE_SETUP
+#line 218 "sksl.flex"
 ECHO;
        YY_BREAK
-#line 1500 "lex.sksl.c"
+#line 1456 "lex.sksl.c"
 case YY_STATE_EOF(INITIAL):
        yyterminate();
 
@@ -1650,7 +1599,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
        char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
        char *source = yyg->yytext_ptr;
-       int number_to_move, i;
+       yy_size_t number_to_move, i;
        int ret_val;
 
        if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
@@ -1679,7 +1628,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
        /* Try to read more data. */
 
        /* First move last chars to start of buffer. */
-       number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1);
+       number_to_move = (yy_size_t) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
 
        for ( i = 0; i < number_to_move; ++i )
                *(dest++) = *(source++);
@@ -1715,7 +1664,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 
                                b->yy_ch_buf = (char *)
                                        /* Include room in for 2 EOB chars. */
-                                       skslrealloc((void *) b->yy_ch_buf,(yy_size_t) (b->yy_buf_size + 2) ,yyscanner );
+                                       skslrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
                                }
                        else
                                /* Can't grow it, we don't own it. */
@@ -1761,10 +1710,10 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
        else
                ret_val = EOB_ACT_CONTINUE_SCAN;
 
-       if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+       if ((int) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
                /* Extend the array by 50%, plus the number we really need. */
                int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
-               YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) skslrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,(yy_size_t) new_size ,yyscanner );
+               YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) skslrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
                if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
                        YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
        }
@@ -1799,10 +1748,10 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
                while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                        {
                        yy_current_state = (int) yy_def[yy_current_state];
-                       if ( yy_current_state >= 271 )
-                               yy_c = yy_meta[yy_c];
+                       if ( yy_current_state >= 276 )
+                               yy_c = yy_meta[(unsigned int) yy_c];
                        }
-               yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+               yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
                }
 
        return yy_current_state;
@@ -1828,11 +1777,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                {
                yy_current_state = (int) yy_def[yy_current_state];
-               if ( yy_current_state >= 271 )
-                       yy_c = yy_meta[yy_c];
+               if ( yy_current_state >= 276 )
+                       yy_c = yy_meta[(unsigned int) yy_c];
                }
-       yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
-       yy_is_jam = (yy_current_state == 270);
+       yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
+       yy_is_jam = (yy_current_state == 275);
 
        (void)yyg;
        return yy_is_jam ? 0 : yy_current_state;
@@ -1909,7 +1858,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 
                else
                        { /* need more input */
-                       int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr);
+                       int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
                        ++yyg->yy_c_buf_p;
 
                        switch ( yy_get_next_buffer( yyscanner ) )
@@ -1956,7 +1905,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
        yyg->yy_hold_char = *++yyg->yy_c_buf_p;
 
        if ( c == '\n' )
-               
+                  
     do{ yylineno++;
         yycolumn=0;
     }while(0)
@@ -2044,12 +1993,12 @@ static void sksl_load_buffer_state  (yyscan_t yyscanner)
        if ( ! b )
                YY_FATAL_ERROR( "out of dynamic memory in sksl_create_buffer()" );
 
-       b->yy_buf_size = size;
+       b->yy_buf_size = (yy_size_t)size;
 
        /* yy_ch_buf has to be 2 characters longer than the size given because
         * we need to put in 2 end-of-buffer characters.
         */
-       b->yy_ch_buf = (char *) skslalloc((yy_size_t) (b->yy_buf_size + 2) ,yyscanner );
+       b->yy_ch_buf = (char *) skslalloc(b->yy_buf_size + 2 ,yyscanner );
        if ( ! b->yy_ch_buf )
                YY_FATAL_ERROR( "out of dynamic memory in sksl_create_buffer()" );
 
@@ -2196,7 +2145,7 @@ void skslpop_buffer_state (yyscan_t yyscanner)
  */
 static void skslensure_buffer_stack (yyscan_t yyscanner)
 {
-       yy_size_t num_to_alloc;
+       int num_to_alloc;
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 
        if (!yyg->yy_buffer_stack) {
@@ -2211,9 +2160,9 @@ static void skslensure_buffer_stack (yyscan_t yyscanner)
                                                                , yyscanner);
                if ( ! yyg->yy_buffer_stack )
                        YY_FATAL_ERROR( "out of dynamic memory in skslensure_buffer_stack()" );
-
+                                                                 
                memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
+                               
                yyg->yy_buffer_stack_max = num_to_alloc;
                yyg->yy_buffer_stack_top = 0;
                return;
@@ -2242,7 +2191,7 @@ static void skslensure_buffer_stack (yyscan_t yyscanner)
  * @param base the character buffer
  * @param size the size in bytes of the character buffer
  * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
+ * @return the newly allocated buffer state object. 
  */
 YY_BUFFER_STATE sksl_scan_buffer  (char * base, yy_size_t  size , yyscan_t yyscanner)
 {
@@ -2258,7 +2207,7 @@ YY_BUFFER_STATE sksl_scan_buffer  (char * base, yy_size_t  size , yyscan_t yysca
        if ( ! b )
                YY_FATAL_ERROR( "out of dynamic memory in sksl_scan_buffer()" );
 
-       b->yy_buf_size = (int) (size - 2);      /* "- 2" to take care of EOB's */
+       b->yy_buf_size = size - 2;      /* "- 2" to take care of EOB's */
        b->yy_buf_pos = b->yy_ch_buf = base;
        b->yy_is_our_buffer = 0;
        b->yy_input_file = NULL;
@@ -2281,7 +2230,7 @@ YY_BUFFER_STATE sksl_scan_buffer  (char * base, yy_size_t  size , yyscan_t yysca
  * @note If you want to scan bytes that may contain NUL values, then use
  *       sksl_scan_bytes() instead.
  */
-YY_BUFFER_STATE sksl_scan_string (const char * yystr , yyscan_t yyscanner)
+YY_BUFFER_STATE sksl_scan_string (yyconst char * yystr , yyscan_t yyscanner)
 {
     
        return sksl_scan_bytes(yystr,(int) strlen(yystr) ,yyscanner);
@@ -2294,15 +2243,15 @@ YY_BUFFER_STATE sksl_scan_string (const char * yystr , yyscan_t yyscanner)
  * @param yyscanner The scanner object.
  * @return the newly allocated buffer state object.
  */
-YY_BUFFER_STATE sksl_scan_bytes  (const char * yybytes, int  _yybytes_len , yyscan_t yyscanner)
+YY_BUFFER_STATE sksl_scan_bytes  (yyconst char * yybytes, int  _yybytes_len , yyscan_t yyscanner)
 {
        YY_BUFFER_STATE b;
        char *buf;
        yy_size_t n;
-       int i;
+       yy_size_t i;
     
        /* Get memory for full buffer, including space for trailing EOB's. */
-       n = (yy_size_t) (_yybytes_len + 2);
+       n = (yy_size_t) _yybytes_len + 2;
        buf = (char *) skslalloc(n ,yyscanner );
        if ( ! buf )
                YY_FATAL_ERROR( "out of dynamic memory in sksl_scan_bytes()" );
@@ -2328,7 +2277,7 @@ YY_BUFFER_STATE sksl_scan_bytes  (const char * yybytes, int  _yybytes_len , yysc
 #define YY_EXIT_FAILURE 2
 #endif
 
-static void yynoreturn yy_fatal_error (const char* msg , yyscan_t yyscanner)
+static void yynoreturn yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
 {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
        (void)yyg;
@@ -2370,7 +2319,7 @@ YY_EXTRA_TYPE skslget_extra  (yyscan_t yyscanner)
 int skslget_lineno  (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
+    
         if (! YY_CURRENT_BUFFER)
             return 0;
     
@@ -2383,7 +2332,7 @@ int skslget_lineno  (yyscan_t yyscanner)
 int skslget_column  (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
+    
         if (! YY_CURRENT_BUFFER)
             return 0;
     
@@ -2505,7 +2454,9 @@ void skslset_debug (int  _bdebug , yyscan_t yyscanner)
  * the ONLY reentrant function that doesn't take the scanner as the last argument.
  * That's why we explicitly handle the declaration, instead of using our macros.
  */
+
 int sksllex_init(yyscan_t* ptr_yy_globals)
+
 {
     if (ptr_yy_globals == NULL){
         errno = EINVAL;
@@ -2532,7 +2483,9 @@ int sksllex_init(yyscan_t* ptr_yy_globals)
  * The user defined value in the first argument will be available to skslalloc in
  * the yyextra field.
  */
+
 int sksllex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
+
 {
     struct yyguts_t dummy_yyguts;
 
@@ -2542,20 +2495,20 @@ int sksllex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
         errno = EINVAL;
         return 1;
     }
-
+       
     *ptr_yy_globals = (yyscan_t) skslalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
-
+       
     if (*ptr_yy_globals == NULL){
         errno = ENOMEM;
         return 1;
     }
-
+    
     /* By setting to 0xAA, we expose bugs in
     yy_init_globals. Leave at 0x00 for releases. */
     memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
-
+    
     skslset_extra (yy_user_defined, *ptr_yy_globals);
-
+    
     return yy_init_globals ( *ptr_yy_globals );
 }
 
@@ -2627,7 +2580,7 @@ int sksllex_destroy  (yyscan_t yyscanner)
  */
 
 #ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner)
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
 {
        struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
        (void)yyg;
@@ -2639,7 +2592,7 @@ static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscann
 #endif
 
 #ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (const char * s , yyscan_t yyscanner)
+static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
 {
        int n;
        for ( n = 0; s[n]; ++n )
@@ -2680,7 +2633,8 @@ void skslfree (void * ptr , yyscan_t yyscanner)
 
 #define YYTABLES_NAME "yytables"
 
-#line 216 "sksl.flex"
+#line 218 "sksl.flex"
+
 
 
 int skslwrap(yyscan_t scanner) {
index 2dd4225..c35ce5d 100644 (file)
@@ -97,6 +97,8 @@ volatile { return SkSL::Token::VOLATILE; }
 
 restrict { return SkSL::Token::RESTRICT; }
 
+buffer { return SkSL::Token::BUFFER; }
+
 sk_has_side_effects { return SkSL::Token::HASSIDEEFFECTS; }
 
 struct { return SkSL::Token::STRUCT; }
index 47b9af8..d443b18 100644 (file)
@@ -459,4 +459,11 @@ DEF_TEST(SkSLDuplicateCase, r) {
                  "error: 1: duplicate case value\n1 error\n");
 }
 
+DEF_TEST(SkSLFieldAfterRuntimeArray, r) {
+    test_failure(r,
+                 "buffer broken { float x[]; float y; };",
+                 "error: 1: only the last entry in an interface block may be a runtime-sized "
+                 "array\n1 error\n");
+}
+
 #endif