| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- package main
- import (
- "bufio"
- "fmt"
- "os"
- "strconv"
- "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 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 {
- 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 opMake(val1, val2 value) value {
- name, index := toNameWithIndex(val1.val)
- _, ok := reserved[name]
- if ok {
- panic(fmt.Errorf("make: %s (%s)", errNameReserved, name))
- }
- val, ok := env[len(env)-1][name]
- if !ok && len(index) > 0 {
- panic(fmt.Errorf("make: %s (%s)", errNameNotFound, name))
- }
- if len(index) > 0 {
- if isWord(val2.val) {
- val2.val = val2.val[1:]
- }
- val2 = value{val: assign(val.val, index, val2.val)}
- }
- if isList(val2.val) && val2.list == nil {
- val2 = parseFunc(val2.val)
- }
- env[len(env)-1][name] = val2
- return val2
- }
- func opThing(val1 value) value {
- name, index := toNameWithIndex(val1.val)
- 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
- }
- }
- panic(fmt.Errorf("thing: %s (%s)", errNameNotFound, name))
- }
- 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: "[ " + strings.Join(list, " ") + " ]"}
- }
|