Skip to content

Commit

Permalink
astgen,lua_ast,codegen,render: fix module generation
Browse files Browse the repository at this point in the history
  • Loading branch information
StunxFS committed Jun 10, 2024
1 parent 2c13621 commit 1103ed6
Show file tree
Hide file tree
Showing 12 changed files with 66 additions and 154 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/compiler_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ jobs:
- name: Run passing tests
run: |
sudo pip3 install lark
python3 bsc examples/syntax.bs
python3 bsc examples/sema.bs
python3 bsc examples/hello_world.bs
python3 bsc tests/sema.bs
4 changes: 3 additions & 1 deletion bsc/AST.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ def __init__(self, pkg_name, alias_name, pos):
self.sym = None

class ModDecl:
def __init__(self, access_modifier, name, is_inline, decls, pos, sym=None):
def __init__(
self, access_modifier, name, is_inline, decls, pos, sym = None
):
self.access_modifier = access_modifier
self.name = name
self.is_inline = is_inline
Expand Down
16 changes: 7 additions & 9 deletions bsc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,24 +85,22 @@ def import_module(self, parent, decl):
dir = os.path.dirname(os.path.relpath(decl.pos.file))
file = os.path.join(dir, f"{decl.name}.bs")
if os.path.isfile(file):
self.parse_file(decl.name, file, parent_mod=parent)
self.parse_file(decl.name, file, parent_mod = parent)
elif os.path.isdir(os.path.join(dir, decl.name)):
mod_bs = os.path.join(dir, decl.name, "mod.bs")
if os.path.isfile(mod_bs):
self.parse_file(decl.name, file, parent_mod=parent)
self.parse_file(decl.name, file, parent_mod = parent)
else:
report.error(f"cannot load module `{decl.name}`, because it does not contain a file `mod.bs`")
report.error(
f"cannot load module `{decl.name}`, because it does not contain a file `mod.bs`"
)
else:
report.error(f"module `{decl.name}` not found", decl.pos)

def parse_input(self):
self.parse_file(
self.prefs.pkg_name, self.prefs.input, is_pkg = True
)
self.parse_file(self.prefs.pkg_name, self.prefs.input, is_pkg = True)

def parse_file(
self, mod_name, file, is_pkg = False, parent_mod = None
):
def parse_file(self, mod_name, file, is_pkg = False, parent_mod = None):
self.source_files.append(
self.astgen.parse_file(mod_name, file, is_pkg, parent_mod)
)
15 changes: 7 additions & 8 deletions bsc/astgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,10 @@ def __init__(self, ctx):
self.source_file = None
self.mod_sym = None

