// package ctx_int -- контекст над целочисленным кварком package ctx_int import ( "fmt" "log" "strconv" "strings" "plt/lev2/vm/ctx_base" "plt/lev2/vm/ctx_int/state_int" "plt/lev2/vm/ctx_int/sym_int" "plt/lev2/vm/pos" "plt/lev2/vm/state_res" "plt/lev2/vm/state_vm" ) // IPrcInt -- интерфейс процесса инструкции ВМ type IPrcInt interface { // Compile -- компилирует символ Compile(begPosY, begPosX int, lstOut []string) func() } // CtxInt -- контекст над целочисленным значением type CtxInt struct { *ctx_base.CtxBase stateInt state_int.IStateInt dictPrc map[string]IPrcInt vmState *state_vm.StateVm posCur pos.IPosMut } var ( vmState = state_vm.VM_State posCur = pos.PosCur ) // NewCtxInt -- возвращает новый контекст над целочисленным значением func NewCtxInt() *CtxInt { log.Println("NewCtxInt()") sf := &CtxInt{ CtxBase: ctx_base.NewCtxBase(), } sf.parse() return sf } // CreateSym-- создает новый целочисленный символ func (sf *CtxInt) CreateSym() func() { log.Println("CtxInt.CreatePrc()") p := sym_int.NewSymInt() return p.Run } // Парсит целочисленный контекст func (sf *CtxInt) 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) cmd := lstOut[0] fnRun := sf.dictPrc[cmd].Compile(begPosY, begPosX, lstOut) sf.stateInt.Append(fnRun) } // switch lenLst { // case 3: // switch cmd { // case "new": // готовит инструкцию создания новой целочисленной переменной // sf.compileNew() // case "+": // Сложение // sf.compileAdd(begPosY, begPosX, lstOut) // default: // panic("PrcInt(): unknown command for case=3") // } // case 2: // switch cmd { // case "++": // sf.compileInc(begPosY, begPosX, lstOut) // case "--": // sf.compileDec(begPosY, begPosX, lstOut) // default: // panic("PrcInt(): unknown command for case=2") // } // } } // Декремент значения func (sf *CtxInt) compileDec(x, y int, lstOut []string) { name := lstOut[1] sf.Run = func() { val := sf.DictRun[name] val-- sf.DictRun[name] = val fmt.Printf("%v:%v\ti(-- %v)\t#(val=%v)\n", x, y, name, val) } } // Инкремент значения func (sf *CtxInt) compileInc(x, y int, lstOut []string) { name := lstOut[1] sf.Run = func() { val := sf.DictRun[name] val++ sf.DictRun[name] = val fmt.Printf("%v:%v\ti(++ %v)\t#(val=%v)\n", x, y, name, val) } } // Складывает два числа func (sf *CtxInt) compileAdd(x, y int, lstOut []string) { var err error name1 := lstOut[1] var val1, val2 int isOkName1 := sf.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 := sf.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 := sf.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 := sf.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 *CtxInt) 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) } sf.DictCompile[name] = true sf.Run = func() { sf.DictRun[name] = val fmt.Printf("%v:%v\ti(New %v %v)\n", x, y, name, val) } }