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