On 12/11/23 11:49, Qian Yun wrote:
>
> Also if my analysis is right, 'savedTimerStack' can also be removed.
>
savedTimerStack is there because when an error is thrown, it is used
to restore $timedNameStack.
While debugging this problem, I find two more problems:
1. in a line like this:
stepA; systemCommand("read fileB"); stepC;
Stats on stepA is ignored and stats on stepC is the sum of
stats on stepC and stats on last line of fileB.
That's because stats are initialized to 0 at the beginning
of 'systemCommand'.
So the correct solution is to move the initialization of
stats to the end of "Read-Eval-Print-Loop".
^was here ^move here
Now the stats on stepA will be mixed with first line of fileB.
But it's an improvement over current situation.
Nested stats is not that useful, right? I don't see any use case
for it yet.
2. some stats are printed before the collection is over.
So stats initialization should be at the end of one "REPL",
and the printing of stats should be just before that.
====
Back to the original problem, I separated 'initializeTimedNames'
into 'initStatToplevel', which should be initialized at the
end of toplevel initialization process.
The following patch should be broken down into 3 patches to
address the above mentioned 3 problems, then apply Waldek's
patch for 'do_read'.
- Qian
=================
diff --git a/src/interp/g-timer.boot b/src/interp/g-timer.boot
index cb373c43..e6f1ea1d 100644
--- a/src/interp/g-timer.boot
+++ b/src/interp/g-timer.boot
@@ -141,6 +141,15 @@ DEFPARAMETER($interpreterTimedClasses, '(
( 4 reclaim . GC) _
))
+-- This init function should only be called once, at the very end of
+-- system initialization sequence.
+initStatToplevel() ==
+ initializeTimedNames($interpreterTimedNames, $interpreterTimedClasses)
+ $timedNameStack := '(other)
+ $oldElapsedTime := get_run_time()
+ $oldElapsedGCTime := elapsedGcTime()
+ $oldElapsedSpace := HEAPELAPSED()
+
initializeTimedNames(listofnames,listofclasses) ==
for [name,:.] in listofnames repeat
PUT(name, 'TimeTotal, 0.0)
@@ -148,9 +157,6 @@ initializeTimedNames(listofnames,listofclasses) ==
for [.,name,:.] in listofclasses repeat
PUT( name, 'ClassTimeTotal, 0.0)
PUT( name, 'ClassSpaceTotal, 0)
- $timedNameStack := '(other)
- computeElapsedTime()
- computeElapsedSpace()
PUT('gc, 'TimeTotal, 0.0)
PUT('gc, 'SpaceTotal, 0)
NIL
diff --git a/src/interp/i-syscmd.boot b/src/interp/i-syscmd.boot
index 0b3e09f5..84a9c1d3 100644
--- a/src/interp/i-syscmd.boot
+++ b/src/interp/i-syscmd.boot
@@ -2212,8 +2212,6 @@ do_read(ll, quiet, pile_mode) ==
$nopiles : local := pile_mode
$edit_file := ll
read_or_compile(quiet, false)
- terminateSystemCommand()
- spadPrompt()
basename(x) == NAMESTRING(PATHNAME_-NAME(x))
diff --git a/src/interp/i-toplev.boot b/src/interp/i-toplev.boot
index 20b4773c..b71ef2d6 100644
--- a/src/interp/i-toplev.boot
+++ b/src/interp/i-toplev.boot
@@ -69,7 +69,6 @@ interpsysInitialization(display_messages) ==
interpOpen(display_messages)
createInitializers()
if $displayStartMsgs then sayKeyedMsg("S2IZ0053",['"interpreter"])
- initializeTimedNames($interpreterTimedNames,$interpreterTimedClasses)
$InteractiveFrame := makeInitialModemapFrame()
initializeSystemCommands()
initializeInterpreterFrameRing()
@@ -104,6 +103,7 @@ interpsys_restart() ==
browseOpen(true)
makeConstructorsAutoLoad()
createInitializers2()
+ initStatToplevel()
readSpadProfileIfThere() ==
-- reads SPADPROF INPUT if it exists
@@ -130,8 +130,6 @@ processInteractive(form, posnForm) ==
-- and then calls processInteractive1 to do most of the work.
-- This function receives the output from the parser.
- initializeTimedNames($interpreterTimedNames,$interpreterTimedClasses)
-
$op: local:= (form is [op,:.] => op; form) --name of operator
$Coerce: local := NIL
$compErrorMessageStack:local := nil
@@ -159,6 +157,9 @@ processInteractive(form, posnForm) ==
CLRHASH $instantRecord
writeHistModesAndValues()
updateHist()
+ if $printTimeIfTrue then printTime()
+ if $printStorageIfTrue then printStorage()
+ initializeTimedNames($interpreterTimedNames, $interpreterTimedClasses)
object
processInteractive1(form, posnForm) ==
@@ -199,31 +200,16 @@ recordAndPrint(x,md) ==
if $QuietCommand = false then
output(x',md')
putHist('%,'value,objNewWrap(x,md),$e)
- if $printTimeIfTrue or $printTypeIfTrue then printTypeAndTime(x',md')
- if $printStorageIfTrue then printStorage()
+ if $printTypeIfTrue then printType(x', md')
'done
-printTypeAndTime(x,m) == --m is the mode/type of the result
- printTypeAndTimeNormal(x, m)
-
-printTypeAndTimeNormal(x,m) ==
- -- called only if either type or time is to be displayed
+printType(x, m) == -- m is the mode/type of the result
if m is ['Union, :argl] then
x' := retract(objNewWrap(x,m))
m' := objMode x'
m := ['Union, :[arg for arg in argl | sameUnionBranch(arg, m')],
'"..."]
- if $printTimeIfTrue then
- timeString := makeLongTimeString($interpreterTimedNames,
- $interpreterTimedClasses)
if $printTypeIfTrue then
type_string := outputDomainConstructor(m)
- $printTimeIfTrue and $printTypeIfTrue =>
- $collectOutput =>
- $outputLines := [msgText("S2GL0012", [type_string]), :$outputLines]
- sayKeyedMsg("S2GL0014", [type_string, timeString])
- $printTimeIfTrue =>
- $collectOutput => nil
- sayKeyedMsg("S2GL0013",[timeString])
$printTypeIfTrue =>
$collectOutput =>
$outputLines :=
@@ -248,6 +234,11 @@ justifyMyType(t) ==
typeTimePrin x ==
maprinSpecial(x,0,79)
+printTime() ==
+ $collectOutput => nil
+ s := makeLongTimeString($interpreterTimedNames, $interpreterTimedClasses)
+ sayKeyedMsg("S2GL0013", [s])
+
printStorage() ==
$collectOutput => nil
storeString :=
@@ -259,6 +250,7 @@ printStorage() ==
interpretTopLevel(x, posnForm) ==
-- Top level entry point from processInteractive1. Sets up catch
-- for a thrown result
+ -- $timedNameStack is saved and restored in case an error is thrown.
savedTimerStack := COPY $timedNameStack
c := CATCH('interpreter,interpret(x, posnForm))
while savedTimerStack ~= $timedNameStack repeat