ctx_int.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. // package ctx_int -- контекст над целочисленным кварком
  2. package ctx_int
  3. import (
  4. "fmt"
  5. "log"
  6. "strconv"
  7. "strings"
  8. "plt/lev2/vm/ctx_base"
  9. "plt/lev2/vm/ctx_int/state_int"
  10. "plt/lev2/vm/ctx_int/sym_int"
  11. "plt/lev2/vm/pos"
  12. "plt/lev2/vm/state_res"
  13. "plt/lev2/vm/state_vm"
  14. )
  15. // IPrcInt -- интерфейс процесса инструкции ВМ
  16. type IPrcInt interface {
  17. // Compile -- компилирует символ
  18. Compile(begPosY, begPosX int, lstOut []string) func()
  19. }
  20. // CtxInt -- контекст над целочисленным значением
  21. type CtxInt struct {
  22. *ctx_base.CtxBase
  23. stateInt state_int.IStateInt
  24. dictPrc map[string]IPrcInt
  25. vmState *state_vm.StateVm
  26. posCur pos.IPosMut
  27. }
  28. var (
  29. vmState = state_vm.VM_State
  30. posCur = pos.PosCur
  31. )
  32. // NewCtxInt -- возвращает новый контекст над целочисленным значением
  33. func NewCtxInt() *CtxInt {
  34. log.Println("NewCtxInt()")
  35. sf := &CtxInt{
  36. CtxBase: ctx_base.NewCtxBase(),
  37. }
  38. sf.parse()
  39. return sf
  40. }
  41. // CreateSym-- создает новый целочисленный символ
  42. func (sf *CtxInt) CreateSym() func() {
  43. log.Println("CtxInt.CreatePrc()")
  44. p := sym_int.NewSymInt()
  45. return p.Run
  46. }
  47. // Парсит целочисленный контекст
  48. func (sf *CtxInt) parse() {
  49. begPosX := 0
  50. begPosY := 0
  51. { // Начать поиск выводимого значения
  52. for vmState.StrCur() != "(" {
  53. vmState.RuneInc()
  54. if vmState.StrCur() == "\n" {
  55. posCur.NextLine()
  56. }
  57. posCur.IncX()
  58. begPosY = posCur.GetY()
  59. }
  60. // Сдвинуть позицию
  61. vmState.RuneInc()
  62. posCur.IncX()
  63. begPosX = posCur.GetX()
  64. }
  65. out := ""
  66. { // Выбрать значение отладки
  67. for vmState.StrCur() != ")" {
  68. strCur := vmState.StrCur()
  69. if strCur == "\n" {
  70. posCur.NextLine()
  71. }
  72. out += vmState.StrNext()
  73. posCur.IncX()
  74. if vmState.IsEnd() {
  75. break
  76. }
  77. }
  78. vmState.RuneInc() // Сдвиг после скобки
  79. out = strings.ReplaceAll(out, "\n\n", "\n")
  80. sf.strOut = fmt.Sprintf("%v:%v\t%v", begPosY, begPosX, out)
  81. }
  82. { // Теперь надо выяснить операцию
  83. out = sf.StripOut(out)
  84. lstOut := strings.Split(out, " ")
  85. // lenLst := len(lstOut)
  86. cmd := lstOut[0]
  87. fnRun := sf.dictPrc[cmd].Compile(begPosY, begPosX, lstOut)
  88. sf.stateInt.Append(fnRun)
  89. }
  90. // switch lenLst {
  91. // case 3:
  92. // switch cmd {
  93. // case "new": // готовит инструкцию создания новой целочисленной переменной
  94. // sf.compileNew()
  95. // case "+": // Сложение
  96. // sf.compileAdd(begPosY, begPosX, lstOut)
  97. // default:
  98. // panic("PrcInt(): unknown command for case=3")
  99. // }
  100. // case 2:
  101. // switch cmd {
  102. // case "++":
  103. // sf.compileInc(begPosY, begPosX, lstOut)
  104. // case "--":
  105. // sf.compileDec(begPosY, begPosX, lstOut)
  106. // default:
  107. // panic("PrcInt(): unknown command for case=2")
  108. // }
  109. // }
  110. }
  111. // Декремент значения
  112. func (sf *CtxInt) compileDec(x, y int, lstOut []string) {
  113. name := lstOut[1]
  114. sf.Run = func() {
  115. val := sf.DictRun[name]
  116. val--
  117. sf.DictRun[name] = val
  118. fmt.Printf("%v:%v\ti(-- %v)\t#(val=%v)\n", x, y, name, val)
  119. }
  120. }
  121. // Инкремент значения
  122. func (sf *CtxInt) compileInc(x, y int, lstOut []string) {
  123. name := lstOut[1]
  124. sf.Run = func() {
  125. val := sf.DictRun[name]
  126. val++
  127. sf.DictRun[name] = val
  128. fmt.Printf("%v:%v\ti(++ %v)\t#(val=%v)\n", x, y, name, val)
  129. }
  130. }
  131. // Складывает два числа
  132. func (sf *CtxInt) compileAdd(x, y int, lstOut []string) {
  133. var err error
  134. name1 := lstOut[1]
  135. var val1, val2 int
  136. isOkName1 := sf.DictCompile[name1]
  137. if !isOkName1 {
  138. val1, err = strconv.Atoi(name1)
  139. if err != nil {
  140. err := fmt.Errorf("PrcInt.compileAdd(): in extract op1(%v), err=\n\t%w",
  141. name1, err)
  142. panic(err)
  143. }
  144. }
  145. name2 := lstOut[2]
  146. isOkName2 := sf.DictCompile[name2]
  147. if !isOkName2 {
  148. val2, err = strconv.Atoi(name2)
  149. if err != nil {
  150. err := fmt.Errorf("PrcInt.cmdAdd(): in extract new val(%v), err=\n\t%w",
  151. name2, err)
  152. panic(err)
  153. }
  154. }
  155. switch {
  156. case isOkName1 && isOkName2:
  157. sf.Run = func() {
  158. res := val1 + val2
  159. vmState.ResRun().Set(state_res.ResTypeInt, res)
  160. fmt.Printf("%v:%v\ti(+ %v %v)\t#(val=%v)\n", x, y, name1, name2, res)
  161. }
  162. case isOkName1 && !isOkName2:
  163. sf.Run = func() {
  164. val1 := sf.DictRun[name1]
  165. res := val1 + val2
  166. vmState.ResRun().Set(state_res.ResTypeInt, res)
  167. fmt.Printf("%v:%v\ti(+ %v %v)\t#(val=%v)\n", x, y, name1, val2, res)
  168. }
  169. case !isOkName1 && isOkName2:
  170. sf.Run = func() {
  171. val2 := sf.DictRun[name2]
  172. res := val1 + val2
  173. vmState.ResRun().Set(state_res.ResTypeInt, res)
  174. fmt.Printf("%v:%v\ti(+ %v %v)\t#(val=%v)\n", x, y, val1, name2, res)
  175. }
  176. case !isOkName1 && !isOkName2:
  177. sf.Run = func() {
  178. res := val1 + val2
  179. vmState.ResRun().Set(state_res.ResTypeInt, res)
  180. fmt.Printf("%v:%v\ti(+ %v %v)\t#(val=%v)\n", x, y, val1, val2, res)
  181. }
  182. }
  183. }
  184. // Создаёт новую целочисленную переменную
  185. func (sf *CtxInt) compileNew(x, y int, lstOut []string) {
  186. name := lstOut[1]
  187. strVal := lstOut[2]
  188. val, err := strconv.Atoi(strVal)
  189. if err != nil {
  190. err := fmt.Errorf("PrcInt.compileNew(): in extract new val(%v), err=\n\t%w",
  191. strVal, err)
  192. panic(err)
  193. }
  194. sf.DictCompile[name] = true
  195. sf.Run = func() {
  196. sf.DictRun[name] = val
  197. fmt.Printf("%v:%v\ti(New %v %v)\n", x, y, name, val)
  198. }
  199. }