1 | # The symbol table is a simple array of struct U.
|
2 |
|
3 |
|
4 |
|
5 | # put symbol at index n
|
6 | Eval_symbolsinfo = ->
|
7 | symbolsinfoToBePrinted = symbolsinfo()
|
8 |
|
9 | if symbolsinfoToBePrinted != ""
|
10 | new_string(symbolsinfoToBePrinted)
|
11 | else
|
12 | push_symbol(NIL)
|
13 |
|
14 | symbolsinfo = ->
|
15 | symbolsinfoToBePrinted = ""
|
16 | for i in [NIL+1...symtab.length]
|
17 | if symtab[i].printname == ""
|
18 | if isSymbolReclaimable[i] == false
|
19 | break
|
20 | else
|
21 | continue
|
22 | symtabi = symtab[i] + ""
|
23 | bindingi = (binding[i] + "").substring(0,4)
|
24 | symbolsinfoToBePrinted += "symbol: " + symtabi + " size: " + countsize(binding[i]) + " value: " + bindingi + "...\n"
|
25 | return symbolsinfoToBePrinted
|
26 |
|
27 |
|
28 |
|
29 | # s is a string, n is an int
|
30 | # TODO: elsewhere when we create a symbol we
|
31 | # rather prefer to create a new entry. Here we just
|
32 | # reuse the existing one. If that can never be a problem
|
33 | # then explain why, otherwise do create a new entry.
|
34 | std_symbol = (s, n, latexPrint) ->
|
35 | p = symtab[n]
|
36 | if !p?
|
37 | debugger
|
38 | p.printname = s
|
39 | if latexPrint?
|
40 | p.latexPrint = latexPrint
|
41 | else
|
42 | p.latexPrint = s
|
43 |
|
44 | # symbol lookup, or symbol creation if symbol doesn't exist yet
|
45 | # this happens often from the scanner. When the scanner sees something
|
46 | # like myVar = 2, it create a tree (SETQ ("myVar" symbol as created/looked up here (2)))
|
47 | # user-defined functions also have a usr symbol.
|
48 | #
|
49 | # Note that some symbols like, say, "abs",
|
50 | # are picked up by the scanner directly as keywords,
|
51 | # so they are not looked up via this.
|
52 | # So in fact you could redefine abs to be abs(x) = x
|
53 | # but still abs would be picked up by the scanner as a particular
|
54 | # node type and calls to abs() will be always to the "native" abs
|
55 | #
|
56 | # Also note that some symbols such as "zero" are (strangely) not picked up by
|
57 | # the scanner as special nodes, rather they are identified as keywords
|
58 | # (e.g. not redefinable) at time of symbol lookup (in Eval_sym) and
|
59 | # evalled, where eval has a case for ZERO.
|
60 | #
|
61 | # Also note that there are a number of symbols, such as a,b,c,x,y,z,...
|
62 | # that are actually created by std_symbols.
|
63 | # They are not special node types (like abs), they are normal symbols
|
64 | # that are looked up, but the advantage is that since they are often
|
65 | # used internally by algebrite, we create the symbol in advance and
|
66 | # we can reference the symbol entry in a clean way
|
67 | # (e.g. symbol(SYMBOL_X)) rather than
|
68 | # by looking up a string.
|
69 |
|
70 | # s is a string
|
71 | usr_symbol = (s) ->
|
72 |
|
73 | #console.log "usr_symbol of " + s
|
74 | #if s == "aaa"
|
75 | # debugger
|
76 |
|
77 | # find either the existing symbol, or if we
|
78 | # reach an empty symbol (printname == "") then
|
79 | # re-use that location.
|
80 | i = 0
|
81 | for i in [0...NSYM]
|
82 | if (symtab[i].printname == "")
|
83 | # found an entry in the symbol table
|
84 | # with no printname
|
85 | break
|
86 | if (s == symtab[i].printname)
|
87 | return symtab[i]
|
88 | if (i == NSYM)
|
89 | stop("symbol table overflow")
|
90 |
|
91 |
|
92 | symtab[i] = new U()
|
93 | symtab[i].k = SYM
|
94 | symtab[i].printname = s
|
95 | # say that we just created the symbol
|
96 | # then, binding[the new symbol entry]
|
97 | # by default points to the symbol.
|
98 | # So the value of an unassigned symbol will
|
99 | # be just its name.
|
100 | binding[i] = symtab[i]
|
101 | isSymbolReclaimable[i] = false
|
102 |
|
103 | return symtab[i]
|
104 |
|
105 | # get the symbol's printname
|
106 |
|
107 | # p is a U
|
108 | get_printname = (p) ->
|
109 | if (p.k != SYM)
|
110 | stop("symbol error")
|
111 | return p.printname
|
112 |
|
113 |
|
114 | # p and q are both U
|
115 | # there are two Us at play here. One belongs to the
|
116 | # symtab array and is the variable name.
|
117 | # The other one is the U with the content, and that
|
118 | # one will go in the corresponding "binding" array entry.
|
119 | set_binding = (p, q) ->
|
120 | if (p.k != SYM)
|
121 | stop("symbol error")
|
122 |
|
123 |
|
124 | #console.log "setting binding of " + p.toString() + " to: " + q.toString()
|
125 | #if p.toString() == "aaa"
|
126 | # debugger
|
127 |
|
128 | indexFound = symtab.indexOf(p)
|
129 | ###
|
130 | if indexFound == -1
|
131 | debugger
|
132 | for i in [0...symtab.length]
|
133 | if p.printname == symtab[i].printname
|
134 | indexFound = i
|
135 | console.log "remedied an index not found!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
136 | break
|
137 | ###
|
138 |
|
139 | if symtab.indexOf(p, indexFound + 1) != -1
|
140 | console.log("ops, more than one element!")
|
141 | debugger
|
142 | if DEBUG then console.log("lookup >> set_binding lookup " + indexFound)
|
143 | isSymbolReclaimable[indexFound] = false
|
144 | binding[indexFound] = q
|
145 |
|
146 | # p is a U
|
147 | get_binding = (p) ->
|
148 | if (p.k != SYM)
|
149 | stop("symbol error")
|
150 |
|
151 | #console.log "getting binding of " + p.toString()
|
152 | #if p.toString() == "aaa"
|
153 | # debugger
|
154 |
|
155 | indexFound = symtab.indexOf(p)
|
156 | ###
|
157 | if indexFound == -1
|
158 | debugger
|
159 | for i in [0...symtab.length]
|
160 | if p.printname == symtab[i].printname
|
161 | indexFound = i
|
162 | console.log "remedied an index not found!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
163 | break
|
164 | ###
|
165 |
|
166 | if symtab.indexOf(p, indexFound + 1) != -1
|
167 | console.log("ops, more than one element!")
|
168 | debugger
|
169 | if DEBUG then console.log("lookup >> get_binding lookup " + indexFound)
|
170 | #if indexFound == 139
|
171 | # debugger
|
172 | #if indexFound == 137
|
173 | # debugger
|
174 | return binding[indexFound]
|
175 |
|
176 | # the concept of user symbol is a little fuzzy
|
177 | # beucase mathematics is full of symbols that actually
|
178 | # have a special meaning, e.g. e,i,I in some cases j...
|
179 | is_usr_symbol = (p) ->
|
180 | if (p.k != SYM)
|
181 | return false
|
182 | theSymnum = symnum(p)
|
183 | # see "defs" file for the naming of the symbols
|
184 | if theSymnum > PI and theSymnum != SYMBOL_I and theSymnum != SYMBOL_IDENTITY_MATRIX
|
185 | return true
|
186 | return false
|
187 |
|
188 | # get symbol's number from ptr
|
189 | # p is U
|
190 | lookupsTotal = 0
|
191 | symnum = (p) ->
|
192 | lookupsTotal++
|
193 | if (p.k != SYM)
|
194 | stop("symbol error")
|
195 | indexFound = symtab.indexOf(p)
|
196 | if symtab.indexOf(p, indexFound + 1) != -1
|
197 | console.log("ops, more than one element!")
|
198 | debugger
|
199 | if DEBUG then console.log("lookup >> symnum lookup " + indexFound + " lookup # " + lookupsTotal)
|
200 | #if lookupsTotal == 21
|
201 | # debugger
|
202 | #if indexFound == 79
|
203 | # debugger
|
204 | return indexFound
|
205 |
|
206 | # push indexed symbol
|
207 |
|
208 | # k is an int
|
209 | push_symbol = (k) ->
|
210 | push(symtab[k])
|
211 |
|
212 | clear_symbols = ->
|
213 | # we can clear just what's assignable.
|
214 | # everything before NIL is not assignable,
|
215 | # so there is no need to clear it.
|
216 | for i in [NIL+1...NSYM]
|
217 |
|
218 | # stop at the first empty
|
219 | # entry that is not reclaimable
|
220 | if symtab[i].printname == ""
|
221 | if isSymbolReclaimable[i] == false
|
222 | break
|
223 | else
|
224 | continue
|
225 |
|
226 | symtab[i] = new U()
|
227 | symtab[i].k = SYM
|
228 | binding[i] = symtab[i]
|
229 | isSymbolReclaimable[i] = false
|
230 | #symtab[i].printname = ""
|
231 | #binding[i] = symtab[i]
|
232 |
|
233 |
|
234 | # collect all the variables in a tree
|
235 | collectUserSymbols = (p, accumulator = []) ->
|
236 |
|
237 | if is_usr_symbol(p)
|
238 | if accumulator.indexOf(p) == -1
|
239 | accumulator.push p
|
240 | return
|
241 |
|
242 | if (istensor(p))
|
243 | for i in [0...p.tensor.nelem]
|
244 | collectUserSymbols p.tensor.elem[i], accumulator
|
245 | return
|
246 |
|
247 | while (iscons(p))
|
248 | collectUserSymbols(car(p), accumulator)
|
249 | p = cdr(p)
|
250 |
|
251 | return
|
252 |
|
253 | $.get_binding = get_binding
|
254 | $.set_binding = set_binding
|
255 | $.usr_symbol = usr_symbol
|
256 | $.symbolsinfo = symbolsinfo
|
257 | $.collectUserSymbols = collectUserSymbols
|