Skip to content

Commit

Permalink
shadowing fixes; arr.clone(); chan type; type assert; type switch; bu…
Browse files Browse the repository at this point in the history
…ndler.go
  • Loading branch information
medvednikov committed Oct 14, 2024
1 parent 20feea4 commit c453993
Show file tree
Hide file tree
Showing 15 changed files with 12,093 additions and 22 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ jobs:
- name: Run tests
run: v -g test .

- name: Run copmplex tests
- name: Run complex tests
run: |
v run . complex_tests/esbuild/api_impl
v run . complex_tests/esbuild/resolver
63 changes: 57 additions & 6 deletions assign_stmt.v
Original file line number Diff line number Diff line change
@@ -1,6 +1,33 @@
// 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) unique_name_anti_shadow(n string) string {
if n == '_' {
return '_'
}
if app.running_test {
return n
}
if n !in app.cur_fn_names {
return n
}
// Increase the i in `name_i` until it's unique.
mut i := 1
mut res := ''
for {
res = '${n}_${i}'

if res !in app.cur_fn_names {
break
}
i++
if i > 100 {
panic('100 levels of shadowing, that cannot be real!')
}
}
// res := n + rand.intn(10000) or { 0 }.str() // LOL fix this
return res
}

fn (mut app App) assign_stmt(assign AssignStmt, no_mut bool) {
for l_idx, lhs_expr in assign.lhs {
Expand All @@ -24,15 +51,20 @@ fn (mut app App) assign_stmt(assign AssignStmt, no_mut bool) {
// 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
n = app.unique_name_anti_shadow(n)
}

app.cur_fn_names[n] = true

new_ident := Ident{
...lhs_expr
name: n
}
app.ident(new_ident) // lhs_expr)
// app.ident(app.go2v_ident(new_ident))
app.ident(new_ident)
} else if lhs_expr is StarExpr {
// Can't use star_expr(), since it generates &
app.gen('*')
app.expr(lhs_expr.x)
} else {
app.expr(lhs_expr)
}
Expand All @@ -43,7 +75,9 @@ fn (mut app App) assign_stmt(assign AssignStmt, no_mut bool) {
}
//
app.gen(assign.tok)
// app.gen('/*F*/')
for r_idx, rhs_expr in assign.rhs {
// app.genln('/* ${rhs_expr} */')
// app.gen('ridx=${r_idx}')
mut needs_close_paren := false
if r_idx == 0 {
Expand Down Expand Up @@ -73,20 +107,37 @@ fn (mut app App) assign_stmt(assign AssignStmt, no_mut bool) {
}

fn (mut app App) check_and_handle_append(assign AssignStmt) bool {
if assign.rhs.len == 0 {
app.genln('// append no rhs')
return false
}
first_rhs := assign.rhs[0]
if first_rhs is CallExpr {
fun := first_rhs.fun
if fun is Ident {
if fun.name == 'append' {
app.gen_append(first_rhs.args)
app.gen_append(first_rhs.args, assign.tok)
return true
}
}
}
return false
}

fn (mut app App) gen_append(args []Expr) {
fn (mut app App) gen_append(args []Expr, assign_tok string) {
// Handle special case `mut x := arr.clone()`
// In Go it's
// `append([]Foo{}, foo...)`

arg0 := args[0]
if arg0 is CompositeLit && arg0.typ is ArrayType {
app.gen(' ${assign_tok} ')
app.expr(args[1])
app.gen('.')
app.genln('clone()')
return
}

app.gen(' << ')
if args.len == 2 {
app.expr(args[1])
Expand Down
28 changes: 27 additions & 1 deletion ast.v
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ type Expr = InvalidExpr
| SliceExpr
| StarExpr
| UnaryExpr
| TypeAssertExpr

type Stmt = AssignStmt
type Stmt = InvalidStmt
| AssignStmt
| BlockStmt
| BranchStmt
| CaseClause
Expand All @@ -37,10 +39,13 @@ type Stmt = AssignStmt
| RangeStmt
| ReturnStmt
| SwitchStmt
| TypeSwitchStmt
| GoStmt

struct InvalidExpr {}

struct InvalidStmt {}

type Specs = ImportSpec | TypeSpec | ValueSpec

type Type = InvalidExpr
Expand All @@ -52,6 +57,7 @@ type Type = InvalidExpr
| Ident
| StarExpr
| SelectorExpr
| ChanType

struct GoFile {
package_name Ident @[json: 'Name']
Expand Down Expand Up @@ -105,6 +111,12 @@ struct MapType {
val Expr @[json: 'Value']
}

struct ChanType {
node_type string @[json: '_type']
dir string @[json: 'Dir']
value Expr @[json: 'Value']
}

struct Ellipsis {
node_type string @[json: '_type']
elt Ident @[json: 'Elt']
Expand Down Expand Up @@ -140,6 +152,13 @@ struct SwitchStmt {
body BlockStmt @[json: 'Body']
}

struct TypeSwitchStmt {
node_type string @[json: '_type']
assign AssignStmt @[json: 'Assign']
// tag Expr @[json: 'Tag']
body BlockStmt @[json: 'Body']
}

struct CaseClause {
node_type string @[json: '_type']
list []Expr @[json: 'List']
Expand Down Expand Up @@ -278,6 +297,12 @@ struct SliceExpr {
high Expr @[json: 'High']
}

struct TypeAssertExpr {
node_type string @[json: '_type']
x Expr @[json: 'X']
typ Type @[json: 'Type']
}

struct StarExpr {
node_type string @[json: '_type']
x Expr @[json: 'X']
Expand Down Expand Up @@ -335,6 +360,7 @@ fn (e Expr) node_type() string {
SliceExpr { return e.node_type }
UnaryExpr { return e.node_type }
FuncType { return e.node_type }
TypeAssertExpr { return e.node_type }
}
return 'unknown node type'
}
Loading

0 comments on commit c453993

Please sign in to comment.