Skip to content

Instantly share code, notes, and snippets.

@srijan-paul
Created July 18, 2021 09:39
Show Gist options
  • Save srijan-paul/e93c05cbeedb2f104166e5ee8506bb14 to your computer and use it in GitHub Desktop.
Save srijan-paul/e93c05cbeedb2f104166e5ee8506bb14 to your computer and use it in GitHub Desktop.
import sys
import os
import re
argc = len(sys.argv)
default_params = "lua_State* L, Udata* G, StackValue* base, Udata* up"
def pln_entry_decl():
global default_params
return f"static void function_03({default_params})"
boxfns = """
static Udata *newBox(lua_State *L, Udata *G)
{
Udata *rec = luaS_newudata(L, sizeof(Box), 0);
return rec;
}
inline
static Box *box_prims(Udata *u)
{
char *p = cast_charp(u) + udatamemoffset(0);
return (Box *) p;
}
"""
t = """
Udata* up = newBox(L, G);
setuvalue(L, s2v(base + 0), up);
luaC_condGC(L, L->top = base + 1, (void)0);
"""
def field_name(n):
if n <= 9: return f"a0{n}"
return f"a{n}"
def box_decls(n):
s = ("typedef struct {\n" +
'\n'.join([ f"\tlua_Integer {field_name(i)};" for i in range(1, n + 1) ]) + '\n} Box;\n')
s += boxfns
return s
def edit(fname, n):
"""Replace /* Function Prototypes */ with:
1. The merged upvalue box
2. The corresponding `prims` and `new_box` function.
Edit the prototype for `function_03`. That means replacing
everything inside the brackets as shown below:
static void function_03( ... );
with:
static void function_03(
lua_State* L, Udata* G, StackValue* base, Udata* up);
"""
with open(fname, "r") as file:
c = file.read()
c = c.replace('/* Function Prototypes */', box_decls(n))
c = re.sub(r'static void function_03\((.|\n)*?\)', pln_entry_decl(), c)
c = re.sub(r'crecord_(\d*)_prims\([\d\w]+\)->f\d+', r'box_prims(up)->a\1', c)
c = re.sub(r'->a0(\d+)1', r'->a\1', c)
c = c.replace('setuvalue(L, &ccl->upvalue[1], x2);', 'setuvalue(L, &ccl->upvalue[1], up);')
c = re.sub(r'setuvalue\(L, &ccl->upvalue\[\d*\], x\d+\);', '', c)
c = re.sub(r'luaF_newCclosure\(L, \d+\)', 'luaF_newCclosure(L, 2)', c);
c = re.sub(r'uv\d+ = uvalue\(&func->upvalue\[(\d+)\]\);', r'//%uv\1x', c)
c = c.replace('//%uv1x', 'Udata* up = uvalue(&func->upvalue[1]);');
c = c.replace('Udata *x2', 'Udata* up');
c = re.sub(r'Udata \*x\d+;.*', '', c);
c = re.sub(r'x2 = crecord_\d+_new\(L, G\);', 'up = newBox(L, G);', c)
c = c.replace('setuvalue(L, s2v(base + 0), x2);', 'setuvalue(L, s2v(base + 0), up);')
c = c.replace('luaC_condGC(L, L->top = base + 1, (void)0);', '//restore_condGC')
c = re.sub(r'luaC_condGC\(L, L->top = base \+ \d+, \(void\)0\);', '', c)
c = c.replace('//restore_condGC', 'luaC_condGC(L, L->top = base + 1, (void)0);')
c = re.sub(r'(x\d+ = crecord_\d+_new\(L, G\);)', '', c)
c = re.sub(r'(setuvalue\(L, s2v\(base \+ \d+\), x\d+\);)', '', c)
c = re.sub(r'Udata \*uv\d+;', '', c)
c = re.sub(r'function_03\(L, G, L->top,.*\)', 'function_03(L, G, L->top, up)', c)
with open(fname, "w") as file:
file.write(c)
if argc != 2:
print("Usage: edit.py <number of values in the box>")
else:
fname = 'temp/out.c'
nfields = int(sys.argv[1])
if os.path.isfile(fname):
edit(fname, nfields)
else:
print("File not found")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment