/* cond.q: conditional expressions $Id: cond.q,v 1.6 2005/07/13 00:49:47 agraef Exp $ */ /* This file is part of the Q programming system. The Q programming system is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. The Q programming system is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ include stdlib, lambda; public special ifelse ~P X Y, when ~P X, unless ~P X; public special dowhile P X, matchp P ~X; public type DoComp : Lambda = special for Cs A; public switch CASES, match X CASES; public special const case X Y, default X; /* ifelse, when, unless: Simple conditional expressions. */ ifelse P:Bool X Y = X if P; = Y otherwise; when P:Bool X = X if P; = () otherwise; unless P:Bool X = X if not P; = () otherwise; /* matchp: Match a pattern against an expression. */ matchp [X1|Y1] [X2|Y2] = matchp X1 X2 and then matchp Y1 Y2; matchp (X1|Y1) (X2|Y2) = matchp X1 X2 and then matchp Y1 Y2; matchp (X1 Y1) (X2 Y2) = matchp X1 X2 and then matchp Y1 Y2; matchp X _ = true if isvar X; matchp X X = true; matchp _ _ = false otherwise; /* switch: General conditional expression, similar to Lisp's cond. */ switch (case P X) = X if P; = () otherwise; switch (case P X|CASES) = X if P; = switch CASES otherwise; switch (default X) = X; switch (default X|CASES) = X; switch () = (); /* match: Pattern-matching conditional expression. */ match X (case P Y) = lambda P Y X if matchp P X; = () otherwise; match X (case P Y|CASES) = lambda P Y X if matchp P X; = match X CASES otherwise; match X (default Y) = Y; match X (default Y|CASES) = Y; match X () = (); /* dowhile: Simple looping construct. */ dowhile P X = X || dowhile P X if P; = () otherwise; /* for: Iterate over lists and streams. */ public const (in) X Y @ 2; // relational in operator private special forx Cs A; lambdax (for Cs A) = forx Cs A; for Cs A = `(forx Cs A); forx () A = 'A; forx (X in Xs|Cs) A = '(do (lambda X `(forx Cs A)) (filter (matchp X) Xs)); forx (X in Xs) A = '(do (lambda X A) (filter (matchp X) Xs)); forx (P|Cs) A = '(ifelse P `(forx Cs A) ()); forx P A = '(ifelse P A ());