summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--comp/compiler.go28
-rw-r--r--interp/interpreter_test.go14
-rw-r--r--parser/decl.go2
-rw-r--r--parser/parse.go8
-rw-r--r--vm/vm.go9
5 files changed, 38 insertions, 23 deletions
diff --git a/comp/compiler.go b/comp/compiler.go
index 37ed0bd..ebb9926 100644
--- a/comp/compiler.go
+++ b/comp/compiler.go
@@ -208,15 +208,25 @@ func (c *Compiler) Generate(tokens parser.Tokens) (err error) {
c.emit(t, vm.Grow, t.Arg[0].(int))
case lang.Define:
- rhs := pop()
- typ := rhs.Type
- if typ == nil {
- typ = rhs.Value.Type
+ showStack(stack)
+ n := t.Arg[0].(int)
+ l := len(stack)
+ rhs := stack[l-n:]
+ stack = stack[:l-n]
+ l = len(stack)
+ lhs := stack[l-n:]
+ stack = stack[:l-n]
+ showStack(stack)
+ for i, r := range rhs {
+ // Propage type of rhs to lhs.
+ typ := r.Type
+ if typ == nil {
+ typ = r.Value.Type
+ }
+ lhs[i].Type = typ
+ c.Data[lhs[i].Index] = vm.NewValue(typ)
}
- lhs := pop()
- lhs.Type = typ
- c.Data[lhs.Index] = vm.NewValue(typ)
- c.emit(t, vm.Vassign)
+ c.emit(t, vm.Vassign, n)
case lang.Assign:
rhs := pop()
@@ -234,7 +244,7 @@ func (c *Compiler) Generate(tokens parser.Tokens) (err error) {
c.Data[lhs.Index] = vm.NewValue(rhs.Type)
c.Symbols[lhs.Name].Type = rhs.Type
}
- c.emit(t, vm.Vassign)
+ c.emit(t, vm.Vassign, t.Arg[0].(int))
case lang.IndexAssign:
s := stack[len(stack)-3]
diff --git a/interp/interpreter_test.go b/interp/interpreter_test.go
index e6274a4..4e8721a 100644
--- a/interp/interpreter_test.go
+++ b/interp/interpreter_test.go
@@ -72,13 +72,13 @@ func TestExpr(t *testing.T) {
func TestAssign(t *testing.T) {
run(t, []etest{
- {src: "var a int = 1; a", res: "1"}, // #00
- {src: "var a, b int = 1, 2; b", res: "2"}, // #01
- {src: "var a, b int; a, b = 1, 2; b", res: "2"}, // #02
- {src: "a, b := 1, 2; b", res: "2"}, // #03
- {src: "func f() int {return 2}; a := f(); a", res: "2"}, // #04
- // {src: "func f() (int, int) {return 2, 3}; a, b := f(), b", res: "3"}, // #05
- // {src: "func f() (int, int) {return 2, 3}; var a, b = f(), b", res: "3"}, // #06
+ {src: "var a int = 1; a", res: "1"}, // #00
+ {src: "var a, b int = 1, 2; b", res: "2"}, // #01
+ {src: "var a, b int; a, b = 1, 2; b", res: "2"}, // #02
+ {src: "a, b := 1, 2; b", res: "2"}, // #03
+ {src: "func f() int {return 2}; a := f(); a", res: "2"}, // #04
+ {src: "func f() (int, int) {return 2, 3}; a, b := f(); b", res: "3"}, // #05
+ // {src: "func f() (int, int) {return 2, 3}; var a, b = f(); b", res: "3"}, // #06
})
}
diff --git a/parser/decl.go b/parser/decl.go
index 378eb56..0ba0075 100644
--- a/parser/decl.go
+++ b/parser/decl.go
@@ -358,7 +358,7 @@ func (p *Parser) parseVarLine(in Tokens) (out Tokens, err error) {
}
out = append(out, newIdent(vars[i], 0))
out = append(out, v...)
- out = append(out, newToken(lang.Assign, "", 0))
+ out = append(out, newToken(lang.Assign, "", 0, 1))
}
return out, err
}
diff --git a/parser/parse.go b/parser/parse.go
index 9c1fd13..68721f2 100644
--- a/parser/parse.go
+++ b/parser/parse.go
@@ -184,11 +184,11 @@ func (p *Parser) parseAssign(in Tokens, aindex int) (out Tokens, err error) {
// Map elements cannot be assigned directly, but only through IndexAssign.
out = out[:len(out)-1]
out = append(out, toks...)
- out = append(out, newToken(lang.IndexAssign, "", in[aindex].Pos))
+ out = append(out, newToken(lang.IndexAssign, "", in[aindex].Pos, len(lhs)))
} else {
out = append(out, toks...)
if out[len(out)-1].Tok != lang.Range {
- out = append(out, newToken(in[aindex].Tok, "", in[aindex].Pos))
+ out = append(out, newToken(in[aindex].Tok, "", in[aindex].Pos, len(lhs)))
}
}
return out, err
@@ -215,10 +215,10 @@ func (p *Parser) parseAssign(in Tokens, aindex int) (out Tokens, err error) {
// Map elements cannot be assigned directly, but only through IndexAssign.
out = out[:len(out)-1]
out = append(out, toks...)
- out = append(out, newToken(lang.IndexAssign, "", in[aindex].Pos))
+ out = append(out, newToken(lang.IndexAssign, "", in[aindex].Pos, 1))
} else {
out = append(out, toks...)
- out = append(out, newToken(in[aindex].Tok, "", in[aindex].Pos))
+ out = append(out, newToken(in[aindex].Tok, "", in[aindex].Pos, 1))
}
}
return out, err
diff --git a/vm/vm.go b/vm/vm.go
index f5bb78e..96d61eb 100644
--- a/vm/vm.go
+++ b/vm/vm.go
@@ -311,8 +311,13 @@ func (m *Machine) Run() (err error) {
mem[sp-3].SetMapIndex(mem[sp-2].Value, mem[sp-1].Value)
mem = mem[:sp-2]
case Vassign:
- mem[sp-2].Set(mem[sp-1].Value)
- mem = mem[:sp-2]
+ n := c.Arg[0]
+ for i := 0; i < n; i++ {
+ mem[sp-n-i-1].Set(mem[sp-n+i].Value)
+ }
+ mem = mem[:sp-n-1]
+ // mem[sp-2].Set(mem[sp-1].Value)
+ // mem = mem[:sp-2]
}
ip++
}