1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | stop = (s) ->
|
7 |
|
8 |
|
9 |
|
10 | errorMessage += "Stop: "
|
11 | errorMessage += s
|
12 |
|
13 | message = errorMessage
|
14 |
|
15 | errorMessage = ''
|
16 | moveTos 0
|
17 |
|
18 | throw new Error(message)
|
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 | findDependenciesInScript = (stringToBeParsed, dontGenerateCode) ->
|
52 |
|
53 | if DEBUG then console.log "stringToBeParsed: " + stringToBeParsed
|
54 |
|
55 | timeStartFromAlgebra = new Date().getTime()
|
56 |
|
57 | if CACHE_DEBUGS or CACHE_HITSMISS_DEBUGS or TIMING_DEBUGS
|
58 | console.log " --------- findDependenciesInScript input: " + stringToBeParsed + " at: " + (new Date())
|
59 | currentStateHash = getStateHash()
|
60 | console.log "state hash: " + currentStateHash
|
61 |
|
62 |
|
63 | inited = true
|
64 | codeGen = true
|
65 | symbolsDependencies = {}
|
66 | symbolsHavingReassignments = []
|
67 | symbolsInExpressionsWithoutAssignments = []
|
68 | patternHasBeenFound = false
|
69 | indexOfPartRemainingToBeParsed = 0
|
70 |
|
71 | allReturnedPlainStrings = ""
|
72 | allReturnedLatexStrings = ""
|
73 |
|
74 | n = 0
|
75 |
|
76 |
|
77 |
|
78 |
|
79 |
|
80 | dependencyInfo =
|
81 | affectsVariables: []
|
82 | affectedBy: []
|
83 |
|
84 |
|
85 | stringToBeRun = stringToBeParsed
|
86 | if ENABLE_CACHING and stringToBeRun != "clearall"
|
87 | currentStateHash = getStateHash()
|
88 | cacheKey = currentStateHash + " stringToBeRun: " + stringToBeRun + " - " + dontGenerateCode
|
89 | if CACHE_DEBUGS then console.log "cached_findDependenciesInScript key: " + cacheKey
|
90 | possiblyCached = cached_findDependenciesInScript.get(cacheKey)
|
91 | if possiblyCached?
|
92 | if CACHE_HITSMISS_DEBUGS then console.log "cached_findDependenciesInScript hit on " + stringToBeRun
|
93 | unfreeze(possiblyCached)
|
94 |
|
95 | if TIMING_DEBUGS
|
96 | totalTime = new Date().getTime() - timeStartFromAlgebra
|
97 | console.log "findDependenciesInScript input: " + stringToBeRun + " time: " + totalTime + "ms, saved " + (possiblyCached[possiblyCached.length-5] - totalTime) + "ms due to cache hit"
|
98 |
|
99 | return [
|
100 | possiblyCached[possiblyCached.length - 7],
|
101 | possiblyCached[possiblyCached.length - 6],
|
102 | possiblyCached[possiblyCached.length - 5],
|
103 | possiblyCached[possiblyCached.length - 4],
|
104 | possiblyCached[possiblyCached.length - 3],
|
105 | possiblyCached[possiblyCached.length - 2],
|
106 | possiblyCached[possiblyCached.length - 1]
|
107 | ]
|
108 |
|
109 | else
|
110 | if CACHE_HITSMISS_DEBUGS then console.log "cached_findDependenciesInScript miss on: " + stringToBeRun
|
111 | if TIMING_DEBUGS
|
112 | cacheMissPenalty = (new Date().getTime() - timeStartFromAlgebra)
|
113 |
|
114 |
|
115 |
|
116 |
|
117 | while (1)
|
118 | try
|
119 | errorMessage = ""
|
120 | check_stack()
|
121 | if DEBUG then console.log "findDependenciesInScript: scanning"
|
122 | n = scan(stringToBeParsed.substring(indexOfPartRemainingToBeParsed))
|
123 | if DEBUG then console.log "scanned"
|
124 | pop()
|
125 | check_stack()
|
126 | catch error
|
127 | if PRINTOUTRESULT then console.log error
|
128 | errorMessage = error + ""
|
129 |
|
130 | reset_after_error()
|
131 | break
|
132 |
|
133 | if (n == 0)
|
134 | break
|
135 |
|
136 | indexOfPartRemainingToBeParsed += n
|
137 |
|
138 | testableString = ""
|
139 |
|
140 |
|
141 |
|
142 | if DEBUG then console.log "all local dependencies ----------------"
|
143 | testableString += "All local dependencies: "
|
144 | for key, value of symbolsDependencies
|
145 | if DEBUG then console.log "variable " + key + " depends on: "
|
146 | dependencyInfo.affectsVariables.push key
|
147 | testableString += " variable " + key + " depends on: "
|
148 | for i in value
|
149 | if DEBUG then console.log " " + i
|
150 | if i[0] != "'"
|
151 | dependencyInfo.affectedBy.push i
|
152 | testableString += i + ", "
|
153 | testableString += "; "
|
154 | testableString += ". "
|
155 |
|
156 |
|
157 | if DEBUG then console.log "Symbols with reassignments ----------------"
|
158 | testableString += "Symbols with reassignments: "
|
159 | for key in symbolsHavingReassignments
|
160 | if dependencyInfo.affectedBy.indexOf(key) == -1
|
161 | dependencyInfo.affectedBy.push key
|
162 | testableString += key + ", "
|
163 | testableString += ". "
|
164 |
|
165 |
|
166 | if DEBUG then console.log "Symbols in expressions without assignments ----------------"
|
167 | testableString += "Symbols in expressions without assignments: "
|
168 | for key in symbolsInExpressionsWithoutAssignments
|
169 | if dependencyInfo.affectedBy.indexOf(key) == -1
|
170 | dependencyInfo.affectedBy.push key
|
171 | testableString += key + ", "
|
172 | testableString += ". "
|
173 |
|
174 |
|
175 | dependencyInfo.affectedBy.push "PATTERN_DEPENDENCY"
|
176 |
|
177 | if patternHasBeenFound
|
178 | dependencyInfo.affectsVariables.push "PATTERN_DEPENDENCY"
|
179 | testableString += " - PATTERN_DEPENDENCY inserted - "
|
180 |
|
181 |
|
182 |
|
183 | if DEBUG then console.log "All dependencies recursively ----------------"
|
184 | testableString += "All dependencies recursively: "
|
185 |
|
186 | scriptEvaluation = ["",""]
|
187 | generatedCode = ""
|
188 | readableSummaryOfGeneratedCode = ""
|
189 |
|
190 | if errorMessage == "" and !dontGenerateCode
|
191 |
|
192 | try
|
193 | allReturnedPlainStrings = ""
|
194 | allReturnedLatexStrings = ""
|
195 | scriptEvaluation = run(stringToBeParsed, true)
|
196 | allReturnedPlainStrings = ""
|
197 | allReturnedLatexStrings = ""
|
198 | catch error
|
199 | if PRINTOUTRESULT then console.log error
|
200 | errorMessage = error + ""
|
201 |
|
202 | init()
|
203 |
|
204 | if errorMessage == ""
|
205 | for key of symbolsDependencies
|
206 |
|
207 |
|
208 | codeGen = true
|
209 | if DEBUG then console.log " variable " + key + " is: " + get_binding(usr_symbol(key)).toString()
|
210 | codeGen = false
|
211 | if DEBUG then console.log " variable " + key + " depends on: "
|
212 | testableString += " variable " + key + " depends on: "
|
213 |
|
214 | recursedDependencies = []
|
215 | variablesWithCycles = []
|
216 | cyclesDescriptions = []
|
217 |
|
218 | recursiveDependencies key, recursedDependencies, [], variablesWithCycles, [], cyclesDescriptions
|
219 |
|
220 | for i in variablesWithCycles
|
221 | if DEBUG then console.log " --> cycle through " + i
|
222 |
|
223 | for i in recursedDependencies
|
224 | if DEBUG then console.log " " + i
|
225 | testableString += i + ", "
|
226 | testableString += "; "
|
227 |
|
228 | for i in cyclesDescriptions
|
229 | testableString += " " + i + ", "
|
230 |
|
231 | if DEBUG then console.log " code generation:" + key + " is: " + get_binding(usr_symbol(key)).toString()
|
232 |
|
233 |
|
234 |
|
235 |
|
236 |
|
237 |
|
238 |
|
239 |
|
240 | push get_binding(usr_symbol(key))
|
241 |
|
242 |
|
243 |
|
244 |
|
245 |
|
246 |
|
247 |
|
248 |
|
249 |
|
250 |
|
251 |
|
252 |
|
253 |
|
254 |
|
255 |
|
256 |
|
257 |
|
258 |
|
259 | replacementsFrom = []
|
260 | replacementsTo = []
|
261 |
|
262 | for eachDependency in recursedDependencies
|
263 | if eachDependency[0] == "'"
|
264 | deQuotedDep = eachDependency.substring(1)
|
265 | originalUserSymbol = usr_symbol(deQuotedDep)
|
266 | newUserSymbol = usr_symbol("AVOID_BINDING_TO_EXTERNAL_SCOPE_VALUE"+deQuotedDep)
|
267 | replacementsFrom.push originalUserSymbol
|
268 | replacementsTo.push newUserSymbol
|
269 | push(originalUserSymbol)
|
270 | push(newUserSymbol)
|
271 | subst()
|
272 | if DEBUG then console.log "after substitution: " + stack[tos-1]
|
273 |
|
274 | try
|
275 | simplifyForCodeGeneration()
|
276 | catch error
|
277 | if PRINTOUTRESULT then console.log error
|
278 | errorMessage = error + ""
|
279 |
|
280 | init()
|
281 |
|
282 | for indexOfEachReplacement in [0...replacementsFrom.length]
|
283 |
|
284 | push(replacementsTo[indexOfEachReplacement])
|
285 | push(replacementsFrom[indexOfEachReplacement])
|
286 | subst()
|
287 |
|
288 | clearRenamedVariablesToAvoidBindingToExternalScope()
|
289 |
|
290 | if errorMessage == ""
|
291 | toBePrinted = pop()
|
292 |
|
293 |
|
294 |
|
295 |
|
296 | userVariablesMentioned = []
|
297 | collectUserSymbols(toBePrinted, userVariablesMentioned)
|
298 |
|
299 | allReturnedPlainStrings = ""
|
300 | allReturnedLatexStrings = ""
|
301 | codeGen = true
|
302 | generatedBody = toBePrinted.toString()
|
303 | codeGen = false
|
304 |
|
305 | origPrintMode = printMode
|
306 | printMode = PRINTMODE_LATEX
|
307 |
|
308 | bodyForReadableSummaryOfGeneratedCode = toBePrinted.toString()
|
309 |
|
310 | printMode = origPrintMode
|
311 |
|
312 | if variablesWithCycles.indexOf(key) != -1
|
313 | generatedCode += "// " + key + " is part of a cyclic dependency, no code generated."
|
314 | readableSummaryOfGeneratedCode += "#" + key + " is part of a cyclic dependency, no code generated."
|
315 | else
|
316 |
|
317 | |
318 |
|
319 |
|
320 |
|
321 |
|
322 |
|
323 |
|
324 |
|
325 |
|
326 |
|
327 |
|
328 |
|
329 |
|
330 |
|
331 |
|
332 |
|
333 |
|
334 |
|
335 |
|
336 |
|
337 |
|
338 |
|
339 |
|
340 |
|
341 | userVariablesMentioned = userVariablesMentioned.filter (x) ->
|
342 | predefinedSymbolsInGlobalScope_doNotTrackInDependencies.indexOf(x + "") == -1
|
343 |
|
344 |
|
345 |
|
346 | userVariablesMentioned = userVariablesMentioned.filter (x) ->
|
347 | recursedDependencies.indexOf(x + "") != -1 or
|
348 | recursedDependencies.indexOf("\'" + x + "") != -1
|
349 |
|
350 | if userVariablesMentioned.length != 0
|
351 | parameters = "("
|
352 | for i in userVariablesMentioned
|
353 | if i.printname != key
|
354 | parameters += i.printname + ", "
|
355 |
|
356 |
|
357 | parameters = parameters.replace /, $/gm , ""
|
358 | parameters += ")"
|
359 | generatedCode += key + " = function " + parameters + " { return ( " + generatedBody + " ); }"
|
360 | readableSummaryOfGeneratedCode += key + parameters + " = " + bodyForReadableSummaryOfGeneratedCode
|
361 | else
|
362 | generatedCode += key + " = " + generatedBody + ";"
|
363 | readableSummaryOfGeneratedCode += key + " = " + bodyForReadableSummaryOfGeneratedCode
|
364 |
|
365 | generatedCode += "\n"
|
366 | readableSummaryOfGeneratedCode += "\n"
|
367 |
|
368 | if DEBUG then console.log " " + generatedCode
|
369 |
|
370 |
|
371 | generatedCode = generatedCode.replace /\n$/gm , ""
|
372 | readableSummaryOfGeneratedCode = readableSummaryOfGeneratedCode.replace /\n$/gm , ""
|
373 |
|
374 |
|
375 |
|
376 | symbolsDependencies = {}
|
377 | symbolsHavingReassignments = []
|
378 | patternHasBeenFound = false
|
379 | symbolsInExpressionsWithoutAssignments = []
|
380 |
|
381 | if DEBUG then console.log "testable string: " + testableString
|
382 |
|
383 | if TIMING_DEBUGS
|
384 | console.log "findDependenciesInScript time for: " + stringToBeRun + " : "+ ((new Date().getTime()) - timeStartFromAlgebra) + "ms"
|
385 |
|
386 | if ENABLE_CACHING and stringToBeRun != "clearall" and errorMessage == ""
|
387 | frozen = freeze()
|
388 | toBeFrozen = [
|
389 | frozen[0],
|
390 | frozen[1],
|
391 | frozen[2],
|
392 | frozen[3],
|
393 | frozen[4],
|
394 | frozen[5],
|
395 | (new Date().getTime() - timeStartFromAlgebra),
|
396 | testableString,
|
397 | scriptEvaluation[0],
|
398 | generatedCode,
|
399 | readableSummaryOfGeneratedCode,
|
400 | scriptEvaluation[1],
|
401 | errorMessage,
|
402 | dependencyInfo
|
403 | ]
|
404 | if CACHE_DEBUGS then console.log "setting cached_findDependenciesInScript on key: " + cacheKey
|
405 | cached_findDependenciesInScript.set(cacheKey, toBeFrozen)
|
406 |
|
407 |
|
408 | return [testableString, scriptEvaluation[0], generatedCode, readableSummaryOfGeneratedCode, scriptEvaluation[1], errorMessage, dependencyInfo]
|
409 |
|
410 | recursiveDependencies = (variableToBeChecked, arrayWhereDependenciesWillBeAdded, variablesAlreadyFleshedOut, variablesWithCycles, chainBeingChecked, cyclesDescriptions) ->
|
411 | variablesAlreadyFleshedOut.push variableToBeChecked
|
412 |
|
413 |
|
414 | if symbolsDependencies[chainBeingChecked[chainBeingChecked.length-1]]?
|
415 | if symbolsDependencies[chainBeingChecked[chainBeingChecked.length-1]].indexOf("'"+variableToBeChecked) != -1
|
416 | if DEBUG then console.log "can't keep following the chain of " + variableToBeChecked + " because it's actually a variable bound to a parameter"
|
417 | if arrayWhereDependenciesWillBeAdded.indexOf("'"+variableToBeChecked) == -1 and arrayWhereDependenciesWillBeAdded.indexOf(variableToBeChecked) == -1
|
418 | arrayWhereDependenciesWillBeAdded.push variableToBeChecked
|
419 | return arrayWhereDependenciesWillBeAdded
|
420 |
|
421 | chainBeingChecked.push variableToBeChecked
|
422 |
|
423 | if !symbolsDependencies[variableToBeChecked]?
|
424 |
|
425 |
|
426 | if arrayWhereDependenciesWillBeAdded.indexOf(variableToBeChecked) == -1
|
427 | arrayWhereDependenciesWillBeAdded.push variableToBeChecked
|
428 | return arrayWhereDependenciesWillBeAdded
|
429 | else
|
430 |
|
431 | for i in symbolsDependencies[variableToBeChecked]
|
432 |
|
433 |
|
434 |
|
435 |
|
436 |
|
437 |
|
438 |
|
439 | if chainBeingChecked.indexOf(i) != -1
|
440 | if DEBUG then console.log " found cycle:"
|
441 | cyclesDescription = ""
|
442 | for k in chainBeingChecked
|
443 | if variablesWithCycles.indexOf(k) == -1
|
444 | variablesWithCycles.push k
|
445 | if DEBUG then console.log k + " --> "
|
446 | cyclesDescription += k + " --> "
|
447 | if DEBUG then console.log " ... then " + i + " again"
|
448 | cyclesDescription += " ... then " + i + " again"
|
449 | cyclesDescriptions.push cyclesDescription
|
450 |
|
451 |
|
452 |
|
453 |
|
454 |
|
455 | if variablesWithCycles.indexOf(i) == -1
|
456 | variablesWithCycles.push i
|
457 | else
|
458 |
|
459 | recursiveDependencies i, arrayWhereDependenciesWillBeAdded, variablesAlreadyFleshedOut, variablesWithCycles, chainBeingChecked, cyclesDescriptions
|
460 | chainBeingChecked.pop()
|
461 |
|
462 |
|
463 | return arrayWhereDependenciesWillBeAdded
|
464 |
|
465 |
|
466 |
|
467 |
|
468 | inited = false
|
469 |
|
470 | latexErrorSign = "\\rlap{\\large\\color{red}\\bigtriangleup}{\\ \\ \\tiny\\color{red}!}"
|
471 | turnErrorMessageToLatex = (theErrorMessage) ->
|
472 | theErrorMessage = theErrorMessage.replace(/\n/g,"")
|
473 | theErrorMessage = theErrorMessage.replace(/_/g, "} \\_ \\text{");
|
474 | theErrorMessage = theErrorMessage.replace(new RegExp(String.fromCharCode(transpose_unicode), 'g'), "}{}^{T}\\text{");
|
475 | theErrorMessage = theErrorMessage.replace(new RegExp(String.fromCharCode(dotprod_unicode), 'g'),"}\\cdot \\text{");
|
476 | theErrorMessage = theErrorMessage.replace("Stop:","} \\quad \\text{Stop:");
|
477 | theErrorMessage = theErrorMessage.replace("->","} \\rightarrow \\text{");
|
478 | theErrorMessage = theErrorMessage.replace("?","}\\enspace " + latexErrorSign + " \\enspace \\text{");
|
479 | theErrorMessage = "$$\\text{" + theErrorMessage.replace(/\n/g,"") + "}$$"
|
480 |
|
481 | return theErrorMessage
|
482 |
|
483 |
|
484 |
|
485 |
|
486 | normaliseDots = (stringToNormalise) ->
|
487 | stringToNormalise = stringToNormalise.replace(new RegExp(String.fromCharCode(8901), 'g'), String.fromCharCode(dotprod_unicode));
|
488 | stringToNormalise = stringToNormalise.replace(new RegExp(String.fromCharCode(8226), 'g'), String.fromCharCode(dotprod_unicode));
|
489 | stringToNormalise = stringToNormalise.replace(new RegExp(String.fromCharCode(12539), 'g'), String.fromCharCode(dotprod_unicode));
|
490 | stringToNormalise = stringToNormalise.replace(new RegExp(String.fromCharCode(55296), 'g'), String.fromCharCode(dotprod_unicode));
|
491 | stringToNormalise = stringToNormalise.replace(new RegExp(String.fromCharCode(65381), 'g'), String.fromCharCode(dotprod_unicode));
|
492 | return stringToNormalise
|
493 |
|
494 |
|
495 | CACHE_DEBUGS = false
|
496 | CACHE_HITSMISS_DEBUGS = false
|
497 | TIMING_DEBUGS = false
|
498 |
|
499 | cacheMissPenalty = 0
|
500 |
|
501 | run = (stringToBeRun, generateLatex = false) ->
|
502 |
|
503 | timeStart = new Date().getTime()
|
504 |
|
505 |
|
506 | stringToBeRun = normaliseDots stringToBeRun
|
507 |
|
508 |
|
509 | if ENABLE_CACHING and stringToBeRun != "clearall"
|
510 | currentStateHash = getStateHash()
|
511 | cacheKey = currentStateHash + " stringToBeRun: " + stringToBeRun
|
512 | if CACHE_DEBUGS then console.log "cached_runs key: " + cacheKey
|
513 | possiblyCached = cached_runs.get(cacheKey)
|
514 |
|
515 | if possiblyCached?
|
516 | if CACHE_HITSMISS_DEBUGS then console.log "cached_runs hit on: " + stringToBeRun
|
517 | unfreeze(possiblyCached)
|
518 |
|
519 | if TIMING_DEBUGS
|
520 | totalTime = new Date().getTime() - timeStart
|
521 | console.log "run time: " + totalTime + "ms, saved " + (possiblyCached[possiblyCached.length-2] - totalTime) + "ms due to cache hit"
|
522 | return possiblyCached[possiblyCached.length - 1]
|
523 | else
|
524 | if CACHE_HITSMISS_DEBUGS then console.log "cached_runs miss on: " + stringToBeRun
|
525 | if TIMING_DEBUGS
|
526 | cacheMissPenalty = (new Date().getTime() - timeStart)
|
527 |
|
528 | if stringToBeRun == "selftest"
|
529 | selftest()
|
530 | return
|
531 |
|
532 |
|
533 |
|
534 |
|
535 | if !inited
|
536 | inited = true
|
537 | init()
|
538 |
|
539 | i = 0
|
540 | n = 0
|
541 | indexOfPartRemainingToBeParsed = 0
|
542 |
|
543 | allReturnedPlainStrings = ""
|
544 | allReturnedLatexStrings = ""
|
545 |
|
546 | while (1)
|
547 |
|
548 |
|
549 |
|
550 | try
|
551 | errorMessage = ""
|
552 | check_stack()
|
553 | n = scan(stringToBeRun.substring(indexOfPartRemainingToBeParsed))
|
554 | p1 = pop()
|
555 | check_stack()
|
556 | catch error
|
557 | if PRINTOUTRESULT then console.log error
|
558 |
|
559 | allReturnedPlainStrings += error.message
|
560 | if generateLatex
|
561 |
|
562 | theErrorMessage = turnErrorMessageToLatex error.message
|
563 | allReturnedLatexStrings += theErrorMessage
|
564 | reset_after_error()
|
565 |
|
566 | break
|
567 |
|
568 |
|
569 |
|
570 | if (n == 0)
|
571 | break
|
572 |
|
573 |
|
574 |
|
575 |
|
576 |
|
577 |
|
578 |
|
579 |
|
580 |
|
581 |
|
582 |
|
583 | indexOfPartRemainingToBeParsed += n
|
584 |
|
585 | push(p1)
|
586 |
|
587 | errorWhileExecution = false
|
588 | try
|
589 | stringsEmittedByUserPrintouts = ""
|
590 | top_level_eval()
|
591 |
|
592 |
|
593 |
|
594 | p2 = pop()
|
595 | check_stack()
|
596 |
|
597 | if (isstr(p2))
|
598 | if DEBUG then console.log(p2.str)
|
599 | if DEBUG then console.log("\n")
|
600 |
|
601 |
|
602 |
|
603 | if (p2 == symbol(NIL))
|
604 |
|
605 | collectedPlainResult = stringsEmittedByUserPrintouts
|
606 | if generateLatex
|
607 | collectedLatexResult = "$$" + stringsEmittedByUserPrintouts + "$$"
|
608 | else
|
609 |
|
610 |
|
611 | collectedPlainResult = print_expr(p2)
|
612 | collectedPlainResult += "\n"
|
613 |
|
614 | if generateLatex
|
615 | collectedLatexResult = "$$" + collectLatexStringFromReturnValue(p2) + "$$"
|
616 | if DEBUG then console.log "collectedLatexResult: " + collectedLatexResult
|
617 |
|
618 | allReturnedPlainStrings += collectedPlainResult
|
619 | if generateLatex then allReturnedLatexStrings += collectedLatexResult
|
620 |
|
621 | if PRINTOUTRESULT
|
622 | if DEBUG then console.log "printline"
|
623 | if DEBUG then console.log collectedPlainResult
|
624 |
|
625 | if PRINTOUTRESULT
|
626 | if DEBUG then console.log "display:"
|
627 | print2dascii(p2)
|
628 |
|
629 | if generateLatex then allReturnedLatexStrings += "\n"
|
630 |
|
631 | catch error
|
632 | errorWhileExecution = true
|
633 | collectedPlainResult = error.message
|
634 | if generateLatex then collectedLatexResult = turnErrorMessageToLatex error.message
|
635 |
|
636 | if PRINTOUTRESULT then console.log collectedPlainResult
|
637 |
|
638 | allReturnedPlainStrings += collectedPlainResult
|
639 | if collectedPlainResult != ""
|
640 | allReturnedPlainStrings += "\n"
|
641 |
|
642 | if generateLatex
|
643 | allReturnedLatexStrings += collectedLatexResult
|
644 | allReturnedLatexStrings += "\n"
|
645 |
|
646 | resetCache()
|
647 | init()
|
648 |
|
649 | if allReturnedPlainStrings[allReturnedPlainStrings.length-1] == "\n"
|
650 | allReturnedPlainStrings = allReturnedPlainStrings.substring(0,allReturnedPlainStrings.length-1)
|
651 |
|
652 | if generateLatex
|
653 | if allReturnedLatexStrings[allReturnedLatexStrings.length-1] == "\n"
|
654 | allReturnedLatexStrings = allReturnedLatexStrings.substring(0,allReturnedLatexStrings.length-1)
|
655 |
|
656 | if generateLatex
|
657 | if DEBUG then console.log "allReturnedLatexStrings: " + allReturnedLatexStrings
|
658 |
|
659 | stringToBeReturned = [allReturnedPlainStrings, allReturnedLatexStrings]
|
660 | else
|
661 | stringToBeReturned = allReturnedPlainStrings
|
662 |
|
663 | if ENABLE_CACHING and stringToBeRun != "clearall" and !errorWhileExecution
|
664 | frozen = freeze()
|
665 | toBeFrozen = [frozen[0], frozen[1], frozen[2], frozen[3], frozen[4], frozen[5], (new Date().getTime() - timeStart), stringToBeReturned]
|
666 | if CACHE_DEBUGS then console.log "setting cached_runs on key: " + cacheKey
|
667 | cached_runs.set(cacheKey, toBeFrozen)
|
668 |
|
669 | if TIMING_DEBUGS
|
670 | timingDebugWrite = "run time on: " + stringToBeRun + " : " + (new Date().getTime() - timeStart) + "ms"
|
671 | if ENABLE_CACHING and stringToBeRun != "clearall" then timingDebugWrite += ", of which cache miss penalty: " + cacheMissPenalty + "ms"
|
672 | console.log timingDebugWrite
|
673 |
|
674 | allReturnedPlainStrings = ""
|
675 | allReturnedLatexStrings = ""
|
676 | return stringToBeReturned
|
677 |
|
678 | check_stack = ->
|
679 | if (tos != 0)
|
680 | debugger
|
681 | stop("stack error")
|
682 | if (frame != TOS)
|
683 | debugger
|
684 | stop("frame error")
|
685 | if chainOfUserSymbolsNotFunctionsBeingEvaluated.length != 0
|
686 | debugger
|
687 | stop("symbols evaluation still ongoing?")
|
688 | if evaluatingAsFloats != 0
|
689 | debugger
|
690 | stop("numeric evaluation still ongoing?")
|
691 | if evaluatingPolar != 0
|
692 | debugger
|
693 | stop("evaluation of polar still ongoing?")
|
694 |
|
695 |
|
696 |
|
697 |
|
698 |
|
699 | top_level_eval = ->
|
700 | if DEBUG then console.log "#### top level eval"
|
701 | save()
|
702 |
|
703 | trigmode = 0
|
704 |
|
705 | p1 = symbol(AUTOEXPAND)
|
706 |
|
707 | if (iszero(get_binding(p1)))
|
708 | expanding = 0
|
709 | else
|
710 | expanding = 1
|
711 |
|
712 | p1 = pop()
|
713 | push(p1)
|
714 | Eval()
|
715 | p2 = pop()
|
716 |
|
717 |
|
718 |
|
719 | if (p2 == symbol(NIL))
|
720 | push(p2)
|
721 | restore()
|
722 | return
|
723 |
|
724 |
|
725 | set_binding(symbol(LAST), p2)
|
726 |
|
727 | if (!iszero(get_binding(symbol(BAKE))))
|
728 | push(p2)
|
729 | bake()
|
730 | p2 = pop()
|
731 |
|
732 |
|
733 |
|
734 |
|
735 |
|
736 | if ((p1 == symbol(SYMBOL_I) || p1 == symbol(SYMBOL_J)) && isimaginaryunit(p2))
|
737 | doNothing = 0
|
738 | else if (isimaginaryunit(get_binding(symbol(SYMBOL_J))))
|
739 | push(p2)
|
740 | push(imaginaryunit)
|
741 | push_symbol(SYMBOL_J)
|
742 | subst()
|
743 | p2 = pop()
|
744 | else if (isimaginaryunit(get_binding(symbol(SYMBOL_I))))
|
745 | push(p2)
|
746 | push(imaginaryunit)
|
747 | push_symbol(SYMBOL_I)
|
748 | subst()
|
749 | p2 = pop()
|
750 |
|
751 |
|
752 |
|
753 |
|
754 |
|
755 |
|
756 |
|
757 |
|
758 |
|
759 |
|
760 |
|
761 |
|
762 |
|
763 |
|
764 |
|
765 | push(p2)
|
766 |
|
767 | restore()
|
768 |
|
769 | check_esc_flag = ->
|
770 | if (esc_flag)
|
771 | stop("esc key")
|
772 |
|
773 |
|
774 |
|
775 |
|
776 |
|
777 |
|
778 |
|
779 | clearAlgebraEnvironment = ->
|
780 |
|
781 | do_clearall()
|
782 |
|
783 | computeDependenciesFromAlgebra = (codeFromAlgebraBlock) ->
|
784 | if DEBUG then console.log "computeDependenciesFromAlgebra!!!"
|
785 |
|
786 |
|
787 |
|
788 |
|
789 | originalcodeFromAlgebraBlock = codeFromAlgebraBlock
|
790 | keepState = true
|
791 | called_from_Algebra_block = true
|
792 |
|
793 |
|
794 |
|
795 | codeFromAlgebraBlock = normaliseDots codeFromAlgebraBlock
|
796 |
|
797 | if !keepState
|
798 | userSimplificationsInListForm = []
|
799 | userSimplificationsInProgramForm = ""
|
800 | for i in userSimplificationsInListForm
|
801 |
|
802 | userSimplificationsInProgramForm += "silentpattern(" + car(i) + ","+ car(cdr(i)) + "," + car(cdr(cdr(i))) + ")\n"
|
803 |
|
804 | do_clearall()
|
805 | codeFromAlgebraBlock = userSimplificationsInProgramForm + codeFromAlgebraBlock
|
806 | if DEBUG then console.log "codeFromAlgebraBlock including patterns: " + codeFromAlgebraBlock
|
807 |
|
808 | if DEBUG
|
809 | console.log "computeDependenciesFromAlgebra: patterns in the list --------------- "
|
810 | for i in userSimplificationsInListForm
|
811 | console.log car(i) + ","+cdr(i)+")"
|
812 | console.log "...end of list --------------- "
|
813 |
|
814 |
|
815 | called_from_Algebra_block = false
|
816 |
|
817 | return findDependenciesInScript(codeFromAlgebraBlock, true)[6]
|
818 |
|
819 | computeResultsAndJavaScriptFromAlgebra = (codeFromAlgebraBlock) ->
|
820 |
|
821 |
|
822 | originalcodeFromAlgebraBlock = codeFromAlgebraBlock
|
823 | keepState = true
|
824 | called_from_Algebra_block = true
|
825 |
|
826 | timeStartFromAlgebra = new Date().getTime()
|
827 |
|
828 | if TIMING_DEBUGS
|
829 | console.log " --------- computeResultsAndJavaScriptFromAlgebra input: " + codeFromAlgebraBlock + " at: " + (new Date())
|
830 |
|
831 |
|
832 |
|
833 |
|
834 |
|
835 |
|
836 |
|
837 | codeFromAlgebraBlock = normaliseDots codeFromAlgebraBlock
|
838 |
|
839 |
|
840 |
|
841 | stringToBeRun = codeFromAlgebraBlock
|
842 |
|
843 | if DEBUG
|
844 | console.log "computeResultsAndJavaScriptFromAlgebra: patterns in the list --------------- "
|
845 | for i in userSimplificationsInListForm
|
846 | console.log car(i) + ","+cdr(i)+")"
|
847 | console.log "...end of list --------------- "
|
848 |
|
849 | if !keepState
|
850 | userSimplificationsInListForm = []
|
851 | userSimplificationsInProgramForm = ""
|
852 | for i in userSimplificationsInListForm
|
853 |
|
854 | userSimplificationsInProgramForm += "silentpattern(" + car(i) + ","+ car(cdr(i)) + "," + car(cdr(cdr(i))) + ")\n"
|
855 |
|
856 | do_clearall()
|
857 | codeFromAlgebraBlock = userSimplificationsInProgramForm + codeFromAlgebraBlock
|
858 | if DEBUG then console.log "codeFromAlgebraBlock including patterns: " + codeFromAlgebraBlock
|
859 |
|
860 |
|
861 | [testableStringIsIgnoredHere,result,code,readableSummaryOfCode, latexResult, errorMessage, dependencyInfo] =
|
862 | findDependenciesInScript(codeFromAlgebraBlock)
|
863 |
|
864 | called_from_Algebra_block = false
|
865 |
|
866 | if readableSummaryOfCode != "" or errorMessage != ""
|
867 | result += "\n" + readableSummaryOfCode
|
868 | if errorMessage != ""
|
869 | result += "\n" + errorMessage
|
870 | result = result.replace /\n/g,"\n\n"
|
871 |
|
872 | latexResult += "\n" + "$$" + readableSummaryOfCode + "$$"
|
873 | if errorMessage != ""
|
874 | latexResult += turnErrorMessageToLatex errorMessage
|
875 | latexResult = latexResult.replace /\n/g,"\n\n"
|
876 |
|
877 |
|
878 |
|
879 |
|
880 | latexResult = latexResult.replace /\n*/,""
|
881 | latexResult = latexResult.replace /\$\$\$\$\n*/g,""
|
882 |
|
883 | code = code.replace /Math\./g,""
|
884 | code = code.replace /\n/g,"\n\n"
|
885 |
|
886 |
|
887 |
|
888 |
|
889 |
|
890 | if TIMING_DEBUGS
|
891 | console.log "computeResultsAndJavaScriptFromAlgebra time (total time from notebook and back) for: " + stringToBeRun + " : "+ ((new Date().getTime()) - timeStartFromAlgebra) + "ms"
|
892 |
|
893 |
|
894 |
|
895 | code: code
|
896 |
|
897 |
|
898 | result: latexResult
|
899 | latexResult: latexResult
|
900 | dependencyInfo: dependencyInfo
|
901 |
|
902 | enableCaching = ->
|
903 | ENABLE_CACHING = true
|
904 |
|
905 | disableCaching = ->
|
906 | ENABLE_CACHING = false
|
907 |
|
908 | (exports ? this).run = run
|
909 | (exports ? this).findDependenciesInScript = findDependenciesInScript
|
910 | (exports ? this).computeDependenciesFromAlgebra = computeDependenciesFromAlgebra
|
911 | (exports ? this).computeResultsAndJavaScriptFromAlgebra = computeResultsAndJavaScriptFromAlgebra
|
912 | (exports ? this).clearAlgebraEnvironment = clearAlgebraEnvironment
|
913 | (exports ? this).enableCaching = enableCaching
|
914 | (exports ? this).disableCaching = disableCaching
|