|
|
@@ -0,0 +1,212 @@
|
|
|
+// 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)
|
|
|
+ }
|
|
|
+}
|