| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- package main
- import (
- "bufio"
- "fmt"
- "io/ioutil"
- "strings"
- )
- func assign(s string, index []string, val string, envs []environ) string {
- if len(index) == 0 {
- return val
- }
- list, _ := parseList(s)
- i := toInt(value{word: index[0]}, envs)
- return spliceList(list, i, 1, assign(indexOfList(list, i), index[1:], val, envs))
- }
- func setValue(s string, val value, envs []environ) (value, error) {
- if !isNameWithIndex(value{word: s}) {
- return value{}, fmt.Errorf("set: %s (%s)", errInvalidName, s)
- }
- name, index := toNameWithIndex(value{word: s})
- _, ok := reserved[name]
- if ok {
- return value{}, fmt.Errorf("set: %s (%s)", errNameReserved, name)
- }
- oldVal, ok := envs[0][name]
- if ok {
- delete(envs[0], name)
- if len(index) > 0 {
- val = value{word: assign(toString(oldVal), index, toString(val), envs)}
- }
- } else if len(index) > 0 {
- return value{}, fmt.Errorf("set: %s (%s)", errNameNotFound, name)
- }
- val = toValue(val, envs[0])
- envs[0][name] = val
- return val, nil
- }
- func getValue(s string, envs []environ) (value, error) {
- if !isNameWithIndex(value{word: s}) {
- return value{}, fmt.Errorf("get: %s (%s)", errInvalidName, s)
- }
- name, index := toNameWithIndex(value{word: s})
- for _, env := range envs {
- val, ok := env[name]
- if ok {
- if len(index) > 0 {
- val = value{word: toString(val)}
- for _, i := range index {
- list, _ := parseList(val.word)
- r := strings.Split(i, ":")
- if len(r) == 1 {
- val = value{word: indexOfList(list, toInt(value{word: r[0]}, envs))}
- if !isList(val) {
- val.word = `"` + val.word
- }
- } else {
- num1, num2 := 0, len(list)
- if r[0] != "" {
- num1 = toInt(value{word: r[0]}, envs)
- }
- if r[1] != "" {
- num2 = toInt(value{word: r[1]}, envs)
- }
- val = value{word: rangeOfList(list, num1, num2)}
- }
- }
- }
- return val, nil
- }
- }
- return value{}, fmt.Errorf("get: %s (%s)", errNameNotFound, name)
- }
- func opMake(val1, val2 value, envs []environ) value {
- val, err := setValue(val1.word, val2, envs)
- if err != nil {
- panic(err)
- }
- return val
- }
- func opThing(val1 value, envs []environ) value {
- val, err := getValue(val1.word, envs)
- if err != nil {
- panic(err)
- }
- return val
- }
- func opErase(val1 value, envs []environ) value {
- name := toName(val1)
- for _, env := range envs {
- val, ok := env[name]
- if ok {
- delete(env, name)
- return val
- }
- }
- panic(fmt.Errorf("erase: %s (%s)", errNameNotFound, name))
- }
- func opExport(val1 value, envs []environ) value {
- name := toName(val1)
- val, ok := envs[0][name]
- if ok {
- envs[2][name] = val
- return val
- }
- panic(fmt.Errorf("export: %s (%s)", errNameNotFound, name))
- }
- func opSave(val1 value, env environ) value {
- name := toName(val1)
- s := ""
- for name, val := range env {
- s += `make "` + name + " " + val.word + "\n"
- }
- err := ioutil.WriteFile(name, []byte(s), 0666)
- if err != nil {
- panic(fmt.Errorf("save: %s (%s)", errFileError, name))
- }
- return val1
- }
- func opLoad(val1 value, env environ) value {
- name := toName(val1)
- s, err := ioutil.ReadFile(name)
- if err != nil {
- panic(fmt.Errorf("load: %s (%s)", errFileError, name))
- }
- scanner := bufio.NewScanner(strings.NewReader(string(s)))
- scanner.Split(splitFunc)
- interpret(&scanProvider{isList: false, scanner: scanner}, []environ{env, nil, nil})
- return value{tp: typeBool, b: true}
- }
- func opErAll(env environ) value {
- for name := range env {
- delete(env, name)
- }
- return value{tp: typeBool, b: true}
- }
- func opPoAll(env environ) value {
- list := []string{}
- for name := range env {
- list = append(list, name)
- }
- return value{word: makeList(list)}
- }
|