bind.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "os"
  6. "strings"
  7. )
  8. func parseFunc(s string) value {
  9. if !isList(s) {
  10. return value{val: s}
  11. }
  12. list := parseList(s)
  13. if len(list) != 2 || !isList(list[0]) || !isList(list[1]) {
  14. return value{val: s, list: list}
  15. }
  16. param := parseList(list[0])
  17. for _, name := range param {
  18. if !isName(`"` + name) {
  19. return value{val: s, list: list}
  20. }
  21. }
  22. local := make(environ)
  23. for name, val := range env[len(env)-1] {
  24. local[name] = val
  25. }
  26. return value{val: s, list: list, param: param, env: local}
  27. }
  28. func getFunc(name string) value {
  29. if !isName(`"` + name) {
  30. return value{}
  31. }
  32. envs := []int{len(env) - 1, len(env) - 2, 1}
  33. for _, id := range envs {
  34. val, ok := env[id][name]
  35. if ok {
  36. return val
  37. }
  38. }
  39. return value{}
  40. }
  41. func opMake(val1, val2 value) value {
  42. name := toName(val1.val)
  43. _, ok := reserved[name]
  44. if ok {
  45. panic(fmt.Errorf("make: %s (%s)", errNameReserved, name))
  46. }
  47. if isList(val2.val) && val2.list == nil {
  48. val2 = parseFunc(val2.val)
  49. }
  50. env[len(env)-1][name] = val2
  51. return val2
  52. }
  53. func opThing(val1 value) value {
  54. name := toName(val1.val)
  55. envs := []int{len(env) - 1, len(env) - 2, 1}
  56. for _, id := range envs {
  57. val, ok := env[id][name]
  58. if ok {
  59. return val
  60. }
  61. }
  62. panic(fmt.Errorf("thing: %s (%s)", errNameNotFound, name))
  63. }
  64. func opErase(val1 value) value {
  65. name := toName(val1.val)
  66. val, ok := env[len(env)-1][name]
  67. if ok {
  68. delete(env[len(env)-1], name)
  69. return val
  70. }
  71. panic(fmt.Errorf("erase: %s (%s)", errNameNotFound, name))
  72. }
  73. func opExport(val1 value) value {
  74. name := toName(val1.val)
  75. val, ok := env[len(env)-1][name]
  76. if ok {
  77. env[1][name] = val
  78. return val
  79. }
  80. panic(fmt.Errorf("export: %s (%s)", errNameNotFound, name))
  81. }
  82. func opSave(val1 value) value {
  83. name := toName(val1.val)
  84. s := ""
  85. for name, val := range env[len(env)-1] {
  86. s += `make "` + name + " " + val.val + "\n"
  87. }
  88. err := os.WriteFile(name, []byte(s), 0666)
  89. if err != nil {
  90. panic(fmt.Errorf("save: %s (%s)", errFileError, name))
  91. }
  92. return val1
  93. }
  94. func opLoad(val1 value) value {
  95. name := toName(val1.val)
  96. s, err := os.ReadFile(name)
  97. if err != nil {
  98. panic(fmt.Errorf("load: %s (%s)", errFileError, name))
  99. }
  100. interpret(bufio.NewScanner(strings.NewReader(string(s))))
  101. return value{val: "true"}
  102. }
  103. func opErAll() value {
  104. env[len(env)-1] = make(environ)
  105. return value{val: "true"}
  106. }
  107. func opPoAll() value {
  108. list := []string{}
  109. for name := range env[len(env)-1] {
  110. list = append(list, name)
  111. }
  112. return value{val: "[ " + strings.Join(list, " ") + " ]"}
  113. }