medfall

A super great game engine
Log | Files | Refs

gen_visitors.lua (1357B)


      1 #! /usr/bin/lua
      2 
      3 assert( arg[ 1 ], "need a file name" )
      4 local f = assert( io.open( arg[ 1 ] ) )
      5 local contents = assert( f:read( "*all" ) )
      6 f:close()
      7 
      8 local output = {
      9 	"/*",
     10 	" * This file was autogenerated by " .. arg[ 0 ] .. " " .. arg[ 1 ],
     11 	" */",
     12 	"",
     13 	"#pragma once",
     14 }
     15 
     16 for struct, members in contents:gmatch( "// AUTOVISITOR%s+struct%s+(%w+)%s+(%b{})" ) do
     17 	members = members:sub( 2, -2 ) -- trim { }
     18 	members = members:gsub( "%b{}", "" )
     19 
     20 	local visitor = {
     21 		"template< typename F >",
     22 		"void visit( " .. struct .. " & obj, F f ) {",
     23 	}
     24 	local const_visitor = {
     25 		"template< typename F >",
     26 		"void visit( const " .. struct .. " & obj, F f ) {",
     27 	}
     28 
     29 	for names in members:gmatch( "\n\t*%w+%s+([%w, ]+)%s*;" ) do
     30 		for name in names:gmatch( "(%w+)" ) do
     31 			table.insert( visitor, "\tvisit( obj." .. name .. ", f );" )
     32 			table.insert( const_visitor, "\tvisit( obj." .. name .. ", f );" )
     33 		end
     34 	end
     35 
     36 	table.insert( visitor, "}" )
     37 	table.insert( const_visitor, "}" )
     38 	table.insert( output, "\n" .. table.concat( visitor, "\n" ) )
     39 	table.insert( output, "\n" .. table.concat( const_visitor, "\n" ) )
     40 end
     41 
     42 print( table.concat( output, "\n" ) )
     43 
     44 local filename = arg[ 1 ]:gsub( "^(.-)%.[^%.]+$", "visitors/%1.h" )
     45 if not contents:find( "#include \"" .. filename .. "\"" ) then
     46 	io.stderr:write( arg[ 1 ] .. " should include " .. filename .. "\n" )
     47 end