// package sym_int -- символ целого числа package sym_int import ( "fmt" "log" "strconv" "strings" "plt/lev2/vm/ctx_base" "plt/lev2/vm/state_res" ) // SymInt -- символ целого числа type SymInt struct { ctx_base.CtxBase strOut string Run func() // Run -- запускает процесс (над целым числом) } // NewSymInt -- возвращает новый символ целого числа func NewSymInt() *SymInt { log.Println("NewSymInt()") sf := &SymInt{} sf.parse() return sf } // Парсит инструкции, вырезает действие func (sf *SymInt) 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 *SymInt) 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 *SymInt) 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 *SymInt) 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 *SymInt) 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) } }