How to break from a loop in Maxima - maxima

I am new to Maxima. I am trying to write a loop in that I am checking if some condition met then exit from the loop.
cp:for i:1 step 1 thru 10 do
block(if(i>6) then break()
else
print(i,"is less than 6"));
I want output:
1 is less than 6
2 is less than 6
3 is less than 6
4 is less than 6
5 is less than 6
6 is less than 6
But when I am running the above code :
after printing 6 is less than 6, it is prompting
Entering a Maxima break point. Type 'exit;' to resume.
and after typing exit; it will again show the above msg
I want the code will come out completely from that loop rather than asking to type exit;
Thank you in advance..

Try return(i) instead of break(). Also, return only returns from the block which encloses it, so you need to remove the block(...) in your example (it's unneeded anyway). I think this works:
cp: for i:1 step 1 thru 10
do if(i>6) then return(i) else print(i,"is less than 6");

Related

How to show line numbers for every 10 lines?

The SynEdit control has an event OnGutterGetText. I would like to use this to make the gutter only display every 10th line number (also line 1 and currently selected line). The same way that the Delphi (XE7) IDE works. How do I determine whether to show the line or not using this event?
The question transpires to be nothing to do with the edit control in reality. You simply want to know if a is an exact multiple of b. That is so if the remainder of a divided by b is zero. And the remainder operator in Delphi is mod.
if a mod b = 0 then
Now, in your case you want
if LineNum mod 10 = 0 then
This assumes that LineNum is one based. If it is zero based then you need
if (LineNum + 1) mod 10 = 0 then

Catching exceptions from a loop

I'm trying to write a Forth word which will drop all items on the stack. I'm using a pretty dumb method, by running an infinite loop with 'drop' and catching the error when 'drop' fails because the stack is empty.
My words are defined as such:
( Infinite drop loop)
: droploop begin drop true while drop repeat ;
( Experimental catch with a single drop)
: dropcatcher ['] drop catch drop ;
( Like dropcatcher, but with 'droploop' instead of 'drop')
: dropall ['] droploop catch drop ;
When I run droploop, I get an error like I'd expect and after execution, the stack is empty.
When I run dropcatcher, it drops if the stack isn't empty, and if the stack is empty it reports nothing.
When I run dropall, I get all sorts of stuff leftover on the stack.
It looks like this:
2 3 4 5 6 7 8 9 10 dropall .s <9> -1 3 -1 5 -1 7 -1 9 -1 ok
I'd expect that dropall would simply clear the stack without complaint because droploop and dropcatcher seem to work right by themselves, but alas, I don't understand why dropall isn't working.
Why does dropall seem to work differently than droploop and dropcatcher? Or, what I'm I doing wrong here?
When droploop throws an error, it will probably call ABORT or -1 THROW, which by definition clears the data stack. So it may well be that droploop doesn't drop the right number of stack items before the error is detected, but the system exception handler does it for you.
When I run droploop myself, it either crashes or hangs. This would seem to confirm my theory that there is a severe stack underflow.
As for the state of the stack after dropall, my guess would be that gforth maybe doesn't detect the stack underflow at the right time, and what you're seeing is some semi-random garbage. Hence this is what droploop leaves on the stack before calling ABORT.
Side note: Your droploop drops two stack items every iteration, which may or may not be what you intended. Also, use again for an endless loop instead of true while. I.e. : droploop begin drop again;
Of course, a better way to clear the stack would be
: clear depth 0 ?do drop loop ;
or
: clear begin depth while drop repeat ;
or
: clear sp0 sp! ;

How to tell if a Lua line number is a valid execution point (from C/C++)?

How Can I tell if line number x in a Lua script will respond to the Lua line hook?
Example:
1 first = 1
2
3 function test ( data )
4 if first == 0 then
5 print ("\r\n")
6 end
7 print(data)
8 --[[
9 first = 0
10 ]]
11 end
12
13 test()
14
Line 2,6,8,9,10,12 and 14 does not call a line hook. After I have loaded and executed the script, can I some how, from C/C++, get a table of the executable line numbers?
lua_getinfo can return a table of valid lines if you include L in what.
Some code sample:
local exec_lines = {}
local function exec_line_counter(event, line)
table.insert(exec_lines, line)$
end
local function count_exec_lines(lua_file)
local external_chunk = loadfile(lua_file)
debug.sethook(exec_line_counter, "l")
external_chunk()
debug.sethook()
-- Removing `debug.sethook()` lines:
table.remove(exec_lines, 1)
table.remove(exec_lines, #exec_lines)
end
count_exec_lines("test.lua")
Output of:
table.sort(exec_lines)
for i, num in ipairs(exec_lines) do
print(num)
end
is
1
3
4
7
11
11 <--- not sure why this duplicates. Lack of return? Or because following tailcall?
13
NOTE: it would log only lines being parsed. In Your test case, it does not cover 5th and 6th line, because first not being 0.
Another way of doing this and solving noted case - just simply parsing Lua source: counting and skipping lines which consists only of Lua comments:
--lines
--[[ blocks ]]
EDIT: ah, shoot, edited Your question of doing this with C/C++. Hooking functions can be done with plain C API too. Might make an example if You didn't get a basic idea from an my answer already made :)

How do I format a PRINT or WRITE statement to overwrite the current line on the console screen?

I want to display the progress of a calculation done with a DO-loop, on the console screen. I can print out the progress variable to the terminal like this:
PROGRAM TextOverWrite_WithLoop
IMPLICIT NONE
INTEGER :: Number, Maximum = 10
DO Number = 1, MAXIMUM
WRITE(*, 100, ADVANCE='NO') REAL(Number)/REAL(Maximum)*100
100 FORMAT(TL10, F10.2)
! Calcultations on Number
END DO
END PROGRAM TextOverWrite_WithLoop
The output of the above code on the console screen is:
10.00 20.00 30.00 40.00 50.00 60.00 70.00 80.00
90.00 100.00
All on the same line, wrapped only by the console window.
The ADVANCE='No' argument and the TL10 (tab left so many spaces) edit descriptor works well to overwrite text on the same line, e.g. the output of the following code:
WRITE(*, 100, ADVANCE='NO') 100, 500
100 FORMAT(I3, 1X, TL4, I3)
Is:
500
Instead of:
100 500
Because of the TL4 edit descriptor.
From these two instances one can conclude that the WRITE statement cannot overwrite what has been written by another WRITE statement or by a previous execution of the same WRITE satement (as in a DO-loop).
Can this be overcome somehow?
I am using the FTN95 compiler on Windows 7 RC1. (The setup program of the G95 compiler bluescreens Windows 7 RC1, even thought it works fine on Vista.)
I know about the question Supressing line breaks in Fortran 95 write statements, but it does not work for me, because the answer to that question means new ouput is added to the previous output on the same line; instead of new output overwriting the previous output.
Thanks in advance.
The following should be portable across systems by use of ACHAR(13) to encode the carriage return.
character*1 creturn
! CODE::
creturn = achar(13) ! generate carriage return
! other code ...
WRITE( * , 101 , ADVANCE='NO' ) creturn , i , npoint
101 FORMAT( a , 'Point number : ',i7,' out of a total of ',i7)
There is no solution to this question within the scope of the Fortran standards. However, if your compiler understand backslash in Fortran strings (GNU Fortran does if you use the option -fbackslash), you can write
write (*,"(A)",advance="no") "foo"
call sleep(1)
write (*,"(A)",advance="no") "\b\b\bbar"
call sleep(1)
write (*,"(A)",advance="no") "\b\b\bgee"
call sleep(1)
write (*,*)
end
This uses the backslash character (\b) to erase previously written characters on that line.
NB: if your compiler does not understand advance="no", you can use related non-standard tricks, such as using the $ specifier in the format string.
The following worked perfectly using g95 fortran:
NF = NF + 1
IF(MOD(NF,5).EQ.0) WRITE(6,42,ADVANCE='NO') NF, ' PDFs'//CHAR(13)
42 FORMAT(I6,A)
gave:
5 PDFs
leaving the cursor at the #1 position on the same line. On the next update,
the 5 turned into a 10. ASCII 13 (decimal) is a carriage return.
OPEN(6,CARRIAGECONTROL ='FORTRAN')
DO I=1,5
WRITE(6,'(1H+" ",I)') I
ENDDO

Is there a safe way to clean up stack-based code when jumping out of a block?

I've been working on Issue 14 on the PascalScript scripting engine, in which using a Goto command to jump out of a Case block produces a compiler error, even though this is perfectly valid (if ugly) Object Pascal code.
Turns out the ProcessCase routine in the compiler calls HasInvalidJumps, which scans for any Gotos that lead outside of the Case block, and gives a compiler error if it finds one. If I comment that check out, it compiles just fine, but ends up crashing at runtime. A disassembly of the bytecode shows why. I've annotated it with the original script code:
[TYPES]
<SNIPPED>
[VARS]
Var [0]: 27 Class TFORM
Var [1]: 28 Class TAPPLICATION
Var [2]: 11 S32 //i: integer
[PROCS]
Proc [0] Export: !MAIN -1
{begin}
[0] ASSIGN GlobalVar[2], [1]
{ i := 1;}
[15] PUSHTYPE 11(S32) // 1
[20] ASSIGN Base[1], GlobalVar[2]
{ case i of}
[31] PUSHTYPE 25(U8) // 2
{ 0:}
[36] COMPARE into Base[2]: [0] = Base[1]
[57] COND_NOT_GOTO currpos + 5 Base[2] [72]
{ end;}
[67] GOTO currpos + 41 [113]
{ 1:}
[72] COMPARE into Base[2]: [1] = Base[1]
[93] COND_NOT_GOTO currpos + 10 Base[2] [113]
{ goto L1;}
[103] GOTO currpos + 8 [116]
{ end;}
[108] GOTO currpos + 0 [113]
{ end; //<-- case}
[113] POP // 1
[114] POP // 0
{ Exit;}
[115] RET
{L1:
Writeln('Label L1');}
[116] PUSHTYPE 17(WideString) // 1
[121] ASSIGN Base[1], ['????????']
[144] CALL 1
{end.}
[149] POP // 0
[150] RET
Proc [1]: External Decl: \00\00 WRITELN
The "goto L1;" statement at 103 skips the cleanup pops at 113 and 114, which leaves the stack in an invalid state.
Delphi doesn't have any trouble with this, because it doesn't use a calculation stack. PascalScript, though, is not as fortunate. I need some way to make this work, as this pattern is very common in some legacy scripts from a much simpler system with little in the way of control structures that I've translated to PascalScript and need to be able to support.
Anyone have any ideas how to patch the codegen so it'll clean up the stack properly?
IIRC the goto rules in classic pascals were:
jumps are only allowed out of a block (iow from a higher to a lower nesting level on the "same" branch of the tree)
from local procedures to their parents.
The later was afaik never supported by Borland derived Pascals, but the first still holds.
So you need to generate exiting code like Martin says, but possibly it can be for multiple block levels, so you can't have a could codegeneration for each goto, but must generate code (to exit the precise number of needed blocks).
A typical test pattern is to exit from multiple nested ifs (possibly within a loop) using a goto, since that was a classic microoptimization that was faster at least up to D7.
Keep in mind that the if evaluation(s) and the begin..end blocks of their branches might have generated temps that need cleanup.
---------- added later
I think the codegenerator needs a way to walk the scopes between the goto and its endpoint, generating the relevant exit code for blocks along the way. That way a fix works for the general case and not just this example.
Since you can only jump out of scopes, and not into it that might not that be that hard.
IOW generate something that is equivalent to (for a hypothetical double case block)
Lgoto1gluecode:
// exit code first block
pop x
pop y
// exit code first block
pop A
pop B
goto real_goto_destination
Additional analysis can be done. E.g. if there is only one scope, and it has already a cleanup exit label, you can jump directly. If you know for certain that the above pop's are only discarded values (and not saves of registers) you can do them at once with add $16,%esp (4*4 byte values) etc.
The straightforward solution would be:
When generating a GOTO for goto statement, prefix the GOTO with the same cleanup code that comes before RET.
It looks to me like the calculation of how far to jump forward is the problem. I would have to spend some time looking at the implementation of the parser to help further, but my guess would be that additional handling must be performed when using a goto and there are values on the stack AND the goto would be placed after those values would be removed from the stack. Of course to determine this you would need to save the current location being parsed (the goto) and the forward parse to the target location watching for stack changes, and if so then to either adjust the goto location backwards, or inject the code as Martin suggested.

Resources