forked from chrislusf/gelo
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtrace.go
155 lines (139 loc) · 3.02 KB
/
trace.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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package gelo
import "fmt"
import "sync"
type _trace byte
const (
Alien_trace _trace = 1 << iota
Runtime_trace
System_trace
Parser_trace
)
const All_traces = Alien_trace | Runtime_trace | System_trace | Parser_trace
//global tracer
var _tracer_mutex sync.RWMutex
var _the_tracer Port
var _level _trace
func SetTracer(p Port) Port {
old := _the_tracer
_tracer_mutex.Lock()
defer _tracer_mutex.Unlock()
_the_tracer = p
return old
}
func TraceOn(lvl _trace) _trace {
_tracer_mutex.Lock()
defer _tracer_mutex.Unlock()
_level |= lvl
return _level
}
func TraceOff(lvl _trace) _trace {
_tracer_mutex.Lock()
defer _tracer_mutex.Unlock()
_level &^= lvl
return _level
}
func DEBUG(all ...interface{}) {
//for internal debugging use only
println(_format_trace("DEBUG::", all).CopyString())
}
func _format_trace(kind string, all []interface{}) *buffer {
buf := newBuf(0)
buf.WriteString(kind)
for _, v := range all {
buf.WriteString(" ")
switch t := v.(type) {
default:
buf.WriteString(fmt.Sprint(v))
case nil:
buf.WriteString("NIL")
case bool:
if t {
buf.WriteString("true")
} else {
buf.WriteString("false")
}
case *command:
if t == nil {
buf.WriteString("No-op")
} else {
buf.WriteString("\n")
for s := t; s != nil; s = s.next {
buf.WriteString("(v)->")
buf.Write(_serialize_parse_tree(s.cmd))
buf.WriteString("\n")
}
buf.WriteString("(0)\n")
}
case *sNode:
buf.Write(_serialize_parse_tree(t))
case Word:
buf.WriteWord(t)
case []byte:
buf.Write(t)
case string:
buf.WriteString(t)
}
}
return buf
}
func _tracer(req _trace, kind string, all []interface{}) {
_tracer_mutex.RLock()
defer _tracer_mutex.RUnlock()
if _level&req != 0 {
tr := _format_trace(kind, all).Symbol()
if _the_tracer != nil {
_the_tracer.Send(tr)
}
}
}
func parse_trace(message ...interface{}) {
_tracer(Parser_trace, "P:", message)
}
func sys_trace(message ...interface{}) {
_tracer(System_trace, "S:", message)
}
func run_trace(message ...interface{}) {
_tracer(Runtime_trace, "R:", message)
}
func alien_trace(message ...interface{}) {
_tracer(Alien_trace, "X:", message)
}
func _serialize_parse_tree(s *sNode) []byte {
buf := newBuf(0)
for ; s != nil; s = s.next {
buf.WriteString("[")
if s == nil {
buf.WriteString("NIL")
} else {
switch s.tag {
case synLiteral:
buf.WriteWord(s.val.(Word))
case synIndirect:
buf.WriteString("$<")
if n, ok := s.val.(*sNode); ok {
buf.Write(_serialize_parse_tree(n))
} else {
buf.WriteWord(s.val.(Word))
}
buf.WriteString(">")
case synSplice:
buf.WriteString("@<")
if n, ok := s.val.(*sNode); ok {
buf.Write(_serialize_parse_tree(n))
} else {
buf.WriteWord(s.val.(Word))
}
buf.WriteString(">")
case synQuote:
buf.WriteString("{")
buf.WriteWord(s.val.(Quote).Ser())
buf.WriteString("}")
case synClause:
buf.Write(_serialize_parse_tree(s.val.(*sNode)))
}
}
buf.WriteString("]->")
}
buf.WriteString("0")
return buf.Bytes()
}