|
@@ -8,48 +8,6 @@ import (
|
|
|
"strings"
|
|
"strings"
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
-func parseFunc(s string) value {
|
|
|
|
|
- if !isList(s) {
|
|
|
|
|
- return value{val: s}
|
|
|
|
|
- }
|
|
|
|
|
- list := parseList(s)
|
|
|
|
|
- if len(list) != 2 || !isList(list[0]) || !isList(list[1]) {
|
|
|
|
|
- return value{val: s, list: list}
|
|
|
|
|
- }
|
|
|
|
|
- param := parseList(list[0])
|
|
|
|
|
- for _, name := range param {
|
|
|
|
|
- if !isName(`"` + name) {
|
|
|
|
|
- return value{val: s, list: list}
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- local := make(environ)
|
|
|
|
|
- for name, val := range env[len(env)-1] {
|
|
|
|
|
- local[name] = val
|
|
|
|
|
- }
|
|
|
|
|
- return value{val: s, list: list, param: param, env: local}
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-func wrapFunc(val value) value {
|
|
|
|
|
- if isList(val.val) && val.list == nil {
|
|
|
|
|
- return parseFunc(val.val)
|
|
|
|
|
- }
|
|
|
|
|
- return val
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-func getFunc(name string) value {
|
|
|
|
|
- if !isName(`"` + name) {
|
|
|
|
|
- return value{}
|
|
|
|
|
- }
|
|
|
|
|
- envs := []int{len(env) - 1, len(env) - 2, 1}
|
|
|
|
|
- for _, id := range envs {
|
|
|
|
|
- val, ok := env[id][name]
|
|
|
|
|
- if ok {
|
|
|
|
|
- return val
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return value{}
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
func assign(s string, index []string, val string) string {
|
|
func assign(s string, index []string, val string) string {
|
|
|
if len(index) == 0 {
|
|
if len(index) == 0 {
|
|
|
return val
|
|
return val
|
|
@@ -58,28 +16,35 @@ func assign(s string, index []string, val string) string {
|
|
|
return spliceList(list, i, 1, assign(indexOfList(list, i), index[1:], val))
|
|
return spliceList(list, i, 1, assign(indexOfList(list, i), index[1:], val))
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func opMake(val1, val2 value) value {
|
|
|
|
|
- name, index := toNameWithIndex(val1.val)
|
|
|
|
|
|
|
+func setValue(s string, val value) (value, error) {
|
|
|
|
|
+ if !isNameWithIndex(s) {
|
|
|
|
|
+ return value{}, fmt.Errorf("setvalue: %s (%s)", errInvalidName, s)
|
|
|
|
|
+ }
|
|
|
|
|
+ name, index := toNameWithIndex(s)
|
|
|
_, ok := reserved[name]
|
|
_, ok := reserved[name]
|
|
|
if ok {
|
|
if ok {
|
|
|
- panic(fmt.Errorf("make: %s (%s)", errNameReserved, name))
|
|
|
|
|
|
|
+ return value{}, fmt.Errorf("setvalue: %s (%s)", errNameReserved, name)
|
|
|
}
|
|
}
|
|
|
- val, ok := env[len(env)-1][name]
|
|
|
|
|
|
|
+ oldVal, ok := env[len(env)-1][name]
|
|
|
if !ok && len(index) > 0 {
|
|
if !ok && len(index) > 0 {
|
|
|
- panic(fmt.Errorf("make: %s (%s)", errNameNotFound, name))
|
|
|
|
|
|
|
+ return value{}, fmt.Errorf("setvalue: %s (%s)", errNameNotFound, name)
|
|
|
}
|
|
}
|
|
|
if len(index) > 0 {
|
|
if len(index) > 0 {
|
|
|
- if isWord(val2.val) {
|
|
|
|
|
- val2.val = val2.val[1:]
|
|
|
|
|
|
|
+ if isWord(val.val) {
|
|
|
|
|
+ val.val = val.val[1:]
|
|
|
}
|
|
}
|
|
|
- val2 = value{val: assign(val.val, index, val2.val)}
|
|
|
|
|
|
|
+ val = value{val: assign(oldVal.val, index, val.val)}
|
|
|
}
|
|
}
|
|
|
- env[len(env)-1][name] = wrapFunc(val2)
|
|
|
|
|
- return val2
|
|
|
|
|
|
|
+ val = toValue(val)
|
|
|
|
|
+ env[len(env)-1][name] = val
|
|
|
|
|
+ return val, nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func opThing(val1 value) value {
|
|
|
|
|
- name, index := toNameWithIndex(val1.val)
|
|
|
|
|
|
|
+func getValue(s string) (value, error) {
|
|
|
|
|
+ if !isNameWithIndex(s) {
|
|
|
|
|
+ return value{}, fmt.Errorf("getvalue: %s (%s)", errInvalidName, s)
|
|
|
|
|
+ }
|
|
|
|
|
+ name, index := toNameWithIndex(s)
|
|
|
envs := []int{len(env) - 1, len(env) - 2, 1}
|
|
envs := []int{len(env) - 1, len(env) - 2, 1}
|
|
|
for _, id := range envs {
|
|
for _, id := range envs {
|
|
|
val, ok := env[id][name]
|
|
val, ok := env[id][name]
|
|
@@ -101,10 +66,26 @@ func opThing(val1 value) value {
|
|
|
val = value{val: rangeOfList(list, toInt(r[0]), toInt(r[1]))}
|
|
val = value{val: rangeOfList(list, toInt(r[0]), toInt(r[1]))}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- return val
|
|
|
|
|
|
|
+ return val, nil
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- panic(fmt.Errorf("thing: %s (%s)", errNameNotFound, name))
|
|
|
|
|
|
|
+ return value{}, fmt.Errorf("getvalue: %s (%s)", errNameNotFound, name)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func opMake(val1, val2 value) value {
|
|
|
|
|
+ val, err := setValue(val1.val, val2)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ panic(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ return val
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func opThing(val1 value) value {
|
|
|
|
|
+ val, err := getValue(val1.val)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ panic(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ return val
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func opErase(val1 value) value {
|
|
func opErase(val1 value) value {
|
|
@@ -160,5 +141,5 @@ func opPoAll() value {
|
|
|
for name := range env[len(env)-1] {
|
|
for name := range env[len(env)-1] {
|
|
|
list = append(list, name)
|
|
list = append(list, name)
|
|
|
}
|
|
}
|
|
|
- return value{val: "[ " + strings.Join(list, " ") + " ]"}
|
|
|
|
|
|
|
+ return value{val: makeList(list)}
|
|
|
}
|
|
}
|