parent
7386adfc99
commit
6c5b638202
|
@ -877,3 +877,16 @@ fn test_plus_assign_string() {
|
|||
a[0] += 'abc'
|
||||
assert a == ['abc']
|
||||
}
|
||||
|
||||
fn test_cross_assign() {
|
||||
mut a := [0, 1]
|
||||
a[0], a[1] = a[1], a[0]
|
||||
assert a[0] == 1
|
||||
assert a[1] == 0
|
||||
|
||||
mut b1 := [1, 2, 3]
|
||||
mut b2 := 4
|
||||
b1[2], b2, b1[0] = b1[0], b1[2], 5
|
||||
assert b1 == [5, 2, 1]
|
||||
assert b2 == 3
|
||||
}
|
||||
|
|
|
@ -410,6 +410,7 @@ pub:
|
|||
pub struct IndexExpr {
|
||||
pub:
|
||||
pos token.Position
|
||||
expr string // a[0] m['a'] etc
|
||||
left Expr
|
||||
index Expr // [0], [start..end] etc
|
||||
pub mut:
|
||||
|
|
|
@ -683,7 +683,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
|||
println('build module `$g.module_built` fn `$node.name`')
|
||||
}
|
||||
}
|
||||
keep_fn_decl := g.fn_decl
|
||||
keep_fn_decl := g.fn_decl
|
||||
g.fn_decl = node
|
||||
if node.name == 'main.main' {
|
||||
g.has_main = true
|
||||
|
@ -1089,6 +1089,18 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
|||
styp := g.typ(assign_stmt.left_types[i])
|
||||
g.writeln('$styp _var_$left.pos.pos = $left.name;')
|
||||
}
|
||||
ast.IndexExpr {
|
||||
sym := g.table.get_type_symbol(left.left_type)
|
||||
if sym.kind == .array {
|
||||
info := sym.info as table.Array
|
||||
styp := g.typ(info.elem_type)
|
||||
g.write('$styp _var_$left.pos.pos = *($styp*)array_get(')
|
||||
g.expr(it.left)
|
||||
g.write(', ')
|
||||
g.expr(it.index)
|
||||
g.writeln(');')
|
||||
}
|
||||
}
|
||||
else {}
|
||||
}
|
||||
}
|
||||
|
@ -1286,6 +1298,22 @@ fn (mut g Gen) gen_cross_tmp_variable(left []ast.Expr, val ast.Expr) {
|
|||
g.expr(val_)
|
||||
}
|
||||
}
|
||||
ast.IndexExpr {
|
||||
mut has_var := false
|
||||
for lx in left {
|
||||
if lx is ast.IndexExpr {
|
||||
inx := lx as ast.IndexExpr
|
||||
if val.expr == inx.expr {
|
||||
g.write('_var_$inx.pos.pos')
|
||||
has_var = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if !has_var {
|
||||
g.expr(val_)
|
||||
}
|
||||
}
|
||||
ast.InfixExpr {
|
||||
g.gen_cross_tmp_variable(left, val.left)
|
||||
g.write(val.op.str())
|
||||
|
|
|
@ -45,14 +45,26 @@ fn (mut p Parser) check_undefined_variables(exprs []ast.Expr, val ast.Expr) {
|
|||
|
||||
fn (mut p Parser) check_cross_variables(exprs []ast.Expr, val ast.Expr) bool {
|
||||
match val {
|
||||
ast.Ident { for expr in exprs {
|
||||
ast.Ident {
|
||||
for expr in exprs {
|
||||
if expr is ast.Ident {
|
||||
ident := expr as ast.Ident
|
||||
if ident.name == val.name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
} }
|
||||
}
|
||||
}
|
||||
ast.IndexExpr {
|
||||
for expr in exprs {
|
||||
if expr is ast.IndexExpr {
|
||||
idx := expr as ast.IndexExpr
|
||||
if idx.expr == val.expr {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ast.InfixExpr { return p.check_cross_variables(exprs, val.left) || p.check_cross_variables(exprs, val.right) }
|
||||
ast.PrefixExpr { return p.check_cross_variables(exprs, val.right) }
|
||||
ast.PostfixExpr { return p.check_cross_variables(exprs, val.expr) }
|
||||
|
@ -77,6 +89,9 @@ fn (mut p Parser) partial_assign_stmt(left []ast.Expr) ast.Stmt {
|
|||
// a, b = b, a
|
||||
for r in right {
|
||||
has_cross_var = p.check_cross_variables(left, r)
|
||||
if has_cross_var {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
for i, lx in left {
|
||||
|
|
|
@ -985,10 +985,12 @@ fn (mut p Parser) index_expr(left ast.Expr) ast.IndexExpr {
|
|||
}
|
||||
}
|
||||
// [expr]
|
||||
end := p.tok.position()
|
||||
p.check(.rsbr)
|
||||
return ast.IndexExpr{
|
||||
left: left
|
||||
index: expr
|
||||
expr: p.scanner.expr_string(left.position(), end).replace(' ', '')
|
||||
pos: p.tok.position()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1379,3 +1379,7 @@ pub fn (mut s Scanner) codegen(newtext string) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (s Scanner) expr_string(start, end token.Position) string {
|
||||
return s.text[start.pos..end.pos].trim_space()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue