// package vm -- интерпретатор промежуточного языка package vm import ( "fmt" "log" "os" // "plt/lev0/spec" "plt/lev2/vm/pos" "plt/lev2/vm/prc_comment" "plt/lev2/vm/prc_debug" "plt/lev2/vm/prc_int" "plt/lev2/vm/prc_res" "plt/lev2/vm/state_vm" ) // Vm -- интерпретатор промежуточного языка type Vm struct { lstPrc []func() // Функция процесса инструкций ВМ } // NewVm -- возвращает новый интерпретатор промежуточного языка func NewVm() *Vm { log.Println("NewVm()") path := os.Getenv("MAIN_PROLET") if path == "" { path = "./main.pli" } log.Printf("NewVm(): path=%q", path) // path := "main.pli" // path := "main.pl binCode, err := os.ReadFile(path) if err != nil { log.Panicf("NewVM(): in read path, path=%q, err=\n\t%v", path, err) } sf := &Vm{ lstPrc: []func(){}, } vmState := state_vm.VM_State // Статус ВМ vmState.CodeStrSet(string(binCode)) sf.parse() // парсинг кода, заполнение структуры s return sf } // Парсит код на промежуточном языке func (sf *Vm) parse() { vmState := state_vm.VM_State // Статус ВМ log.Printf("Vm.parse(): len=%v,\n", vmState.RuneLen()) posCur := pos.PosCur // Текущая позиция в коде fmt.Println("") for vmState.RuneLen() > vmState.IndRune() { r := vmState.StrCur() // fmt.Printf("%v", string(r)) switch r { case "#": // Поиск коммента vmState.RuneInc() prcComment := prc_comment.NewPrcComment() sf.lstPrc = append(sf.lstPrc, prcComment.Run) case "d": // Поиск отладки prcDebug := prc_debug.NewPrcDebug() sf.lstPrc = append(sf.lstPrc, prcDebug.Run) case "i": // Поиск операции с целым числым prcInt := prc_int.NewPrcInt() sf.lstPrc = append(sf.lstPrc, prcInt.Run) case "r": // Установка результата prcRes := prc_res.NewPrcRes() sf.lstPrc = append(sf.lstPrc, prcRes.Run) case "\n": // Поиск перевода строки posCur.NextLine() vmState.RuneInc() default: // Дефолтное действие fmt.Print(string(r)) vmState.RuneInc() } } fmt.Printf("\n%v PARSE END\n", posCur) } // Run -- запускает интерпретатор промежуточного языка func (sf *Vm) Run() { log.Println("Vm.Run()") for _, fnRun := range sf.lstPrc { fnRun() } fmt.Println("") }