parent
7386adfc99
commit
6c5b638202
|
@ -877,3 +877,16 @@ fn test_plus_assign_string() {
|
||||||
a[0] += 'abc'
|
a[0] += 'abc'
|
||||||
assert a == ['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 struct IndexExpr {
|
||||||
pub:
|
pub:
|
||||||
pos token.Position
|
pos token.Position
|
||||||
|
expr string // a[0] m['a'] etc
|
||||||
left Expr
|
left Expr
|
||||||
index Expr // [0], [start..end] etc
|
index Expr // [0], [start..end] etc
|
||||||
pub mut:
|
pub mut:
|
||||||
|
|
|
@ -683,7 +683,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||||
println('build module `$g.module_built` fn `$node.name`')
|
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
|
g.fn_decl = node
|
||||||
if node.name == 'main.main' {
|
if node.name == 'main.main' {
|
||||||
g.has_main = true
|
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])
|
styp := g.typ(assign_stmt.left_types[i])
|
||||||
g.writeln('$styp _var_$left.pos.pos = $left.name;')
|
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 {}
|
else {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1286,6 +1298,22 @@ fn (mut g Gen) gen_cross_tmp_variable(left []ast.Expr, val ast.Expr) {
|
||||||
g.expr(val_)
|
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 {
|
ast.InfixExpr {
|
||||||
g.gen_cross_tmp_variable(left, val.left)
|
g.gen_cross_tmp_variable(left, val.left)
|
||||||
g.write(val.op.str())
|
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 {
|
fn (mut p Parser) check_cross_variables(exprs []ast.Expr, val ast.Expr) bool {
|
||||||
match val {
|
match val {
|
||||||
ast.Ident { for expr in exprs {
|
ast.Ident {
|
||||||
|
for expr in exprs {
|
||||||
if expr is ast.Ident {
|
if expr is ast.Ident {
|
||||||
ident := expr as ast.Ident
|
ident := expr as ast.Ident
|
||||||
if ident.name == val.name {
|
if ident.name == val.name {
|
||||||
return true
|
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.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.PrefixExpr { return p.check_cross_variables(exprs, val.right) }
|
||||||
ast.PostfixExpr { return p.check_cross_variables(exprs, val.expr) }
|
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
|
// a, b = b, a
|
||||||
for r in right {
|
for r in right {
|
||||||
has_cross_var = p.check_cross_variables(left, r)
|
has_cross_var = p.check_cross_variables(left, r)
|
||||||
|
if has_cross_var {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i, lx in left {
|
for i, lx in left {
|
||||||
|
|
|
@ -985,10 +985,12 @@ fn (mut p Parser) index_expr(left ast.Expr) ast.IndexExpr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// [expr]
|
// [expr]
|
||||||
|
end := p.tok.position()
|
||||||
p.check(.rsbr)
|
p.check(.rsbr)
|
||||||
return ast.IndexExpr{
|
return ast.IndexExpr{
|
||||||
left: left
|
left: left
|
||||||
index: expr
|
index: expr
|
||||||
|
expr: p.scanner.expr_string(left.position(), end).replace(' ', '')
|
||||||
pos: p.tok.position()
|
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