UNPKG

6.76 kBtext/coffeescriptView Raw
1# The symbol table is a simple array of struct U.
2
3
4
5# put symbol at index n
6Eval_symbolsinfo = ->
7 symbolsinfoToBePrinted = symbolsinfo()
8
9 if symbolsinfoToBePrinted != ""
10 new_string(symbolsinfoToBePrinted)
11 else
12 push_symbol(NIL)
13
14symbolsinfo = ->
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.
34std_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
71usr_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
108get_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.
119set_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
147get_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...
179is_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
190lookupsTotal = 0
191symnum = (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
209push_symbol = (k) ->
210 push(symtab[k])
211
212clear_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
235collectUserSymbols = (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