bind.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "os"
  6. "strconv"
  7. "strings"
  8. )
  9. func assign(s string, index []string, val string) string {
  10. if len(index) == 0 {
  11. return val
  12. }
  13. list, i := parseList(s), toInt(index[0])
  14. return spliceList(list, i, 1, assign(indexOfList(list, i), index[1:], val))
  15. }
  16. func setValue(s string, val value) (value, error) {
  17. if !isNameWithIndex(s) {
  18. return value{}, fmt.Errorf("setvalue: %s (%s)", errInvalidName, s)
  19. }
  20. name, index := toNameWithIndex(s)
  21. _, ok := reserved[name]
  22. if ok {
  23. return value{}, fmt.Errorf("setvalue: %s (%s)", errNameReserved, name)
  24. }
  25. oldVal, ok := env[len(env)-1][name]
  26. if !ok && len(index) > 0 {
  27. return value{}, fmt.Errorf("setvalue: %s (%s)", errNameNotFound, name)
  28. }
  29. if len(index) > 0 {
  30. if isWord(val.val) {
  31. val.val = val.val[1:]
  32. }
  33. val = value{val: assign(oldVal.val, index, val.val)}
  34. }
  35. val = toValue(val)
  36. env[len(env)-1][name] = val
  37. return val, nil
  38. }
  39. func getValue(s string) (value, error) {
  40. if !isNameWithIndex(s) {
  41. return value{}, fmt.Errorf("getvalue: %s (%s)", errInvalidName, s)
  42. }
  43. name, index := toNameWithIndex(s)
  44. envs := []int{len(env) - 1, len(env) - 2, 1}
  45. for _, id := range envs {
  46. val, ok := env[id][name]
  47. if ok {
  48. for _, i := range index {
  49. list, r := parseList(val.val), strings.Split(i, ":")
  50. if len(r) == 1 {
  51. val = value{val: indexOfList(list, toInt(r[0]))}
  52. if !isList(val.val) {
  53. val.val = `"` + val.val
  54. }
  55. } else {
  56. if r[0] == "" {
  57. r[0] = "0"
  58. }
  59. if r[1] == "" {
  60. r[1] = strconv.FormatInt(int64(len(list)), 10)
  61. }
  62. val = value{val: rangeOfList(list, toInt(r[0]), toInt(r[1]))}
  63. }
  64. }
  65. return val, nil
  66. }
  67. }
  68. return value{}, fmt.Errorf("getvalue: %s (%s)", errNameNotFound, name)
  69. }
  70. func opMake(val1, val2 value) value {
  71. val, err := setValue(val1.val, val2)
  72. if err != nil {
  73. panic(err)
  74. }
  75. return val
  76. }
  77. func opThing(val1 value) value {
  78. val, err := getValue(val1.val)
  79. if err != nil {
  80. panic(err)
  81. }
  82. return val
  83. }
  84. func opErase(val1 value) value {
  85. name := toName(val1.val)
  86. val, ok := env[len(env)-1][name]
  87. if ok {
  88. delete(env[len(env)-1], name)
  89. return val
  90. }
  91. panic(fmt.Errorf("erase: %s (%s)", errNameNotFound, name))
  92. }
  93. func opExport(val1 value) value {
  94. name := toName(val1.val)
  95. val, ok := env[len(env)-1][name]
  96. if ok {
  97. env[1][name] = val
  98. return val
  99. }
  100. panic(fmt.Errorf("export: %s (%s)", errNameNotFound, name))
  101. }
  102. func opSave(val1 value) value {
  103. name := toName(val1.val)
  104. s := ""
  105. for name, val := range env[len(env)-1] {
  106. s += `make "` + name + " " + val.val + "\n"
  107. }
  108. err := os.WriteFile(name, []byte(s), 0666)
  109. if err != nil {
  110. panic(fmt.Errorf("save: %s (%s)", errFileError, name))
  111. }
  112. return val1
  113. }
  114. func opLoad(val1 value) value {
  115. name := toName(val1.val)
  116. s, err := os.ReadFile(name)
  117. if err != nil {
  118. panic(fmt.Errorf("load: %s (%s)", errFileError, name))
  119. }
  120. interpret(bufio.NewScanner(strings.NewReader(string(s))))
  121. return value{val: "true"}
  122. }
  123. func opErAll() value {
  124. env[len(env)-1] = make(environ)
  125. return value{val: "true"}
  126. }
  127. func opPoAll() value {
  128. list := []string{}
  129. for name := range env[len(env)-1] {
  130. list = append(list, name)
  131. }
  132. return value{val: makeList(list)}
  133. }