Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. %{
  2. /*
  3.  * Copyright © 2009 Intel Corporation
  4.  *
  5.  * Permission is hereby granted, free of charge, to any person obtaining a
  6.  * copy of this software and associated documentation files (the "Software"),
  7.  * to deal in the Software without restriction, including without limitation
  8.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9.  * and/or sell copies of the Software, and to permit persons to whom the
  10.  * Software is furnished to do so, subject to the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice (including the next
  13.  * paragraph) shall be included in all copies or substantial portions of the
  14.  * Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22.  * DEALINGS IN THE SOFTWARE.
  23.  */
  24. #include "main/glheader.h"
  25. #include "main/imports.h"
  26. #include "program/prog_instruction.h"
  27. #include "program/prog_statevars.h"
  28. #include "program/symbol_table.h"
  29. #include "program/program_parser.h"
  30. #include "program/program_parse.tab.h"
  31.  
  32. #define require_ARB_vp (yyextra->mode == ARB_vertex)
  33. #define require_ARB_fp (yyextra->mode == ARB_fragment)
  34. #define require_NV_fp  (yyextra->option.NV_fragment)
  35. #define require_shadow (yyextra->option.Shadow)
  36. #define require_rect   (yyextra->option.TexRect)
  37. #define require_texarray        (yyextra->option.TexArray)
  38.  
  39. #ifndef HAVE_UNISTD_H
  40. #define YY_NO_UNISTD_H
  41. #endif
  42.  
  43. #define return_token_or_IDENTIFIER(condition, token)    \
  44.    do {                                                 \
  45.       if (condition) {                                  \
  46.          return token;                                  \
  47.       } else {                                          \
  48.          return handle_ident(yyextra, yytext, yylval);  \
  49.       }                                                 \
  50.    } while (0)
  51.  
  52. #define return_token_or_DOT(condition, token)           \
  53.    do {                                                 \
  54.       if (condition) {                                  \
  55.          return token;                                  \
  56.       } else {                                          \
  57.          yyless(1);                                     \
  58.          return DOT;                                    \
  59.       }                                                 \
  60.    } while (0)
  61.  
  62.  
  63. #define return_opcode(condition, token, opcode, len)    \
  64.    do {                                                 \
  65.       if (condition &&                                  \
  66.           _mesa_parse_instruction_suffix(yyextra,       \
  67.                                          yytext + len,  \
  68.                                          & yylval->temp_inst)) {        \
  69.          yylval->temp_inst.Opcode = OPCODE_ ## opcode;  \
  70.          return token;                                  \
  71.       } else {                                          \
  72.          return handle_ident(yyextra, yytext, yylval);  \
  73.       }                                                 \
  74.    } while (0)
  75.  
  76. #define SWIZZLE_INVAL  MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \
  77.                                      SWIZZLE_NIL, SWIZZLE_NIL)
  78.  
  79. static unsigned
  80. mask_from_char(char c)
  81. {
  82.    switch (c) {
  83.    case 'x':
  84.    case 'r':
  85.       return WRITEMASK_X;
  86.    case 'y':
  87.    case 'g':
  88.       return WRITEMASK_Y;
  89.    case 'z':
  90.    case 'b':
  91.       return WRITEMASK_Z;
  92.    case 'w':
  93.    case 'a':
  94.       return WRITEMASK_W;
  95.    }
  96.  
  97.    return 0;
  98. }
  99.  
  100. static unsigned
  101. swiz_from_char(char c)
  102. {
  103.    switch (c) {
  104.    case 'x':
  105.    case 'r':
  106.       return SWIZZLE_X;
  107.    case 'y':
  108.    case 'g':
  109.       return SWIZZLE_Y;
  110.    case 'z':
  111.    case 'b':
  112.       return SWIZZLE_Z;
  113.    case 'w':
  114.    case 'a':
  115.       return SWIZZLE_W;
  116.    }
  117.  
  118.    return 0;
  119. }
  120.  
  121. static int
  122. handle_ident(struct asm_parser_state *state, const char *text, YYSTYPE *lval)
  123. {
  124.    lval->string = strdup(text);
  125.  
  126.    return (_mesa_symbol_table_find_symbol(state->st, 0, text) == NULL)
  127.       ? IDENTIFIER : USED_IDENTIFIER;
  128. }
  129.  
  130. #define YY_USER_ACTION                                                  \
  131.    do {                                                                 \
  132.       yylloc->first_column = yylloc->last_column;                       \
  133.       yylloc->last_column += yyleng;                                    \
  134.       if ((yylloc->first_line == 1)                                     \
  135.           && (yylloc->first_column == 1)) {                             \
  136.          yylloc->position = 1;                                          \
  137.       } else {                                                          \
  138.          yylloc->position += yylloc->last_column - yylloc->first_column; \
  139.       }                                                                 \
  140.    } while(0);
  141.  
  142. #define YY_NO_INPUT
  143.  
  144. /* Yes, this is intentionally doing nothing. We have this line of code
  145. here only to avoid the compiler complaining about an unput function
  146. that is defined, but never called. */
  147. #define YY_USER_INIT while (0) { unput(0); }
  148.  
  149. #define YY_EXTRA_TYPE struct asm_parser_state *
  150.  
  151. /* Flex defines a couple of functions with no declarations nor the
  152. static keyword. Declare them here to avoid a compiler warning. */
  153. int yyget_column  (yyscan_t yyscanner);
  154. void yyset_column (int  column_no , yyscan_t yyscanner);
  155.  
  156. %}
  157.  
  158. num    [0-9]+
  159. exp    [Ee][-+]?[0-9]+
  160. frac   "."[0-9]+
  161. dot    "."[ \t]*
  162.  
  163. sz     [HRX]?
  164. szf    [HR]?
  165. cc     C?
  166. sat    (_SAT)?
  167.  
  168. %option prefix="_mesa_program_lexer_"
  169. %option bison-bridge bison-locations reentrant noyywrap
  170. %%
  171.  
  172. "!!ARBvp1.0"              { return ARBvp_10; }
  173. "!!ARBfp1.0"              { return ARBfp_10; }
  174. ADDRESS                   {
  175.    yylval->integer = at_address;
  176.    return_token_or_IDENTIFIER(require_ARB_vp, ADDRESS);
  177. }
  178. ALIAS                     { return ALIAS; }
  179. ATTRIB                    { return ATTRIB; }
  180. END                       { return END; }
  181. OPTION                    { return OPTION; }
  182. OUTPUT                    { return OUTPUT; }
  183. PARAM                     { return PARAM; }
  184. TEMP                      { yylval->integer = at_temp; return TEMP; }
  185.  
  186. ABS{sz}{cc}{sat}   { return_opcode(             1, VECTOR_OP, ABS, 3); }
  187. ADD{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, ADD, 3); }
  188. ARL                { return_opcode(require_ARB_vp, ARL, ARL, 3); }
  189.  
  190. CMP{sat}           { return_opcode(require_ARB_fp, TRI_OP, CMP, 3); }
  191. COS{szf}{cc}{sat}  { return_opcode(require_ARB_fp, SCALAR_OP, COS, 3); }
  192.  
  193. DDX{szf}{cc}{sat}  { return_opcode(require_NV_fp,  VECTOR_OP, DDX, 3); }
  194. DDY{szf}{cc}{sat}  { return_opcode(require_NV_fp,  VECTOR_OP, DDY, 3); }
  195. DP3{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, DP3, 3); }
  196. DP4{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, DP4, 3); }
  197. DPH{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, DPH, 3); }
  198. DST{szf}{cc}{sat}  { return_opcode(             1, BIN_OP, DST, 3); }
  199.  
  200. EX2{szf}{cc}{sat}  { return_opcode(             1, SCALAR_OP, EX2, 3); }
  201. EXP                { return_opcode(require_ARB_vp, SCALAR_OP, EXP, 3); }
  202.  
  203. FLR{sz}{cc}{sat}   { return_opcode(             1, VECTOR_OP, FLR, 3); }
  204. FRC{sz}{cc}{sat}   { return_opcode(             1, VECTOR_OP, FRC, 3); }
  205.  
  206. KIL                { return_opcode(require_ARB_fp, KIL, KIL, 3); }
  207.  
  208. LIT{szf}{cc}{sat}  { return_opcode(             1, VECTOR_OP, LIT, 3); }
  209. LG2{szf}{cc}{sat}  { return_opcode(             1, SCALAR_OP, LG2, 3); }
  210. LOG                { return_opcode(require_ARB_vp, SCALAR_OP, LOG, 3); }
  211. LRP{sz}{cc}{sat}   { return_opcode(require_ARB_fp, TRI_OP, LRP, 3); }
  212.  
  213. MAD{sz}{cc}{sat}   { return_opcode(             1, TRI_OP, MAD, 3); }
  214. MAX{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, MAX, 3); }
  215. MIN{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, MIN, 3); }
  216. MOV{sz}{cc}{sat}   { return_opcode(             1, VECTOR_OP, MOV, 3); }
  217. MUL{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, MUL, 3); }
  218.  
  219. PK2H               { return_opcode(require_NV_fp,  VECTOR_OP, PK2H, 4); }
  220. PK2US              { return_opcode(require_NV_fp,  VECTOR_OP, PK2US, 5); }
  221. PK4B               { return_opcode(require_NV_fp,  VECTOR_OP, PK4B, 4); }
  222. PK4UB              { return_opcode(require_NV_fp,  VECTOR_OP, PK4UB, 5); }
  223. POW{szf}{cc}{sat}  { return_opcode(             1, BINSC_OP, POW, 3); }
  224.  
  225. RCP{szf}{cc}{sat}  { return_opcode(             1, SCALAR_OP, RCP, 3); }
  226. RFL{szf}{cc}{sat}  { return_opcode(require_NV_fp,  BIN_OP,    RFL, 3); }
  227. RSQ{szf}{cc}{sat}  { return_opcode(             1, SCALAR_OP, RSQ, 3); }
  228.  
  229. SCS{sat}           { return_opcode(require_ARB_fp, SCALAR_OP, SCS, 3); }
  230. SEQ{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SEQ, 3); }
  231. SFL{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SFL, 3); }
  232. SGE{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, SGE, 3); }
  233. SGT{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SGT, 3); }
  234. SIN{szf}{cc}{sat}  { return_opcode(require_ARB_fp, SCALAR_OP, SIN, 3); }
  235. SLE{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SLE, 3); }
  236. SLT{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, SLT, 3); }
  237. SNE{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SNE, 3); }
  238. STR{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, STR, 3); }
  239. SUB{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, SUB, 3); }
  240. SWZ{sat}           { return_opcode(             1, SWZ, SWZ, 3); }
  241.  
  242. TEX{cc}{sat}       { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, 3); }
  243. TXB{cc}{sat}       { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, 3); }
  244. TXD{cc}{sat}       { return_opcode(require_NV_fp,  TXD_OP, TXD, 3); }
  245. TXP{cc}{sat}       { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, 3); }
  246.  
  247. UP2H{cc}{sat}      { return_opcode(require_NV_fp,  SCALAR_OP, UP2H, 4); }
  248. UP2US{cc}{sat}     { return_opcode(require_NV_fp,  SCALAR_OP, UP2US, 5); }
  249. UP4B{cc}{sat}      { return_opcode(require_NV_fp,  SCALAR_OP, UP4B, 4); }
  250. UP4UB{cc}{sat}     { return_opcode(require_NV_fp,  SCALAR_OP, UP4UB, 5); }
  251.  
  252. X2D{szf}{cc}{sat}  { return_opcode(require_NV_fp,  TRI_OP, X2D, 3); }
  253. XPD{sat}           { return_opcode(             1, BIN_OP, XPD, 3); }
  254.  
  255. vertex                    { return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); }
  256. fragment                  { return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); }
  257. program                   { return PROGRAM; }
  258. state                     { return STATE; }
  259. result                    { return RESULT; }
  260.  
  261. {dot}ambient              { return AMBIENT; }
  262. {dot}attenuation          { return ATTENUATION; }
  263. {dot}back                 { return BACK; }
  264. {dot}clip                 { return_token_or_DOT(require_ARB_vp, CLIP); }
  265. {dot}color                { return COLOR; }
  266. {dot}depth                { return_token_or_DOT(require_ARB_fp, DEPTH); }
  267. {dot}diffuse              { return DIFFUSE; }
  268. {dot}direction            { return DIRECTION; }
  269. {dot}emission             { return EMISSION; }
  270. {dot}env                  { return ENV; }
  271. {dot}eye                  { return EYE; }
  272. {dot}fogcoord             { return FOGCOORD; }
  273. {dot}fog                  { return FOG; }
  274. {dot}front                { return FRONT; }
  275. {dot}half                 { return HALF; }
  276. {dot}inverse              { return INVERSE; }
  277. {dot}invtrans             { return INVTRANS; }
  278. {dot}light                { return LIGHT; }
  279. {dot}lightmodel           { return LIGHTMODEL; }
  280. {dot}lightprod            { return LIGHTPROD; }
  281. {dot}local                { return LOCAL; }
  282. {dot}material             { return MATERIAL; }
  283. {dot}program              { return MAT_PROGRAM; }
  284. {dot}matrix               { return MATRIX; }
  285. {dot}matrixindex          { return_token_or_DOT(require_ARB_vp, MATRIXINDEX); }
  286. {dot}modelview            { return MODELVIEW; }
  287. {dot}mvp                  { return MVP; }
  288. {dot}normal               { return_token_or_DOT(require_ARB_vp, NORMAL); }
  289. {dot}object               { return OBJECT; }
  290. {dot}palette              { return PALETTE; }
  291. {dot}params               { return PARAMS; }
  292. {dot}plane                { return PLANE; }
  293. {dot}point                { return_token_or_DOT(require_ARB_vp, POINT_TOK); }
  294. {dot}pointsize            { return_token_or_DOT(require_ARB_vp, POINTSIZE); }
  295. {dot}position             { return POSITION; }
  296. {dot}primary              { return PRIMARY; }
  297. {dot}projection           { return PROJECTION; }
  298. {dot}range                { return_token_or_DOT(require_ARB_fp, RANGE); }
  299. {dot}row                  { return ROW; }
  300. {dot}scenecolor           { return SCENECOLOR; }
  301. {dot}secondary            { return SECONDARY; }
  302. {dot}shininess            { return SHININESS; }
  303. {dot}size                 { return_token_or_DOT(require_ARB_vp, SIZE_TOK); }
  304. {dot}specular             { return SPECULAR; }
  305. {dot}spot                 { return SPOT; }
  306. {dot}texcoord             { return TEXCOORD; }
  307. {dot}texenv               { return_token_or_DOT(require_ARB_fp, TEXENV); }
  308. {dot}texgen               { return_token_or_DOT(require_ARB_vp, TEXGEN); }
  309. {dot}q                    { return_token_or_DOT(require_ARB_vp, TEXGEN_Q); }
  310. {dot}s                    { return_token_or_DOT(require_ARB_vp, TEXGEN_S); }
  311. {dot}t                    { return_token_or_DOT(require_ARB_vp, TEXGEN_T); }
  312. {dot}texture              { return TEXTURE; }
  313. {dot}transpose            { return TRANSPOSE; }
  314. {dot}attrib               { return_token_or_DOT(require_ARB_vp, VTXATTRIB); }
  315. {dot}weight               { return_token_or_DOT(require_ARB_vp, WEIGHT); }
  316.  
  317. texture                   { return_token_or_IDENTIFIER(require_ARB_fp, TEXTURE_UNIT); }
  318. 1D                        { return_token_or_IDENTIFIER(require_ARB_fp, TEX_1D); }
  319. 2D                        { return_token_or_IDENTIFIER(require_ARB_fp, TEX_2D); }
  320. 3D                        { return_token_or_IDENTIFIER(require_ARB_fp, TEX_3D); }
  321. CUBE                      { return_token_or_IDENTIFIER(require_ARB_fp, TEX_CUBE); }
  322. RECT                      { return_token_or_IDENTIFIER(require_ARB_fp && require_rect, TEX_RECT); }
  323. SHADOW1D                  { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW1D); }
  324. SHADOW2D                  { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW2D); }
  325. SHADOWRECT                { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_rect, TEX_SHADOWRECT); }
  326. ARRAY1D                   { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY1D); }
  327. ARRAY2D                   { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY2D); }
  328. ARRAYSHADOW1D             { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW1D); }
  329. ARRAYSHADOW2D             { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW2D); }
  330.  
  331. [_a-zA-Z$][_a-zA-Z0-9$]*  { return handle_ident(yyextra, yytext, yylval); }
  332.  
  333. ".."                      { return DOT_DOT; }
  334.  
  335. {num}                     {
  336.    yylval->integer = strtol(yytext, NULL, 10);
  337.    return INTEGER;
  338. }
  339. {num}?{frac}{exp}?        {
  340.    yylval->real = _mesa_strtof(yytext, NULL);
  341.    return REAL;
  342. }
  343. {num}"."/[^.]             {
  344.    yylval->real = _mesa_strtof(yytext, NULL);
  345.    return REAL;
  346. }
  347. {num}{exp}                {
  348.    yylval->real = _mesa_strtof(yytext, NULL);
  349.    return REAL;
  350. }
  351. {num}"."{exp}             {
  352.    yylval->real = _mesa_strtof(yytext, NULL);
  353.    return REAL;
  354. }
  355.  
  356. ".xyzw"                   {
  357.    yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
  358.    yylval->swiz_mask.mask = WRITEMASK_XYZW;
  359.    return MASK4;
  360. }
  361.  
  362. ".xy"[zw]                 {
  363.    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
  364.    yylval->swiz_mask.mask = WRITEMASK_XY
  365.       | mask_from_char(yytext[3]);
  366.    return MASK3;
  367. }
  368. ".xzw"                    {
  369.    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
  370.    yylval->swiz_mask.mask = WRITEMASK_XZW;
  371.    return MASK3;
  372. }
  373. ".yzw"                    {
  374.    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
  375.    yylval->swiz_mask.mask = WRITEMASK_YZW;
  376.    return MASK3;
  377. }
  378.  
  379. ".x"[yzw]                 {
  380.    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
  381.    yylval->swiz_mask.mask = WRITEMASK_X
  382.       | mask_from_char(yytext[2]);
  383.    return MASK2;
  384. }
  385. ".y"[zw]                  {
  386.    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
  387.    yylval->swiz_mask.mask = WRITEMASK_Y
  388.       | mask_from_char(yytext[2]);
  389.    return MASK2;
  390. }
  391. ".zw"                     {
  392.    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
  393.    yylval->swiz_mask.mask = WRITEMASK_ZW;
  394.    return MASK2;
  395. }
  396.  
  397. "."[xyzw]                 {
  398.    const unsigned s = swiz_from_char(yytext[1]);
  399.    yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
  400.    yylval->swiz_mask.mask = mask_from_char(yytext[1]);
  401.    return MASK1;
  402. }
  403.  
  404. "."[xyzw]{4}              {
  405.    yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
  406.                                             swiz_from_char(yytext[2]),
  407.                                             swiz_from_char(yytext[3]),
  408.                                             swiz_from_char(yytext[4]));
  409.    yylval->swiz_mask.mask = 0;
  410.    return SWIZZLE;
  411. }
  412.  
  413. ".rgba"                   {
  414.    yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
  415.    yylval->swiz_mask.mask = WRITEMASK_XYZW;
  416.    return_token_or_DOT(require_ARB_fp, MASK4);
  417. }
  418.  
  419. ".rg"[ba]                 {
  420.    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
  421.    yylval->swiz_mask.mask = WRITEMASK_XY
  422.       | mask_from_char(yytext[3]);
  423.    return_token_or_DOT(require_ARB_fp, MASK3);
  424. }
  425. ".rba"                    {
  426.    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
  427.    yylval->swiz_mask.mask = WRITEMASK_XZW;
  428.    return_token_or_DOT(require_ARB_fp, MASK3);
  429. }
  430. ".gba"                    {
  431.    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
  432.    yylval->swiz_mask.mask = WRITEMASK_YZW;
  433.    return_token_or_DOT(require_ARB_fp, MASK3);
  434. }
  435.  
  436. ".r"[gba]                 {
  437.    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
  438.    yylval->swiz_mask.mask = WRITEMASK_X
  439.       | mask_from_char(yytext[2]);
  440.    return_token_or_DOT(require_ARB_fp, MASK2);
  441. }
  442. ".g"[ba]                  {
  443.    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
  444.    yylval->swiz_mask.mask = WRITEMASK_Y
  445.       | mask_from_char(yytext[2]);
  446.    return_token_or_DOT(require_ARB_fp, MASK2);
  447. }
  448. ".ba"                     {
  449.    yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
  450.    yylval->swiz_mask.mask = WRITEMASK_ZW;
  451.    return_token_or_DOT(require_ARB_fp, MASK2);
  452. }
  453.  
  454. "."[gba]                  {
  455.    const unsigned s = swiz_from_char(yytext[1]);
  456.    yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
  457.    yylval->swiz_mask.mask = mask_from_char(yytext[1]);
  458.    return_token_or_DOT(require_ARB_fp, MASK1);
  459. }
  460.  
  461.  
  462. ".r"                      {
  463.    if (require_ARB_vp) {
  464.       return TEXGEN_R;
  465.    } else {
  466.       yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X,
  467.                                                 SWIZZLE_X, SWIZZLE_X);
  468.       yylval->swiz_mask.mask = WRITEMASK_X;
  469.       return MASK1;
  470.    }
  471. }
  472.  
  473. "."[rgba]{4}              {
  474.    yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
  475.                                             swiz_from_char(yytext[2]),
  476.                                             swiz_from_char(yytext[3]),
  477.                                             swiz_from_char(yytext[4]));
  478.    yylval->swiz_mask.mask = 0;
  479.    return_token_or_DOT(require_ARB_fp, SWIZZLE);
  480. }
  481.  
  482. "."                       { return DOT; }
  483.  
  484. \n                        {
  485.    yylloc->first_line++;
  486.    yylloc->first_column = 1;
  487.    yylloc->last_line++;
  488.    yylloc->last_column = 1;
  489.    yylloc->position++;
  490. }
  491. [ \t\r]+                  /* eat whitespace */ ;
  492. #.*$                      /* eat comments */ ;
  493. .                         { return yytext[0]; }
  494. %%
  495.  
  496. void
  497. _mesa_program_lexer_ctor(void **scanner, struct asm_parser_state *state,
  498.                          const char *string, size_t len)
  499. {
  500.    yylex_init_extra(state, scanner);
  501.    yy_scan_bytes(string, len, *scanner);
  502. }
  503.  
  504. void
  505. _mesa_program_lexer_dtor(void *scanner)
  506. {
  507.    yylex_destroy(scanner);
  508. }
  509.