sym_int.go 4.6 KB

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