2021-01-12 23:11:00 +11:00
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
--
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
--
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
-- THIS SOFTWARE.
2018-04-25 10:04:34 +10:00
2020-03-30 08:43:38 +11:00
-- This library helps in crunching down the installer a bit further.
2018-04-25 10:04:34 +10:00
local sequences = {
{ " \n " , " " } ,
{ " " , " " } ,
{ " # " , " # " } ,
{ " # " , " # " } ,
{ " , " , " , " } ,
{ " , " , " , " } ,
{ " ( " , " ( " } ,
{ " ( " , " ( " } ,
{ " ) " , " ) " } ,
{ " ) " , " ) " } ,
2020-03-31 22:41:08 +11:00
{ " { " , " { " } ,
{ " { " , " { " } ,
{ " } " , " } " } ,
{ " } " , " } " } ,
2018-04-25 10:04:34 +10:00
{ " < " , " < " } ,
{ " < " , " < " } ,
{ " > " , " > " } ,
{ " > " , " > " } ,
{ " * " , " * " } ,
{ " * " , " * " } ,
{ " ~ " , " ~ " } ,
{ " ~ " , " ~ " } ,
{ " / " , " / " } ,
{ " / " , " / " } ,
{ " % " , " % " } ,
{ " % " , " % " } ,
{ " = " , " = " } ,
{ " = " , " = " } ,
{ " - " , " - " } ,
{ " - " , " - " } ,
{ " + " , " + " } ,
{ " + " , " + " } ,
{ " .. " , " .. " } ,
{ " .. " , " .. " } ,
{ " \" \" " , " \" \" " } ,
{ " =0 t " , " =0t " } ,
{ " >0 t " , " >0t " } ,
{ " >1 t " , " >1t " } ,
{ " =1 w " , " =1w " } ,
{ " =380 l " , " =380l " } ,
{ " =127 t " , " =127t " } ,
2018-06-10 09:06:12 +10:00
{ " <128 t " , " <128t " } ,
2018-04-25 10:04:34 +10:00
{ " =128 t " , " =128t " } ,
{ " >255 t " , " >255t " } ,
{ " =512 t " , " =512t " }
}
local function pass ( buffer )
local ob = " "
local smode = false
while # buffer > 0 do
if not smode then
local ds = true
while ds do
ds = false
for _ , v in ipairs ( sequences ) do
if buffer : sub ( 1 , # ( v [ 1 ] ) ) == v [ 1 ] then
buffer = v [ 2 ] .. buffer : sub ( # ( v [ 1 ] ) + 1 )
ds = true
end
end
end
end
local ch = buffer : sub ( 1 , 1 )
buffer = buffer : sub ( 2 )
ob = ob .. ch
if ch == " \" " then
smode = not smode
end
end
return ob
end
2020-03-30 08:43:38 +11:00
2020-03-31 21:59:58 +11:00
-- Context creation --
return function ( )
local forwardSymTab = { }
local reverseSymTab = { }
local temporaryPool = { }
2020-03-31 22:41:08 +11:00
local stackFrames = { }
2020-03-31 23:38:49 +11:00
local log = { }
2020-03-31 21:59:58 +11:00
local possible = { }
for i = 1 , 52 do
possible [ i ] = ( " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ " ) : sub ( i , i )
end
local function allocate ( reason )
for _ , v in pairs ( possible ) do
if not reverseSymTab [ v ] then
reverseSymTab [ v ] = reason
return v
end
2020-03-30 08:43:38 +11:00
end
end
2020-03-31 21:59:58 +11:00
2020-03-31 23:38:49 +11:00
local function allocTmp ( id )
assert ( not forwardSymTab [ id ] , " var already exists: " .. id )
local val = table.remove ( temporaryPool , 1 )
if not val then val = allocate ( " temporary " ) end
forwardSymTab [ id ] = val
table.insert ( log , " allocTmp " .. id .. " -> " .. val )
return val
end
2020-03-31 22:41:08 +11:00
local lexCrunch = { }
function lexCrunch . dump ( file )
file : write ( " forward table: \n " )
for k , v in pairs ( forwardSymTab ) do
file : write ( k .. " -> " .. v .. " \n " )
end
file : write ( " reverse table (where differing): \n " )
for k , v in pairs ( reverseSymTab ) do
if forwardSymTab [ v ] ~= k then
file : write ( v .. " -> " .. k .. " \n " )
end
end
2020-03-31 23:38:49 +11:00
file : write ( " log: \n " )
for k , v in ipairs ( log ) do
file : write ( v .. " \n " )
end
2020-03-31 22:41:08 +11:00
end
function lexCrunch . process ( op , defines )
2020-03-31 21:59:58 +11:00
-- symbol replacement
2020-03-31 22:41:08 +11:00
op = op : gsub ( " %$[%$a-z%{%}%|A-Z0-9]* " , function ( str )
2020-03-31 21:59:58 +11:00
if str : sub ( 2 , 2 ) == " $ " then
-- defines
assert ( defines [ str ] , " no define " .. str )
return defines [ str ]
2020-03-31 22:41:08 +11:00
end
2020-04-01 03:52:24 +11:00
local com = { }
for v in str : sub ( 2 ) : gmatch ( " [^%|]* " ) do
table.insert ( com , v )
end
if com [ 1 ] == " L " then
assert ( # com == 2 )
local id = " $ " .. com [ 2 ]
2020-03-31 23:38:49 +11:00
assert ( stackFrames [ 1 ] , " allocation of " .. id .. " outside of stack frame " )
2020-03-31 22:41:08 +11:00
table.insert ( stackFrames [ 1 ] , id )
2020-03-31 23:38:49 +11:00
return allocTmp ( id )
2020-04-01 03:52:24 +11:00
elseif com [ 1 ] == " { " then
assert ( # com == 1 )
2020-03-31 22:41:08 +11:00
table.insert ( stackFrames , 1 , { } )
return " "
2020-04-01 03:52:24 +11:00
elseif com [ 1 ] == " } " then
assert ( # com == 1 )
2020-03-31 22:41:08 +11:00
for _ , id in ipairs ( table.remove ( stackFrames , 1 ) ) do
table.insert ( temporaryPool , forwardSymTab [ id ] )
forwardSymTab [ id ] = nil
end
return " "
2020-03-31 21:59:58 +11:00
else
2020-04-01 03:52:24 +11:00
assert ( # com == 1 )
local id = " $ " .. com [ 1 ]
2020-03-31 21:59:58 +11:00
-- normal handling
2020-03-31 22:41:08 +11:00
if forwardSymTab [ id ] then
return forwardSymTab [ id ]
2020-03-31 21:59:58 +11:00
end
2020-03-31 22:41:08 +11:00
local v = allocate ( id )
forwardSymTab [ id ] = v
2020-03-31 21:59:58 +11:00
return v
end
end )
-- comment removal
while true do
local np = op : gsub ( " %-%-[^ \n ]* \n " , " " )
np = np : gsub ( " %-%-[^ \n ]*$ " , " " )
if np == op then
break
end
op = np
end
-- stripping
while true do
local np = pass ( op )
if np == op then
return np
end
op = np
2020-03-30 08:43:38 +11:00
end
2020-03-31 21:59:58 +11:00
return op
2018-04-25 10:04:34 +10:00
end
2020-03-31 22:41:08 +11:00
return lexCrunch
2018-04-25 10:04:34 +10:00
end