| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- package main
- import (
- "bufio"
- "fmt"
- "os"
- "strings"
- )
- func parseFunc(val string) value {
- if !isList(val) {
- return value{body: errNop}
- }
- list := strings.Split(val, " ")
- if list[1] != "[" {
- return value{body: errNop}
- }
- i := 2
- for ; list[i] != "]"; i++ {
- if !isName(`"` + list[i]) {
- return value{body: errNop}
- }
- }
- if i == len(list)-2 {
- return value{body: errNop}
- }
- j, bracketCnt := i+1, 0
- for ; j < len(list)-1; j++ {
- if list[j] == "[" {
- bracketCnt++
- }
- if list[j] == "]" {
- bracketCnt--
- }
- if bracketCnt == 0 && j < len(list)-2 {
- return value{body: errNop}
- }
- }
- local := make(environ)
- for name, val := range env[len(env)-1] {
- local[name] = val
- }
- return value{
- val: val,
- param: list[2:i],
- body: strings.Join(list[i+1:len(list)-1], " "),
- env: local}
- }
- func getFunc(name string) value {
- if !isName(`"` + name) {
- return value{body: errNop}
- }
- envs := []int{len(env) - 1, len(env) - 2, 1}
- for _, id := range envs {
- val, ok := env[id][name]
- if ok {
- return val
- }
- }
- return value{body: errNop}
- }
- func opMake(val1, val2 value) value {
- name := toName(val1.val)
- _, ok := reserved[name]
- if ok {
- panic(fmt.Errorf("make: %s (%s)", errNameReserved, name))
- }
- if isList(val2.val) && val2.body == "" {
- val2 = parseFunc(val2.val)
- }
- env[len(env)-1][name] = val2
- return val2
- }
- func opThing(val1 value) value {
- name := toName(val1.val)
- envs := []int{len(env) - 1, len(env) - 2, 1}
- for _, id := range envs {
- val, ok := env[id][name]
- if ok {
- 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, " ") + " ]"}
- }
|