split SimpleVar to SimpleVar and AutomaticVar
SimpleVar uses string, while AutomaticVar uses []byte
diff --git a/ast.go b/ast.go
index 7a418be..a8a2d8b 100644
--- a/ast.go
+++ b/ast.go
@@ -55,9 +55,16 @@
// TODO(ukai): handle ast.opt == "export"
switch ast.op {
case ":=":
- var buf bytes.Buffer
- ast.rhs.Eval(&buf, ev)
- return &SimpleVar{value: buf.Bytes(), origin: origin}
+ switch v := ast.rhs.(type) {
+ case literal:
+ return &SimpleVar{value: v.String(), origin: origin}
+ case tmpval:
+ return &SimpleVar{value: v.String(), origin: origin}
+ default:
+ var buf bytes.Buffer
+ v.Eval(&buf, ev)
+ return &SimpleVar{value: buf.String(), origin: origin}
+ }
case "=":
return &RecursiveVar{expr: ast.rhs, origin: origin}
case "+=":
diff --git a/func.go b/func.go
index 4bde31a..3378ebc 100644
--- a/func.go
+++ b/func.go
@@ -813,9 +813,8 @@
for i, arg := range args {
name := strconv.FormatInt(int64(i), 10)
restores = append(restores, ev.outVars.save(name))
- ev.outVars.Assign(name, &SimpleVar{
- value: arg,
- origin: "automatic", // ??
+ ev.outVars.Assign(name, &AutomaticVar{
+ value: arg,
})
}
@@ -989,9 +988,10 @@
if err != nil {
panic(fmt.Sprintf("eval assign error: %q: %v", f.String(), err))
}
- var vbuf bytes.Buffer
- expr.Eval(&vbuf, ev)
- rvalue = &SimpleVar{value: tmpval(vbuf.Bytes()), origin: "file"}
+ vbuf := newBuf()
+ expr.Eval(vbuf, ev)
+ rvalue = &SimpleVar{value: vbuf.String(), origin: "file"}
+ freeBuf(vbuf)
case "=":
rvalue = &RecursiveVar{expr: tmpval(rhs), origin: "file"}
case "+=":
@@ -1118,11 +1118,7 @@
space := false
for ws.Scan() {
word := ws.Bytes()
- ev.outVars.Assign(varname,
- &SimpleVar{
- value: tmpval(word),
- origin: "automatic",
- })
+ ev.outVars.Assign(varname, &AutomaticVar{value: word})
if space {
w.Write([]byte{' '})
}
diff --git a/main.go b/main.go
index 41eea88..5a0924c 100644
--- a/main.go
+++ b/main.go
@@ -221,7 +221,7 @@
origin: "environment",
})
}
- vars.Assign("MAKEFILE_LIST", &SimpleVar{value: []byte{}, origin: "file"})
+ vars.Assign("MAKEFILE_LIST", &SimpleVar{value: "", origin: "file"})
for _, v := range clvars {
kv := strings.SplitN(v, "=", 2)
Logf("cmdlinevar %q", kv)
diff --git a/serialize.go b/serialize.go
index 4ee0b29..fbcbed0 100644
--- a/serialize.go
+++ b/serialize.go
@@ -354,7 +354,7 @@
case "simple":
return &SimpleVar{
- value: []byte(sv.V),
+ value: sv.V,
origin: sv.Origin,
}
case "recursive":
diff --git a/var.go b/var.go
index 8b0b6ef..5425e6d 100644
--- a/var.go
+++ b/var.go
@@ -16,6 +16,7 @@
import (
"bytes"
+ "fmt"
"io"
)
@@ -78,8 +79,7 @@
}
type SimpleVar struct {
- // TODO(ukai): []byte -> Value (literal or so?)
- value []byte
+ value string
origin string
}
@@ -87,20 +87,20 @@
func (v *SimpleVar) Origin() string { return v.origin }
func (v *SimpleVar) IsDefined() bool { return true }
-func (v *SimpleVar) String() string { return string(v.value) }
+func (v *SimpleVar) String() string { return v.value }
func (v *SimpleVar) Eval(w io.Writer, ev *Evaluator) {
- w.Write(v.value)
+ io.WriteString(w, v.value)
}
func (v *SimpleVar) Serialize() SerializableVar {
return SerializableVar{
Type: "simple",
- V: string(v.value),
+ V: v.value,
Origin: v.origin,
}
}
func (v *SimpleVar) Dump(w io.Writer) {
dumpByte(w, ValueTypeSimple)
- dumpBytes(w, v.value)
+ dumpString(w, v.value)
dumpString(w, v.origin)
}
@@ -109,6 +109,45 @@
if err != nil {
panic(err)
}
+ abuf := newBuf()
+ val.Eval(abuf, ev)
+ v.value += " " + abuf.String()
+ freeBuf(abuf)
+ return v
+}
+
+func (v *SimpleVar) AppendVar(ev *Evaluator, val Value) Var {
+ abuf := newBuf()
+ val.Eval(abuf, ev)
+ v.value += " " + abuf.String()
+ freeBuf(abuf)
+ return v
+}
+
+type AutomaticVar struct {
+ value []byte
+}
+
+func (v *AutomaticVar) Flavor() string { return "simple" }
+func (v *AutomaticVar) Origin() string { return "automatic" }
+func (v *AutomaticVar) IsDefined() bool { return true }
+
+func (v *AutomaticVar) String() string { return string(v.value) }
+func (v *AutomaticVar) Eval(w io.Writer, ev *Evaluator) {
+ w.Write(v.value)
+}
+func (v *AutomaticVar) Serialize() SerializableVar {
+ panic(fmt.Sprintf("cannnot serialize automatic var:%s", v.value))
+}
+func (v *AutomaticVar) Dump(w io.Writer) {
+ panic(fmt.Sprintf("cannnot dump automatic var:%s", v.value))
+}
+
+func (v *AutomaticVar) Append(ev *Evaluator, s string) Var {
+ val, _, err := parseExpr([]byte(s), nil, false)
+ if err != nil {
+ panic(err)
+ }
buf := bytes.NewBuffer(v.value)
buf.WriteByte(' ')
val.Eval(buf, ev)
@@ -116,7 +155,7 @@
return v
}
-func (v *SimpleVar) AppendVar(ev *Evaluator, val Value) Var {
+func (v *AutomaticVar) AppendVar(ev *Evaluator, val Value) Var {
buf := bytes.NewBuffer(v.value)
buf.WriteByte(' ')
val.Eval(buf, ev)