mua.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "math/rand"
  6. "os"
  7. "strings"
  8. "time"
  9. )
  10. var reserved = map[string]int{
  11. "make": 2, "thing": 1, "print": 1, "read": 0, "add": 2,
  12. "sub": 2, "mul": 2, "div": 2, "mod": 2, "erase": 1,
  13. "isname": 1, "run": 1, "eq": 2, "gt": 2, "lt": 2,
  14. "and": 2, "or": 2, "not": 1, "if": 3, "isnumber": 1,
  15. "isword": 1, "islist": 1, "isbool": 1, "isempty": 1, "return": 1,
  16. "export": 1, "readlist": 0, "word": 2, "sentence": 2, "list": 2,
  17. "join": 2, "first": 1, "last": 1, "butfirst": 1, "butlast": 1,
  18. "random": 1, "int": 1, "sqrt": 1, "save": 1, "load": 1,
  19. "erall": 0, "poall": 0,
  20. "false": 0, "true": 0}
  21. func interpret(scanner *scanProvider, envs []environ) (val value, returned bool) {
  22. stack, returned := []value{}, false
  23. for !returned && scanner.Scan() {
  24. // for _, v := range stack {
  25. // fmt.Println(toString(v))
  26. // }
  27. // fmt.Println()
  28. // fmt.Println(envs[0])
  29. // fmt.Println()
  30. s := scanner.Text()
  31. if s == "\n" {
  32. continue
  33. }
  34. if s[0] == ':' {
  35. leading := len(s) - len(strings.TrimLeft(s, ":"))
  36. val := toValue(&_unknown{s: `"` + s[leading:]}, envs)
  37. for i := 0; i < leading; i++ {
  38. val = toValue(opThing(val, envs), envs)
  39. }
  40. stack = append(stack, val)
  41. } else if s[0] == '[' && !scanner.isList {
  42. list, bracketCnt := []string{}, 0
  43. for {
  44. leading := len(s) - len(strings.TrimLeft(s, "["))
  45. trailing := len(s) - len(strings.TrimRight(s, "]"))
  46. escape := len(s) - len(strings.TrimRight(strings.TrimRight(s, "]"), `\`)) - trailing
  47. trailing -= escape & 1
  48. s = s[leading : len(s)-trailing]
  49. for i := 0; i < leading; i++ {
  50. list = append(list, "[")
  51. }
  52. if len(s) > 0 {
  53. list = append(list, s)
  54. }
  55. for i := 0; i < trailing; i++ {
  56. list = append(list, "]")
  57. }
  58. bracketCnt += leading - trailing
  59. if bracketCnt < 0 {
  60. panic(fmt.Errorf("list: %s", errUnmatchedBracket))
  61. }
  62. if bracketCnt == 0 {
  63. break
  64. }
  65. s = "\n"
  66. for s == "\n" && scanner.Scan() {
  67. s = scanner.Text()
  68. }
  69. if s == "\n" {
  70. panic(fmt.Errorf("list: %s", errUnmatchedBracket))
  71. }
  72. }
  73. stack = append(stack, &_unknown{s: strings.Join(list, " ")})
  74. } else {
  75. stack = append(stack, &_unknown{s: s})
  76. }
  77. for updated := true; !returned && updated; {
  78. updated = false
  79. for i := len(stack) - 1; i >= 0; i-- {
  80. if _, ok := stack[i].(*_unknown); !ok || !isName(stack[i]) {
  81. continue
  82. }
  83. op := stack[i].String()
  84. if paramCnt, ok := reserved[op]; ok {
  85. if op == "false" || op == "true" {
  86. continue
  87. }
  88. if paramCnt == len(stack)-1-i {
  89. for j := i + 1; j < len(stack); j++ {
  90. stack[j] = toValue(stack[j], envs)
  91. }
  92. switch op {
  93. case "make":
  94. stack[i] = opMake(stack[i+1], stack[i+2], envs)
  95. case "thing":
  96. stack[i] = opThing(stack[i+1], envs)
  97. case "print":
  98. stack[i] = opPrint(stack[i+1])
  99. case "read":
  100. stack[i] = opRead(scanner)
  101. case "add":
  102. stack[i] = opAdd(stack[i+1], stack[i+2])
  103. case "sub":
  104. stack[i] = opSub(stack[i+1], stack[i+2])
  105. case "mul":
  106. stack[i] = opMul(stack[i+1], stack[i+2])
  107. case "div":
  108. stack[i] = opDiv(stack[i+1], stack[i+2])
  109. case "mod":
  110. stack[i] = opMod(stack[i+1], stack[i+2])
  111. case "erase":
  112. stack[i] = opErase(stack[i+1], envs)
  113. case "isname":
  114. stack[i] = opIsName(stack[i+1], envs)
  115. case "run":
  116. stack[i], returned = opRun(stack[i+1], envs)
  117. case "eq":
  118. stack[i] = opEq(stack[i+1], stack[i+2])
  119. case "gt":
  120. stack[i] = opGt(stack[i+1], stack[i+2])
  121. case "lt":
  122. stack[i] = opLt(stack[i+1], stack[i+2])
  123. case "and":
  124. stack[i] = opAnd(stack[i+1], stack[i+2])
  125. case "or":
  126. stack[i] = opOr(stack[i+1], stack[i+2])
  127. case "not":
  128. stack[i] = opNot(stack[i+1])
  129. case "if":
  130. stack[i], returned = opIf(stack[i+1], stack[i+2], stack[i+3], envs)
  131. case "isnumber":
  132. stack[i] = opIsNumber(stack[i+1])
  133. case "isword":
  134. stack[i] = opIsWord(stack[i+1])
  135. case "islist":
  136. stack[i] = opIsList(stack[i+1])
  137. case "isbool":
  138. stack[i] = opIsBool(stack[i+1])
  139. case "isempty":
  140. stack[i] = opIsEmpty(stack[i+1])
  141. case "return":
  142. stack[i], returned = stack[i+1], true
  143. case "export":
  144. stack[i] = opExport(stack[i+1], envs)
  145. case "readlist":
  146. stack[i] = opReadList(scanner)
  147. case "word":
  148. stack[i] = opWord(stack[i+1], stack[i+2])
  149. case "sentence":
  150. stack[i] = opSentence(stack[i+1], stack[i+2])
  151. case "list":
  152. stack[i] = opList(stack[i+1], stack[i+2])
  153. case "join":
  154. stack[i] = opJoin(stack[i+1], stack[i+2])
  155. case "first":
  156. stack[i] = opFirst(stack[i+1])
  157. case "last":
  158. stack[i] = opLast(stack[i+1])
  159. case "butfirst":
  160. stack[i] = opButFirst(stack[i+1])
  161. case "butlast":
  162. stack[i] = opButLast(stack[i+1])
  163. case "random":
  164. stack[i] = opRandom(stack[i+1])
  165. case "int":
  166. stack[i] = opInt(stack[i+1])
  167. case "sqrt":
  168. stack[i] = opSqrt(stack[i+1])
  169. case "save":
  170. stack[i] = opSave(stack[i+1], envs[0])
  171. case "load":
  172. stack[i] = opLoad(stack[i+1], envs[0])
  173. case "erall":
  174. stack[i] = opErAll(envs[0])
  175. case "poall":
  176. stack[i] = opPoAll(envs[0])
  177. }
  178. stack = stack[:i+1]
  179. updated = true
  180. }
  181. break
  182. }
  183. val, _ := getValue(op, envs)
  184. if val, ok := val.(*_list); ok && val.param != nil {
  185. if len(val.param) == len(stack)-1-i {
  186. for j := i + 1; j < len(stack); j++ {
  187. stack[j] = toValue(stack[j], envs)
  188. }
  189. local := environ{}
  190. for name, val := range val.env {
  191. local[name] = val
  192. }
  193. local[op] = val
  194. for j, name := range val.param {
  195. local[name] = stack[i+1+j]
  196. }
  197. global := envs[0]
  198. if envs[1] != nil {
  199. global = envs[1]
  200. }
  201. stack[i], _ = opRun(&_list{list: val.body}, []environ{local, global})
  202. stack = stack[:i+1]
  203. updated = true
  204. }
  205. break
  206. }
  207. panic(fmt.Errorf("func: %s (%s)", errFunctionExpected, op))
  208. }
  209. }
  210. }
  211. if len(stack) == 0 {
  212. val = &_list{list: []string{}}
  213. } else {
  214. val = toValue(stack[len(stack)-1], envs)
  215. }
  216. return
  217. }
  218. func main() {
  219. rand.Seed(time.Now().UnixNano())
  220. env := map[string]value{"pi": &_number{num: 3.141592654}}
  221. if len(os.Args) > 1 {
  222. file, err := os.Open(os.Args[1])
  223. if err != nil {
  224. panic(fmt.Errorf("script: %s (%s)", errFileError, os.Args[1]))
  225. }
  226. os.Stdin = file
  227. }
  228. scanner := bufio.NewScanner(os.Stdin)
  229. scanner.Split(splitFunc)
  230. interpret(&scanProvider{isList: false, scanner: scanner}, []environ{env, nil})
  231. }