bind.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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(&_unknown{s: 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(&_unknown{s: s}) {
  18. return nil, fmt.Errorf("set: %s (%s)", errInvalidName, s)
  19. }
  20. name, index := toNameWithIndex(&_unknown{s: s})
  21. _, ok := reserved[name]
  22. if ok {
  23. return nil, 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 = &_unknown{s: assign(oldVal.String(), index, val.String(), envs)}
  30. }
  31. } else if len(index) > 0 {
  32. return nil, fmt.Errorf("set: %s (%s)", errNameNotFound, name)
  33. }
  34. val = toValue(val, envs)
  35. envs[0][name] = val
  36. return val, nil
  37. }
  38. func getValue(s string, envs []environ) (value, error) {
  39. if !isNameWithIndex(&_unknown{s: s}) {
  40. return nil, fmt.Errorf("get: %s (%s)", errInvalidName, s)
  41. }
  42. name, index := toNameWithIndex(&_unknown{s: s})
  43. for _, env := range envs {
  44. val, ok := env[name]
  45. if ok {
  46. if len(index) > 0 {
  47. for _, i := range index {
  48. list := parseList(val.String())
  49. r, s := strings.Split(i, ":"), ""
  50. if len(r) == 1 {
  51. s = indexOfList(list, toInt(&_unknown{s: r[0]}, envs))
  52. if !isList(&_unknown{s: s}) {
  53. s = `"` + s
  54. }
  55. } else {
  56. num1, num2 := 0, len(list)
  57. if len(r[0]) > 0 {
  58. num1 = toInt(&_unknown{s: r[0]}, envs)
  59. }
  60. if len(r[1]) > 0 {
  61. num2 = toInt(&_unknown{s: r[1]}, envs)
  62. }
  63. s = rangeOfList(list, num1, num2)
  64. }
  65. val = &_unknown{s: s}
  66. }
  67. }
  68. return val, nil
  69. }
  70. }
  71. return nil, fmt.Errorf("get: %s (%s)", errNameNotFound, name)
  72. }
  73. func opMake(val1, val2 value, envs []environ) value {
  74. val, err := setValue(val1.String(), 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.String(), 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. if envs[1] != nil {
  103. envs[1][name] = val
  104. }
  105. return val
  106. }
  107. panic(fmt.Errorf("export: %s (%s)", errNameNotFound, name))
  108. }
  109. func opSave(val1 value, env environ) value {
  110. name := toName(val1)
  111. s := ""
  112. for name, val := range env {
  113. s += `make "` + name + " " + val.String() + "\n"
  114. }
  115. err := ioutil.WriteFile(name, []byte(s), 0666)
  116. if err != nil {
  117. panic(fmt.Errorf("save: %s (%s)", errFileError, name))
  118. }
  119. return val1
  120. }
  121. func opLoad(val1 value, env environ) *_bool {
  122. name := toName(val1)
  123. s, err := ioutil.ReadFile(name)
  124. if err != nil {
  125. panic(fmt.Errorf("load: %s (%s)", errFileError, name))
  126. }
  127. scanner := bufio.NewScanner(strings.NewReader(string(s)))
  128. scanner.Split(splitFunc)
  129. interpret(&scanProvider{isList: false, scanner: scanner}, []environ{env, nil, nil})
  130. return &_bool{b: true}
  131. }
  132. func opErAll(env environ) *_bool {
  133. for name := range env {
  134. delete(env, name)
  135. }
  136. return &_bool{b: true}
  137. }
  138. func opPoAll(env environ) *_list {
  139. list := []string{}
  140. for name := range env {
  141. list = append(list, name)
  142. }
  143. return &_list{list: list}
  144. }