Differences From
Artifact [dc6db86c51]:
- File
types.go
— part of check-in
[0b245d054f]
at
2017-01-06 07:49:02
on branch trunk
— Bugfixes, extra levels of compilation, and prefix fixes
(user:
yumaikas
- File
types.go
— part of check-in
[f33549b221]
at
2017-02-20 05:53:05
on branch trunk
— Added eq and deep-slow-reflect-eq to prepare for building a test suite
(user:
yumaikas
1 1 package main
2 2
3 3 import (
4 4 "bytes"
5 5 "fmt"
6 + "reflect"
6 7 "strconv"
7 8 )
8 9
9 10 type stackEntry interface {
10 11 String() string
11 12 Type() string
12 13 }
13 14
14 15 type lenable interface {
15 16 Length() int
16 17 }
17 18
19 +func runEq(m *machine) error {
20 + a := m.popValue()
21 + b := m.popValue()
22 + m.pushValue(Boolean(eq(a, b)))
23 + return nil
24 +}
25 +
26 +// Check if two arrays are
27 +func arrayRefEq(a, b Array) bool {
28 + if len(a) != len(b) {
29 + return false
30 + }
31 + if len(a) == 0 {
32 + return true
33 + }
34 + return &a[0] == &b[0]
35 +}
36 +
37 +func mapRefEq(a, b Dict) bool {
38 + if len(a) != len(b) {
39 + return false
40 + }
41 + if len(a) == 0 {
42 + return true
43 + }
44 + aVal := reflect.ValueOf(a).Pointer()
45 + bVal := reflect.ValueOf(b).Pointer()
46 + return aVal == bVal
47 +}
48 +
49 +func eq(a, b stackEntry) bool {
50 +
51 + if a.Type() != b.Type() {
52 + return false
53 + }
54 + // Otherwise, the types are the same and we can compare them
55 + switch a.Type() {
56 + case "Boolean":
57 + return a.(Boolean) == b.(Boolean)
58 + case "String":
59 + return a.String() == b.String()
60 + case "Integer":
61 + return a.(Integer) == b.(Integer)
62 + case "Double":
63 + return a.(Double) == b.(Double)
64 + case "Symbol":
65 + return a.(Symbol) == b.(Symbol)
66 + case "Vector":
67 + return arrayRefEq(a.(Array), b.(Array))
68 + case "Dictionary":
69 + return mapRefEq(a.(Dict), b.(Dict))
70 + case "Quotation":
71 + return &a == &b
72 + case "Go Word":
73 + return &a == &b
74 + }
75 + // If we got here, something
76 + panic("eq failed!!!")
77 +
78 +}
79 +
80 +// Boolean is the PISC wrapper around bools
18 81 type Boolean bool
82 +
83 +// Integer is the PISC wrapper around ints
19 84 type Integer int
85 +
86 +// Double is the PISC wrapper aroudn float64
20 87 type Double float64
88 +
89 +// Dict is the wrapper around dictionaries.
90 +// TODO: Find a way to support dicts with arbitrary keys, not just strings
21 91 type Dict map[string]stackEntry
92 +
93 +// Array is the wrapper around slices of stackEntry
22 94 type Array []stackEntry
95 +
96 +// String is the PISC wrapper around strings
23 97 type String string
98 +
99 +// Symbol is used for unique symboles
24 100 type Symbol int64
25 101
26 102 // This is a separate sematic from arrays.
27 103 type quotation struct {
28 104 inner *codeQuotation
29 105 locals Dict
30 106 }
................................................................................
36 112
37 113 type GoFunc GoWord
38 114
39 115 func (g GoFunc) String() string {
40 116 return "<Native Code>"
41 117 }
42 118
43 -func (g GoFunc) Type() string {
44 - return "Go Word"
45 -}
46 -
47 119 func (s String) String() string {
48 120 return string(s)
49 121 }
50 122
51 123 func (s Symbol) String() string {
52 124 return "#" + fmt.Sprint(int(s))
53 125 }
................................................................................
89 161 }
90 162
91 163 }
92 164
93 165 func (a Array) String() string {
94 166 return fmt.Sprint([]stackEntry(a))
95 167 }
168 +
169 +func (g GoFunc) Type() string {
170 + return "Go Word"
171 +}
96 172
97 173 func (i Integer) Type() string {
98 174 return "Integer"
99 175 }
100 176
101 177 func (d Double) Type() string {
102 178 return "Double"
................................................................................
119 195 }
120 196
121 197 func (s String) Type() string {
122 198 return "String"
123 199 }
124 200
125 201 func (s Symbol) Type() string {
126 - return "ERROR: Symbol observed on stack!"
202 + return "Symbol"
127 203 }
128 204
129 205 func (dict Dict) Length() int {
130 206 return len(dict)
131 207 }
132 208
133 209 func (a Array) Length() int {
134 210 return len(a)
135 211 }
136 212
137 213 func (s String) Length() int {
138 214 return len(s)
139 215 }