def parse_file(
self, mod_name, file, is_pkg = False, parent_mod = None
):
def parse_file(self, mod_name, file, is_pkg = False, parent_mod = None):
self.file = file
self.mod_sym = Module(
AccessModifier.public, mod_name, Scope(self.ctx.universe),
is_pkg
AccessModifier.public, mod_name, Scope(self.ctx.universe), is_pkg
)
self.source_file = SourceFile(
self.file, self.transform(bs_parser.parse(open(file).read())),
Expand Down Expand Up @@ -70,10 +67,12 @@ def mod_decl(self, *nodes):
if not is_inline:
pos += nodes[2].pos
mod_sym = Module(
access_modifier, nodes[2].name, Scope(self.mod_sym, True),
False
access_modifier, nodes[2].name, Scope(self.mod_sym, True), False,
is_inline
)
return ModDecl(
access_modifier, nodes[2].name, is_inline, decls, pos, mod_sym
)
return ModDecl(access_modifier, nodes[2].name, is_inline, decls, pos, mod_sym)

def enum_decl(self, *nodes):
pos = self.mkpos(nodes[1])
Expand Down
29 changes: 19 additions & 10 deletions bsc/codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ def gen_decls(self, decls):

def gen_decl(self, decl):
if isinstance(decl, AST.ModDecl):
if decl.is_inline:
self.gen_inline_mod(decl)
self.gen_mod(decl)
elif isinstance(decl, AST.EnumDecl):
self.gen_enum_decl(decl)
elif isinstance(decl, AST.FnDecl):
Expand All @@ -43,18 +42,28 @@ def gen_enum_decl(self, decl):
fields = []
for i, f in enumerate(decl.fields):
fields.append(LuaTableField(f.name, str(i)))
self.decls.append(LuaTable(decl.sym.mod_qualname("."), fields))
self.decls.append(LuaTable(decl.sym.codegen_qualname(), fields))

def gen_inline_mod(self, decl):
old_decls = self.decls
self.decls = []
self.gen_decls(decl.decls)
old_decls.append(LuaModule(decl.sym.mod_qualname("."), self.decls))
self.decls = old_decls
def gen_mod(self, decl):
if decl.is_inline:
old_decls = self.decls
self.decls = []
self.gen_decls(decl.decls)
old_decls.append(
LuaModule(decl.sym.codegen_qualname(), self.decls, True)
)
self.decls = old_decls
else:
self.decls.append(
LuaModule(
decl.sym.codegen_qualname(), [], False,
lua_filename = decl.name
)
)

def gen_fn_decl(self, decl):
args = []
for arg in decl.args:
args.append(LuaIdent(arg.name))
luafn = LuaFunction(decl.sym.mod_qualname("."), args)
luafn = LuaFunction(decl.sym.codegen_qualname(), args)
self.decls.append(luafn)
4 changes: 3 additions & 1 deletion bsc/lua_ast/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
# LICENSE file.

class LuaModule:
def __init__(self, name, decls = []):
def __init__(self, name, decls = [], is_inline = False, lua_filename = ""):
self.name = name
self.decls = decls
self.is_inline = is_inline
self.lua_filename = lua_filename

class LuaTableField:
def __init__(self, name, value):
Expand Down
16 changes: 11 additions & 5 deletions bsc/lua_ast/render.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,22 @@ def render_decls(self, decls):

def render_decl(self, decl):
if isinstance(decl, LuaModule):
self.render_inline_mod(decl)
self.render_mod(decl)
elif isinstance(decl, LuaTable):
self.render_table(decl)
elif isinstance(decl, LuaFunction):
self.render_fn_decl(decl)

def render_mod(self, decl):
if decl.is_inline:
self.writeln(f"{decl.name} = {{}} -- inline module\n")
self.render_decls(decl.decls)
self.writeln(f"-- end module `{decl.name}`\n")
else:
self.writeln(
f"{decl.name} = require(\"bsc-out.{decl.lua_filename}\") -- load module file\n"
)

def render_table(self, decl):
self.writeln(f"{decl.name} = {{")
self.indent += 1
Expand All @@ -66,10 +76,6 @@ def render_table(self, decl):
self.indent -= 1
self.writeln("}\n")

def render_inline_mod(self, decl):
self.writeln(f"{decl.name} = {{}} -- inline module\n")
self.render_decls(decl.decls)

def render_fn_decl(self, decl):
self.write(f"function {decl.name}(")
for i, arg in enumerate(decl.args):
Expand Down
9 changes: 5 additions & 4 deletions bsc/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@

def _format(pos, kind, kindc, msg):
return "{} {}".format(
utils.bold("{}:{}:{}: {}".format(pos.file, pos.line, pos.column, kindc(kind))),
msg
utils.bold(
"{}:{}:{}: {}".format(pos.file, pos.line, pos.column, kindc(kind))
), msg
)

def error(msg, pos):
global errors
utils.eprint(_format(pos, "error: ", utils.red, msg))
utils.eprint(_format(pos, "error:", utils.red, msg))
errors += 1

def warn(msg, pos):
utils.eprint(_format(pos, "warning: ", utils.yellow, msg))
utils.eprint(_format(pos, "warning:", utils.yellow, msg))
6 changes: 4 additions & 2 deletions bsc/sema.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,10 @@ def check_decl(self, decl):

def check_mod_decl(self, decl):
old_sym = self.cur_sym
if self.first_pass and decl.is_inline:
self.add_sym(decl.sym, decl.pos)
if self.first_pass:
decl.sym.parent = self.cur_sym
if decl.is_inline:
self.add_sym(decl.sym, decl.pos)
self.cur_sym = decl.sym
self.cur_scope = decl.sym.scope
self.check_decls(decl.decls)
Expand Down
9 changes: 5 additions & 4 deletions bsc/sym.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ def qualname(self, sep = "::"):
return f"{self.parent.qualname(sep)}{sep}{self.name}"
return self.name

def mod_qualname(self, sep = "::"):
def codegen_qualname(self, sep = "."):
if self.parent:
if isinstance(self.parent, Module):
if isinstance(self.parent, Module) and not self.parent.is_inline:
return f"{self.parent.name}{sep}{self.name}"
if not self.parent.scope.is_universe:
return f"{self.parent.mod_qualname(sep)}{sep}{self.name}"
return f"{self.parent.codegen_qualname(sep)}{sep}{self.name}"
return self.name

def __repr__(self):
Expand Down Expand Up @@ -158,11 +158,12 @@ def type_kind(self):
return str(self.kind)

class Module(Sym):
def __init__(self, access_modifier, name, scope, is_pkg):
def __init__(self, access_modifier, name, scope, is_pkg, is_inline = False):
super().__init__(access_modifier, name)
scope.owner = self
self.scope = scope
self.is_pkg = is_pkg
self.is_inline = is_inline

class Function(Sym):
def __init__(self, access_modifier, name, args, scope):
Expand Down
13 changes: 0 additions & 13 deletions examples/sema.bs

This file was deleted.

95 changes: 0 additions & 95 deletions examples/syntax.bs

This file was deleted.

0 comments on commit 1103ed6

Please sign in to comment.