PageRenderTime 50ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/forth/error.go

http://github.com/unixdj/forego
Go | 95 lines | 81 code | 11 blank | 3 comment | 6 complexity | 15bf54e2ebb1563d0a8ea36849f67404 MD5 | raw file
Possible License(s): AGPL-3.0
  1. package forth
  2. // List of VM traps for Errno
  3. const (
  4. Bye = Errno(iota)
  5. EOF
  6. StackOverflow
  7. StackUnderflow
  8. RStackOverflow
  9. RStackUnderflow
  10. IllegalInstruction
  11. IllegalAddress
  12. UnalignedAddress
  13. ZeroDivision
  14. IOError
  15. )
  16. var strError = []string{
  17. "BYE",
  18. "EOF",
  19. "stack overflow",
  20. "stack underflow",
  21. "return stack overflow",
  22. "return stack underflow",
  23. "illegal instruction",
  24. "illegal address",
  25. "unaligned address",
  26. "zero division",
  27. "I/O error",
  28. }
  29. // Errno describes the reason for a VM trap.
  30. type Errno int
  31. func (e Errno) Error() string {
  32. return strError[e]
  33. }
  34. func rstackError(e error) error {
  35. if e == nil {
  36. return nil
  37. }
  38. return e.(Errno) + (RStackOverflow - StackOverflow)
  39. }
  40. // Error describes the cause and the context of a VM trap.
  41. type Error struct {
  42. Errno Errno // nature of the trap
  43. Err error // I/O error when Errno is IOError
  44. PC Cell // program counter before the trap
  45. Instr Instr // instruction that raised the trap
  46. Addr Cell // address when Errno is IllegalAddress or UnalignedAddress
  47. Stack Stack // data stack
  48. RStack Stack // return stack
  49. }
  50. func (e *Error) Error() string {
  51. var msg = "forego: "
  52. if e.Err != nil {
  53. msg += e.Err.Error()
  54. } else {
  55. msg += e.Errno.Error()
  56. switch e.Errno {
  57. case IllegalInstruction:
  58. msg += " " + Cell(e.Instr).String()
  59. case IllegalAddress, UnalignedAddress:
  60. msg += " " + e.Addr.String()
  61. }
  62. }
  63. return msg + " at " + e.PC.String()
  64. }
  65. func (vm *VM) newErrorFull(errno Errno, err error, addr Cell) error {
  66. return &Error{
  67. Errno: errno,
  68. Err: err,
  69. PC: vm.lastpc,
  70. Addr: addr,
  71. Instr: vm.icell,
  72. Stack: append(make([]Cell, 0, stackDepth), vm.stack...),
  73. RStack: append(make([]Cell, 0, stackDepth), vm.rstack...),
  74. }
  75. }
  76. func (vm *VM) newErrorAddr(errno Errno, addr Cell) error {
  77. return vm.newErrorFull(errno, nil, addr)
  78. }
  79. func (vm *VM) newError(errno Errno) error {
  80. return vm.newErrorAddr(errno, 0)
  81. }
  82. func (vm *VM) newIOError(e error) error {
  83. return vm.newErrorFull(IOError, e, 0)
  84. }