bind.go 3.5 KB

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