ReadEvalPrintLoop.st
author Claus Gittinger <cg@exept.de>
Thu, 07 Dec 2006 19:07:27 +0100
changeset 10255 a50472b6354a
parent 10254 e576d49220c2
child 10256 63993a2b4d15
permissions -rw-r--r--
directives

"
 COPYRIGHT (c) 2006 by eXept Software AG
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
"{ Package: 'stx:libbasic' }"

Object subclass:#ReadEvalPrintLoop
	instanceVariableNames:'inputStream outputStream errorStream compiler prompt
		doChunkFormat traceFlag timingFlag'
	classVariableNames:''
	poolDictionaries:''
	category:'* uncategorized *'
!

!ReadEvalPrintLoop class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 2006 by eXept Software AG
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
! !

!ReadEvalPrintLoop methodsFor:'accessing'!

compiler:something
    compiler := something.
!

doChunkFormat:something
    doChunkFormat := something.

    "Created: / 07-12-2006 / 18:24:04 / cg"
!

error:something
    errorStream := something.

    "Created: / 07-12-2006 / 17:33:39 / cg"
!

input:something
    inputStream := something.

    "Modified: / 07-12-2006 / 17:33:31 / cg"
!

output:something
    outputStream := something.

    "Created: / 07-12-2006 / 17:27:48 / cg"
!

prompt:something
    prompt := something.
! !

!ReadEvalPrintLoop methodsFor:'directives'!

cmd_clear:lineStream
    self cmd_setOrClear:lineStream to:false

    "Created: / 07-12-2006 / 19:04:50 / cg"
!

cmd_exit:lineStream
    Smalltalk exit

    "Created: / 07-12-2006 / 18:55:46 / cg"
!

cmd_help:lineStream
    errorStream
        nextPutAll:
'Everything entered up to an empty line is called a "chunk" and evaluated as a block.
Lines starting with "#" are commands to the read-eval-print interpreter.

Valid commands are:
    help ............... this text
    exit ............... exit smalltalk
    use <package>....... use a package
        stx:libwidg ........ GUI package
        stx:libtool ........ IDE tool package
    show <what> ........ show info
        variables .......... interpreter variables
        processes .......... processes
        memory ............. memory usage
        flags .............. flags
    set/clear <flag> ... set or clear a flag
        trace .............. tracing execution
        timing ............. timing execution
'

    "Created: / 07-12-2006 / 18:54:20 / cg"
!

cmd_set:lineStream
    self cmd_setOrClear:lineStream to:true

    "Modified: / 07-12-2006 / 19:04:46 / cg"
!

cmd_setOrClear:lineStream to:aBoolean
    |what|

    lineStream skipSeparators.
    what := lineStream nextAlphaNumericWord.
    (what startsWith:'tra') ifTrue:[
        traceFlag := aBoolean.
        ^ self.
    ].
    (what startsWith:'tim') ifTrue:[
        timingFlag := aBoolean.
        ^ self.
    ].

    errorStream nextPutLine:'?? which flag ?'.

    "Modified: / 07-12-2006 / 19:06:00 / cg"
!

cmd_show:lineStream
    |what|

    lineStream skipSeparators.
    what := lineStream nextAlphaNumericWord.
    (what startsWith:'var') ifTrue:[
        ^ self.
    ].
    (what startsWith:'proc') ifTrue:[
        MiniDebugger basicNew showProcesses.
        ^ self.
    ].
    (what startsWith:'mem') ifTrue:[
        errorStream nextPutAll:('overall: ',(ObjectMemory bytesUsed / 1024) printString,' kb').
        errorStream nextPutAll:('free   : ',(ObjectMemory freeSpace / 1024) printString,' kb').
        errorStream nextPutAll:('minorGC: ',(ObjectMemory scavengeCount) printString).
        errorStream nextPutAll:('majorGC: ',(ObjectMemory garbageCollectCount) printString).
        ^ self.
    ].
    (what startsWith:'flag') ifTrue:[
        errorStream nextPutAll:('trace : ',traceFlag printString).
        errorStream nextPutAll:('timing: ',timingFlag printString).
        ^ self.
    ].

    errorStream nextPutLine:'?? show what ?'.

    "Modified: / 07-12-2006 / 19:06:31 / cg"
!

cmd_use:lineStream
    |pkg|

    lineStream skipSeparators.
    pkg := lineStream upToEnd withoutSeparators.
    Smalltalk loadPackage:pkg

    "Created: / 07-12-2006 / 19:07:56 / cg"
!

directive:line
    |s cmd|

    s := line readStream.
    s next. "/ skip the hash
    s skipSeparators.

    cmd := s nextAlphaNumericWord.
    self 
        perform:('cmd_',cmd,':') asSymbol with:s 
        ifNotUnderstood:[   
            (errorStream ? Stderr) 
                nextPutAll:'?? invalid command: ';
                nextPutAll:cmd;
                nextPutAll:'. Type "#help" for help.';
                cr.
        ].

    "Created: / 07-12-2006 / 18:49:17 / cg"
! !

!ReadEvalPrintLoop methodsFor:'evaluation'!

readEvalPrintLoop
    "{ Pragma: +optSpace }"

    "simple read-eval-print loop for non-graphical Minitalk.
     If the chunkFormat-argument is true, chunks are read.
     Otherwise, lines up to an empty line (or EOF) are read."

    [
        |input output error lines chunk compilerClass|

        input := inputStream ? Stdin.
        output := outputStream ? Stdout.
        error := errorStream ? Stderr.
        compilerClass := compiler ? Compiler.

        prompt notNil ifTrue:[
            output nextPutAll:prompt.
        ].

        input atEnd ifTrue:[
            ^ self.
        ].

        (doChunkFormat ? true) ifTrue:[
            input skipSeparators.
            chunk := input nextChunk.
        ] ifFalse:[
            lines := OrderedCollection new.
            [
                |line|

                line := input nextLine.
                line notEmptyOrNil ifTrue:[
                    (line startsWith:'#') ifTrue:[
                        self directive:line
                    ] ifFalse:[
                        lines add:line.
                    ]
                ].
                line notEmptyOrNil.
            ] whileTrue.
            chunk := lines asStringWith:Character cr.
        ].

        chunk notEmptyOrNil ifTrue:[
            AbortAllOperationRequest handle:[:ex |
                error nextPutLine:('Evaluation aborted: ', ex description)
            ] do:[
                |value|

                value := (compilerClass new requestor:self) evaluate:chunk.
                value printOn:output.
                output cr.
            ].
        ].
    ] loop.

    "
     (ReadEvalPrintLoop new prompt:'>') readEvalPrintLoop
    "

    "Created: / 07-12-2006 / 17:27:21 / cg"
    "Modified: / 07-12-2006 / 18:45:44 / cg"
! !

!ReadEvalPrintLoop class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libbasic/ReadEvalPrintLoop.st,v 1.6 2006-12-07 18:07:27 cg Exp $'
! !