Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: FishingCactus/ShaderShaker
...
head fork: FishingCactus/ShaderShaker
  • 6 commits
  • 17 files changed
  • 0 commit comments
  • 1 contributor
View
3  .gitignore
@@ -17,4 +17,5 @@ bin/*
#Generated project
*.xcodeproj
-*.xcworkspace
+*.xcworkspace
+src/host/scripts.cpp
View
4 premake4.lua
@@ -109,11 +109,11 @@
-- a release build.
--
--- dofile("scripts/embed.lua")
+ dofile("scripts/embed.lua")
newaction {
trigger = "embed",
- description = "Embed scripts in scripts.c; required before release builds",
+ description = "Embed scripts in scripts.cpp; required before release builds",
execute = doembed
}
View
99 scripts/embed.lua
@@ -0,0 +1,99 @@
+-- Credits goes to premake4. This code has been copied from there.
+-- Embed the Lua scripts into src/host/scripts.cpp as static data buffers.
+-- I embed the actual scripts, rather than Lua bytecodes, because the
+-- bytecodes are not portable to different architectures, which causes
+-- issues in Mac OS X Universal builds.
+--
+
+ local function stripfile(fname)
+ local f = io.open(fname)
+ local s = assert(f:read("*a"))
+ f:close()
+
+ -- strip tabs
+ s = s:gsub("[\t]", "")
+
+ -- strip any CRs
+ s = s:gsub("[\r]", "")
+
+ -- strip out block comments
+ s = s:gsub("%-%-%[%[.-%-%-%]%]", "")
+
+ -- strip out inline comments
+ s = s:gsub("\n%-%-[^\n]*", "")
+
+ -- escape backslashes
+ s = s:gsub("\\", "\\\\")
+
+ -- strip duplicate line feeds
+ s = s:gsub("\n+", "\n")
+
+ -- strip out leading comments
+ s = s:gsub("^%-%-\n", "")
+
+ -- escape line feeds
+ s = s:gsub("\n", "\\n")
+
+ -- escape double quote marks
+ s = s:gsub("\"", "\\\"")
+
+ return s
+ end
+
+
+ local function writeline(out, s, continues)
+ out:write("\t\"")
+ out:write(s)
+ out:write(iif(continues, "\"\n", "\",\n"))
+ end
+
+
+ local function writefile(out, fname, contents)
+ local max = 1024
+
+ out:write("\t/* " .. fname .. " */\n")
+
+ -- break up large strings to fit in Visual Studio's string length limit
+ local start = 1
+ local len = contents:len()
+ while start <= len do
+ local n = len - start
+ if n > max then n = max end
+ local finish = start + n
+
+ -- make sure I don't cut an escape sequence
+ while contents:sub(finish, finish) == "\\" do
+ finish = finish - 1
+ end
+
+ writeline(out, contents:sub(start, finish), finish < len)
+ start = finish + 1
+ end
+
+ out:write("\n")
+ end
+
+
+ function doembed()
+ -- load the manifest of script files
+ scripts = dofile("src/_manifest.lua")
+
+ -- main script always goes at the end
+ table.insert(scripts, "_shader_shaker_main.lua")
+
+ -- open scripts.c and write the file header
+ local out = io.open("src/host/scripts.cpp", "w+b")
+ out:write("/* ShaderShaker's Lua scripts, as static data buffers for release mode builds */\n")
+ out:write("/* DO NOT EDIT - this file is autogenerated */\n")
+ out:write("/* To regenerate this file, run: premake4 embed */ \n\n")
+ out:write("const char* builtin_scripts[] = {\n")
+
+ for i,fn in ipairs(scripts) do
+ print(fn)
+ local s = stripfile("src/" .. fn)
+ writefile(out, fn, s)
+ end
+
+ out:write("\t0\n};\n");
+ out:close()
+ end
View
41 src/_manifest.lua
@@ -2,24 +2,27 @@
return {
- -- language
-
- "language/types.lua",
- "language/intrinsics.lua",
- "language/input.lua",
- "language/output.lua",
- "language/technique.lua",
- "language/texture.lua",
- "language/constant.lua",
-
- -- Intermediate representation
-
- "ir/ast_to_ir.lua",
-
- -- Printer
-
- "printer/hlsl_printer.lua",
-
- "utilities/output.lua"
+ -- language
+
+ "language/types.lua",
+ "language/intrinsics.lua",
+ "language/input.lua",
+ "language/output.lua",
+ "language/technique.lua",
+ "language/texture.lua",
+ "language/constant.lua",
+
+ -- Intermediate representation
+
+ "ir/ast_to_ir.lua",
+
+ -- Printer
+
+ "printer/printer_manager.lua", -- Must remain first of printer files
+ "printer/hlsl_printer.lua",
+
+ -- Utilities
+
+ "utilities/output.lua"
}
View
37 src/_shader_shaker_main.lua
@@ -1,21 +1,22 @@
-function _shader_shaker_main(script_path, output_file)
+function _shader_shaker_main(script_path, output_file, override_language)
- -- if running off the disk (in debug mode), load everything
- -- listed in _manifest.lua; the list divisions make sure
- -- everything gets initialized in the proper order.
-
- if script_path then
- local scripts = dofile(script_path .. "/_manifest.lua")
- for _,v in ipairs(scripts) do
- dofile(script_path .. "/" .. v)
- end
- end
-
-
- if output_file ~= nil then
- InitializeOutputFile( output_file )
- else
- InitializeOutputPrint()
- end
+ -- if running off the disk (in debug mode), load everything
+ -- listed in _manifest.lua; the list divisions make sure
+ -- everything gets initialized in the proper order.
+
+ if script_path then
+ local scripts = dofile(script_path .. "/_manifest.lua")
+ for _,v in ipairs(scripts) do
+ dofile(script_path .. "/" .. v)
+ end
+ end
+
+ SelectPrinter( output_file, override_language )
+
+ if output_file ~= nil then
+ InitializeOutputFile( output_file )
+ else
+ InitializeOutputPrint()
+ end
end
View
0  src/host/scripts.cpp
No changes.
View
70 src/host/shader_shaker.cpp
@@ -14,7 +14,8 @@ extern const char* builtin_scripts[];
static const char
* LocalInputFile = 0,
- * LocalOutputFile = 0;
+ * LocalOutputFile = 0,
+ * LocalLanguage = 0;
static bool process_command_line( lua_State * L, int argc, const char ** argv );
static void usage();
@@ -84,6 +85,30 @@ static bool process_command_line( lua_State * L, int argument_count, const char
}
break;
+ case 'x':
+ {
+ if( argument[ 2 ] != 0 )
+ {
+ return false;
+ }
+ else if( LocalLanguage != 0 )
+ {
+ std::cerr << "Two languages given, aborting\n";
+ return false;
+ }
+ else if( argument_index == ( argument_count - 1 )
+ || argument_table[ argument_index + 1 ][ 0 ] == '-'
+ )
+ {
+ std::cerr << "No language given after '-x', aborting\n\n";
+ return false;
+ }
+
+ LocalLanguage = argument_table[ argument_index + 1 ];
+ ++argument_index;
+ }
+ break;
+
case '-':
{
lua_pushboolean( L, true );
@@ -134,8 +159,6 @@ bool load_builtin_scripts(lua_State* L)
{
const char
* filename;
- int
- argument_count;
//:TODO: option to change scripts directory
filename = "src/_shader_shaker_main.lua";
@@ -148,14 +171,26 @@ bool load_builtin_scripts(lua_State* L)
lua_getglobal(L, "_shader_shaker_main");
lua_pushstring(L, "src" );
- argument_count = 1;
+
if( LocalOutputFile )
{
lua_pushstring( L, LocalOutputFile );
- ++argument_count;
+ }
+ else
+ {
+ lua_pushnil( L );
+ }
+
+ if( LocalLanguage )
+ {
+ lua_pushstring( L, LocalLanguage );
+ }
+ else
+ {
+ lua_pushnil( L );
}
- if (lua_pcall(L, argument_count, 1, 0) != 0)
+ if (lua_pcall(L, 3, 1, 0) != 0)
{
std::cerr << lua_tostring(L, -1);
return false;
@@ -188,9 +223,28 @@ bool load_builtin_scripts(lua_State* L)
}
/* hand off control to the scripts */
- lua_getglobal(L, "_premake_main");
+ lua_getglobal(L, "_shader_shaker_main");
+ lua_pushnil( L );
+
+ if( LocalOutputFile )
+ {
+ lua_pushstring( L, LocalOutputFile );
+ }
+ else
+ {
+ lua_pushnil( L );
+ }
+
+ if( LocalLanguage )
+ {
+ lua_pushstring( L, LocalLanguage );
+ }
+ else
+ {
+ lua_pushnil( L );
+ }
- if (lua_pcall(L, 0, 1, 0) != 0)
+ if (lua_pcall(L, 3, 1, 0) != 0)
{
std::cerr << lua_tostring(L, -1);
return false;
View
190 src/ir/ast_to_ir.lua
@@ -3,139 +3,141 @@
Ir = Ir or {}
Ir.CreateVariable = function( representation, variable_type )
- local variable_name = "temp" .. representation.variable_index
- representation.variable_index = representation.variable_index + 1
-
- representation.code[ #(representation.code) + 1 ] = { type = "Declaration", variable_type = variable_type, name = variable_name }
-
- return variable_name
+ local variable_name = "temp" .. representation.variable_index
+ representation.variable_index = representation.variable_index + 1
+
+ representation.code[ #(representation.code) + 1 ] = { type = "Declaration", variable_type = variable_type, name = variable_name }
+
+ return variable_name
end
Ir.HandleOutput = function( node, representation )
- for k,v in pairs( node.__variable ) do
- local variable = Ir.HandleNode( v, representation )
- local definition = node.__definition[ k ]
- representation.code[ #(representation.code) + 1 ] = { type = "Assignment", variable = "output." .. k, value = variable }
- representation.output[ k ] = { semantic = definition.semantic, type = definition.type }
- end
+ for k,v in pairs( node.__variable ) do
+ local variable = Ir.HandleNode( v, representation )
+ local definition = node.__definition[ k ]
+ representation.code[ #(representation.code) + 1 ] = { type = "Assignment", variable = "output." .. k, value = variable }
+ representation.output[ k ] = { semantic = definition.semantic, type = definition.type }
+ end
end
Ir.HandleInput = function( node, representation )
- representation.input[ node.value ] = { semantic = node.semantic, type = node.type }
- return "input." .. node.value
+ representation.input[ node.value ] = { semantic = node.semantic, type = node.type }
+ return "input." .. node.value
end
Ir.HandleConstructor = function( node, representation )
- local variable_table = {}
- for i,v in ipairs( node.value ) do
- if type( v ) == "number" then
- variable_table[i] = v
- else
- variable_table[i] = Ir.HandleNode( v, representation )
- end
- end
- local output_variable_name = Ir.CreateVariable( representation, node.type )
-
- representation.code[ #(representation.code) + 1 ] = { type = "Constructor", constructor_type = node.type, arguments = variable_table, variable = output_variable_name }
-
- return output_variable_name
+ local variable_table = {}
+ for i,v in ipairs( node.value ) do
+ if type( v ) == "number" then
+ variable_table[i] = v
+ else
+ variable_table[i] = Ir.HandleNode( v, representation )
+ end
+ end
+ local output_variable_name = Ir.CreateVariable( representation, node.type )
+
+ representation.code[ #(representation.code) + 1 ] = { type = "Constructor", constructor_type = node.type, arguments = variable_table, variable = output_variable_name }
+
+ return output_variable_name
end
Ir.HandleConstant = function( node, representation )
- representation.constant[ node.name ] = { type = node.type }
- return node.name
+ representation.constant[ node.name ] = { type = node.type }
+ return node.name
end
Ir.HandleSwizzle = function( node, representation )
- local variable_name = Ir.CreateVariable( representation, node.type )
- local source_variable_name = Ir.HandleNode( node.arguments[ 1 ], representation )
-
- representation.variable[ node ] = variable_name
- representation.code[ #(representation.code) + 1 ]
- = { type = "Swizzle", variable_type = node.type, variable = variable_name, arguments = { source_variable_name, node.arguments[2] } }
-
- return variable_name
+ local variable_name = Ir.CreateVariable( representation, node.type )
+ local source_variable_name = Ir.HandleNode( node.arguments[ 1 ], representation )
+
+ representation.variable[ node ] = variable_name
+ representation.code[ #(representation.code) + 1 ]
+ = { type = "Swizzle", variable_type = node.type, variable = variable_name, arguments = { source_variable_name, node.arguments[2] } }
+
+ return variable_name
end
Ir.HandleVariable = function( node, representation )
-
- local value = rawget( node, "value" )
- local variable_name
- variable_name = Ir.CreateVariable( representation, node.type )
-
- if type( value ) == "number" or value.type == nil then
- representation.code[ #(representation.code) + 1 ] = { type = "Assignment", variable_type = node.type, variable = variable_name, value = value }
- else
- output_variable_name = Ir.HandleNode( value )
- representation.code[ #(representation.code) + 1 ] = { type = "Assignment", variable_type = node.type, variable = variable_name, value = output_variable_name }
- end
-
- representation.variable[ node ] = variable_name
-
- return variable_name
+
+ local value = rawget( node, "value" )
+ local variable_name
+ variable_name = Ir.CreateVariable( representation, node.type )
+
+ if type( value ) == "number" or value.type == nil then
+ representation.code[ #(representation.code) + 1 ] = { type = "Assignment", variable_type = node.type, variable = variable_name, value = value }
+ else
+ output_variable_name = Ir.HandleNode( value )
+ representation.code[ #(representation.code) + 1 ] = { type = "Assignment", variable_type = node.type, variable = variable_name, value = output_variable_name }
+ end
+
+ representation.variable[ node ] = variable_name
+
+ return variable_name
end
Ir.HandleTexture = function( node, representation )
- return node.name
+
+ representation.texture[ node.name ] = { type = node.type }
+ return { type = "Texture", name = node.name }
end
Ir.HandleFunction = function( node, representation )
- local variable_name_table = {}
- for i,v in ipairs( node.arguments ) do
- variable_name_table[i] = Ir.HandleNode( v, representation )
- end
- local output_variable_name = Ir.CreateVariable( representation, node.type )
- representation.code[ #(representation.code) + 1 ] = { type = "CallFunction", name = node.name, arguments = variable_name_table, variable = output_variable_name }
-
- return output_variable_name
+ local variable_name_table = {}
+ for i,v in ipairs( node.arguments ) do
+ variable_name_table[i] = Ir.HandleNode( v, representation )
+ end
+ local output_variable_name = Ir.CreateVariable( representation, node.type )
+ representation.code[ #(representation.code) + 1 ] = { type = "CallFunction", name = node.name, arguments = variable_name_table, variable = output_variable_name }
+
+ return output_variable_name
end
Ir.HandleOperation = function( node, representation )
- local variable_name_table = {}
- for i,v in ipairs( node.arguments ) do
- variable_name_table[i] = Ir.HandleNode( v, representation )
- end
-
- local output_variable_name = Ir.CreateVariable( representation, node.type )
- representation.code[ #(representation.code) + 1 ] = { type = "Operation", operation = node.operation, arguments = variable_name_table, variable = output_variable_name }
-
- return output_variable_name
+ local variable_name_table = {}
+ for i,v in ipairs( node.arguments ) do
+ variable_name_table[i] = Ir.HandleNode( v, representation )
+ end
+
+ local output_variable_name = Ir.CreateVariable( representation, node.type )
+ representation.code[ #(representation.code) + 1 ] = { type = "Operation", operation = node.operation, arguments = variable_name_table, variable = output_variable_name }
+
+ return output_variable_name
end
Ir.HandleNode = function( ast_node, representation )
- if type( ast_node ) == "number" then
- local varname = Ir.CreateVariable( representation, "float" )
- representation.code[ #(representation.code) + 1 ] = { type = "Assignment", variable_type = "float", variable = varname, value = ast_node }
-
- return varname
- end
-
- if ast_node.node == nil then
- print( ast_node )
- print ( "ast_node : " .. table.tostring( ast_node ) )
- error( "No node field found in ast_node", 2 )
- end
-
- local handle_function = Ir["Handle" .. ast_node.node];
-
- if handle_function == nil then
- error( "No handle function found for " .. ast_node.node, 2 )
- end
-
- return handle_function( ast_node, representation )
+ if type( ast_node ) == "number" then
+ local varname = Ir.CreateVariable( representation, "float" )
+ representation.code[ #(representation.code) + 1 ] = { type = "Assignment", variable_type = "float", variable = varname, value = ast_node }
+
+ return varname
+ end
+
+ if ast_node.node == nil then
+ print( ast_node )
+ print ( "ast_node : " .. table.tostring( ast_node ) )
+ error( "No node field found in ast_node", 2 )
+ end
+
+ local handle_function = Ir["Handle" .. ast_node.node];
+
+ if handle_function == nil then
+ error( "No handle function found for " .. ast_node.node, 2 )
+ end
+
+ return handle_function( ast_node, representation )
end
function AstToIR( ast )
- local representation = { code={}, input={}, output={}, constant={}, variable={}, variable_index = 0 }
+ local representation = { code={}, input={}, output={}, constant={}, texture={}, variable={}, variable_index = 0 }
- Ir.HandleNode( ast, representation )
-
- return representation
+ Ir.HandleNode( ast, representation )
+
+ return representation
end
View
32 src/language/input.lua
@@ -1,26 +1,26 @@
function DefineInput()
- input = { __semantic = {} }
+ input = { __semantic = {} }
end
function InputAttribute( name, type, semantic )
- if input[ name ] ~= nil then
- error( "An entry named '" .. name .."' already exists in the input structure", 2 )
- end
-
- if input.__semantic[ semantic ] ~= nil then
- error( "An entry already have the semantic '" .. semantic .. "' in the input structure", 2 )
- end
-
- -- :TODO: Validate semantic and type value
-
- local input_variable = { type = type, value = name, node = "Input", semantic = semantic }
- input[ name ] = input_variable
- input.__semantic[ semantic ] = input_variable
- Language.AttachVectorMetatable( input_variable )
+ if input[ name ] ~= nil then
+ error( "An entry named '" .. name .."' already exists in the input structure", 2 )
+ end
+
+ if input.__semantic[ semantic ] ~= nil then
+ error( "An entry already have the semantic '" .. semantic .. "' in the input structure", 2 )
+ end
+
+ -- :TODO: Validate semantic and type value
+
+ local input_variable = { type = type, value = name, node = "Input", semantic = semantic }
+ input[ name ] = input_variable
+ input.__semantic[ semantic ] = input_variable
+ Language.AttachVectorMetatable( input_variable )
end
function EndInput()
- -- :TODO: Validate structure
+ -- :TODO: Validate structure
end
View
47 src/language/intrinsics.lua
@@ -1,17 +1,36 @@
function tex2D( texcoord, texture )
-
- if texture.type ~= "texture_2d" then
- error( "Wrong texture, expect texture_2d got " .. texture.type, 2 )
- end
-
- if texcoord.type ~= "float2" then
- error( "Wrong coordinate type, expect float2 got " .. texcoord.type, 2 )
- end
-
- local result = { type = "float4", node="Function", name="tex2D", arguments={texcoord, texture} };
-
- Language.AttachVectorMetatable( result );
-
- return result;
+
+ if texture.type ~= "texture2D" then
+ error( "Wrong texture, expect texture2D got " .. texture.type, 2 )
+ end
+
+ if texcoord.type ~= "float2" then
+ error( "Wrong coordinate type, expect float2 got " .. texcoord.type, 2 )
+ end
+
+ local result = { type = "float4", node="Function", name="tex2D", arguments={texcoord, texture} };
+
+ Language.AttachVectorMetatable( result );
+
+ return result;
+end
+
+function lerp( a, b, factor )
+
+ if a.type ~= b.type then
+ error( "Both values should have the same type ( " .. a.type .. " and " .. b.type " )", 2 )
+ end
+
+ if not Language.IsNumber( factor ) or factor.type ~= "float" then
+ error( "Wrong factor type, expect float got " .. factor.type, 2 )
+ end
+
+ local result = { type = a.type, node="Function", name="lerp", arguments={a, b, factor} };
+
+ Language.AttachVectorMetatable( result );
+
+ return result;
+
+
end
View
68 src/language/output.lua
@@ -2,50 +2,50 @@ Language = Language or {}
-- :TRICKY: output must be assigned, so this needs a metatable
Language.OutputMetaType = {
- __newindex = function( table, key, value )
-
- if rawget( table, key ) ~= nil then
- error( "Entry " .. key .. " of output structure has already been assigned", 2 )
- end
-
- if table.__definition[ key ] == nil then
- error( "Unknown entry in output structure : " .. key, 2 )
- end
-
- if table.__definition[ key ].type ~= value.type then
- error( "Invalid type for " .. ", expect " .. table.__definition[ key ].type .. " got " .. value.type, 2 )
- end
-
- table.__variable[ key ] = value
-
- end
+ __newindex = function( table, key, value )
+
+ if rawget( table, key ) ~= nil then
+ error( "Entry " .. key .. " of output structure has already been assigned", 2 )
+ end
+
+ if table.__definition[ key ] == nil then
+ error( "Unknown entry in output structure : " .. key, 2 )
+ end
+
+ if table.__definition[ key ].type ~= value.type then
+ error( "Invalid type for " .. ", expect " .. table.__definition[ key ].type .. " got " .. value.type, 2 )
+ end
+
+ table.__variable[ key ] = value
+
+ end
}
function DefineOutput()
- output = { __definition={}, __semantic = {}, __variable = {}, node = "Output" }
- setmetatable( output, Language.OutputMetaType );
+ output = { __definition={}, __semantic = {}, __variable = {}, node = "Output" }
+ setmetatable( output, Language.OutputMetaType );
end
function OutputAttribute( name, type, semantic )
- if output.__definition[ name ] ~= nil then
- error( "An entry named '" .. name .."' already exists in the output structure", 2 )
- end
-
- if output.__semantic[ semantic ] ~= nil then
- error( "An entry already have the semantic '" .. semantic .. "' in the output structure", 2 )
- end
-
- -- :TODO: Validate semantic and type value
-
- local output_variable = { type = type, value = "output." .. name, semantic = semantic }
- output.__definition[ name ] = output_variable
- output.__semantic[ semantic ] = output_variable
+ if output.__definition[ name ] ~= nil then
+ error( "An entry named '" .. name .."' already exists in the output structure", 2 )
+ end
+
+ if output.__semantic[ semantic ] ~= nil then
+ error( "An entry already have the semantic '" .. semantic .. "' in the output structure", 2 )
+ end
+
+ -- :TODO: Validate semantic and type value
+
+ local output_variable = { type = type, value = "output." .. name, semantic = semantic }
+ output.__definition[ name ] = output_variable
+ output.__semantic[ semantic ] = output_variable
end
function EndOutput()
- -- :TODO: Validate structure
-
+ -- :TODO: Validate structure
+
end
View
28 src/language/technique.lua
@@ -39,19 +39,19 @@ end
function technique( technique_definition )
- local language_printer = HLSL;
- local representation = AstToIR( technique_definition.vs );
+ local language_printer = GetSelectedPrinter();
+ local representation = AstToIR( technique_definition.vs );
- language_printer.PrintFunctionPrologue( representation, technique_definition.name .. "_vs" )
- language_printer.PrintCode( representation )
- language_printer.PrintFunctionEpilogue( representation )
-
- representation = AstToIR( technique_definition.ps );
-
- language_printer.PrintFunctionPrologue( representation, technique_definition.name .. "_ps" )
- language_printer.PrintCode( representation )
- language_printer.PrintFunctionEpilogue( representation )
-
- language_printer.PrintTechnique( technique_definition.name, technique_definition.name .. "_vs", technique_definition.name .. "_ps" )
-
+ language_printer.PrintFunctionPrologue( representation, technique_definition.name .. "_vs" )
+ language_printer.PrintCode( representation )
+ language_printer.PrintFunctionEpilogue( representation )
+
+ representation = AstToIR( technique_definition.ps );
+
+ language_printer.PrintFunctionPrologue( representation, technique_definition.name .. "_ps" )
+ language_printer.PrintCode( representation )
+ language_printer.PrintFunctionEpilogue( representation )
+
+ language_printer.PrintTechnique( technique_definition.name, technique_definition.name .. "_vs", technique_definition.name .. "_ps" )
+
end
View
2  src/language/texture.lua
@@ -1,4 +1,4 @@
function Texture2D( name )
- _G[ name ] = { type = "texture_2d", node = "Texture", name = name };
+ _G[ name ] = { type = "texture2D", node = "Texture", name = name };
end
View
408 src/language/types.lua
@@ -1,249 +1,249 @@
Language = Language or {}
Language.IsNumber = function( variable )
- return type( variable ) == "number"
+ return type( variable ) == "number"
end
local IsNumber = Language.IsNumber
Language.IsVector = function( variable )
- if type( variable ) ~= "string" then error( "Type string expected", 2 ) end
-
- return string.match( variable, "float[2-4]*" ) == variable
+ if type( variable ) ~= "string" then error( "Type string expected", 2 ) end
+
+ return string.match( variable, "float[2-4]*" ) == variable
end
local IsVector = Language.IsVector
Language.IsMatrix = function( variable )
- if type( variable ) ~= "string" then error( "Type string expected", 2 ) end
-
- return string.match( variable, "float[2-4]x[2-4]" ) == variable
+ if type( variable ) ~= "string" then error( "Type string expected", 2 ) end
+
+ return string.match( variable, "float[2-4]x[2-4]" ) == variable
end
local IsMatrix = Language.IsMatrix
Language.GetMatrixSize = function( matrix )
- assert( IsMatrix( matrix ) )
- local row, column = string.match( matrix, "(%d)x(%d)" )
+ assert( IsMatrix( matrix ) )
+ local row, column = string.match( matrix, "(%d)x(%d)" )
- return tonumber( row ), tonumber( column )
+ return tonumber( row ), tonumber( column )
end
local GetMatrixSize = Language.GetMatrixSize
Language.GetVectorSize = function( vector )
- return tonumber( string.sub( string.reverse( vector ), 1, 1 ) ) or 1;
+ return tonumber( string.sub( string.reverse( vector ), 1, 1 ) ) or 1;
end
local GetVectorSize = Language.GetVectorSize
Language.IsValidMultiplication = function( a, b )
- if a == b then
- return true
- end
-
- if IsMatrix( a ) then
- local row, column = GetMatrixSize( a )
- local vector_size = GetVectorSize( b )
-
- return row == vector_size;
- else
- assert( IsMatrix( b ) )
-
- local row, column = GetMatrixSize( b )
- local vector_size = GetVectorSize( a )
-
- return column == vector_size;
-
- end
+ if a == b then
+ return true
+ end
+
+ if IsMatrix( a ) then
+ local row, column = GetMatrixSize( a )
+ local vector_size = GetVectorSize( b )
+
+ return row == vector_size;
+ else
+ assert( IsMatrix( b ) )
+
+ local row, column = GetMatrixSize( b )
+ local vector_size = GetVectorSize( a )
+
+ return column == vector_size;
+
+ end
end
local IsValidMultiplication = Language.IsValidMultiplication
Language.MultiplyVectorMatrix = function( a, b )
- assert( IsMatrix( a.type ) ~= IsMatrix( b.type ) )
-
- local result = { node="Operation", operation="mul", arguments={a,b} }
-
- if IsMatrix( a.type ) then
- local row, column = GetMatrixSize( a.type )
- local vector_size = GetVectorSize( b.type )
-
- result.type = "float" .. column
- else
- local row, column = GetMatrixSize( b.type )
- local vector_size = GetVectorSize( a.type )
-
- result.type = "float" .. row
- end
-
- Language.AttachVectorMetatable( result )
- return result;
+ assert( IsMatrix( a.type ) ~= IsMatrix( b.type ) )
+
+ local result = { node="Operation", operation="mul", arguments={a,b} }
+
+ if IsMatrix( a.type ) then
+ local row, column = GetMatrixSize( a.type )
+ local vector_size = GetVectorSize( b.type )
+
+ result.type = "float" .. column
+ else
+ local row, column = GetMatrixSize( b.type )
+ local vector_size = GetVectorSize( a.type )
+
+ result.type = "float" .. row
+ end
+
+ Language.AttachVectorMetatable( result )
+ return result;
end
Language.IsValidSwizzle = function( swizzle, type )
- local position_swizzle = "xyzw"
- local color_swizzle = "rgba"
- local parameter_count = Language.GetVectorSize( type );
-
- parameter_count = parameter_count or 1;
-
- return
- ( string.match( swizzle, "[" ..string.sub( position_swizzle, 1, parameter_count ) .. "]*" ) == swizzle )
- or ( string.match( swizzle, "[" .. string.sub( color_swizzle, 1, parameter_count ) .. "]*" ) == swizzle )
+ local position_swizzle = "xyzw"
+ local color_swizzle = "rgba"
+ local parameter_count = Language.GetVectorSize( type );
+
+ parameter_count = parameter_count or 1;
+
+ return
+ ( string.match( swizzle, "[" ..string.sub( position_swizzle, 1, parameter_count ) .. "]*" ) == swizzle )
+ or ( string.match( swizzle, "[" .. string.sub( color_swizzle, 1, parameter_count ) .. "]*" ) == swizzle )
end
Language.VectorMetatable = {
- __add = function( a, b )
- if a.type ~= b.type then
- error( "Can't add two vector of different size", 2 )
- end
- local result = { type = a.type, node=="Operation", operation="add", arguments={a,b} }
- setmetatable( result, Language.VectorMetatable )
- return result
- end,
-
- __mul = function( a, b )
-
- if not( IsNumber(a) or IsNumber(b) or IsValidMultiplication( a.type, b.type ) ) then
- error( "Mismatch in size, multiplication parameters don't match", 2 );
- end
-
- local result
-
- if not IsNumber( a ) and not IsNumber( b ) and ( IsMatrix( a.type ) or IsMatrix( b.type ) ) then
- result = Language.MultiplyVectorMatrix( a, b )
- else
- result = { type = ( IsNumber(a) and b.type ) or a.type, node="Operation", operation="mul", arguments={a,b} }
- end
- setmetatable( result, Language.VectorMetatable )
- return result
- end,
-
- __newindex = function( table, key, value )
- error( "No support for swizzled assignment yet", 2 )
- end,
-
- __index = function( vector, key )
-
- if not Language.IsValidSwizzle( key, vector.type ) then
- error( "Invalid swizzle", 2 );
- end
-
- local result = { type = "float"..tonumber( string.len(key) ), node="Swizzle", arguments={ vector, key } }
- setmetatable( result, Language.VectorMetatable )
- return result
- end
-
+ __add = function( a, b )
+ if a.type ~= b.type then
+ error( "Can't add two vector of different size", 2 )
+ end
+ local result = { type = a.type, node=="Operation", operation="add", arguments={a,b} }
+ setmetatable( result, Language.VectorMetatable )
+ return result
+ end,
+
+ __mul = function( a, b )
+
+ if not( IsNumber(a) or IsNumber(b) or IsValidMultiplication( a.type, b.type ) ) then
+ error( "Mismatch in size, multiplication parameters don't match", 2 );
+ end
+
+ local result
+
+ if not IsNumber( a ) and not IsNumber( b ) and ( IsMatrix( a.type ) or IsMatrix( b.type ) ) then
+ result = Language.MultiplyVectorMatrix( a, b )
+ else
+ result = { type = ( IsNumber(a) and b.type ) or a.type, node="Operation", operation="mul", arguments={a,b} }
+ end
+ setmetatable( result, Language.VectorMetatable )
+ return result
+ end,
+
+ __newindex = function( table, key, value )
+ error( "No support for swizzled assignment yet", 2 )
+ end,
+
+ __index = function( vector, key )
+
+ if not Language.IsValidSwizzle( key, vector.type ) then
+ error( "Invalid swizzle", 2 );
+ end
+
+ local result = { type = "float"..tonumber( string.len(key) ), node="Swizzle", arguments={ vector, key } }
+ setmetatable( result, Language.VectorMetatable )
+ return result
+ end
+
}
Language.MatrixMetatable = {
- __add = function( a, b )
- if a.type ~= b.type then
- error( "Can't add two matrix of different size", 2 )
- end
- local result = { type = a.type, node=="Operation", operation="add", arguments={a,b} }
- setmetatable( result, Language.MatrixMetatable )
- return result
- end,
-
- __mul = function( a, b )
-
- if not( IsNumber(a) or IsNumber(b) or IsValidMultiplication( a.type, b.type ) ) then
- error( "Mismatch in size, multiplication parameters don't match", 2 );
- end
-
- local result
-
- if not IsNumber( a ) and not IsNumber( b ) and ( IsVector( a.type ) or IsVector( b.type ) ) then
- result = Language.MultiplyVectorMatrix( a, b )
- else
- result = { type = ( IsNumber(a) and b.type ) or a.type, node="Operation", operation="mul", arguments={a,b} }
- setmetatable( result, Language.MatrixMetatable )
- end
- return result
- end,
-
- __newindex = function( table, key, value )
- error( "No support for swizzled assignment yet", 2 )
- end,
-
- __index = function( vector, key )
-
- if not IsNumber( key ) or key < 0 or key > 3 then
- error( "Invalid array index", 2 );
- end
-
- local row, column = GetMatrixSize( vector )
- local result = { type = "float".. row, node="ArrayIndex", arguments={ vector, key } }
- setmetatable( result, Language.VectorMetatable )
- return result
- end
-
+ __add = function( a, b )
+ if a.type ~= b.type then
+ error( "Can't add two matrix of different size", 2 )
+ end
+ local result = { type = a.type, node=="Operation", operation="add", arguments={a,b} }
+ setmetatable( result, Language.MatrixMetatable )
+ return result
+ end,
+
+ __mul = function( a, b )
+
+ if not( IsNumber(a) or IsNumber(b) or IsValidMultiplication( a.type, b.type ) ) then
+ error( "Mismatch in size, multiplication parameters don't match", 2 );
+ end
+
+ local result
+
+ if not IsNumber( a ) and not IsNumber( b ) and ( IsVector( a.type ) or IsVector( b.type ) ) then
+ result = Language.MultiplyVectorMatrix( a, b )
+ else
+ result = { type = ( IsNumber(a) and b.type ) or a.type, node="Operation", operation="mul", arguments={a,b} }
+ setmetatable( result, Language.MatrixMetatable )
+ end
+ return result
+ end,
+
+ __newindex = function( table, key, value )
+ error( "No support for swizzled assignment yet", 2 )
+ end,
+
+ __index = function( vector, key )
+
+ if not IsNumber( key ) or key < 0 or key > 3 then
+ error( "Invalid array index", 2 );
+ end
+
+ local row, column = GetMatrixSize( vector )
+ local result = { type = "float".. row, node="ArrayIndex", arguments={ vector, key } }
+ setmetatable( result, Language.VectorMetatable )
+ return result
+ end
+
}
Language.DefineVectorType = function( type, count )
- local name
-
- if count == 1 then
- name = type
- else
- name = type .. count
- end
-
- _G[ name ] =
- function( ... )
- local arguments = {...}
- local parameter_count = 0
-
- for _,arg in ipairs( arguments ) do
- if IsNumber( arg ) then
- parameter_count = parameter_count + 1
- elseif IsVector( arg.type ) then
- parameter_count = parameter_count + GetVectorSize( arg.type )
- else
- error( "Wrong argument to constructor " .. name .. ": only vector and number are supported" , 2 )
- end
- end
-
- if parameter_count ~= count then
- error( "Wrong argument count, expect " .. count .. " got " .. parameter_count, 2 )
- end
-
- local var = { type = name, node = "Constructor", value={...} }
-
- Language.AttachVectorMetatable( var )
-
- return var;
- end
-
- return var;
+ local name
+
+ if count == 1 then
+ name = type
+ else
+ name = type .. count
+ end
+
+ _G[ name ] =
+ function( ... )
+ local arguments = {...}
+ local parameter_count = 0
+
+ for _,arg in ipairs( arguments ) do
+ if IsNumber( arg ) then
+ parameter_count = parameter_count + 1
+ elseif IsVector( arg.type ) then
+ parameter_count = parameter_count + GetVectorSize( arg.type )
+ else
+ error( "Wrong argument to constructor " .. name .. ": only vector and number are supported" , 2 )
+ end
+ end
+
+ if parameter_count ~= count then
+ error( "Wrong argument count, expect " .. count .. " got " .. parameter_count, 2 )
+ end
+
+ local var = { type = name, node = "Constructor", value={...} }
+
+ Language.AttachVectorMetatable( var )
+
+ return var;
+ end
+
+ return var;
end
Language.DefineMatrixType = function( type, row, column )
- local name
-
- assert( row ~= 1 and column ~= 1 )
-
- name = type .. row .. "x" ..column
-
- _G[ name ] =
- function( ... )
- if #{...} ~= count then
- error( "Wrong argument count, expect " .. ( row * column ) .. " got " .. #{...}, 2 )
- end
-
- local var = { type = name, node = "Constructor", value={...} }
-
- Language.AttachMatrixMetatable( var )
-
- return var;
- end
-
- return var;
+ local name
+
+ assert( row ~= 1 and column ~= 1 )
+
+ name = type .. row .. "x" ..column
+
+ _G[ name ] =
+ function( ... )
+ if #{...} ~= count then
+ error( "Wrong argument count, expect " .. ( row * column ) .. " got " .. #{...}, 2 )
+ end
+
+ local var = { type = name, node = "Constructor", value={...} }
+
+ Language.AttachMatrixMetatable( var )
+
+ return var;
+ end
+
+ return var;
end
@@ -264,19 +264,19 @@ Language.DefineVectorType( "float", 4, 3 )
Language.DefineVectorType( "float", 4, 4 )
Language.AttachVectorMetatable = function( variable )
-
- assert( variable.type == "float" or variable.type == "float2" or variable.type == "float3" or variable.type == "float4" );
-
- variable.node = variable.node or "Variable"
- setmetatable( variable, Language.VectorMetatable );
+
+ assert( variable.type == "float" or variable.type == "float2" or variable.type == "float3" or variable.type == "float4" );
+
+ variable.node = variable.node or "Variable"
+ setmetatable( variable, Language.VectorMetatable );
end
Language.AttachMatrixMetatable = function( variable )
-
- assert( IsMatrix( variable.type ) );
-
- variable.node = variable.node or "Variable"
- setmetatable( variable, Language.MatrixMetatable );
+
+ assert( IsMatrix( variable.type ) );
+
+ variable.node = variable.node or "Variable"
+ setmetatable( variable, Language.MatrixMetatable );
end
View
185 src/printer/hlsl_printer.lua
@@ -2,127 +2,148 @@ HLSL = HLSL or {}
HLSL.GetDeclaration = function( declaration )
- return declaration.variable_type .. " " .. declaration.name .. ";\n"
+ return declaration.variable_type .. " " .. declaration.name .. ";\n"
end
HLSL.GetCallFunction = function( call_function )
- local code
-
- code = call_function.variable .. " = " .. call_function.name .. "( "
-
- for i,v in ipairs( call_function.arguments ) do
-
- if i ~= 1 then
- code = code .. ", "
- end
-
- code = code .. v
- end
-
- code = code .. " );\n"
-
- return code
+ local code
+
+ code = call_function.variable .. " = " .. call_function.name .. "( "
+
+ for i,v in ipairs( call_function.arguments ) do
+
+ if i ~= 1 then
+ code = code .. ", "
+ end
+
+ if type(v) == "table" and v.type == "Texture" then
+ code = code .. v.name .. "Sampler"
+ else
+ code = code .. v
+ end
+ end
+
+ code = code .. " );\n"
+
+ return code
end
HLSL.GetSwizzle = function( swizzle )
-
- return swizzle.variable .. " = " .. swizzle.arguments[ 1 ] .. "." .. swizzle.arguments[ 2 ] .. ";\n"
+
+ return swizzle.variable .. " = " .. swizzle.arguments[ 1 ] .. "." .. swizzle.arguments[ 2 ] .. ";\n"
end
HLSL.OperationTable = {
- mul = "*",
- add = "+",
- sub = "-",
- div = "/"
+ mul = "*",
+ add = "+",
+ sub = "-",
+ div = "/"
}
HLSL.GetOperation = function( operation )
-
- assert( #( operation.arguments ) == 2 )
-
- return operation.variable .. " = " .. operation.arguments[ 1 ] .. " " .. HLSL.OperationTable[ operation.operation ] .. " " .. operation.arguments[ 2 ] .. ";\n";
+
+ assert( #( operation.arguments ) == 2 )
+
+ return operation.variable .. " = " .. operation.arguments[ 1 ] .. " " .. HLSL.OperationTable[ operation.operation ] .. " " .. operation.arguments[ 2 ] .. ";\n";
end
HLSL.GetAssignment = function( assignment )
- if type( assignment.value ) == "table" then
- return assignment.variable .. " = " .. assignment.variable_type .. "(" .. table.concat( assignment.value, "," ) .. ");\n"
- else
- return assignment.variable .. " = " .. assignment.value .. ";\n"
- end
+ if type( assignment.value ) == "table" then
+ return assignment.variable .. " = " .. assignment.variable_type .. "(" .. table.concat( assignment.value, "," ) .. ");\n"
+ else
+ return assignment.variable .. " = " .. assignment.value .. ";\n"
+ end
end
HLSL.GenerateStructure = function( prefix, input_definition, function_name )
- ShaderPrint( "struct " .. prefix .. "_" .. function_name .. "\n{\n" )
-
- for name, description in pairs( input_definition ) do
- ShaderPrint( 1, description.type .. " " .. name .. " : " .. description.semantic .. ";\n" )
- end
-
- ShaderPrint( "\n};\n" )
+ ShaderPrint( "struct " .. prefix .. "_" .. function_name .. "\n{\n" )
+
+ for name, description in pairs( input_definition ) do
+ ShaderPrint( 1, description.type .. " " .. name .. " : " .. description.semantic .. ";\n" )
+ end
+
+ ShaderPrint( "\n};\n" )
end
HLSL.GenerateConstants = function( constants )
- for constant, value in pairs( constants ) do
- ShaderPrint( value.type .. " " .. constant ..";\n" );
- end
+ for constant, value in pairs( constants ) do
+ ShaderPrint( value.type .. " " .. constant ..";\n" );
+ end
+end
+
+HLSL.SamplerFromTexture = {
+ texture2D = "sampler2D"
+}
+
+HLSL.GenerateTextures = function( textures )
+
+ for texture, value in pairs( textures ) do
+ ShaderPrint( value.type .. " " .. texture ..";\n" );
+ ShaderPrint( HLSL.SamplerFromTexture[ value.type ] .. " " .. texture .. "Sampler = sampler_state\n{\n" )
+ ShaderPrint( 1, "Texture = <" .. texture .. ">;\n" )
+ ShaderPrint( "};\n" )
+ end
end
HLSL.GetConstructor = function( constructor )
- local code = constructor.variable .. " = " .. constructor.constructor_type .. " ( "
-
- for _, value in ipairs( constructor.arguments ) do
-
- if _ ~= 1 then
- code = code .. ", "
- end
-
- code = code .. value
- end
-
- code = code .. " );\n"
-
- return code;
+ local code = constructor.variable .. " = " .. constructor.constructor_type .. " ( "
+
+ for _, value in ipairs( constructor.arguments ) do
+
+ if _ ~= 1 then
+ code = code .. ", "
+ end
+
+ code = code .. value
+ end
+
+ code = code .. " );\n"
+
+ return code;
end
HLSL.PrintFunctionPrologue = function( representation, function_name )
-
- HLSL.GenerateConstants( representation.constant )
- HLSL.GenerateStructure( "INPUT", representation.input, function_name )
- HLSL.GenerateStructure( "OUTPUT", representation.output, function_name )
-
- ShaderPrint( "OUTPUT_" .. function_name .. " " .. function_name .. " ( INPUT_" .. function_name .. " input )\n{\n" )
- ShaderPrint( 1, "OUTPUT_" .. function_name .. " output;\n" )
+
+ HLSL.GenerateConstants( representation.constant )
+ HLSL.GenerateTextures( representation.texture )
+ HLSL.GenerateStructure( "INPUT", representation.input, function_name )
+ HLSL.GenerateStructure( "OUTPUT", representation.output, function_name )
+
+ ShaderPrint( "OUTPUT_" .. function_name .. " " .. function_name .. " ( INPUT_" .. function_name .. " input )\n{\n" )
+ ShaderPrint( 1, "OUTPUT_" .. function_name .. " output;\n" )
end
HLSL.PrintFunctionEpilogue = function( representation, function_name )
- ShaderPrint( 1, "return output;\n}\n\n" )
+ ShaderPrint( 1, "return output;\n}\n\n" )
end
HLSL.PrintCode = function ( representation )
- for i,v in ipairs( representation.code ) do
-
- if HLSL[ "Get" .. v.type ] == nil then
- error( "No printer for type " .. v.type .. " in HLSL printer", 1 )
- end
-
- ShaderPrint( 1, HLSL[ "Get" .. v.type ]( v ) )
- end
+ for i,v in ipairs( representation.code ) do
+
+ if HLSL[ "Get" .. v.type ] == nil then
+ error( "No printer for type " .. v.type .. " in HLSL printer", 1 )
+ end
+
+ ShaderPrint( 1, HLSL[ "Get" .. v.type ]( v ) )
+ end
end
HLSL.PrintTechnique = function( technique_name, vertex_shader_name, pixel_shader_name )
-
- ShaderPrint( "technique " .. technique_name .. "\n{" )
- ShaderPrint( 1, "pass P0\n" )
- ShaderPrint( 1, "{\n" )
- ShaderPrint( 2, "VertexShader = compile vs_3_0 " .. vertex_shader_name .. "();\n" )
- ShaderPrint( 2, "PixelShader = compile ps_3_0 " .. pixel_shader_name .. "();\n" )
- ShaderPrint( 1, "}" )
- ShaderPrint( "\n}" )
-
-end
+
+ ShaderPrint( "technique " .. technique_name .. "\n{" )
+ ShaderPrint( 1, "pass P0\n" )
+ ShaderPrint( 1, "{\n" )
+ ShaderPrint( 2, "VertexShader = compile vs_3_0 " .. vertex_shader_name .. "();\n" )
+ ShaderPrint( 2, "PixelShader = compile ps_3_0 " .. pixel_shader_name .. "();\n" )
+ ShaderPrint( 1, "}" )
+ ShaderPrint( "\n}" )
+
+end
+
+RegisterPrinter( HLSL, "hlsl", "fx" )
View
48 src/printer/printer_manager.lua
@@ -0,0 +1,48 @@
+local PrinterTable = {}
+local SelectedPrinter
+
+function RegisterPrinter( printer, name, file_extension )
+
+ PrinterTable[ name ] = { printer = printer, extension = file_extension };
+end
+
+
+function GetSelectedPrinter()
+ if SelectedPrinter == nil then
+ error( "No printer selected" )
+ end
+ return SelectedPrinter
+end
+
+function SelectPrinter( filename, override_name )
+
+ if override_name ~= nil then
+ if PrinterTable[ override_name ] == nil then
+ error( "Invalid language name" )
+ end
+
+ SelectedPrinter = PrinterTable[ override_name ].printer
+ return
+ end
+
+ if filename == nil then
+ error( "Language should be specified when outputing to the console" )
+ end
+
+ local extension = string.match( filename, "%w%.(%w)" )
+
+ if extension == nil then
+ error( "Unable to extract file extension" );
+ end
+
+ for name, description in pairs( PrinterTable ) do
+
+ if description.extension == extension then
+ SelectedPrinter = description.printer
+ return
+ end
+
+ end
+
+ error( "Unable to detect language from file extension" )
+end
View
30 src/utilities/output.lua
@@ -3,30 +3,30 @@ local stream
local old_print = print
print = function( ... )
- error( "Don't use print", 2 );
+ error( "Don't use print", 2 );
end
function ShaderPrint( ... )
- local argument = {...}
-
- if type( argument[ 1 ] ) == "number" then
- stream:write( string.rep( "\t", argument[1] ) )
- stream:write( argument[ 2 ] )
- else
- stream:write( argument[ 1 ] )
- end
+ local argument = {...}
+
+ if type( argument[ 1 ] ) == "number" then
+ stream:write( string.rep( "\t", argument[1] ) )
+ stream:write( argument[ 2 ] )
+ else
+ stream:write( argument[ 1 ] )
+ end
end
function InitializeOutputPrint()
- stream = io.stdout
+ stream = io.stdout
end
function InitializeOutputFile( file )
- stream, error_message = io.open( file, "w" )
-
- if stream == nil then
- error( "Error while opening file : " .. error_message, 2 )
- end
+ stream, error_message = io.open( file, "w" )
+
+ if stream == nil then
+ error( "Error while opening file : " .. error_message, 2 )
+ end
end

No commit comments for this range

Something went wrong with that request. Please try again.