| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- // package prc_int -- процесс над целочисленным кварком
- package prc_int
- import (
- "fmt"
- "log"
- "strconv"
- "strings"
- "plt/lev2/vm/pos"
- "plt/lev2/vm/prc_base"
- "plt/lev2/vm/state_res"
- "plt/lev2/vm/state_vm"
- )
- // PrcInt -- процесс над целочисленным значением
- type PrcInt struct {
- prc_base.PrcBase
- strOut string
- Run func() // Run -- запускает процесс (над целым числом)
- }
- var (
- // DictRun -- словарь переменных времени исполнения
- DictRun = map[string]int{}
- // DictCompile -- словарь имён времени компиляции
- DictCompile = map[string]bool{}
- vmState = state_vm.VM_State
- posCur = pos.PosCur
- )
- // NewPrcInt -- возвращает новый процесс над целочисленным значением
- func NewPrcInt() *PrcInt {
- log.Println("NewPrcInt()")
- sf := &PrcInt{}
- sf.parse()
- return sf
- }
- // Парсит инструкции, вырезает действие
- func (sf *PrcInt) parse() {
- begPosX := 0
- begPosY := 0
- { // Начать поиск выводимого значения
- for vmState.StrCur() != "(" {
- vmState.RuneInc()
- if vmState.StrCur() == "\n" {
- posCur.NextLine()
- }
- posCur.IncX()
- begPosY = posCur.GetY()
- }
- // Сдвинуть позицию
- vmState.RuneInc()
- posCur.IncX()
- begPosX = posCur.GetX()
- }
- out := ""
- { // Выбрать значение отладки
- for vmState.StrCur() != ")" {
- strCur := vmState.StrCur()
- if strCur == "\n" {
- posCur.NextLine()
- }
- out += vmState.StrNext()
- posCur.IncX()
- if vmState.IsEnd() {
- break
- }
- }
- vmState.RuneInc() // Сдвиг после скобки
- out = strings.ReplaceAll(out, "\n\n", "\n")
- sf.strOut = fmt.Sprintf("%v:%v\t%v", begPosY, begPosX, out)
- }
- { // Теперь надо выяснить операцю
- out = sf.StripOut(out)
- lstOut := strings.Split(out, " ")
- lenLst := len(lstOut)
- switch lenLst {
- case 3:
- cmd := lstOut[0]
- switch cmd {
- case "New": // готовит инструкцию создания новой целочисленной переменной
- sf.compileNew(begPosY, begPosX, lstOut)
- case "+": // Сложение
- sf.compileAdd(begPosY, begPosX, lstOut)
- default:
- panic("PrcInt(): unknown command for case=3")
- }
- case 2:
- cmd := lstOut[0]
- switch cmd {
- case "++":
- sf.compileInc(begPosY, begPosX, lstOut)
- case "--":
- sf.compileDec(begPosY, begPosX, lstOut)
- default:
- panic("PrcInt(): unknown command for case=2")
- }
- }
- }
- }
- // Декремент значения
- func (sf *PrcInt) compileDec(x, y int, lstOut []string) {
- name := lstOut[1]
- sf.Run = func() {
- val := DictRun[name]
- val--
- DictRun[name] = val
- fmt.Printf("%v:%v\ti(-- %v)\t#(val=%v)\n", x, y, name, val)
- }
- }
- // Инкремент значения
- func (sf *PrcInt) compileInc(x, y int, lstOut []string) {
- name := lstOut[1]
- sf.Run = func() {
- val := DictRun[name]
- val++
- DictRun[name] = val
- fmt.Printf("%v:%v\ti(++ %v)\t#(val=%v)\n", x, y, name, val)
- }
- }
- // Складывает два числа
- func (sf *PrcInt) compileAdd(x, y int, lstOut []string) {
- var err error
- name1 := lstOut[1]
- var val1, val2 int
- isOkName1 := DictCompile[name1]
- if !isOkName1 {
- val1, err = strconv.Atoi(name1)
- if err != nil {
- err := fmt.Errorf("PrcInt.compileAdd(): in extract op1(%v), err=\n\t%w",
- name1, err)
- panic(err)
- }
- }
- name2 := lstOut[2]
- isOkName2 := DictCompile[name2]
- if !isOkName2 {
- val2, err = strconv.Atoi(name2)
- if err != nil {
- err := fmt.Errorf("PrcInt.cmdAdd(): in extract new val(%v), err=\n\t%w",
- name2, err)
- panic(err)
- }
- }
- switch {
- case isOkName1 && isOkName2:
- sf.Run = func() {
- res := val1 + val2
- vmState.ResRun().Set(state_res.ResTypeInt, res)
- fmt.Printf("%v:%v\ti(+ %v %v)\t#(val=%v)\n", x, y, name1, name2, res)
- }
- case isOkName1 && !isOkName2:
- sf.Run = func() {
- val1 := DictRun[name1]
- res := val1 + val2
- vmState.ResRun().Set(state_res.ResTypeInt, res)
- fmt.Printf("%v:%v\ti(+ %v %v)\t#(val=%v)\n", x, y, name1, val2, res)
- }
- case !isOkName1 && isOkName2:
- sf.Run = func() {
- val2 := DictRun[name2]
- res := val1 + val2
- vmState.ResRun().Set(state_res.ResTypeInt, res)
- fmt.Printf("%v:%v\ti(+ %v %v)\t#(val=%v)\n", x, y, val1, name2, res)
- }
- case !isOkName1 && !isOkName2:
- sf.Run = func() {
- res := val1 + val2
- vmState.ResRun().Set(state_res.ResTypeInt, res)
- fmt.Printf("%v:%v\ti(+ %v %v)\t#(val=%v)\n", x, y, val1, val2, res)
- }
- }
- }
- // Создаёт новую целочисленную переменную
- func (sf *PrcInt) compileNew(x, y int, lstOut []string) {
- name := lstOut[1]
- strVal := lstOut[2]
- val, err := strconv.Atoi(strVal)
- if err != nil {
- err := fmt.Errorf("PrcInt.compileNew(): in extract new val(%v), err=\n\t%w",
- strVal, err)
- panic(err)
- }
- DictCompile[name] = true
- sf.Run = func() {
- DictRun[name] = val
- fmt.Printf("%v:%v\ti(New %v %v)\n", x, y, name, val)
- }
- }
|