| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- // 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)
- }
- }
|