| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- package main
- import (
- "bufio"
- "fmt"
- "os"
- "strconv"
- "strings"
- )
- func assign(s string, index []string, val string) string {
- if len(index) == 0 {
- return val
- }
- list, i := parseList(s), toInt(index[0])
- return spliceList(list, i, 1, assign(indexOfList(list, i), index[1:], 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]
- if ok {
- return value{}, fmt.Errorf("setvalue: %s (%s)", errNameReserved, name)
- }
- oldVal, ok := env[len(env)-1][name]
- if !ok && len(index) > 0 {
- return value{}, fmt.Errorf("setvalue: %s (%s)", errNameNotFound, name)
- }
- if len(index) > 0 {
- if isWord(val.val) {
- val.val = val.val[1:]
- }
- val = value{val: assign(oldVal.val, index, val.val)}
- }
- val = toValue(val)
- env[len(env)-1][name] = val
- return val, nil
- }
- 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}
- for _, id := range envs {
- val, ok := env[id][name]
- if ok {
- for _, i := range index {
- list, r := parseList(val.val), strings.Split(i, ":")
- if len(r) == 1 {
- val = value{val: indexOfList(list, toInt(r[0]))}
- if !isList(val.val) {
- val.val = `"` + val.val
- }
- } else {
- if r[0] == "" {
- r[0] = "0"
- }
- if r[1] == "" {
- r[1] = strconv.FormatInt(int64(len(list)), 10)
- }
- val = value{val: rangeOfList(list, toInt(r[0]), toInt(r[1]))}
- }
- }
- return val, nil
- }
- }
- 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 {
- name := toName(val1.val)
- val, ok := env[len(env)-1][name]
- if ok {
- delete(env[len(env)-1], name)
- return val
- }
- panic(fmt.Errorf("erase: %s (%s)", errNameNotFound, name))
- }
- func opExport(val1 value) value {
- name := toName(val1.val)
- val, ok := env[len(env)-1][name]
- if ok {
- env[1][name] = val
- return val
- }
- panic(fmt.Errorf("export: %s (%s)", errNameNotFound, name))
- }
- func opSave(val1 value) value {
- name := toName(val1.val)
- s := ""
- for name, val := range env[len(env)-1] {
- s += `make "` + name + " " + val.val + "\n"
- }
- err := os.WriteFile(name, []byte(s), 0666)
- if err != nil {
- panic(fmt.Errorf("save: %s (%s)", errFileError, name))
- }
- return val1
- }
- func opLoad(val1 value) value {
- name := toName(val1.val)
- s, err := os.ReadFile(name)
- if err != nil {
- panic(fmt.Errorf("load: %s (%s)", errFileError, name))
- }
- interpret(bufio.NewScanner(strings.NewReader(string(s))))
- return value{val: "true"}
- }
- func opErAll() value {
- env[len(env)-1] = make(environ)
- return value{val: "true"}
- }
- func opPoAll() value {
- list := []string{}
- for name := range env[len(env)-1] {
- list = append(list, name)
- }
- return value{val: makeList(list)}
- }
|