2020-06-07 23:22:18 +10:00
local preproc = { }
preproc.directives = { }
function preproc . parsewords ( line ) -- string -- table -- Returns a table of words from the string *line*, parsing quotes and escapes.
local rt = { " " }
local escaped , quoted = false , false
for c in line : gmatch ( " . " ) do
if escaped then
rt [ # rt ] = rt [ # rt ] .. c
elseif c == ' " ' or c == " ' " then
quoted = not quoted
elseif c == " \\ " then
escaped = true
elseif c : match ( " %s " ) and not quoted and rt [ # rt ] : len ( ) > 0 then
rt [ # rt + 1 ] = " "
else
rt [ # rt ] = rt [ # rt ] .. c
end
end
return rt
end
function preproc . line ( line ) -- string -- -- Returns either a function - which can be called to get lines until it returns nil - or a string from processing *line* using preprocessor directives.
if line : match ( " ^%-%-# " ) then
local directive , args = line : match ( " ^%-%-#(%S+)%s(.+) " )
print ( directive , args )
local args = preproc.parsewords ( args )
if preproc.directives [ directive ] then
return preproc.directives [ directive ] ( table.unpack ( args ) )
else
error ( " unknown preprocessor directive: " .. directive )
end
else
return line
end
end
function preproc . preproc ( ... ) -- string -- string -- Returns the output from preprocessing the files listed in *...*.
local tA = { ... }
local output = " "
for _ , fname in ipairs ( tA ) do
local f , e = io.open ( fname )
if not f then error ( " unable to open file " .. fname .. " : " .. e ) end
for line in f : lines ( ) do
local r = preproc.line ( line )
if type ( r ) == " function " then
while true do
local rs = r ( )
if not rs then break end
output = output .. rs .. " \n "
end
else
output = output .. r .. " \n "
end
end
end
return output
end
preproc.directives . include = preproc.preproc
2023-08-01 18:17:49 +10:00
function preproc . directives . includelib ( file , name ) -- string string -- string -- Returns a preprocessed inlined library
return string.format ( " package.loaded.%s = (function() \n %s \n end)() " , name , preproc.preproc ( file ) )
end
function preproc . directives . includepkgfile ( package , file )
if ( _OSVERSION or " " ) : sub ( 1 , 7 ) == " PsychOS " then
return preproc.preproc ( string.format ( " /pkg/%s " , file ) )
else
for path in ( os.getenv ( " PSYCHOSPACKAGES " ) or " ../PsychOSPackages " ) : gmatch ( " [^:]+ " ) do
local f = io.open ( string.format ( " %s/%s/%s " , path , package , file ) , " r " )
if f then
f : close ( )
return preproc.preproc ( string.format ( " %s/%s/%s " , path , package , file ) )
end
end
end
error ( string.format ( " unable to locate file %s from package %s " , file , package ) )
end
function preproc . directives . includepkglib ( package , file , name ) -- string string -- string -- Returns a preprocessed inlined library
return string.format ( " package.loaded.%s = (function() \n %s \n end)() " , name , preproc.directives . includepkgfile ( package , file ) )
end
--[[
function preproc . directives . includepkglib ( package , file , name )
if ( _OSVERSION or " " ) : sub ( 1 , 7 ) == " PsychOS " then
return preproc.directives . includelib ( string.format ( " /pkg/%s " , file ) , name )
else
for path in ( os.getenv ( " PSYCHOSPACKAGES " ) or " ../PsychOSPackages " ) : gmatch ( " [^:]+ " ) do
print ( string.format ( " %s/%s/%s " , path , package , file ) )
local f = io.open ( string.format ( " %s/%s/%s " , path , package , file ) , " r " )
if f then
f : close ( )
return preproc.directives . includelib ( string.format ( " %s/%s/%s " , path , package , file ) , name )
end
end
end
error ( string.format ( " unable to locate library %s from package %s " , name , package ) )
end
] ]
2020-06-07 23:22:18 +10:00
return setmetatable ( preproc , { __call = function ( _ , ... )
local tA = { ... }
local out = table.remove ( tA , # tA )
local f , e = io.open ( out , " wb " )
if not f then error ( " unable to open file " .. out .. " : " .. e ) end
f : write ( preproc.preproc ( table.unpack ( tA ) ) )
f : close ( )
end } )