aboutsummaryrefslogtreecommitdiff
path: root/src/interp/int-top.boot
diff options
context:
space:
mode:
Diffstat (limited to 'src/interp/int-top.boot')
-rw-r--r--src/interp/int-top.boot439
1 files changed, 439 insertions, 0 deletions
diff --git a/src/interp/int-top.boot b/src/interp/int-top.boot
new file mode 100644
index 00000000..9d444b3f
--- /dev/null
+++ b/src/interp/int-top.boot
@@ -0,0 +1,439 @@
+-- Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+-- All rights reserved.
+-- Copyright (C) 2007, Gabriel Dos Reis.
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions are
+-- met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+-- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+-- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+-- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+-- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+-- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+-- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+)package "BOOT"
+
+ncParseAndInterpretString s ==
+ processInteractive(packageTran parseFromString s, nil)
+
+ncParseFromString s ==
+ zeroOneTran packageTran CATCH("SPAD_READER", parseFromString s)
+
+ncINTERPFILE(file, echo) ==
+ savedEcho := $EchoLines
+ savedReadingFile := $ReadingFile
+ $EchoLines: fluid := echo
+ $ReadingFile: fluid := true
+ result := SpadInterpretFile file
+ $EchoLines := savedEcho
+ $ReadingFile := savedReadingFile
+ result
+
+ncGetFunction(op, dom, sig) ==
+ applyInPackage(function getNCfunction,_
+ [rePackageTran(op, '"boot"),_
+ rePackageTran(dom, '"boot"),_
+ rePackageTran(sig, '"boot")],_
+ '"BOOT")
+
+applyInPackage(fun, args, package) ==
+ savedPackage := _*PACKAGE_*
+ SETQ(_*PACKAGE_*, FIND_-PACKAGE package)
+ result := apply(fun, args)
+ SETQ(_*PACKAGE_*, savedPackage)
+ result
+
+ncSetCurrentLine l ==
+ setCurrentLine l
+
+
+--% INTERPRETER TOP LEVEL
+
+spad() ==
+ -- starts the interpreter but does not read in profiles, etc.
+ $PrintCompilerMessageIfTrue: local
+ $inLispVM : local := nil
+ setOutputAlgebra "%initialize%"
+ runspad()
+ 'EndOfSpad
+
+runspad() ==
+ mode:='restart
+ while mode='restart repeat
+ resetStackLimits()
+ CATCH($quitTag, CATCH('coerceFailure,
+ mode:=CATCH('top__level, ncTopLevel())))
+
+ncTopLevel() ==
+-- Top-level read-parse-eval-print loop for the interpreter. Uses
+-- the Bill Burge's parser.
+ IN_-STREAM: fluid := CURINSTREAM
+ _*EOF_*: fluid := NIL
+ $InteractiveMode :fluid := true
+ $BOOT: fluid := NIL
+ $NEWSPAD: fluid := true
+ $SPAD: fluid := true
+ $e:fluid := $InteractiveFrame
+ ncIntLoop()
+
+
+ncIntLoop() ==
+ CURINSTREAM : local := _*STANDARD_-OUTPUT_*
+ CUROUTSTREAM : local := _*STANDARD_-INPUT_*
+ intloop()
+
+
+intloop () ==
+ mode := $intRestart
+ while mode = $intRestart repeat
+ resetStackLimits()
+ mode := CATCH($intTopLevel,
+ SpadInterpretStream(1, ["TIM", "DALY", "?"], true))
+
+
+SpadInterpretStream(str, source, interactive?) ==
+ $fn : local := source
+ pile? := not interactive?
+ $libQuiet : local := not interactive?
+ $newcompMode : local := false
+-- following seems useless and causes ccl package problems
+-- $InteractiveMode : local := false
+
+ $newcompErrorCount: local := 0 -- SMW Feb 2/90.
+ -- Used in highComplete, ncHardError etc.
+
+ $okToExecuteMachineCode: local := true -- set false on error
+ $inclAssertions: local := ["AIX", "CommonLisp"] -- Jan 28/90
+
+
+ $lastPos : local := $nopos ------------>!!!
+ $erMsgToss : local := false --------------->!!!
+ $ncMsgList : local := nil
+
+ $systemCommandFunction : local := function InterpExecuteSpadSystemCommand
+ $shoeReadLineFunction : local := function serverReadLine
+ $promptMsg : local := 'S2CTP023
+
+ interactive? =>
+ PRINC(MKPROMPT())
+ intloopReadConsole('"", str)
+ []
+ intloopInclude (source,0)
+ []
+
+ -----------------------------------------------------------------
+
+intloopReadConsole(b, n)==
+ a:= serverReadLine(_*STANDARD_-INPUT_*)
+ not STRINGP a => leaveScratchpad()
+ #a=0 =>
+ PRINC(MKPROMPT())
+ intloopReadConsole('"", n)
+ $DALYMODE and intloopPrefix?('"(",a) =>
+ intnplisp(a)
+ PRINC(MKPROMPT())
+ intloopReadConsole('"",n)
+ pfx := stripSpaces intloopPrefix?('")fi",a)
+ pfx and ((pfx = '")fi") or (pfx = '")fin")) => []
+ b = '"" and (d := intloopPrefix?('")", a)) =>
+ setCurrentLine d
+ c := ncloopCommand(d,n)
+ PRINC(MKPROMPT())
+ intloopReadConsole('"", c)
+ a:=CONCAT(b,a)
+ ncloopEscaped a => intloopReadConsole(SUBSEQ(a, 0, (LENGTH a) - 1),n)
+ c := intloopProcessString(a, n)
+ PRINC(MKPROMPT())
+ intloopReadConsole('"", c)
+
+intloopPrefix?(prefix,whole) ==
+ #prefix > #whole => false
+ good := true
+ leading := true
+ spaces := 0
+ i := 0
+ len := #prefix
+ wlen := #whole
+ for j in 0.. while (good and i < len and j < wlen) repeat
+ good := (prefix.i = whole.j) or (leading and (whole.j = char " "))
+ if prefix.i = whole.j then i := i+1
+ if (whole.j = char " ") and leading then
+ spaces := spaces + 1
+ else leading := false
+ spaces = wlen => nil
+ if good then SUBSTRING(whole,spaces,nil) else good
+
+
+intloopProcess(n,interactive,s)==
+ StreamNull s => n
+ [lines,ptree]:=CAR s
+ pfAbSynOp?(ptree,"command")=>
+ if interactive then setCurrentLine tokPart ptree
+ FUNCALL($systemCommandFunction, tokPart ptree)
+ intloopProcess(n ,interactive ,CDR s)
+ intloopProcess(intloopSpadProcess(n,lines,ptree,interactive)
+ ,interactive ,CDR s)
+
+intloopEchoParse s==
+ [dq,stream]:=CAR s
+ [lines,rest]:=ncloopDQlines(dq,$lines)
+ setCurrentLine(mkLineList(lines))
+ if $EchoLines then ncloopPrintLines lines
+ $lines:=rest
+ cons([[lines,npParse dqToList dq]],CDR s)
+
+intloopInclude0(st, name, n) ==
+ $lines:local:=incStream(st,name)
+ intloopProcess(n,false,
+ next(function intloopEchoParse,
+ next(function insertpile,
+ next(function lineoftoks,$lines))))
+
+intloopInclude(name, n) ==
+ WITH_-OPEN_-FILE(st name, intloopInclude0(st, name, n))
+
+intloopInclude1(name,n) ==
+ a:=ncloopIncFileName name
+ a => intloopInclude(a,n)
+ n
+
+intloopProcessString(s,n) ==
+ setCurrentLine s
+ intloopProcess(n,true,
+ next(function ncloopParse,
+ next(function lineoftoks,incString s)))
+
+$pfMacros := []
+
+intloopSpadProcess(stepNo,lines,ptree,interactive?)==
+ $stepNo:local := stepNo
+ $currentCarrier := cc := ['carrier]
+ ncPutQ(cc, 'stepNumber, stepNo)
+ ncPutQ(cc, 'messages, $ncMsgList)
+ ncPutQ(cc, 'lines, lines)
+ $ncMsgList := nil
+ result := CatchAsCan(flung, Catch("SpadCompileItem",
+ CATCH($intCoerceFailure, CATCH($intSpadReader,
+ interp(cc, ptree, interactive?))))) where
+
+ interp(cc, ptree, interactive?) ==
+ ncConversationPhase(function phParse, [cc, ptree])
+ ncConversationPhase(function phMacro, [cc])
+ ncConversationPhase(function phIntReportMsgs,[cc, interactive?])
+ ncConversationPhase(function phInterpret, [cc])
+
+ #ncEltQ(cc, 'messages) ^= 0 => ncError()
+
+ intSetNeedToSignalSessionManager()
+ $prevCarrier := $currentCarrier
+ result = 'ncEnd => stepNo
+ result = 'ncError => stepNo
+ result = 'ncEndItem => stepNo
+ stepNo+1
+
+phInterpret carrier ==
+ ptree := ncEltQ(carrier, 'ptree)
+ val := intInterpretPform(ptree)
+ ncPutQ(carrier, 'value, val)
+
+
+--% phReportMsgs: carrier[lines,messages,..]-> carrier[lines,messages,..]
+phIntReportMsgs(carrier, interactive?) ==
+ $erMsgToss => 'OK
+ lines := ncEltQ(carrier, 'lines)
+ msgs := ncEltQ(carrier, 'messages)
+ nerr := #msgs
+ ncPutQ(carrier, 'ok?, nerr = 0)
+ nerr = 0 => 'OK
+ processMsgList(msgs, lines)
+ intSayKeyedMsg ('S2CTP010,[nerr])
+ 'OK
+
+mkLineList lines ==
+ l := [CDR line for line in lines | nonBlank CDR line]
+ #l = 1 => CAR l
+ l
+
+nonBlank str ==
+ value := false
+ for i in 0..MAXINDEX str repeat
+ str.i ^= char " " =>
+ value := true
+ return value
+ value
+
+ncloopCommand (line,n) ==
+ a:=ncloopPrefix?('")include",line)=>
+ ncloopInclude1( a,n)
+ FUNCALL($systemCommandFunction,line)
+ n
+
+ncloopEscaped x==
+ esc :=false
+ done:=false
+ for i in (# x) - 1 .. 0 by -1 while not done repeat
+ done:=
+ x.i='" ".0 =>false
+ x.i='"__".0=>
+ esc:=true
+ true
+ true
+ esc
+
+ncloopDQlines (dq,stream)==
+ StreamNull stream
+ a:= poGlobalLinePosn tokPosn CADR dq
+ b:= poGlobalLinePosn CAAR stream
+ streamChop (a-b+1,stream)
+
+streamChop(n,s)==
+ if StreamNull s
+ then [nil,nil]
+ else if EQL(n,0)
+ then [nil,s]
+ else
+ [a,b]:= streamChop(n-1,cdr s)
+ line:=car s
+ c:=ncloopPrefix?('")command",CDR line)
+ d:= cons(car line,if c then c else cdr line)
+ [cons(d,a),b]
+
+ncloopPrintLines lines ==
+ for line in lines repeat WRITE_-LINE CDR line
+ WRITE_-LINE '" "
+
+ncloopIncFileName string==
+ fn := incFileName string
+ not fn =>
+ WRITE_-LINE (CONCAT(string, '" not found"))
+ []
+ fn
+
+ncloopParse s==
+ [dq,stream]:=CAR s
+ [lines,rest]:=ncloopDQlines(dq,stream)
+ cons([[lines,npParse dqToList dq]],CDR s)
+
+ncloopInclude0(st, name, n) ==
+ $lines:local := incStream(st, name)
+ ncloopProcess(n,false,
+ next(function ncloopEchoParse,
+ next(function insertpile,
+ next(function lineoftoks,$lines))))
+
+ncloopInclude(name, n) ==
+ WITH_-OPEN_-FILE(st name, ncloopInclude0(st, name, n))
+
+ncloopInclude1(name,n) ==
+ a:=ncloopIncFileName name
+ a => ncloopInclude(a,n)
+ n
+
+incString s== incRenumber incLude(0,[s],0,['"strings"] ,[Top])
+
+ncError() ==
+ THROW("SpadCompileItem",'ncError)
+
+--% Compilation Carriers
+-- This data structure is used to carry information between phases.
+
+--% phParse: carrier[tokens,...] -> carrier[ptree, tokens,...]
+--)line (defun pretty (x) (boottran::reallyprettyprint x))
+--)line (defun packagetran (x) (boot::|packageTran|))
+phParse(carrier,ptree) ==
+ phBegin 'Parsing
+ if $ncmParse then
+ nothing
+ intSayKeyedMsg ('S2CTP003,[%pform ptree])
+ ncPutQ(carrier, 'ptree, ptree)
+ 'OK
+
+
+--% phMacro: carrier[ptree,...] -> carrier[ptree, ptreePremacro,...]
+phMacro carrier ==
+ phBegin 'Macroing
+ ptree := ncEltQ(carrier, 'ptree)
+ ncPutQ(carrier, 'ptreePremacro, ptree)
+
+ ptree := macroExpanded ptree
+ if $ncmMacro then
+ intSayKeyedMsg ('S2CTP007,[%pform ptree] )
+
+ ncPutQ(carrier, 'ptree, ptree)
+ 'OK
+
+--% phReportMsgs: carrier[lines,messages,..]-> carrier[lines,messages,..]
+phReportMsgs(carrier, interactive?) ==
+ $erMsgToss => 'OK
+ lines := ncEltQ(carrier, 'lines)
+ msgs := ncEltQ(carrier, 'messages)
+ nerr := #msgs
+ ncPutQ(carrier, 'ok?, nerr = 0)
+ interactive? and nerr = 0 => 'OK
+ processMsgList(msgs, lines)
+ intSayKeyedMsg ('S2CTP010,[nerr])
+ 'OK
+
+ncConversationPhase(fn, args) ==
+ carrier := first args
+
+ $ncMsgList: local := []
+ $convPhase: local := 'NoPhase
+
+ UNWIND_-PROTECT( APPLY(fn, args), wrapup(carrier) ) where
+ wrapup(carrier) ==
+ for m in $ncMsgList repeat
+ ncPutQ(carrier, 'messages, [m, :ncEltQ(carrier, 'messages)])
+
+ncloopPrefix?(prefix,whole) ==
+ #prefix > #whole => false
+ good:=true
+ for i in 0..#prefix-1 for j in 0.. while good repeat
+ good:= prefix.i = whole.j
+ if good then SUBSTRING(whole,#prefix,nil) else good
+
+phBegin id ==
+ $convPhase := id
+ if $ncmPhase then intSayKeyedMsg('S2CTP021,[id])
+
+PullAndExecuteSpadSystemCommand stream ==
+ ExecuteSpadSystemCommand CAR stream
+ CDR stream
+
+ExecuteSpadSystemCommand string ==
+ FUNCALL($systemCommandFunction, string)
+
+
+clearMacroTable() ==
+ $pfMacros := nil
+
+getParserMacros() ==
+ $pfMacros
+
+displayParserMacro m ==
+ m := ASSQ(m, $pfMacros)
+ null m => nil
+ pfPrintSrcLines CADDR m
+
+