vm.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // package vm -- интерпретатор промежуточного языка
  2. package vm
  3. import (
  4. "fmt"
  5. "log"
  6. "os"
  7. // "plt/lev0/spec"
  8. "plt/lev2/vm/ctx_int"
  9. "plt/lev2/vm/pos"
  10. "plt/lev2/vm/prc_comment"
  11. "plt/lev2/vm/prc_debug"
  12. "plt/lev2/vm/prc_res"
  13. "plt/lev2/vm/state_vm"
  14. )
  15. // Vm -- интерпретатор промежуточного языка
  16. type Vm struct {
  17. lstPrc []func() // Функция процесса инструкций ВМ
  18. ctxInt *ctx_int.CtxInt // Контекст целых чисел
  19. }
  20. var (
  21. vmState = state_vm.VM_State // Статус ВМ
  22. posCur = pos.PosCur // Текущая позиция в коде
  23. )
  24. // NewVm -- возвращает новый интерпретатор промежуточного языка
  25. func NewVm() *Vm {
  26. log.Println("NewVm()")
  27. path := os.Getenv("MAIN_PROLET")
  28. if path == "" {
  29. path = "./main.pli"
  30. }
  31. log.Printf("NewVm(): path=%q", path)
  32. // path := "main.pli"
  33. // path := "main.pl
  34. binCode, err := os.ReadFile(path)
  35. if err != nil {
  36. log.Panicf("NewVM(): in read path, path=%q, err=\n\t%v", path, err)
  37. }
  38. sf := &Vm{
  39. lstPrc: []func(){},
  40. ctxInt: ctx_int.NewCtxInt(),
  41. }
  42. vmState.CodeStrSet(string(binCode))
  43. sf.parse() // парсинг кода, заполнение структуры s
  44. return sf
  45. }
  46. // Парсит код на промежуточном языке
  47. func (sf *Vm) parse() {
  48. log.Printf("Vm.parse(): len=%v,\n", vmState.RuneLen())
  49. for vmState.RuneLen() > vmState.IndRune() {
  50. r := vmState.StrCur()
  51. // fmt.Printf("%v", string(r))
  52. switch r {
  53. case "#": // Поиск коммента
  54. vmState.RuneInc()
  55. prcComment := prc_comment.NewPrcComment()
  56. sf.lstPrc = append(sf.lstPrc, prcComment.Run)
  57. case "debug": // Поиск отладки
  58. prcDebug := prc_debug.NewPrcDebug()
  59. sf.lstPrc = append(sf.lstPrc, prcDebug.Run)
  60. case "int": // Поиск операции с целым числым
  61. symInt := sf.ctxInt.CreateSym()
  62. sf.lstPrc = append(sf.lstPrc, symInt.Run)
  63. case "reg": // Установка результата
  64. prcRes := prc_res.NewPrcRes()
  65. sf.lstPrc = append(sf.lstPrc, prcRes.Run)
  66. case "\n": // Поиск перевода строки
  67. posCur.NextLine()
  68. vmState.RuneInc()
  69. default: // Дефолтное действие
  70. fmt.Print(string(r))
  71. vmState.RuneInc()
  72. }
  73. }
  74. fmt.Printf("\n%v PARSE END\n", posCur)
  75. }
  76. // Run -- запускает интерпретатор промежуточного языка
  77. func (sf *Vm) Run() {
  78. log.Println("Vm.Run()")
  79. for _, fnRun := range sf.lstPrc {
  80. fnRun()
  81. }
  82. fmt.Println("")
  83. }