Skip to content

Commit

Permalink
astgen: generate Lua functions as anonymous
Browse files Browse the repository at this point in the history
  • Loading branch information
StunxFS committed Jul 8, 2024
1 parent 2981e5e commit 76fdcf5
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 43 deletions.
50 changes: 29 additions & 21 deletions bsc/codegen/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,7 @@ def gen_mod_decl(self, decl):

self.cur_block = LuaBlock()
self.gen_decls(decl.decls)

module_fields = []
for sym in decl.sym.scope.syms:
if sym.access_modifier.is_public():
module_fields.append(
LuaTableField(LuaIdent(sym.name), LuaIdent(sym.name))
)
self.cur_block.add_stmt(
LuaAssignment([LuaIdent(decl.name)], [LuaTable(module_fields)],
False)
)
self.export_public_symbols(decl.sym)

mod_decls = self.cur_block
self.cur_block = old_block
Expand All @@ -113,26 +103,30 @@ def gen_const_decl(self, decl):
self.cur_block.add_stmt(lua_assign)

def gen_enum_decl(self, decl):
fields = []
self.cur_block.add_stmt(LuaAssignment([LuaIdent(decl.sym.name)], []))
old_block = self.cur_block
self.cur_block = LuaBlock()
for i, f in enumerate(decl.fields):
fields.append(LuaTableField(LuaIdent(f.name), LuaNumberLit(str(i))))
self.cur_block.add_stmt(
LuaAssignment([LuaIdent(decl.sym.name)], [LuaTable(fields)], False)
)
self.cur_block.add_stmt(
LuaAssignment([LuaSelector(LuaIdent(decl.name), f.name)],
[LuaNumberLit(str(i))], False)
)
self.switch_cur_sym(decl.sym)
self.gen_decls(decl.decls)
self.export_public_symbols(decl.sym)
self.switch_cur_sym()
old_block.add_stmt(self.cur_block)
self.cur_block = old_block

def gen_fn_decl(self, decl):
if not decl.has_body: return
old_block = self.cur_block
args = []
if decl.is_method:
args.append(LuaIdent("self"))
for arg in decl.args:
args.append(LuaIdent(arg.name))
luafn = LuaFunction(
decl.sym.cg_method_qualname(), args,
is_static = decl.sym.is_static()
)
luafn = LuaFunction(args, is_static = decl.sym.is_static())
for arg in decl.args:
if arg.default_value != None:
left = LuaIdent(arg.name)
Expand All @@ -148,7 +142,9 @@ def gen_fn_decl(self, decl):
self.gen_stmts(decl.stmts)
self.cur_fn = None
self.cur_block = old_block
self.cur_block.add_stmt(luafn)
self.cur_block.add_stmt(
LuaAssignment([LuaIdent(decl.sym.name)], [luafn])
)

## == Statements ============================================

Expand Down Expand Up @@ -269,3 +265,15 @@ def gen_expr(self, expr):
ret_expr = self.gen_expr(expr.expr)
self.cur_block.add_stmt(LuaReturn(ret_expr))
return LuaSkip()

def export_public_symbols(self, decl_sym):
exported_fields = []
for sym in decl_sym.scope.syms:
if sym.access_modifier.is_public():
exported_fields.append(
LuaTableField(LuaIdent(sym.name), LuaIdent(sym.name))
)
self.cur_block.add_stmt(
LuaAssignment([LuaIdent(decl_sym.name)],
[LuaTable(exported_fields)], False)
)
3 changes: 1 addition & 2 deletions bsc/codegen/lua_ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ def __init__(self, fields):
self.fields = fields

class LuaFunction:
def __init__(self, name, args, is_static = False):
self.name = name
def __init__(self, args, is_static = False):
self.args = args
self.is_static = is_static
self.block = LuaBlock()
Expand Down
25 changes: 11 additions & 14 deletions bsc/codegen/lua_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,20 +94,6 @@ def render_stmt(self, stmt):
else:
self.render_expr(stmt) # support for using expressions as statements

def render_fn_stmt(self, stmt):
if not stmt.is_static:
self.write("local ")
self.write(f"function {stmt.name}(")
for i, arg in enumerate(stmt.args):
self.write(arg.name)
if i < len(stmt.args) - 1:
self.write(", ")
self.writeln(")")
self.indent += 1
self.render_stmts(stmt.block.stmts)
self.indent -= 1
self.writeln("end\n")

def render_assign_stmt(self, stmt):
if stmt.is_local: self.write("local ")
for i, left in enumerate(stmt.lefts):
Expand All @@ -127,6 +113,17 @@ def render_expr(self, expr):
self.write("(")
self.render_expr(expr.expr)
self.write(")")
elif isinstance(expr, LuaFunction):
self.write(f"function(")
for i, arg in enumerate(expr.args):
self.write(arg.name)
if i < len(expr.args) - 1:
self.write(", ")
self.writeln(")")
self.indent += 1
self.render_stmts(expr.block.stmts)
self.indent -= 1
self.writeln("end\n")
elif isinstance(expr, LuaTable):
if len(expr.fields) == 0:
self.write("{}")
Expand Down
5 changes: 0 additions & 5 deletions bsc/sym.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,6 @@ def qualname(self, sep = "::"):
return f"{self.parent.qualname(sep)}{sep}{self.name}"
return self.name

def cg_method_qualname(self):
if isinstance(self.parent, TypeSym):
return f"{self.parent.name}.{self.name}"
return self.name

def __eq__(self, other):
return str(self) == str(other)

Expand Down
2 changes: 1 addition & 1 deletion tests/syntax.bs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub enum WorldLevel {
underworld,
undefined = 0xFF

fn from_string(s: string) Self {
pub fn from_string(s: string) Self {
unsafe {
$lua("function x() end");
}
Expand Down

0 comments on commit 76fdcf5

Please sign in to comment.