Skip to content

Instantly share code, notes, and snippets.

@GamePlayer-8
Created June 27, 2023 12:17
Show Gist options
  • Save GamePlayer-8/da42c5eccf031c9453b418359ff0cb2f to your computer and use it in GitHub Desktop.
Save GamePlayer-8/da42c5eccf031c9453b418359ff0cb2f to your computer and use it in GitHub Desktop.
Abandoned Lua-made bison + flex builtin compiler for CodeQ syntax
--[[
Developed by @GamePlayer-8
on
AERO KIANIT LICENSE 1.0
]]--
--[[ Abanboned - Replaced by C version ]]--
function file_exists(name)
local f=io.open(name,"r")
if f~=nil then io.close(f) return true else return false end
end
function lines_from(file)
if not file_exists(file) then return {} end
local lines = {}
for line in io.lines(file) do
lines[#lines + 1] = line
end
return lines
end
if #(arg) < 1 then
print('[CodeQ Run] Missing file.')
return
end
function string.begins_with(String,Start)
return string.sub(String,1,string.len(Start))==Start
end
flags = {}
file_dir = ""
file_flags = ""
state = 0
for k in ipairs(arg) do
if state == 0 then
if string.begins_with(arg[k], '--') then
flags[#(flags)] = arg[k]
else
state = 1
end
end
if state == 1 then
file_dir = arg[k]
state = 2
end
if state == 2 then
file_flags = file_flags .. "'" .. arg[k] .. "', \n\t"
end
end
if #(flags) == 0 then
flags = {'--run'}
end
if not file_exists(file_dir) then
print('[CodeQ Run] File \'' .. file_dir .. '\' not found.')
return
end
function script_path()
local str = debug.getinfo(2, "S").source:sub(2)
return str:match("(.*/)")
end
function struct_lines(file)
local liner = {}
local is_string = 0
local line_block = ''
local continue = 0
local lastly = ''
for l in io.lines(file) do
for i = 1, #l do
local ll = string.sub(l, i, i)
if is_string == 0 then
if ll == ';' then
liner[#liner + 1] = line_block
line_block = ''
elseif ll == '[' then
continue = continue + 1
line_block = line_block .. ll
elseif ll == ']' then
continue = continue - 1
line_block = line_block .. ll
elseif ll == '\t' then
else
line_block = line_block .. ll
end
elseif not lastly == '\\' then
if ll == '\'' then
if is_string == 1 then
is_string = 0
elseif is_string == 0 then
is_string = 1
end
line_block = line_block .. ll
elseif ll == '"' then
if is_string == 2 then
is_string = 0
elseif is_string == 0 then
is_string = 2
end
line_block = line_block .. ll
else
line_block = line_block .. ll
end
else
line_block = line_block .. ll
end
lastly = ll
end
if continue == 0 then
liner[#liner + 1] = line_block
line_block = ''
end
end
if not line_block == '' then
liner[#liner + 1] = line_block
end
return liner
end
function isempty(s)
return s == nil or s == ''
end
function line_loader(line)
local struct = {}
local block = ''
local is_string = 0
local lastly = ''
for i = 1, #line do
local letter = string.sub(line, i, i)
if is_string == 0 then
if letter == ' ' then
if not isempty(block) then
struct[#struct + 1] = block
end
block = ''
elseif letter == '[' then
if not isempty(block) then
struct[#struct + 1] = block
end
struct[#struct + 1] = '['
block = ''
elseif letter == ']' then
if not isempty(block) then
struct[#struct + 1] = block
end
struct[#struct + 1] = ']'
block = ''
else
block = block .. letter
end
elseif not lastly == '\\' then
if letter == '\'' then
if is_string == 0 then
is_string = 1
elseif is_string == 1 then
is_string = 0
end
if not isempty(block) then
struct[#struct + 1] = block
end
block = ''
struct[#struct + 1] = '\''
elseif letter == '"' then
if is_string == 0 then
is_string = 2
elseif is_string == 2 then
is_string = 0
end
if not isempty(block) then
struct[#struct + 1] = block
end
block = ''
struct[#struct + 1] = '"'
else
block = block .. letter
end
else
block = block .. letter
end
lastly = letter
end
if not isempty(block) then
struct[#struct + 1] = block
end
return struct
end
function replacer(input_string, letter_in, letter_tgt)
local string_out = ''
for i = 1, #input_string do
local letter = string.sub(input_string, i, i)
if letter == letter_in then
string_out = string_out .. letter_tgt
else
string_out = string_out .. letter
end
end
return string_out
end
function split_strings(struct_array)
local struct = {}
local li = ''
local is_str = false
for h in ipairs(struct_array) do
local o_obj = struct_array[h]
for y = 1, #o_obj do
local lu = string.sub(o_obj, y, y)
if lu == '\'' then
if li == '\\' then
else
is_str = not is_str
end
end
li = lu
end
if is_str then
struct[#struct] = struct[#struct] .. ' ' .. o_obj
else
struct[#struct + 1] = o_obj
end
end
return struct
end
function intepreter(struct_array)
local struct = {}
local is_string = 0
local is_function = ''
local is_array = 0
local limit = 0
for k in ipairs(struct_array) do
local struct_data = struct_array[k]
if struct_data == '!catch' then
local f_path = struct_array[2]
local is_global = true
for x = 1, #f_path do
local x = f_path[k]
if x == '/' then
is_global = false
break
end
end
if is_global then
f_path = '~/.codeq/libs/' .. f_path
end
f_path = f_path .. '.cq'
if file_exists(struct_array[2] .. '.lua') then
print('[CodeQ WARN]: Library <' .. struct_array[2] .. '> already compiled.')
struct[#struct + 1] = 'dofile(\'' .. struct_array[2] .. '.lua\')'
limit = 2
break
end
local g_f = io.open(struct_array[2] .. '.lua', 'w')
g_f:write(get_lib(struct_array[2]))
g_f:close()
struct[#struct + 1] = 'dofile(\'' .. struct_array[2] .. '.lua\')'
limit = 2
break
elseif struct_data == '!jump' then
struct[#struct + 1] = 'goto ' .. struct_array[2]
limit = 2
break
elseif struct_data == '!section' then
struct[#struct + 1] = ' :: ' .. struct_array[2] .. ' :: '
limit = 2
break
elseif struct_data == '!exit' then
struct[#struct + 1] = 'os.exit()'
limit = 1
break
elseif string.sub(struct_data, 1, 1) == '#' then
local c_string = '--[[ '
for x in ipairs(struct_array) do
local n_s = struct_array[x]
c_string = c_string .. n_s .. ' '
end
c_string = c_string .. ' ]]--'
struct[#struct + 1] = c_string
limit = #struct
break
elseif string.sub(struct_data, 1, 1) == ':' then
local f_n = string.sub(struct_data, 2, #struct_data)
local str_args = ''
local str_tick = 0
local is_first = true
local is_sry = false
for x in ipairs(struct_array) do
if str_tick == #struct_array - 1 or struct_array[x + 1] == '#' then
break
end
if string.sub(str_args, #str_args, #str_args) == '\'' then
if string.sub(str_args, #str_args - 1, #str_args - 1) == '\\' then
else
is_sry = not is_sry
end
end
if is_first then
is_first = false
else
if not(struct_array[x + 1] == ',' or struct_array[x + 1] == ']') then
if string.sub(str_args, #str_args, #str_args) == ',' then
elseif string.sub(str_args, #str_args, #str_args) == '[' then
elseif string.sub(str_args, #str_args -2, #str_args-1) == '==' then
elseif string.sub(str_args, #str_args -3, #str_args) == 'and ' then
elseif string.sub(str_args, #str_args -2, #str_args) == 'or ' then
elseif string.sub(str_args, #str_args -3, #str_args) == 'not ' then
elseif struct_array[x + 1] == '&&' then
elseif struct_array[x + 1] == '&=' then
elseif struct_array[x + 1] == '&!' then
elseif struct_array[x + 1] == '&?' then
elseif is_sry then
str_args = str_args .. ' '
else
str_args = str_args .. ', '
end
end
end
local c_c = struct_array[x + 1]
if c_c == '&=' then
c_c = ' == '
elseif c_c == '&!' then
c_c = ' not '
elseif c_c == '&?' then
c_c = ' or '
elseif c_c == '&&' then
c_c = ' and '
end
str_args = str_args .. c_c
str_tick = str_tick + 1
end
str_args = replacer(replacer(str_args, '[', '{'), ']', '}')
local end_c = ''
if struct_array[str_tick + 2] == '#' then
local c_string = ' --[[ '
for x in ipairs(struct_array) do
if str_tick - 2 == #struct_array then
break
end
local n_s = struct_array[str_tick + 2]
if n_s == nil then
break
end
c_string = c_string .. n_s .. ' '
str_tick = str_tick + 1
end
c_string = c_string .. ' ]]--'
end_c = c_string
end
struct[#struct + 1] = f_n .. '({' .. str_args .. '})' .. end_c
limit = str_tick + 1
break
else
local str_args = ''
local str_tick = 0
local is_ar = false
local is_ar_first = true
for x in ipairs(struct_array) do
local c_d = struct_array[x]
if c_d == '#' then
break
end
local is_sry = false
if string.sub(c_d, 1, 1) == ':' then
local f_s = string.sub(c_d, 2, #c_d)
local a_args = ''
local t_args = 4
local f_args = true
local is_s = false
for g in ipairs(struct_array) do
if t_args == #struct_array then
break
end
if struct_array[t_args] == '#' then
str_tick = str_tick + t_args - 3
break
end
if f_args then
f_args = false
else
if not is_s then
a_args = a_args .. ', '
else
a_args = a_args .. ' '
end
end
local lv = ''
for h = 1, #struct_array[t_args] do
local lt = string.sub(struct_array[t_args], h, h)
if lt == '\'' then
if lv == '\\' then
else
is_s = not is_s
end
end
lv = lt
end
a_args = a_args .. struct_array[t_args]
t_args = t_args + 1
end
str_args = str_args .. f_s .. '({' .. a_args .. '}) '
break
end
if c_d == '[' and string.sub(str_args, #str_args - 1, #str_args - 1) == '=' then
c_d = '{'
is_ar = true
is_ar_first = true
elseif c_d == ']' and ( string.sub(str_args, #str_args - 1, #str_args - 1) == '{' or is_ar ) then
if string.sub(str_args, #str_args - 1, #str_args - 1) == '{' then
else
str_args = string.sub(str_args, 1, #str_args - 2)
end
c_d = ' }'
is_ar = false
is_ar_first = true
end
if string.sub(c_d, #c_d, #c_d) == '\'' then
if string.sub(c_d, #c_d - 1, #c_d - 1) == '\\' then
else
is_sry = not is_sry
end
end
if is_ar then
if is_ar_first then
str_args = str_args .. c_d .. ' '
is_ar_first = false
else
if is_sry then
str_args = str_args .. c_d .. ' '
else
str_args = str_args .. c_d .. ', '
end
end
else
str_args = str_args .. c_d .. ' '
end
str_tick = str_tick + 1
end
if struct_array[str_tick + 1] == '#' then
str_args = str_args .. ' --[[ # '
local g_f = true
for y in ipairs(struct_array) do
if str_tick + 1 == #struct_array then
break
end
if g_f then
g_f = false
else
str_args = str_args .. ' '
end
str_args = str_args .. struct_array[str_tick + 2]
str_tick = str_tick + 1
end
str_args = str_args .. ' ]]-- '
end
struct[#struct + 1] = str_args
limit = #struct_array
break
end
end
if #struct > limit then
struct[#struct + 1] = ';'
local s_a = 1
for k in ipairs(struct_array) do
local struct_data = struct_array[k]
if s_a > limit then
struct[#struct + 1] = struct_data
end
s_a = s_a + 1
end
end
return struct
end
function rolling_intepreter(struct_array)
local struct = {}
local out = intepreter(struct_array)
local state = 0
local n_struct = {}
for k in ipairs(out) do
local g_d = out[k]
if g_d == ';' then
state = 1
elseif state == 0 then
struct[#struct + 1] = g_d
elseif state == 1 then
n_struct[#n_struct + 1] = g_d
end
end
if #n_struct > 0 then
local out2 = rolling_intepreter(n_struct)
for k in ipairs(out2) do
local g_d = out2[k]
struct[#struct + 1] = g_d
end
end
return struct
end
function get_lib(file_name)
if not file_exists(file_name) then
print('[CodeQ Warn]: Missing file <' .. file_name .. '>.')
return 'print(\'-!- Lib ' .. file_name .. ' missing.\')'
end
local file_out = ''
file_out = file_out .. '--[[ CodeQ to Lua by @GamePlayer-8 ]]--'
local lx = struct_lines(file_name)
for xx in pairs(lx) do
local xy = lx[xx]
local ox = rolling_intepreter(line_loader(xy))
for k in ipairs(ox) do
local g_d = ox[k]
file_out = file_out .. g_d
end
file_out = file_out .. '\n'
end
return file_out .. '\n'
end
function get_script(file_name, args)
if not file_exists(file_name) then
print('[CodeQ Warn]: Missing file <' .. file_name .. '>.')
return 'print(\'-!- Script ' .. file_name .. ' missing.\')'
end
local file_out = ''
file_out = file_out .. '--[[ CodeQ to Lua by @GamePlayer-8 ]]--'
file_out = file_out .. '\n\nargs = {\n'
file_out = file_out .. '\t' .. args .. '\n'
file_out = file_out .. '}\nfilepath = \'' .. file_name .. '\'\nexecpath = \'' .. '\'\n\n'
local lx = struct_lines(file_name)
for xx in pairs(lx) do
local xy = lx[xx]
local ox = rolling_intepreter(line_loader(xy))
for k in ipairs(ox) do
local g_d = ox[k]
file_out = file_out .. g_d
end
file_out = file_out .. '\n'
end
return file_out .. '\n'
end
function write_script(f, fl)
local g_f = io.open(f .. '.lua', 'w')
g_f:write(get_script(f, fl))
g_f:close()
end
function definer(type, f, fl)
if type == '--run' then
write_script(f, fl)
assert(loadfile(f .. '.lua'))
elseif type == '--compile' then
write_script(f, fl)
else
print('[CodeQ Run] Unknown operation \'' .. type .. '\'.')
end
end
for k in ipairs(flags) do
definer(arg[k], file_dir, file_flags)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment