Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core: prepare introduction of package scopes #248

Merged
merged 9 commits into from
Nov 28, 2024
25 changes: 24 additions & 1 deletion lib/bait/ast/scope.bt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
package ast

pub struct Scope {
pub parent Scope
pub parent &Scope
pub objects map[string]ScopeObject
}

Expand All @@ -26,6 +26,29 @@ pub enum ObjectKind {
label
}

pub fun (mut t Table) preregister_scopes(pkg_name string) &Scope {
// FFI scopes
t.get_pkg_scope("C", 0 as any)
t.get_pkg_scope("JS", 0 as any)

// Packages
builtin_scope := t.get_pkg_scope("builtin", 0 as any)
pkg_scope := t.get_pkg_scope(pkg_name, builtin_scope)
return pkg_scope
}

pub fun (mut t Table) get_pkg_scope(pkg string, parent &Scope) &Scope {
if t.scopes.contains(pkg) {
return t.scopes[pkg]
}

s := &Scope{
parent = parent
}
t.scopes[pkg] = s
return s
}

pub fun (s Scope) register(name string, obj ScopeObject) {
if s.objects.contains(name) {
return
Expand Down
3 changes: 2 additions & 1 deletion lib/bait/ast/table.bt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
package ast

pub struct Table {
pub mut global_scope Scope
pub mut global_scope &Scope // TODO entirely replace by scopes
pub mut scopes map[string]&Scope
pub mut fun_decls map[string]FunDecl
pub mut type_idxs map[string]Type
pub mut type_symbols []TypeSymbol
Expand Down
1 change: 0 additions & 1 deletion lib/bait/checker/checker.bt
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ fun (mut c Checker) change_file(file ast.File) {
c.pkg = file.pkg_name

c.scope = ast.Scope{
// TODO how to handle recursive sturct inits?
parent = c.table.global_scope
}
}
Expand Down
4 changes: 2 additions & 2 deletions lib/bait/gen/c/auto_str.bt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const LB := if os.platform() == 'windows' { '\\r\\n' } else { '\\n' }
fun (mut g Gen) get_str_fun(typ ast.Type) string {
g.table.needed_str_funs.push(typ)
sym := g.table.get_sym(typ)
return c_name('${sym.name}_str')
return c_esc('${sym.name}_str')
}

fun (mut g Gen) generate_str_fun(typ ast.Type) {
Expand All @@ -26,7 +26,7 @@ fun (mut g Gen) generate_str_fun(typ ast.Type) {

g.generated_str_funs.push(typ)

sname := c_name(sym.name)
sname := c_esc(sym.name)
fname := sname + '_str'

if sym.kind == .struct_ {
Expand Down
10 changes: 7 additions & 3 deletions lib/bait/gen/c/cgen.bt
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ fun (mut g Gen) gen_test_main() {
for key, func in g.table.fun_decls {
if func.is_test {
nr_test_funs += 1
name := c_name(func.name)
name := c_esc(func.name)
esc_path := g.path.replace('\\', '\\\\')
g.writeln('TestRunner_set_test_info(&test_runner, from_c_string("${esc_path}"), from_c_string("${name}"));')
g.writeln('${name}();')
Expand Down Expand Up @@ -142,7 +142,7 @@ fun (g Gen) get_concrete_name(name string, concrete_types []ast.Type) string {
for t in concrete_types {
full_name += '_' + g.table.get_sym(t).name
}
return c_name(full_name)
return c_esc(full_name)
}

fun (mut g Gen) new_temp_var() string {
Expand Down Expand Up @@ -203,7 +203,11 @@ fun (mut g Gen) save_stmt_offset() {
}

fun c_name(n string) string {
name := n.replace('.', '__').replace('[]', 'Array_')
return n.replace('.', '__').replace('[]', 'Array_')
}

fun c_esc(n string) string {
name := c_name(n)
if C_RESERVED.contains(name) {
return 'bait_${name}'
}
Expand Down
10 changes: 5 additions & 5 deletions lib/bait/gen/c/expr.bt
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ fun (mut g Gen) char_literal(node ast.CharLiteral) {
}

fun (mut g Gen) enum_val(node ast.EnumVal) {
g.write(c_name(node.val))
g.write(c_esc(node.val))
}

fun (mut g Gen) hash_expr(node ast.HashExpr) {
Expand All @@ -109,7 +109,7 @@ fun (mut g Gen) hash_expr(node ast.HashExpr) {

fun (mut g Gen) ident(node ast.Ident) {
if node.lang == .bait {
g.write(c_name(node.name))
g.write(c_esc(node.name))
return
}
g.write(node.name.replace('C.', ''))
Expand Down Expand Up @@ -180,7 +180,7 @@ fun (mut g Gen) infix_expr(node ast.InfixExpr) {
if node.op == .ne {
g.write('!')
}
g.write(c_name(lsym.name + '_' + overload.name))
g.write(c_esc(lsym.name + '_' + overload.name))
g.write('(')
g.expr(node.left)
g.write(', ')
Expand Down Expand Up @@ -255,7 +255,7 @@ fun (mut g Gen) struct_init(node ast.StructInit) {

info := g.table.get_sym(node.typ).info as ast.StructInfo
for i, field in info.fields {
name := c_name(field.name)
name := c_esc(field.name)
g.write('.${name} = ')
init_idx := inited_fields.index(field.name)
if init_idx == -1 {
Expand Down Expand Up @@ -291,7 +291,7 @@ fun (mut g Gen) expr_to_string(expr ast.Expr, typ ast.Type) {
str_def := g.table.get_method(sym, 'str')
if str_def.name.length > 0 {
final_sym := g.table.get_sym(str_def.params[0].typ)
mut name := c_name(final_sym.name)
mut name := c_esc(final_sym.name)
g.write('${name}_str(')
g.expr(expr)
g.write(')')
Expand Down
10 changes: 5 additions & 5 deletions lib/bait/gen/c/fun.bt
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ fun (mut g Gen) fun_decl(node ast.FunDecl) {
g.cur_fun = node

type_str := g.typ(node.return_type)
mut name := c_name(node.name)
mut name := c_esc(node.name)
if node.is_method {
sym := g.table.get_sym(node.params[0].typ)
name = c_name(sym.name + '_' + node.name)
name = c_esc(sym.name + '_' + node.name)
}
if g.cur_concrete_types.length > 0 {
name = g.get_concrete_name(name, g.cur_concrete_types.values())
Expand All @@ -68,7 +68,7 @@ fun (mut g Gen) fun_decl(node ast.FunDecl) {

fun (mut g Gen) fun_params(params []ast.Param){
for i, p in params {
s := g.typ(p.typ) + ' ' + c_name(p.name)
s := g.typ(p.typ) + ' ' + c_esc(p.name)
g.fun_decls_out += s
g.write(s)

Expand All @@ -94,7 +94,7 @@ fun (mut g Gen) call_expr(node ast.CallExpr) {
return
}

mut name := c_name(node.name)
mut name := c_esc(node.name)
if node.is_method {
sym := g.table.get_sym(node.left_type)
final_sym := g.table.get_final_sym(sym)
Expand All @@ -113,7 +113,7 @@ fun (mut g Gen) call_expr(node ast.CallExpr) {
}
}

name = c_name(sym.name + '_' + node.name)
name = c_esc(sym.name + '_' + node.name)
} else if node.lang != .bait{
name = node.name.replace('C.', '')
}
Expand Down
6 changes: 3 additions & 3 deletions lib/bait/gen/c/stmt.bt
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ fun (mut g Gen) assign_stmt(node ast.AssignStmt) {
if lsym.overloads.contains(node.op.c_repr()) {
g.write(' = ')
overload := lsym.overloads[node.op.c_repr()]
g.write(c_name(lsym.name + '_' + overload.name))
g.write(c_esc(lsym.name + '_' + overload.name))
g.write('(')
g.expr(node.left)
g.write(', ')
Expand Down Expand Up @@ -84,7 +84,7 @@ fun (mut g Gen) const_decl(node ast.ConstDecl){
return
}

name := c_name(node.name)
name := c_esc(node.name)
val := g.expr_string(node.expr)

if node.expr is ast.ArrayInit or node.expr is ast.CallExpr or node.expr is ast.MapInit {
Expand Down Expand Up @@ -162,7 +162,7 @@ fun (mut g Gen) loop_control_stmt(node ast.LoopControlStmt){
}

fun (mut g Gen) global_decl(node ast.GlobalDecl){
name := c_name(node.name)
name := c_esc(node.name)
expr := g.expr_string(node.expr)
typ := g.typ(node.typ)
g.globals_out += '${typ} ${name} = ${expr};\n'
Expand Down
6 changes: 3 additions & 3 deletions lib/bait/gen/c/type.bt
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ fun (mut g Gen) write_types() {
continue
}

cname := c_name(sym.name)
cname := c_esc(sym.name)
if sym.info is ast.StructInfo {
info := sym.info as ast.StructInfo
g.type_defs_out += 'typedef struct ${cname} ${cname};\n'
g.type_impls_out += 'struct ${cname} {\n'
for field in info.fields {
type_str := g.typ(field.typ)
field_name := c_name(field.name)
field_name := c_esc(field.name)
g.type_impls_out += '\t${type_str} ${field_name};\n'
}
g.type_impls_out += '};\n'
Expand All @@ -62,7 +62,7 @@ fun (mut g Gen) write_types() {
info := sym.info as ast.EnumInfo
g.type_defs_out += 'enum ${cname} {\n'
for val in info.vals {
g.type_defs_out += '\t${c_name(val)},\n'
g.type_defs_out += '\t${c_esc(val)},\n'
}
g.type_defs_out += '};\n'
}
Expand Down
8 changes: 4 additions & 4 deletions lib/bait/gen/js/auto_str.bt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const LB := if os.platform() == 'windows' { '\\r\\n' } else { '\\n' }
fun (mut g Gen) get_str_fun(typ ast.Type) string {
g.table.needed_str_funs.push(typ)
sym := g.table.get_sym(typ)
return js_name('${sym.name}_str')
return js_esc('${sym.name}_str')
}

fun (mut g Gen) generate_str_fun(typ ast.Type) {
Expand All @@ -26,7 +26,7 @@ fun (mut g Gen) generate_str_fun(typ ast.Type) {

g.generated_str_funs.push(typ)

name := js_name('${sym.name}_str')
name := js_esc('${sym.name}_str')

if sym.kind == .array {
info := sym.info as ast.ArrayInfo
Expand Down Expand Up @@ -103,7 +103,7 @@ fun (mut g Gen) generate_str_fun(typ ast.Type) {
g.fun_decls_out += 'function ${name}(it, indent) {\n'
for var in info.variants {
var_sym := g.table.get_sym(var)
g.fun_decls_out += '\tif (it instanceof ${js_name(var_sym.name)}) {
g.fun_decls_out += '\tif (it instanceof ${js_esc(var_sym.name)}) {
return ${g.get_str_fun(var)}(it, indent)
}
'
Expand All @@ -117,7 +117,7 @@ fun (mut g Gen) generate_str_fun(typ ast.Type) {
switch(it) {\n'
info := sym.info as ast.EnumInfo
for val in info.vals {
g.fun_decls_out += '\t\tcase ${js_name(sym.name)}.${val}: return from_js_string("${val}")\n'
g.fun_decls_out += '\t\tcase ${js_esc(sym.name)}.${val}: return from_js_string("${val}")\n'
}
g.fun_decls_out += '\t}\n}\n\n'
return
Expand Down
8 changes: 4 additions & 4 deletions lib/bait/gen/js/expr.bt
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ fun (mut g Gen) char_literal(node ast.CharLiteral) {
}

fun (mut g Gen) enum_val(node ast.EnumVal) {
g.write(js_name(node.name) + '.' + node.val)
g.write(js_esc(node.name) + '.' + node.val)
}

fun (mut g Gen) float_literal(node ast.FloatLiteral){
Expand All @@ -134,7 +134,7 @@ fun (mut g Gen) ident(node ast.Ident) {
return
}

g.write(js_name(node.name))
g.write(js_esc(node.name))
}

fun (mut g Gen) integer_literal(node ast.IntegerLiteral){
Expand Down Expand Up @@ -205,7 +205,7 @@ fun (mut g Gen) infix_expr(node ast.InfixExpr){
if node.op == .ne {
g.write('!')
}
g.write(js_name(lsym.name + '_' + overload.name))
g.write(js_esc(lsym.name + '_' + overload.name))
g.write('(')
g.expr(node.left)
g.write(', ')
Expand Down Expand Up @@ -324,7 +324,7 @@ fun (mut g Gen) expr_to_string(expr ast.Expr, typ ast.Type) {
str_def := g.table.get_method(sym, 'str')
if str_def.name.length > 0 {
final_sym := g.table.get_sym(str_def.params[0].typ)
mut name := js_name(final_sym.name)
mut name := js_esc(final_sym.name)
g.write('${name}_str(')
g.expr(expr)
g.write(')')
Expand Down
12 changes: 6 additions & 6 deletions lib/bait/gen/js/fun.bt
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ fun (mut g Gen) fun_decl(node ast.FunDecl) {
mut name := ''
if node.is_method {
sym := g.table.get_sym(node.params[0].typ)
name = js_name(sym.name + '_' + node.name)
name = js_esc(sym.name + '_' + node.name)
} else {
name = js_name(node.name)
name = js_esc(node.name)
}
if g.cur_concrete_types.length > 0 {
name = g.get_concrete_name(name, g.cur_concrete_types.values())
Expand All @@ -50,15 +50,15 @@ fun (mut g Gen) fun_decl(node ast.FunDecl) {

export_attr := node.attrs.find_attr('export')
if export_attr.name != '' {
g.writeln('module.exports.${export_attr.value} = ${js_name(node.name)}')
g.writeln('module.exports.${export_attr.value} = ${js_esc(node.name)}')
}

g.writeln('')
}

fun (mut g Gen) fun_params(params []ast.Param){
for i, p in params {
g.write(js_name(p.name))
g.write(js_esc(p.name))
if i < params.length - 1 {
g.write(", ")
}
Expand Down Expand Up @@ -142,9 +142,9 @@ fun (mut g Gen) call_expr_no_or(node ast.CallExpr) {
return
}

name = js_name(sym.name + '_' + node.name)
name = js_esc(sym.name + '_' + node.name)
} else if node.lang == .bait{
name = js_name(node.name)
name = js_esc(node.name)
}

if node.concrete_types.length > 0 {
Expand Down
12 changes: 8 additions & 4 deletions lib/bait/gen/js/jsgen.bt
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ fun (mut g Gen) gen_test_main() {
for key, func in g.table.fun_decls {
if func.is_test {
nr_test_funs += 1
name := js_name(func.name)
name := js_esc(func.name)
esc_path := g.path.replace('\\', '\\\\')
g.writeln('TestRunner_set_test_info(test_runner, from_js_string("${esc_path}"), from_js_string("${name}"))')
g.writeln('${name}()')
Expand Down Expand Up @@ -241,7 +241,7 @@ fun (mut g Gen) write_default_value(typ ast.Type) {
keys = []ast.Expr
})
} else if sym.kind == .struct_ {
g.write('new ${js_name(sym.name)}({})')
g.write('new ${js_esc(sym.name)}({})')
} else if sym.kind == .alias_type {
g.write_default_value(sym.parent)
} else if sym.kind == .enum_ {
Expand All @@ -259,7 +259,7 @@ fun (g Gen) get_concrete_name(name string, concrete_types []ast.Type) string {
for t in concrete_types {
full_name += '_' + g.table.get_sym(t).name
}
return js_name(full_name)
return js_esc(full_name)
}

fun (g Gen) concrete_sym(typ ast.Type) ast.TypeSymbol {
Expand All @@ -272,7 +272,11 @@ fun (g Gen) concrete_sym(typ ast.Type) ast.TypeSymbol {
}

fun js_name(n string) string {
name := n.replace('.', '__').replace('[]', 'Array_').replace('[', '_').replace(']', '_')
return n.replace('.', '__').replace('[]', 'Array_').replace('[', '_').replace(']', '_')
}

fun js_esc(n string) string {
name := js_name(n)
// TODO this might have bad performance impact due to array size and frequent use
if JS_RESERVED.contains(name) {
return 'bait_${name}'
Expand Down
Loading