Skip to content

Commit

Permalink
shadowing; go stmt; goto; global vars fix; [][]Foo; path.foo() fix
Browse files Browse the repository at this point in the history
  • Loading branch information
medvednikov committed Oct 2, 2024
1 parent a40dbf6 commit 56e24c1
Show file tree
Hide file tree
Showing 12 changed files with 111 additions and 25 deletions.
18 changes: 17 additions & 1 deletion assign_stmt.v
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) 2024 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by a GPL license that can be found in the LICENSE file.
import rand

fn (mut app App) assign_stmt(assign AssignStmt, no_mut bool) {
for l_idx, lhs_expr in assign.lhs {
Expand All @@ -19,7 +20,22 @@ fn (mut app App) assign_stmt(assign AssignStmt, no_mut bool) {
} else {
app.gen(', ')
}
app.expr(lhs_expr)
if lhs_expr is Ident {
// Handle shadowing
mut n := lhs_expr.name
if assign.tok == ':=' && n != '_' && n in app.cur_fn_names {
n += rand.intn(10000) or { 0 }.str() // LOL fix this
}

app.cur_fn_names[n] = true
new_ident := Ident{
...lhs_expr
name: n
}
app.ident(new_ident) // lhs_expr)
} else {
app.expr(lhs_expr)
}
}
// Special case for 'append()' => '<<'
if app.check_and_handle_append(assign) {
Expand Down
7 changes: 7 additions & 0 deletions ast.v
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type Stmt = AssignStmt
| RangeStmt
| ReturnStmt
| SwitchStmt
| GoStmt

struct InvalidExpr {}

Expand Down Expand Up @@ -295,6 +296,7 @@ struct ReturnStmt {
struct BranchStmt {
node_type string @[json: '_type']
tok string @[json: 'Tok']
label Ident @[json: 'Label'] // only for `goto`
}

struct FuncLit {
Expand All @@ -303,6 +305,11 @@ struct FuncLit {
body BlockStmt @[json: 'Body']
}

struct GoStmt {
node_type string @[json: '_type']
call Expr @[json: 'Call']
}

fn parse_go_ast(file_path string) !GoFile {
data := os.read_file(file_path)!
return json.decode(GoFile, data)!
Expand Down
13 changes: 7 additions & 6 deletions complex_tests/esbuild/api_impl/api_impl.vv
Original file line number Diff line number Diff line change
Expand Up @@ -318,9 +318,7 @@ fn validate_loader(value Loader) config.Loader {
}
}

__global versionRegex STRUCT
TYPE

__global versionRegex = regexp.mustcompile(r'^([0-9]+)(?:\.([0-9]+))?(?:\.([0-9]+))?(-[A-Za-z0-9]+(?:\.[A-Za-z0-9]+)*)?$')
fn validate_features(log logger.Log, target Target, engines []Engine) (compat.JSFeature, compat.CSSFeature, map[css_ast.D]compat.CSSPrefix, string) {
if target == default_target && engines.len == 0 {
return 0, 0, nil, ''
Expand Down Expand Up @@ -1183,7 +1181,8 @@ fn validate_build_options(buildOpts BuildOptions, log logger.Log, realFS fs.FS)
mut out_js, out_css := validate_output_extensions(log, build_opts.out_extension)
mut banner_js, banner_css := validate_banner_or_footer(log, 'banner', build_opts.banner)
mut footer_js, footer_css := validate_banner_or_footer(log, 'footer', build_opts.footer)
mut minify := build_opts.minify_whitespace && build_opts.minify_identifiers && build_opts.minify_syntax
mut minify := build_opts.minify_whitespace && build_opts.minify_identifiers
&& build_opts.minify_syntax
mut platform := validate_platform(build_opts.platform)
mut defines, injected_defines := validate_defines(log, build_opts.define, build_opts.pure,
platform, true, minify, build_opts.drop)
Expand Down Expand Up @@ -1312,7 +1311,8 @@ fn validate_build_options(buildOpts BuildOptions, log logger.Log, realFS fs.FS)
options.abs_output_dir = real_fs.dir(options.abs_output_file)
} else if options.abs_output_dir == '' {
options.write_to_stdout = true
if options.source_map != config.source_map_none && options.source_map != config.source_map_inline {
if options.source_map != config.source_map_none
&& options.source_map != config.source_map_inline {
log.adderror(nil, logger.Range{}, 'Cannot use an external source map without an output path')
}
if options.legal_comments.hasexternalfile() {
Expand Down Expand Up @@ -1781,7 +1781,8 @@ fn (impl &pluginImpl) on_resolve(options OnResolveOptions, callback fn () (OnRes
result.plugin_name = response.plugin_name
result.abs_watch_files = impl.validatepathsarray(response.watch_files, 'watch file')
result.abs_watch_dirs = impl.validatepathsarray(response.watch_dirs, 'watch directory')
if err == nil && response.suffix != '' && response.suffix[0] != `?` && response.suffix[0] != `#` {
if err == nil && response.suffix != '' && response.suffix[0] != `?`
&& response.suffix[0] != `#` {
err = strconv.errorf('Invalid path suffix %q returned from plugin (must start with "?" or "#")',
response.suffix)
}
Expand Down
6 changes: 6 additions & 0 deletions expr.v
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ fn quoted_lit(s string, quote string) string {

fn (mut app App) selector_expr(s SelectorExpr) {
force_upper := app.force_upper // save force upper for `mod.ForceUpper`
app.force_upper = false
app.expr(s.x)
app.gen('.')
app.force_upper = force_upper
Expand Down Expand Up @@ -156,6 +157,10 @@ fn (mut app App) array_type(node ArrayType) {
app.gen('[]')
app.func_type(node.elt)
}
ArrayType {
app.gen('[]')
app.array_type(node.elt)
}
else {
app.gen('UNKNOWN ELT ${node.elt.type_name()}')
}
Expand All @@ -165,6 +170,7 @@ fn (mut app App) array_type(node ArrayType) {
fn (mut app App) map_type(node MapType) {
app.force_upper = true
app.gen('map[')
app.force_upper = true
app.expr(node.key)
app.gen(']')
app.force_upper = true
Expand Down
36 changes: 26 additions & 10 deletions fn_call.v
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@ fn (mut app App) call_expr(call CallExpr) {
elt := fun.elt
if elt is Ident && elt.name == 'byte' {
x := call.args[0]
if x is BasicLit {
app.expr(x)
app.gen('.bytes()')
return
}
// TODO not every expr/type can be handled like this?
// if x is BasicLit {
app.expr(x)
app.gen('.bytes()')
return
}
}

Expand Down Expand Up @@ -130,10 +130,14 @@ fn (mut app App) selector_expr_fn_call(call CallExpr, sel SelectorExpr) {
// app.genln('///selector_expr_fn_call')
if sel.x is Ident {
if sel.x.name in nonexistent_modules {
app.handle_nonexistent_module_call(sel.x.name, sel.sel.name, call)
app.handle_nonexistent_module_call(sel, sel.x.name, sel.sel.name, call)
return
}
}
app.selector_xxx(sel)
}

fn (mut app App) selector_xxx(sel SelectorExpr) {
app.expr(sel.x)
app.gen('.')
mut sel_name := sel.sel.name.to_lower()
Expand All @@ -145,9 +149,16 @@ fn (mut app App) selector_expr_fn_call(call CallExpr, sel SelectorExpr) {

fn (mut app App) make_call(call CallExpr) {
// app.genln('//make ${call.fun.type_name()} ar0=${call.args[0].type_name()}')
app.force_upper = true
app.expr(call.args[0])
// len only
if call.args.len == 2 {
app.gen('{ len: ')
app.expr(call.args[1])
app.gen(' }')
}
// cap + len
if call.args.len == 3 {
else if call.args.len == 3 {
app.gen('{ len: ')
app.expr(call.args[1])
app.gen(', cap: ')
Expand All @@ -158,13 +169,13 @@ fn (mut app App) make_call(call CallExpr) {
}
}

fn (mut app App) handle_nonexistent_module_call(mod_name string, fn_name string, node CallExpr) {
fn (mut app App) handle_nonexistent_module_call(sel SelectorExpr, mod_name string, fn_name string, node CallExpr) {
match mod_name {
'strings' {
app.handle_strings_call(app.go2v_ident(fn_name), node.args)
}
'path' {
app.handle_path_call(app.go2v_ident(fn_name), node.args)
app.handle_path_call(sel, app.go2v_ident(fn_name), node.args)
}
'fmt' {
app.handle_fmt_call(app.go2v_ident(fn_name), node.args)
Expand All @@ -181,10 +192,15 @@ fn (mut app App) handle_strings_call(fn_name string, args []Expr) {
app.skip_first_arg = true
}

fn (mut app App) handle_path_call(fn_name string, _ []Expr) {
fn (mut app App) handle_path_call(sel SelectorExpr, fn_name string, x []Expr) {
if fn_name == 'base' {
app.gen('os.base')
}
// Go allows module name shadowing, so we can have a variable
// `path`
else {
app.selector_xxx(sel)
}
}

fn (mut app App) handle_fmt_call(fn_name string, _ []Expr) {
Expand Down
13 changes: 11 additions & 2 deletions fn_decl.v
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Use of this source code is governed by a GPL license that can be found in the LICENSE file.

fn (mut app App) func_decl(decl FuncDecl) {
app.cur_fn_names.clear()
app.genln('')
app.comments(decl.doc)
method_name := app.go2v_ident(decl.name.name) // decl.name.name.to_lower()
Expand Down Expand Up @@ -53,17 +54,25 @@ fn (mut app App) func_return_type(results FieldList) {
// app.genln(results)
// Return types
return_types := results.list
if return_types.len > 1 {
needs_pars := return_types.len > 1
//|| (return_types.len > 0 && return_types[0].names.len > 0 && return_types[0].names[0].name != '')
if needs_pars {
app.gen('(')
}
for i, res in return_types {
/*
if res.names.len > 0 && res.names[0].name != '' {
app.gen(app.go2v_ident(res.names[0].name))
app.gen(' ')
}
*/
app.typ(res.typ)
if i < return_types.len - 1 {
app.gen(',')
}
//' ${decl.typ.results.list.map(type_or_ident(it.typ)).join(', ')}'
}
if return_types.len > 1 {
if needs_pars {
app.gen(')')
}
}
Expand Down
3 changes: 3 additions & 0 deletions go2v_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ fn test_all() {
mut test_names := os.ls('tests') or { return }
test_names.sort()
mut tests_failures := []string{}
complex_names := os.ls('complex_tests/esbuild') or { return }
assert complex_names.len > 0
test_names << complex_names
for test_name in test_names {
println('='.repeat(44))
create_json(subdir, test_name)
Expand Down
4 changes: 3 additions & 1 deletion main.v
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ mut:
force_upper bool // for `field Type` in struct decl, `mod.UpperCase` types etc
type_decl_name string
is_enum_decl bool
is_mut_recv bool // so that `mut f Foo` is generated instead of `mut f &Foo`
is_mut_recv bool // so that `mut f Foo` is generated instead of `mut f &Foo`
cur_fn_names map[string]bool // for fixing shadowing
}

fn (mut app App) genln(s string) {
Expand Down Expand Up @@ -146,6 +147,7 @@ fn (mut app App) run_test(subdir string, test_name string) ! {
res := os.execute('v fmt -w ${v_path}')
if res.exit_code != 0 {
println(res)
app.tests_ok = false
}

mut formatted_v_code := os.read_file(v_path) or { panic(err) }
Expand Down
18 changes: 15 additions & 3 deletions stmt.v
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ fn (mut app App) stmt(stmt Stmt) {
DeferStmt {
app.defer_stmt(stmt)
}
GoStmt {
app.go_stmt(stmt)
}
else {
app.genln('\t// unhandled in stmt: ${stmt}')
} // Add additional handlers as needed
Expand All @@ -61,6 +64,11 @@ fn (mut app App) expr_stmt(stmt ExprStmt) {
app.expr(stmt.x)
}

fn (mut app App) go_stmt(stmt GoStmt) {
app.gen('go ')
app.expr(stmt.call)
}

fn (mut app App) block_stmt(body BlockStmt) {
app.genln('{')
// println('LIST=')
Expand Down Expand Up @@ -126,12 +134,12 @@ fn (mut app App) range_stmt(node RangeStmt) {
if node.key.name == '' {
app.gen('_ ')
} else {
app.gen(node.key.name)
app.gen(app.go2v_ident(node.key.name))
app.gen(', ')
if node.value.name == '' {
app.gen(' _ ')
} else {
app.gen(node.value.name)
app.gen(app.go2v_ident(node.value.name))
}
}
app.gen(' in ')
Expand Down Expand Up @@ -227,5 +235,9 @@ fn (mut app App) return_stmt(node ReturnStmt) {

// continue break etc
fn (mut app App) branch_stmt(node BranchStmt) {
app.genln(node.tok)
app.gen(node.tok)
if node.label.name != '' {
app.gen(' ' + node.label.name)
}
app.genln('')
}
5 changes: 4 additions & 1 deletion struct.v
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ fn (mut app App) struct_decl(struct_name string, spec StructType) {
app.genln('pub mut:')
}
for field in spec.fields.list {
app.comments(field.doc)
for n in field.names {
app.gen('\t')
app.gen(app.go2v_ident(n.name))
Expand Down Expand Up @@ -202,7 +203,9 @@ fn (mut app App) struct_init(c CompositeLit) {
typ := c.typ
match typ {
Ident {
app.gen('${typ.name}{')
app.force_upper = true
n := app.go2v_ident(typ.name)
app.gen('${n}{')
if c.elts.len > 0 {
app.genln('')
}
Expand Down
5 changes: 5 additions & 0 deletions todo.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
- Fix shadowing ("redefinition of xxx")
- Fix `else if x := .... ; x {`
- Implement `if obj, ok := json.Data.(*js_ast.EObject); ok {`
- []u8(byteptr) cast ???

8 changes: 7 additions & 1 deletion util.v
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,13 @@ fn (mut app App) go2v_ident(ident string) string {
// println('ident=${ident} force_upper=${app.force_upper}')
if app.force_upper {
app.force_upper = false
return ident // go2v_ident2(ident)
if ident in v_keywords_which_are_not_go_keywords {
return ident + '_'
}
if ident in ['string', 'int', 'float64'] {
return ident
}
return ident.capitalize()
}
return go2v_ident2(ident)
/*
Expand Down

0 comments on commit 56e24c1

Please sign in to comment.