186 self cmd_setOrClear:lineStream to:false |
215 self cmd_setOrClear:lineStream to:false |
187 |
216 |
188 "Created: / 07-12-2006 / 19:04:50 / cg" |
217 "Created: / 07-12-2006 / 19:04:50 / cg" |
189 ! |
218 ! |
190 |
219 |
|
220 cmd_debug:lineStream |
|
221 MiniDebugger enter. |
|
222 ! |
|
223 |
|
224 cmd_edit:lineStream |
|
225 "edit a class or selector in an external editor" |
|
226 |
|
227 |errStream classOrMethodName cls methodName selector |
|
228 code isNewClass editFullClass tmpFile modifiedTime| |
|
229 |
|
230 errStream := self errorStream. |
|
231 |
|
232 isNewClass := editFullClass := false. |
|
233 |
|
234 lineStream skipSeparators. |
|
235 lineStream atEnd ifTrue:[ |
|
236 cls := lastEditedClass. |
|
237 methodName := lastEditedSelector. |
|
238 ] ifFalse:[ |
|
239 |
|
240 classOrMethodName := lineStream |
|
241 upToElementForWhich:[:ch | |
|
242 ch isLetterOrDigit not and:[ch ~~ $_] |
|
243 ]. |
|
244 "/ |
|
245 (classOrMethodName isUppercaseFirst) ifTrue:[ |
|
246 (cls := Smalltalk classNamed:classOrMethodName) isNil ifTrue:[ |
|
247 errStream show:'edit: no such class: ',classOrMethodName,' ; create (y/n)? '. |
|
248 (self inputStream nextLine withoutSeparators startsWith:'y') ifFalse:[^ self]. |
|
249 isNewClass := true. |
|
250 code := |
|
251 '"/ change the code as required, then save and exit the editor. |
|
252 "/ To cancel this edit, leave the editor WITHOUT saving. |
|
253 "/ |
|
254 |
|
255 Object |
|
256 subclass:#%1 |
|
257 instanceVariableNames:'''' |
|
258 classVariableNames:'''' |
|
259 poolDictionaries:'''' |
|
260 category:''user classes'' |
|
261 ' bindWith:classOrMethodName. |
|
262 ] ifFalse:[ |
|
263 lineStream skipSeparators. |
|
264 lineStream atEnd ifFalse:[ |
|
265 methodName := lineStream upToSeparator. |
|
266 ]. |
|
267 ]. |
|
268 ] ifFalse:[ |
|
269 methodName := classOrMethodName |
|
270 ]. |
|
271 ]. |
|
272 |
|
273 isNewClass ifFalse:[ |
|
274 cls := cls ? lastEditedClass. |
|
275 cls isNil ifTrue:[ |
|
276 errStream showCR:'edit usage:'. |
|
277 errStream showCR:' #edit className selector'. |
|
278 errStream showCR:' #edit className '. |
|
279 errStream showCR:' #edit selector (class as in previous edit)'. |
|
280 errStream showCR:' #edit (class/method as in previous edit)'. |
|
281 ^ self. |
|
282 ]. |
|
283 lastEditedClass := cls. |
|
284 lastEditedSelector := methodName. |
|
285 |
|
286 methodName isNil ifTrue:[ |
|
287 editFullClass := true. |
|
288 code := cls source asString |
|
289 ] ifFalse:[ |
|
290 ((selector := methodName asSymbolIfInterned) isNil |
|
291 or:[ (cls implements:selector) not]) ifTrue:[ |
|
292 errStream show:('"',methodName,'" is a new method; create (y/n)? '). |
|
293 (self inputStream nextLine withoutSeparators startsWith:'y') ifFalse:[^ self]. |
|
294 code := |
|
295 '"/ change the code as required, then save and exit the editor. |
|
296 "/ To cancel this edit, leave the editor WITHOUT saving. |
|
297 |
|
298 %1 |
|
299 "this is a new method" |
|
300 self halt |
|
301 ' bindWith:methodName. |
|
302 ] ifFalse:[ |
|
303 code := (cls compiledMethodAt:selector) source. |
|
304 ]. |
|
305 ]. |
|
306 ]. |
|
307 |
|
308 [ |
|
309 |ok cmd| |
|
310 |
|
311 tmpFile := Filename newTemporary. |
|
312 tmpFile contents:code. |
|
313 modifiedTime := tmpFile modificationTime. |
|
314 |
|
315 cmd := '%1 "%2"'. |
|
316 OperatingSystem isUNIXlike ifTrue:[ |
|
317 cmd := '%1 "%2" </dev/tty'. |
|
318 ]. |
|
319 |
|
320 ok := OperatingSystem |
|
321 executeCommand:(cmd bindWith:(self editorCommand) with:tmpFile pathName) |
|
322 inputFrom:Stdin |
|
323 outputTo:Stdout |
|
324 errorTo:Stderr |
|
325 auxFrom:nil |
|
326 environment:nil |
|
327 inDirectory:nil |
|
328 lineWise:false |
|
329 newPgrp:false |
|
330 showWindow:true |
|
331 onError:[:status | false]. |
|
332 |
|
333 (ok and:[tmpFile modificationTime ~= modifiedTime]) ifTrue:[ |
|
334 isNewClass ifTrue:[ |
|
335 Compiler evaluate:tmpFile contentsOfEntireFile. |
|
336 errStream showCR:'Class (re)defined.' |
|
337 ] ifFalse:[ |
|
338 editFullClass ifTrue:[ |
|
339 tmpFile fileIn. |
|
340 errStream showCR:'Class (re)compiled.' |
|
341 ] ifFalse:[ |
|
342 cls compile:tmpFile contentsOfEntireFile classified:'*as yet uncategorized'. |
|
343 errStream showCR:'Method (re)compiled.' |
|
344 ]. |
|
345 ]. |
|
346 ] ifFalse:[ |
|
347 errStream showCR:'No change.' |
|
348 ]. |
|
349 ] ensure:[ |
|
350 tmpFile notNil ifTrue:[ |
|
351 tmpFile remove |
|
352 ] |
|
353 ]. |
|
354 |
|
355 " |
|
356 Smalltalk readEvalPrintLoop |
|
357 |
|
358 self new |
|
359 input:Stdin; |
|
360 cmd_edit:'MyClass foo' readStream |
|
361 " |
|
362 |
|
363 "Modified: / 08-11-2016 / 22:46:12 / cg" |
|
364 ! |
|
365 |
191 cmd_exit:lineStream |
366 cmd_exit:lineStream |
192 exitAction value |
367 exitAction value |
193 |
368 |
194 "Created: / 07-12-2006 / 18:55:46 / cg" |
369 "Created: / 07-12-2006 / 18:55:46 / cg" |
195 ! |
370 ! |
196 |
371 |
197 cmd_help:lineStream |
372 cmd_help:lineStream |
198 self errorStream |
373 self errorStream |
199 nextPutAll: |
374 nextPutAll: |
200 'Everything entered up to an empty line or a line ending in "." is called a "chunk" and evaluated. |
375 'Everything entered up to an empty line or a line ending in "." is called a "chunk" and evaluated. |
201 Lines starting with "#" are commands to the read-eval-print interpreter. |
376 Lines starting with "#" are commands to the read-eval-print interpreter. |
202 |
377 |
203 Valid commands are: |
378 Valid commands are: |
204 #help ............... this text |
379 #help ............... this text |
205 #exit ............... exit interpreter loop |
380 #exit ............... exit interpreter loop |
206 #use <package>....... use (load) a package |
381 #use <package>....... use (load) a package |
207 stx:libwidg .............. GUI package |
382 stx:libwidg .............. GUI package |
208 stx:libtool .............. IDE tool package |
383 stx:libtool .............. IDE tool package |
209 stx:goodies/regex ........ regex package |
384 stx:goodies/regex ........ regex package |
210 stx:goodies/petitparser .. peg parser package |
385 stx:goodies/petitparser .. peg parser package |
211 #read <filename>..... read another script or source file |
386 #read <filename>..... read another script or source file |
212 #show <what> ........ show info |
387 #show <what> ........ show info |
213 variables .......... interpreter variables |
388 variables .......... interpreter variables |
214 processes .......... processes |
389 processes .......... processes |
215 memory ............. memory usage |
390 memory ............. memory usage |
216 flags .............. flags |
391 flags .............. flags |
217 modules ............ loaded modules |
392 modules ............ loaded modules |
|
393 packages ........... available packages to load |
|
394 all ................ all of the above |
218 #set/clear <flag> ... set or clear a flag |
395 #set/clear <flag> ... set or clear a flag |
219 trace .............. tracing execution |
396 trace .............. tracing execution |
220 timing ............. timing execution |
397 timing ............. timing execution |
221 chunkFormat ........ traditional bang chunk format input mode |
398 profiling .......... show execution profile |
|
399 chunkFormat ........ traditional bang chunk format input mode |
|
400 editor ............. command used with #edit directive |
|
401 #debug ................. enter a MiniDebugger |
|
402 #edit <what> ........ open an external editor |
|
403 class .............. on a class |
|
404 class selector ..... on a method |
|
405 <empty> ............ on previously edited method/last class |
222 |
406 |
223 The MiniDebugger (if entered) shows its own help with "?". |
407 The MiniDebugger (if entered) shows its own help with "?". |
224 ' |
408 ' |
225 |
409 |
226 "Created: / 07-12-2006 / 18:54:20 / cg" |
410 "Created: / 07-12-2006 / 18:54:20 / cg" |
|
411 "Modified: / 08-11-2016 / 22:53:53 / cg" |
227 ! |
412 ! |
228 |
413 |
229 cmd_read:lineStream |
414 cmd_read:lineStream |
230 |filename newInput savedPrompt savedPrint savedInput savedCurrentDirectory| |
415 |filename newInput savedPrompt savedPrint savedInput savedCurrentDirectory savedDoChunkFormat| |
231 |
416 |
232 lineStream skipSeparators. |
417 lineStream skipSeparators. |
233 filename := lineStream upToEnd withoutSeparators. |
418 filename := lineStream upToEnd withoutSeparators. |
234 filename isNil ifTrue:[ |
419 filename isNil ifTrue:[ |
235 '? which file?' errorPrintCR. |
420 self errorStream showCR:'? which file?'. |
236 ^ self. |
421 ^ self. |
237 ]. |
422 ]. |
238 filename := filename withoutSeparators. |
423 filename := filename withoutSeparators. |
239 filename isEmpty ifTrue:[ |
424 filename isEmpty ifTrue:[ |
240 '? which file?' errorPrintCR. |
425 self errorStream showCR:'? which file?'. |
241 ^ self. |
426 ^ self. |
242 ]. |
427 ]. |
|
428 |
|
429 currentDirectory := currentDirectory ? (Filename currentDirectory). |
243 |
430 |
244 filename := filename asFilename. |
431 filename := filename asFilename. |
245 filename isAbsolute ifFalse:[ |
432 filename isAbsolute ifFalse:[ |
246 filename := currentDirectory construct:filename. |
433 filename := currentDirectory construct:filename. |
247 ]. |
434 ]. |
248 |
435 |
249 newInput := filename readStream. |
436 StreamError ignoreIn:[ |
|
437 newInput := filename readStream. |
|
438 ]. |
250 newInput isNil ifTrue:[ |
439 newInput isNil ifTrue:[ |
251 ('Could not find file: "',filename,'"') errorPrintCR. |
440 self errorStream showCR:('Could not find file: "',filename pathName,'"'). |
252 ^ self. |
441 ^ self. |
253 ]. |
442 ]. |
254 |
443 |
255 [ |
444 [ |
256 savedCurrentDirectory := currentDirectory. |
445 savedCurrentDirectory := currentDirectory. |
257 savedInput := inputStream. |
446 savedDoChunkFormat := doChunkFormat. |
258 savedPrint := printFlag. |
447 savedInput := inputStream. |
259 savedPrompt := prompt. |
448 savedPrint := printFlag. |
260 |
449 savedPrompt := prompt. |
261 currentDirectory := filename directory. |
450 |
262 inputStream := newInput. |
451 currentDirectory := filename directory. |
263 |
452 inputStream := newInput. |
264 self |
453 |
265 basicReadEvalPrintLoopWithInput:newInput |
454 self |
266 output:outputStream |
455 basicReadEvalPrintLoopWithInput:newInput |
267 error:errorStream |
456 output:outputStream |
268 compiler:compiler |
457 error:errorStream |
269 prompt:false |
458 compiler:(compiler ? Compiler ? Parser) |
270 print:false. |
459 prompt:false |
|
460 print:false. |
271 ] ensure:[ |
461 ] ensure:[ |
272 currentDirectory := savedCurrentDirectory. |
462 newInput close. |
273 inputStream := savedInput. |
463 doChunkFormat := savedDoChunkFormat. |
274 printFlag := savedPrint. |
464 currentDirectory := savedCurrentDirectory. |
275 prompt := savedPrompt |
465 inputStream := savedInput. |
|
466 printFlag := savedPrint. |
|
467 prompt := savedPrompt. |
276 ]. |
468 ]. |
277 ! |
469 ! |
278 |
470 |
279 cmd_set:lineStream |
471 cmd_set:lineStream |
280 self cmd_setOrClear:lineStream to:true |
472 self cmd_setOrClear:lineStream to:true |
286 |what| |
478 |what| |
287 |
479 |
288 lineStream skipSeparators. |
480 lineStream skipSeparators. |
289 what := lineStream nextAlphaNumericWord. |
481 what := lineStream nextAlphaNumericWord. |
290 what notNil ifTrue:[ |
482 what notNil ifTrue:[ |
291 (what startsWith:'tra') ifTrue:[ |
483 (what startsWith:'tra') ifTrue:[ |
292 traceFlag := aBoolean. |
484 traceFlag := aBoolean. |
293 ^ self. |
485 ^ self. |
294 ]. |
486 ]. |
295 (what startsWith:'tim') ifTrue:[ |
487 (what startsWith:'tim') ifTrue:[ |
296 timingFlag := aBoolean. |
488 timingFlag := aBoolean. |
297 ^ self. |
489 ^ self. |
298 ]. |
490 ]. |
299 (what startsWith:'chunk') ifTrue:[ |
491 (what startsWith:'pro') ifTrue:[ |
300 doChunkFormat := aBoolean. |
492 profilingFlag := aBoolean. |
301 ^ self. |
493 ^ self. |
302 ]. |
494 ]. |
303 ]. |
495 (what startsWith:'chunk') ifTrue:[ |
304 self errorStream nextPutLine:'? which flag ?'. |
496 doChunkFormat := aBoolean. |
305 |
497 ^ self. |
306 "Modified: / 07-12-2006 / 19:13:34 / cg" |
498 ]. |
|
499 (what startsWith:'edi') ifTrue:[ |
|
500 aBoolean ifTrue:[ |
|
501 "/ set editor cmd |
|
502 lineStream skipSeparators. |
|
503 editorCommand := lineStream upToEnd. |
|
504 ] ifFalse:[ |
|
505 editorCommand := nil. |
|
506 ]. |
|
507 ^ self. |
|
508 ]. |
|
509 ]. |
|
510 self errorStream showCR:'? which flag ?'. |
|
511 |
|
512 "Modified: / 08-11-2016 / 22:49:17 / cg" |
307 ! |
513 ! |
308 |
514 |
309 cmd_show:lineStream |
515 cmd_show:lineStream |
310 |errStream what all printModule| |
516 |errStream what showAll ok| |
311 |
517 |
312 " |
|
313 self basicNew cmd_show:'packages' readStream |
|
314 " |
|
315 errStream := self errorStream. |
518 errStream := self errorStream. |
316 |
519 |
317 lineStream skipSeparators. |
520 lineStream skipSeparators. |
318 what := lineStream nextAlphaNumericWord. |
521 what := lineStream nextAlphaNumericWord. |
|
522 ok := false. |
|
523 |
319 what notNil ifTrue:[ |
524 what notNil ifTrue:[ |
320 (what startsWith:'var') ifTrue:[ |
525 showAll := (what startsWith:'all'). |
321 Workspace notNil ifTrue:[ |
526 |
322 Workspace workspaceVariables keysAndValuesDo:[:nm :h | |
527 (showAll or:[ what startsWith:'var' ]) ifTrue:[ |
323 errStream nextPutAll:nm; nextPutAll:' -> '; nextPutLine:h value. |
528 showAll ifTrue:[ errStream showCR:'Variables:'; showCR:'----------' ]. |
324 ]. |
529 self showVariables. |
325 ]. |
530 ok := true. |
326 ^ self. |
531 ]. |
327 ]. |
532 |
328 (what startsWith:'proc') ifTrue:[ |
533 (showAll or:[ what startsWith:'proc' ]) ifTrue:[ |
329 MiniDebugger basicNew showProcesses. |
534 showAll ifTrue:[ errStream cr; showCR:'Threads:'; showCR:'--------' ]. |
330 ^ self. |
535 MiniDebugger basicNew showProcesses. |
331 ]. |
536 ok := true. |
332 (what startsWith:'mod') ifTrue:[ |
537 ]. |
333 printModule := |
538 |
334 [:mod | |
539 ("showAll or:[" what startsWith:'pack' "]") ifTrue:[ |
335 errStream |
540 showAll ifTrue:[ errStream cr; showCR:'Available Packages:'; showCR:'--------' ]. |
336 nextPutAll:' '; |
541 self showPackages. |
337 nextPutAll:(mod package "libraryName"); |
542 ok := true. |
338 nextPutLine:' (',(mod type),')'. |
543 ]. |
339 ]. |
544 |
340 |
545 (showAll or:[ what startsWith:'mod' ]) ifTrue:[ |
341 errStream nextPutLine:'builtIn:'. |
546 showAll ifTrue:[ errStream cr; showCR:'Modules:'; showCR:'--------' ]. |
342 ((ObjectMemory binaryModuleInfo |
547 self showModules. |
343 reject:[:m | m dynamic]) |
548 |
344 asSortedCollection:[:a :b | a name < b name]) do:printModule. |
549 ok := true. |
345 |
550 ]. |
346 errStream nextPutLine:'dynamic:'. |
551 |
347 ((ObjectMemory binaryModuleInfo |
552 (showAll or:[ what startsWith:'mem' ]) ifTrue:[ |
348 select:[:m | m dynamic]) |
553 |allMem| |
349 asSortedCollection:[:a :b | a name < b name]) do:printModule. |
554 |
350 |
555 showAll ifTrue:[ errStream cr; showCR:'Memory:'; showCR:'-------' ]. |
351 ^ self. |
556 "/ allMem := ObjectMemory oldSpaceUsed + ObjectMemory symSpaceUsed |
352 ]. |
557 "/ + ObjectMemory newSpaceUsed. |
353 (what startsWith:'mem') ifTrue:[ |
558 errStream |
354 all := ObjectMemory oldSpaceUsed + ObjectMemory symSpaceUsed |
559 "/ showCR:('overall: ',(allMem // 1024) printString,' Kb'); |
355 + ObjectMemory newSpaceUsed. |
560 showCR:('used : ',(ObjectMemory bytesUsed // 1024) printString,' Kb'); |
356 errStream |
561 showCR:('free : ',(ObjectMemory freeSpace // 1024) printString,' Kb'); |
357 nextPutLine:('overall: ',(all // 1024) printString,' Kb'); |
562 show:('minorGC: ',(ObjectMemory scavengeCount) printString); |
358 nextPutLine:('in use : ',(ObjectMemory bytesUsed // 1024) printString,' Kb'); |
563 showCR:(' majorGC: ',(ObjectMemory garbageCollectCount) printString). |
359 nextPutLine:('free : ',(ObjectMemory freeSpace // 1024) printString,' Kb'); |
564 ok := true. |
360 nextPutLine:('minorGC: ',(ObjectMemory scavengeCount) printString); |
565 ]. |
361 nextPutLine:('majorGC: ',(ObjectMemory garbageCollectCount) printString). |
566 |
362 ^ self. |
567 (showAll or:[ what startsWith:'flag' ]) ifTrue:[ |
363 ]. |
568 showAll ifTrue:[ errStream cr; showCR:'Flags:'; showCR:'------' ]. |
364 (what startsWith:'flag') ifTrue:[ |
569 errStream |
365 errStream |
570 showCR:('trace : ',(traceFlag ? false) printString); |
366 nextPutLine:('trace : ',traceFlag printString); |
571 showCR:('timing: ',(timingFlag ? false) printString); |
367 nextPutLine:('timing: ',timingFlag printString); |
572 showCR:('profiling: ',(profilingFlag ? false) printString); |
368 nextPutLine:('chunkFormat: ',doChunkFormat printString). |
573 showCR:('chunkFormat: ',(doChunkFormat ? false) printString); |
369 ^ self. |
574 showCR:('editor: ',self editorCommand printString). |
370 ]. |
575 ok := true. |
371 ]. |
576 ]. |
372 |
577 ]. |
373 errStream nextPutLine:'? show what ?'. |
578 |
374 |
579 ok ifFalse:[ |
375 "Modified: / 07-12-2011 / 22:15:07 / cg" |
580 errStream showCR:'? show what ?'. |
|
581 ]. |
|
582 |
|
583 " |
|
584 self basicNew cmd_show:'packages' readStream |
|
585 " |
|
586 |
|
587 "Modified: / 08-11-2016 / 22:46:51 / cg" |
376 ! |
588 ! |
377 |
589 |
378 cmd_use:lineStream |
590 cmd_use:lineStream |
379 |pkg| |
591 |pkg| |
380 |
592 |
381 lineStream skipSeparators. |
593 lineStream skipSeparators. |
382 pkg := lineStream upToEnd. |
594 pkg := lineStream upToEnd. |
383 pkg isNil ifTrue:[ |
595 pkg isNil ifTrue:[ |
384 '? which package?' errorPrintCR. |
596 self errorStream showCR:'? which package?'. |
385 ^ self. |
597 ^ self. |
386 ]. |
598 ]. |
387 pkg := pkg withoutSeparators. |
599 pkg := pkg withoutSeparators. |
388 pkg isEmpty ifTrue:[ |
600 pkg isEmpty ifTrue:[ |
389 '? which package?' errorPrintCR. |
601 self errorStream showCR:'? which package?'. |
390 ^ self. |
602 ^ self. |
391 ]. |
603 ]. |
392 |
604 |
393 [ |
605 [ |
394 Smalltalk loadPackage:pkg. |
606 Smalltalk loadPackage:pkg. |
395 ] on:PackageLoadError do:[:ex| |
607 ] on:PackageLoadError do:[:ex| |
396 "/ allow for some shortcuts... |
608 "/ allow for some shortcuts... |
397 (pkg includes:$:) ifTrue:[ |
609 (pkg includes:$:) ifTrue:[ |
398 self errorStream nextPutLine:('Failed to load package: "',pkg,'"'). |
610 self errorStream showCR:('Failed to load package: "',pkg,'"'). |
399 ] ifFalse:[ |
611 ] ifFalse:[ |
400 "/ try stx standard package |
612 "/ try stx standard package |
401 pkg := 'stx:', pkg. |
613 pkg := 'stx:', pkg. |
402 ex restart. |
614 ex restart. |
403 ]. |
615 ]. |
404 ]. |
616 ]. |
405 |
617 |
406 "Created: / 07-12-2006 / 19:07:56 / cg" |
618 "Created: / 07-12-2006 / 19:07:56 / cg" |
407 ! |
619 ! |
408 |
620 |
409 directive:line |
621 directive:line |
410 |s cmd| |
622 |s cmd| |
411 |
623 |
412 s := line readStream. |
624 s := line readStream. |
413 s next. "/ skip the hash |
625 s next. "/ skip the hash |
|
626 s peek == $!! ifTrue:[ |
|
627 "/ skip shebang line |
|
628 ^ self. |
|
629 ]. |
414 s skipSeparators. |
630 s skipSeparators. |
415 |
631 |
416 cmd := s nextAlphaNumericWord. |
632 cmd := s nextAlphaNumericWord. |
417 cmd notNil ifTrue:[ |
633 cmd notNil ifTrue:[ |
418 self |
634 AbortAllOperationRequest handle:[:ex | |
419 perform:('cmd_',cmd) asMutator with:s |
635 self errorStream showCR:('Directive aborted: ', ex description) |
420 ifNotUnderstood:[ |
636 ] do:[ |
421 self errorStream |
637 Error handle:[:ex | |
422 nextPutAll:'?? invalid command: '; |
638 self errorStream showCR:('Caught in directive: ', ex description). |
423 nextPutAll:cmd; |
639 ex suspendedContext fullPrintAll. |
424 nextPutAll:'. Type "#help" for help.'; |
640 ] do:[ |
425 cr. |
641 ControlInterrupt handle:[:ex | |
426 ]. |
642 MiniDebugger enter. |
|
643 "/ self errorStream showCR:('Ignored in directive: ', ex description). |
|
644 "/ ex reject. |
|
645 "/ ex proceed. |
|
646 ] do:[ |
|
647 self |
|
648 perform:('cmd_',cmd) asMutator with:s |
|
649 ifNotUnderstood:[ |
|
650 self errorStream |
|
651 show:'?? invalid command: '; show:cmd; |
|
652 showCR:'. Type "#help" for help.' |
|
653 ]. |
|
654 ]. |
|
655 ]. |
|
656 ]. |
427 ]. |
657 ]. |
428 |
658 |
429 "Created: / 07-12-2006 / 18:49:17 / cg" |
659 "Created: / 07-12-2006 / 18:49:17 / cg" |
|
660 "Modified: / 08-11-2016 / 21:59:16 / cg" |
|
661 ! |
|
662 |
|
663 showModules |
|
664 |errStream printModule| |
|
665 |
|
666 errStream := self errorStream. |
|
667 |
|
668 printModule := |
|
669 [:mod | |
|
670 errStream |
|
671 show:' '; |
|
672 show:(mod package "libraryName"); |
|
673 showCR:' (',(mod type),')'. |
|
674 ]. |
|
675 |
|
676 errStream nextPutLine:'builtIn:'. |
|
677 ((ObjectMemory binaryModuleInfo |
|
678 reject:[:m | m dynamic]) |
|
679 asSortedCollection:[:a :b | a name < b name]) do:printModule. |
|
680 |
|
681 errStream nextPutLine:'dynamic:'. |
|
682 ((ObjectMemory binaryModuleInfo |
|
683 select:[:m | m dynamic]) |
|
684 asSortedCollection:[:a :b | a name < b name]) do:printModule. |
|
685 |
|
686 " |
|
687 ReadEvalPrintLoop basicNew showModules |
|
688 " |
|
689 ! |
|
690 |
|
691 showPackages |
|
692 |all| |
|
693 |
|
694 all := Set new. |
|
695 Smalltalk knownLoadablePackagesDo:[:packageID :type :path | |
|
696 all add:packageID |
|
697 ]. |
|
698 all := all asOrderedCollection sort. |
|
699 all do:[:eachPackage | |
|
700 self errorStream show:eachPackage. |
|
701 (Smalltalk isPackageLoaded:eachPackage) ifTrue:[ |
|
702 self errorStream show:' (loaded)'. |
|
703 ]. |
|
704 self errorStream cr. |
|
705 ]. |
|
706 |
|
707 " |
|
708 ReadEvalPrintLoop basicNew showPackages |
|
709 ReadEvalPrintLoop basicNew showModules |
|
710 " |
|
711 ! |
|
712 |
|
713 showVariables |
|
714 Workspace notNil ifTrue:[ |
|
715 Workspace workspaceVariables keys asOrderedCollection sort do:[:nm | |
|
716 |holder| |
|
717 holder := Workspace workspaceVariables at:nm. |
|
718 self errorStream |
|
719 show:nm; |
|
720 show:' -> '; |
|
721 showCR:holder value printString. |
|
722 ]. |
|
723 ]. |
|
724 |
|
725 " |
|
726 ReadEvalPrintLoop basicNew showVariables |
|
727 " |
430 ! ! |
728 ! ! |
431 |
729 |
432 !ReadEvalPrintLoop methodsFor:'evaluation'! |
730 !ReadEvalPrintLoop methodsFor:'evaluation'! |
433 |
731 |
434 basicReadEvalPrintLoopWithInput:input output:output error:error |
732 basicReadEvalPrintLoopWithInput:input output:output error:error |
438 |
736 |
439 "the core of the interpreter loop; extracted and parametrized, so it can be called recursive |
737 "the core of the interpreter loop; extracted and parametrized, so it can be called recursive |
440 for included scripts. |
738 for included scripts. |
441 If chunkFormat is true, chunks are read. |
739 If chunkFormat is true, chunks are read. |
442 Otherwise, lines up to an empty line (or EOF) or a line ending in '.' are read. |
740 Otherwise, lines up to an empty line (or EOF) or a line ending in '.' are read. |
443 A '#' character appearing in the first column of the first line turns off chunkmode." |
741 A '#' character appearing in the first column of the first line turns off chunkmode, |
|
742 which allows for convenient shell scripts containing a #/bin/stx as the first line." |
|
743 |
|
744 exitAction := [^ self]. |
444 |
745 |
445 [ |
746 [ |
446 |lines chunk| |
747 |lines chunk| |
447 |
748 |
448 prompt notNil ifTrue:[ |
749 prompt notNil ifTrue:[ |
449 error nextPutAll:prompt. |
750 error show:prompt. |
450 ]. |
751 ]. |
451 |
752 |
452 input atEnd ifTrue:[ |
753 input atEnd ifTrue:[ |
453 error cr. |
754 doPrint ifTrue:[ error cr ]. |
454 ^ self. |
755 ^ self. |
455 ]. |
756 ]. |
456 |
757 |
457 input peek == $# ifTrue:[ |
758 input peek == $# ifTrue:[ |
458 self doChunkFormat:false. |
759 self doChunkFormat:false. |
459 ]. |
760 ]. |
460 |
761 |
461 self doChunkFormat ifTrue:[ |
762 self doChunkFormat ifTrue:[ |
462 input skipSeparators. |
763 input skipSeparators. |
463 chunk := input nextChunk. |
764 chunk := input nextChunk. |
464 ] ifFalse:[ |
765 ] ifFalse:[ |
465 lines := OrderedCollection new. |
766 lines := OrderedCollection new. |
466 [ |
767 [ |
467 |line| |
768 |line| |
468 |
769 |
469 line := input nextLine. |
770 line := input nextLine. |
470 line notEmptyOrNil ifTrue:[ |
771 line notEmptyOrNil ifTrue:[ |
471 line = '?' ifTrue:[ |
772 line = '?' ifTrue:[ |
472 self cmd_help:nil. |
773 self cmd_help:nil. |
473 prompt notNil ifTrue:[ |
774 prompt notNil ifTrue:[ |
474 error nextPutAll:prompt. |
775 error show:prompt. |
475 ]. |
776 ]. |
476 ] ifFalse:[ |
777 ] ifFalse:[ |
477 (line startsWith:'#') ifTrue:[ |
778 (line startsWith:'#') ifTrue:[ |
478 self directive:line. |
779 self directive:line. |
479 prompt notNil ifTrue:[ |
780 prompt notNil ifTrue:[ |
480 error nextPutAll:prompt. |
781 error show:prompt. |
481 ]. |
782 ]. |
482 ] ifFalse:[ |
783 ] ifFalse:[ |
483 lines add:line. |
784 lines add:line. |
484 ] |
785 ] |
485 ] |
786 ] |
486 ]. |
787 ]. |
487 line notEmptyOrNil and:[(line endsWith:$.) not]. |
788 line notEmptyOrNil and:[(line endsWith:$.) not]. |
488 ] whileTrue. |
789 ] whileTrue. |
489 chunk := lines asStringWith:Character cr. |
790 chunk := lines asStringWith:Character cr. |
490 ]. |
791 ]. |
491 |
792 |
492 (chunk notEmptyOrNil and:[chunk withoutSeparators notEmpty]) ifTrue:[ |
793 (chunk notEmptyOrNil |
493 "abortAll is handled, but not asked for here!!" |
794 and:[chunk withoutSeparators notEmpty |
494 AbortAllOperationRequest handle:[:ex | |
795 and:[chunk withoutSeparators ~= '.']] |
495 error nextPutLine:('Evaluation aborted: ', ex description) |
796 ) ifTrue:[ |
496 ] do:[ |
797 "abortAll is handled, but not asked for here!!" |
497 (Error, ControlInterrupt) handle:[:ex | |
798 AbortAllOperationRequest handle:[:ex | |
498 prompt isNil ifTrue:[ |
799 error nextPutLine:('Evaluation aborted: ', ex description) |
499 ex reject |
800 ] do:[ |
500 ]. |
801 (Error, ControlInterrupt) handle:[:ex | |
501 MiniDebugger enterWithMessage:(ex errorString) mayProceed:true. |
802 prompt isNil ifTrue:[ |
502 ex mayProceed ifTrue:[ |
803 ex reject |
503 ex proceed. |
804 ]. |
504 ]. |
805 MiniDebugger enterWithMessage:(ex errorString) mayProceed:true. |
505 error nextPutLine:('Evaluation aborted: ', ex description). |
806 ex mayProceed ifTrue:[ |
506 ex return. |
807 ex proceed. |
507 ] do:[ |
808 ]. |
508 |value ms us| |
809 error showCR:('Evaluation aborted: ', ex description). |
509 |
810 ex return. |
510 ms := Time millisecondsToRun:[ |
811 ] do:[ |
511 us := Time microsecondsToRun:[ |
812 |value ms us| |
512 value := (compilerClass new |
813 |
513 requestor:self) |
814 profilingFlag == true ifTrue:[ |
514 evaluate:chunk |
815 MessageTally spyDetailedOn:[ |
515 compile:true. |
816 value := (compilerClass new requestor:self) |
516 ]. |
817 evaluate:chunk |
517 ]. |
818 compile:true. |
518 doPrint ifTrue:[ |
819 ]. |
519 value printOn:output. output cr. |
820 doPrint ifTrue:[ |
520 ]. |
821 value printOn:output. output cr. |
521 |
822 output flush. |
522 timingFlag == true ifTrue:[ |
823 ]. |
523 'execution time: ' printOn:error. |
824 ] ifFalse:[ |
524 ms < 1 ifTrue:[ |
825 us := Time microsecondsToRun:[ |
525 us < 1 ifTrue:[ |
826 value := (compilerClass new requestor:self) |
526 'too small to measure (<1us)' printOn:error. |
827 evaluate:chunk compile:true. |
527 ] ifFalse:[ |
828 ]. |
528 us printOn:output. 'us' printOn:error. |
829 doPrint ifTrue:[ |
529 ] |
830 value isVoid ifFalse:[ |
530 ] ifFalse:[ |
831 value printOn:output. output cr. |
531 ms printOn:output. 'ms' printOn:error. |
832 ]. |
532 ]. |
833 ]. |
533 error cr. |
834 |
534 ]. |
835 timingFlag == true ifTrue:[ |
535 Workspace notNil ifTrue:[ |
836 'execution time: ' printOn:error. |
536 Workspace workspaceVariableAt:'_$$' put:value. |
837 us < 1000 ifTrue:[ |
537 ]. |
838 us < 1 ifTrue:[ |
538 ]. |
839 'too small to measure (<1us)' printOn:error. |
539 ]. |
840 ] ifFalse:[ |
540 ]. |
841 us printOn:output. 'us' printOn:error. |
|
842 ] |
|
843 ] ifFalse:[ |
|
844 ((us / 1000) asFixedPoint:2) printOn:output. 'ms' printOn:error. |
|
845 ]. |
|
846 error cr. |
|
847 ]. |
|
848 ]. |
|
849 Workspace notNil ifTrue:[ |
|
850 Workspace rememberResultAsWorkspaceVariable:value. |
|
851 ]. |
|
852 ]. |
|
853 ]. |
|
854 ]. |
541 ] loop. |
855 ] loop. |
542 |
856 |
543 " |
857 " |
|
858 Smalltalk readEvalPrintLoop. |
|
859 |
544 (ReadEvalPrintLoop new prompt:'>') readEvalPrintLoop |
860 (ReadEvalPrintLoop new prompt:'>') readEvalPrintLoop |
545 " |
861 " |
546 |
862 |
547 "Created: / 07-12-2006 / 17:27:21 / cg" |
863 "Created: / 07-12-2006 / 17:27:21 / cg" |
548 "Modified: / 06-12-2011 / 15:29:03 / cg" |
864 "Modified: / 08-11-2016 / 22:41:47 / cg" |
549 ! |
865 ! |
550 |
866 |
551 readEvalPrintLoop |
867 readEvalPrintLoop |
552 "{ Pragma: +optSpace }" |
868 "{ Pragma: +optSpace }" |
553 |
869 |
555 If the chunkFormat-argument is true, chunks are read. |
871 If the chunkFormat-argument is true, chunks are read. |
556 Otherwise, lines up to an empty line (or EOF) are read. |
872 Otherwise, lines up to an empty line (or EOF) are read. |
557 A '#' character appearing in the first column of the first line |
873 A '#' character appearing in the first column of the first line |
558 switches to chunkmode." |
874 switches to chunkmode." |
559 |
875 |
560 exitAction := [^ self]. |
|
561 |
|
562 ControlInterrupt handle:[:ex | |
876 ControlInterrupt handle:[:ex | |
563 self errorStream nextPutLine:('Caught: ', ex description). |
877 self errorStream showCR:('Caught: ', ex description). |
564 ex restart. |
878 self inputStream atEnd ifTrue:[ |
|
879 ex return. |
|
880 ]. |
|
881 MiniDebugger enter. |
|
882 ex proceed. |
|
883 "/ ex restart. |
565 ] do:[ |
884 ] do:[ |
566 |input output error compilerClass| |
885 |input output error compilerClass| |
567 |
886 |
568 "/ re-evaluate these in the loop, so they can be changed dynamically |
887 "/ re-evaluate these in the loop, so they can be changed dynamically |
569 input := self inputStream. |
888 input := self inputStream. |
570 output := self outputStream. |
889 output := self outputStream. |
571 error := self errorStream. |
890 error := self errorStream. |
572 |
891 |
573 compilerClass := compiler ? Compiler ? Parser. |
892 compilerClass := compiler ? Compiler ? Parser. |
574 compilerClass isNil ifTrue:[ |
893 compilerClass isNil ifTrue:[ |
575 self errorStream nextPutLine:('oops - no Compiler class found'). |
894 error showCR:('oops - no Compiler class found'). |
576 ^ self. |
895 ^ self. |
577 ]. |
896 ]. |
578 self |
897 StreamError handle:[:ex | |
579 basicReadEvalPrintLoopWithInput:input output:output error:error |
898 (input isOpen not or:[input atEnd]) ifTrue:[ |
580 compiler:compilerClass prompt:prompt print:(printFlag ? true). |
899 error showCR:'EOF on input'. |
581 ] |
900 ex return. |
582 |
901 ]. |
583 " |
902 (output isOpen not) ifTrue:[ |
|
903 error showCR:'no output'. |
|
904 ]. |
|
905 (error isOpen not) ifTrue:[ |
|
906 ]. |
|
907 ] do:[ |
|
908 input signalAtEnd:true. |
|
909 self |
|
910 basicReadEvalPrintLoopWithInput:input output:output error:error |
|
911 compiler:compilerClass prompt:prompt print:(printFlag ? true). |
|
912 ] |
|
913 ]. |
|
914 "/ self errorStream showCR:('done.'). |
|
915 |
|
916 " |
|
917 Stdin atEnd |
|
918 Stdin clearEOF |
|
919 Smalltalk readEvalPrintLoop |
584 (ReadEvalPrintLoop new prompt:'>') readEvalPrintLoop |
920 (ReadEvalPrintLoop new prompt:'>') readEvalPrintLoop |
585 " |
921 " |
586 |
922 |
587 "Created: / 07-12-2006 / 17:27:21 / cg" |
923 "Created: / 07-12-2006 / 17:27:21 / cg" |
588 "Modified: / 06-12-2011 / 15:29:03 / cg" |
924 "Modified: / 08-11-2016 / 22:42:21 / cg" |
589 ! ! |
925 ! ! |
590 |
926 |
591 !ReadEvalPrintLoop methodsFor:'queries'! |
927 !ReadEvalPrintLoop methodsFor:'queries'! |
592 |
928 |
593 autoDefineVariables |
929 autoDefineVariables |