prc_int.go 5.0 KB

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