Position Independent Source Code

Diff
Login

Differences From Artifact [dc6db86c51]:

To Artifact [d64d73fe80]:


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
..
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
..
89
90
91
92
93
94
95




96
97
98
99
100
101
102
...
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package main

import (
	"bytes"
	"fmt"

	"strconv"
)

type stackEntry interface {
	String() string
	Type() string
}

type lenable interface {
	Length() int
}































































type Boolean bool


type Integer int


type Double float64



type Dict map[string]stackEntry


type Array []stackEntry


type String string


type Symbol int64

// This is a separate sematic from arrays.
type quotation struct {
	inner  *codeQuotation
	locals Dict
}
................................................................................

type GoFunc GoWord

func (g GoFunc) String() string {
	return "<Native Code>"
}

func (g GoFunc) Type() string {
	return "Go Word"
}

func (s String) String() string {
	return string(s)
}

func (s Symbol) String() string {
	return "#" + fmt.Sprint(int(s))
}
................................................................................
	}

}

func (a Array) String() string {
	return fmt.Sprint([]stackEntry(a))
}





func (i Integer) Type() string {
	return "Integer"
}

func (d Double) Type() string {
	return "Double"
................................................................................
}

func (s String) Type() string {
	return "String"
}

func (s Symbol) Type() string {
	return "ERROR: Symbol observed on stack!"
}

func (dict Dict) Length() int {
	return len(dict)
}

func (a Array) Length() int {
	return len(a)
}

func (s String) Length() int {
	return len(s)
}





>












>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>

>
>

>
>
>

>
>

>
>

>
>







 







<
<
<
<







 







>
>
>
>







 







|













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
101
102
103
104
105
106
...
112
113
114
115
116
117
118




119
120
121
122
123
124
125
...
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
...
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
package main

import (
	"bytes"
	"fmt"
	"reflect"
	"strconv"
)

type stackEntry interface {
	String() string
	Type() string
}

type lenable interface {
	Length() int
}

func runEq(m *machine) error {
	a := m.popValue()
	b := m.popValue()
	m.pushValue(Boolean(eq(a, b)))
	return nil
}

// Check if two arrays are
func arrayRefEq(a, b Array) bool {
	if len(a) != len(b) {
		return false
	}
	if len(a) == 0 {
		return true
	}
	return &a[0] == &b[0]
}

func mapRefEq(a, b Dict) bool {
	if len(a) != len(b) {
		return false
	}
	if len(a) == 0 {
		return true
	}
	aVal := reflect.ValueOf(a).Pointer()
	bVal := reflect.ValueOf(b).Pointer()
	return aVal == bVal
}

func eq(a, b stackEntry) bool {

	if a.Type() != b.Type() {
		return false
	}
	// Otherwise, the types are the same and we can compare them
	switch a.Type() {
	case "Boolean":
		return a.(Boolean) == b.(Boolean)
	case "String":
		return a.String() == b.String()
	case "Integer":
		return a.(Integer) == b.(Integer)
	case "Double":
		return a.(Double) == b.(Double)
	case "Symbol":
		return a.(Symbol) == b.(Symbol)
	case "Vector":
		return arrayRefEq(a.(Array), b.(Array))
	case "Dictionary":
		return mapRefEq(a.(Dict), b.(Dict))
	case "Quotation":
		return &a == &b
	case "Go Word":
		return &a == &b
	}
	// If we got here, something
	panic("eq failed!!!")

}

// Boolean is the PISC wrapper around bools
type Boolean bool

// Integer is the PISC wrapper around ints
type Integer int

// Double is the PISC wrapper aroudn float64
type Double float64

// Dict is the wrapper around dictionaries.
// TODO: Find a way to support dicts with arbitrary keys, not just strings
type Dict map[string]stackEntry

// Array is the wrapper around slices of stackEntry
type Array []stackEntry

// String is the PISC wrapper around strings
type String string

// Symbol is used for unique symboles
type Symbol int64

// This is a separate sematic from arrays.
type quotation struct {
	inner  *codeQuotation
	locals Dict
}
................................................................................

type GoFunc GoWord

func (g GoFunc) String() string {
	return "<Native Code>"
}





func (s String) String() string {
	return string(s)
}

func (s Symbol) String() string {
	return "#" + fmt.Sprint(int(s))
}
................................................................................
	}

}

func (a Array) String() string {
	return fmt.Sprint([]stackEntry(a))
}

func (g GoFunc) Type() string {
	return "Go Word"
}

func (i Integer) Type() string {
	return "Integer"
}

func (d Double) Type() string {
	return "Double"
................................................................................
}

func (s String) Type() string {
	return "String"
}

func (s Symbol) Type() string {
	return "Symbol"
}

func (dict Dict) Length() int {
	return len(dict)
}

func (a Array) Length() int {
	return len(a)
}

func (s String) Length() int {
	return len(s)
}