forked from skx/go.vm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
traps.go
100 lines (87 loc) · 1.89 KB
/
traps.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
//
// This file contains the callbacks that the virtual machine
// can implement via the `int` operation.
//
//
package cpu
import (
"fmt"
"strings"
)
//
// TrapFunction is the signature for a function that is available
// as a trap.
//
type TrapFunction func(c *CPU, num int) error
//
// TRAPS is an array of our trap-functions.
//
var TRAPS [0xffff]TrapFunction
//
// Trap Functions now follow
//
// TrapNOP is the default trap-function for any trap IDs that haven't
// explicitly been setup.
func TrapNOP(c *CPU, num int) error {
return fmt.Errorf("trap function not defined: 0x%04X", num)
}
// StrLenTrap returns the length of a string.
//
// Input:
// The string to measure in register 0.
// Output:
// Sets register 0 with the length
//
func StrLenTrap(c *CPU, num int) error {
str, err := c.regs[0].GetString()
if err != nil {
return err
}
c.regs[0].SetInt(len(str))
return nil
}
// ReadStringTrap reads a string from the console
//
// Input: None
//
// Ouptut:
// Sets register 0 with the user-provided string
//
func ReadStringTrap(c *CPU, num int) error {
text, err := c.STDIN.ReadString('\n')
if err != nil {
return err
}
c.regs[0].SetString(text)
return nil
}
// RemoveNewLineTrap removes any trailing newline from the string in #0
//
// Input:
// The string operate upon in #0.
// Output:
// Sets register #0 with the updated string
//
func RemoveNewLineTrap(c *CPU, num int) error {
str, err := c.regs[0].GetString()
if err != nil {
return err
}
c.regs[0].SetString(strings.TrimSpace(str))
return nil
}
// init configures our registered traps.
func init() {
// Default to all traps being "empty", i.e. configured to
// to hold a reference to a function that just reports an
// error.
for i := 0; i < 0xFFFF; i++ {
TRAPS[i] = TrapNOP
}
//
// Now setup the actual traps we implement.
//
TRAPS[0] = StrLenTrap
TRAPS[1] = ReadStringTrap
TRAPS[2] = RemoveNewLineTrap
}