diff --git a/test/sandbox/lex/.gitignore b/test/sandbox/lex/.gitignore new file mode 100644 index 00000000..7b525ac4 --- /dev/null +++ b/test/sandbox/lex/.gitignore @@ -0,0 +1,4 @@ +lex.yy.c +lolfx.tab.c +lolfx.tab.h +parser diff --git a/test/sandbox/lex/Makefile b/test/sandbox/lex/Makefile new file mode 100644 index 00000000..265f202f --- /dev/null +++ b/test/sandbox/lex/Makefile @@ -0,0 +1,10 @@ + +parser: lex.yy.c lolfx.tab.c + $(CXX) $^ -o $@ -lfl + +lolfx.tab.c: lolfx.y + bison -d $^ + +lex.yy.c: lolfx.l + flex -d $^ + diff --git a/test/sandbox/lex/lolfx.l b/test/sandbox/lex/lolfx.l new file mode 100644 index 00000000..8e1164ae --- /dev/null +++ b/test/sandbox/lex/lolfx.l @@ -0,0 +1,50 @@ +%{ +#include +#define YY_DECL extern "C" int yylex() +#include "lolfx.tab.h" +%} + +%x C_COMMENT +%x CPP_COMMENT + +%% + + /* + * Our language's keywords + */ + +"technique" { return TECHNIQUE; } +"pass" { return PASS; } + + /* + * Various tokens + */ + +[0-9]+\.[0-9]+ { yylval.fval = atof(yytext); return FLOAT; } +[0-9]+ { yylval.ival = atoi(yytext); return INT; } +[a-zA-Z][a-zA-Z0-9_]* { + /* Copy token for now */ + yylval.sval = strdup(yytext); + return NAME; +} +[ \t\n]+ ; +. { return *yytext; } + + /* + * Ignore C comments + */ + +"/*" { BEGIN(C_COMMENT); } +"*/" { BEGIN(INITIAL); } +[^*]* { } +. { } + + /* + * Ignore C++ comments + */ + +"//" { BEGIN(CPP_COMMENT); } +.*\n { BEGIN(INITIAL); } + +%% + diff --git a/test/sandbox/lex/lolfx.y b/test/sandbox/lex/lolfx.y new file mode 100644 index 00000000..d0c12817 --- /dev/null +++ b/test/sandbox/lex/lolfx.y @@ -0,0 +1,126 @@ +%{ +#include +#include + +extern "C" int yylex(); +extern "C" int yyparse(); +extern "C" FILE *yyin; +extern "C" int yylineno; + +void yyerror(const char *s); +%} + +/* The classic Bison union trick */ +%union +{ + int ival; + float fval; + char *sval; +} + + /* + * All the LolFx tokens + */ + +%token TECHNIQUE PASS +%token INT +%token FLOAT +%token STRING NAME + +%% + +fx: + section_list + ; + +section_list: + section + | section_list section + ; + +section: + technique + | shader + ; + + /* + * Grammar for techniques + */ + +technique: + TECHNIQUE NAME '{' pass_list '}' { std::cout << "TECHNIQUE" << std::endl; } + ; + + /* + * Grammar for passes + */ + +pass_list: + pass + | pass_list pass + ; + +pass: + PASS NAME '{' pass_stmt_list '}' { std::cout << "PASS" << std::endl; } + ; + +pass_stmt_list: + pass_stmt + | pass_stmt_list pass_stmt + ; + +pass_stmt: + ';' + | NAME '=' NAME ';' + | NAME '=' INT ';' + | NAME '[' INT ']' '=' NAME ';' + | NAME '[' INT ']' '=' INT ';' + ; + + /* + * Grammar for shaders + */ + +shader: + shader_region shader_code + | shader_region + ; + +shader_region: + '#' NAME shader_name { std::cout << "new shader " << $2 << std::endl; } + ; + +shader_name: + NAME + | shader_name '.' NAME + ; + +shader_code: + INT shader_code { std::cout << "int: " << $1 << std::endl; } + | FLOAT shader_code { std::cout << "float: " << $1 << std::endl; } + | STRING shader_code { std::cout << "string: " << $1 << std::endl; } + | INT { std::cout << "int: " << $1 << std::endl; } + | FLOAT { std::cout << "float: " << $1 << std::endl; } + | STRING { std::cout << "string: " << $1 << std::endl; } + ; + +%% + +main() +{ + yyin = fopen("test.lolfx", "r"); + do + { + yyparse(); + } + while (!feof(yyin)); + + fclose(yyin); +} + +void yyerror(const char *s) +{ + std::cout << "Parse error line " << yylineno << ": " << s << std::endl; + exit(-1); +} + diff --git a/test/sandbox/lex/test.lolfx b/test/sandbox/lex/test.lolfx new file mode 100644 index 00000000..b9111a7b --- /dev/null +++ b/test/sandbox/lex/test.lolfx @@ -0,0 +1,103 @@ +/* + * LolFx Test Material + */ + +// Can have lots of different techniques in a single lolfx file, +// especially if they share common shader code. +technique Foo +{ + // Multiple passes, with alpha on/off, with various blending methods, + // with depth test disabled... + pass p0 + { + texture[0] = null; + texture[1] = null; + texture[2] = null; + + cullmode = none; // ccw + lighting = false; + zenable = true; // false + alphablendenable = true; // false + srcblend = src_alpha; // one + destblend = inv_src_alpha; + + colorop[0] = select_arg1; + colorarg1[0] = diffuse; + + alphaop[0] = select_arg1; + alphaarg1[0] = diffuse; + + colorop[1] = disable; + + alphaop[1] = disable; + + // Ye old way + vertexshader = blah; + geometryshader = blah; + pixelshader = blah; + + // Ogre crap + + // The D3D11 way, but we must make it work with GLSL too + //SetBlendState(AdditiveBlending, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF); + //SetDepthStencilState(DisableDepth, 0); + //SetRasterizerState() + + //SetVertexShader + //SetDomainShader + //SetHullShader + //SetGeometryShader + //SetPixelShader + //SetComputeShader /* WTF? */ + + //SetRenderTargets(RTV0, DSV); + //SetRenderTargets(RTV0, RTV1, DSV); + //... + //SetRenderTargets(RTV0, RTV1, RTV2, RTV3, RTV4, RTV5, RTV6, RTV7, DSV); + } + + pass p1 + { + // Autres vertex/pixel shaders avec éventuellement des + // dépendances sur le résultat des passes précédentes + vertexshader = something_else; + } +} + +/* Defines GLSL shader "Prout" */ + +#section GLSL.Prout + +#version 120 + +/* Valid with my GLSL compiler */ +#pragma lolfx semantic(in_Vertex, POSITION) +#pragma lolfx semantic(in_Normal, NORMAL) +#pragma lolfx semantic(in_Color, COLOR) +attribute vec3 in_Vertex; +attribute vec3 in_Normal; +attribute vec4 in_Color; + +void main(void) +{ + ... +} + +/* Defines GLSL shader "Zob" */ + +#section GLSL.Zob + +void main(void) +{ + shit fuck fuck shit; +} + +/* Defines HLSL shader "Prout" */ + +#section HLSL.Prout + +void main(void) +{ + /* Blah */ +} +