@@ -0,0 +1,4 @@ | |||
lex.yy.c | |||
lolfx.tab.c | |||
lolfx.tab.h | |||
parser |
@@ -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 $^ | |||
@@ -0,0 +1,50 @@ | |||
%{ | |||
#include <iostream> | |||
#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); } | |||
<C_COMMENT>"*/" { BEGIN(INITIAL); } | |||
<C_COMMENT>[^*]* { } | |||
<C_COMMENT>. { } | |||
/* | |||
* Ignore C++ comments | |||
*/ | |||
"//" { BEGIN(CPP_COMMENT); } | |||
<CPP_COMMENT>.*\n { BEGIN(INITIAL); } | |||
%% | |||
@@ -0,0 +1,126 @@ | |||
%{ | |||
#include <cstdio> | |||
#include <iostream> | |||
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 <ival> INT | |||
%token <fval> FLOAT | |||
%token <sval> 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); | |||
} | |||
@@ -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 */ | |||
} | |||