On Mon, 2006-07-17 at 17:22 -0700, Erick Tryzelaar wrote:
> Here's another: for-else, while-else and break statements
>
> I'm a big fan of python's for-else, while-else and etc constructions.
> For those unfamiliar with the construct, it allows the "else" block to
> be run if the loop was not explicitly broken out of. It'd be pretty
> simple to implement via the macros, except we apparently don't support
> the "break" statement. Any way that we could implement it? Would
> something like this work?
>
>
> #statement#
> whilst expr do statements else statements done ; =>#
> macro {
> macro lab1 is new;
> macro lab2 is new;
> macro lab3 is new;
> macro val break = goto lab3;
> lab1:>
> if not _1 goto lab3;
> _3;
> goto lab1;
> lab2:>
> _5;
> lab3:>
> };
> #
Why ask an idiot like me .. when you can ask the guru, Felix?
Some notes:
* you cannot use 'else' as a separator here.
Why? Because it isn't a statement terminator.
Here's the Ocamlyacc grammar:
statementsx:
| statement_aster statements_terminator { $1, $2 }
statements_terminator:
| DONE { DONE $1 }
| USER_KEYWORD { USER_KEYWORD $1 }
| ENDMARKER { ENDMARKER }
The built-in control structures can do it,
by luck, because that uses an LALR(1) parser.
The user parser is recursive descent.
<statements> is an 'open' list of statements,
so it has to know when the list ends, it needs
a termination symbol distinct from something
that could start another statement.
note that 'else' is actually allowed *inside*
a statement .. if .. then .. else .. endif ..
* you can (re)introduce keywords like
#keyword fred
The set of keywords is GLOBAL .. software engineering nightmare.
* For some reason I do not understand, you need this:
macro var break = { goto lab3; };
You need the { goto lab3; } because a macro
var/val must resolve to an expression, in this case
a macro function closure. Applying that expression
to its argument () will evaluate its contents.
Note the usual kind of hack applies so that
break; // means break ();
What I don't understand at the moment is why this works
with a macro var, but NOT a macro val.
* In your code _5 is never executed. The Python form
you are so fond of is hard to understand, I don't
understand what it does .. and neither do you!
Try this .. noting the STILL ugly failure to properly
detect the last iteration.
#import <flx.flxh>
#keyword initially
#keyword always
#keyword finally
#keyword otherwise
#statement#
whilst expr do // 1
initially statements // 4
always statements // 6
finally statements // 8
otherwise statements // 10
done ; =>#
macro {
macro labend is new;
macro labloop is new;
macro labother is new;
macro var break = { goto labfinal; };
if (not _1) goto labother;
_4;
labloop:>
if (not _1) goto labfinal;
_6;
goto labloop;
labfinal:>
_8;
goto labend;
labother:> // otherwise
_10;
labend:>
};
#
proc print_ints (first:int,last:int, stride:int)
{
var i = first;
var count = 0;
whilst i <= last do
initially
print "{";
always
print i;
if i+stride <= last do print ","; done;
++count;
if count > 5 do
print " ... ";
break;
done;
i+=stride;
finally
print "}";
otherwise
print "EMPTY";
done;
endl;
}
print_ints$ 1,3,1;
print_ints$ 1,100,2;
print_ints$ 1,100,0;
print_ints$ 100,1,1;
------------------------------
{1,2,3}
{1,3,5,7,9,11, ... }
{1,1,1,1,1,1, ... }
EMPTY
--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Felix-language mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/felix-language