/* ********************************************************************* This source file is a part of the standard library of Scol For the latest info, see http://www.scolring.org Copyright (c) 2013 Stephane Bisaro aka Iri. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/lesser.txt ********************************************************************* */ /* * Standard functions for loop * See http://redmine.scolring.org/projects/tutorials/wiki/Scol_usage * for more informations */ /*! \file loop.pkg * \author Scol team * \version 0.1 * \copyright GNU Lesser General Public License 2.0 or later * \brief Scol Standard Library - Loop API * * \details This API provides few loop for Scol * This API requires the floatting point numbers API ( lib/std/float.pkg ) * **/ /*! \brief Perform a switch-like loop, as some another languages. * \ingroup std_loop * \details The switch statement is similar to a series of IF statements * on the same expression. * According to a value / a result of expression, a function is called with * a specific argument. * * The list contains a tuple with an integer and any object. This integer * is the expression result. * * \see std_switchStr * \see std_switchStri * * Prototype: fun [I fun [I u0] u1 [[I u0] r1]] u1 * * \param I : a variable or an expression. * \param fun [I u0] u1 : the function to call * \param [[I u0] r1] : a list with the result of the condition and the * user parameters * * \return u1 : the value returned by the called function **/ fun std_switch (cond, cbfun, list)= let switch list cond -> value in if value != nil then exec cbfun with [cond value] else let switch list nil -> default in exec cbfun with [cond default];; /*! \brief Perform a switch-like loop, as some another languages. * * \ingroup std_loop * \details The switch statement is similar to a series of IF statements * on the same expression. * According to a value / a result of expression, a function is called with * a specific argument. Value or result expression must be a string(S). * This function is case-sensitive. * * The list contains a tuple with an integer and any object. This integer * is the expression result. * * Prototype: fun [S fun [S u0] u1 [[S u0] r1]] u1 * * \param I : a variable or an expression. * \param fun [I u0] u1 : the function to call * \param [[I u0] r1] : a list with the result of the condition and the * user parameters * * \return u1 : the value returned by the called function **/ fun std_switchStr (cond, cbfun, list)= let switchstr list cond -> value in if value != nil then exec cbfun with [cond value] else let switch list nil -> default in exec cbfun with [cond default];; /*! \brief Perform a switch-like loop, as some another languages. * * \ingroup std_loop * \details The switch statement is similar to a series of IF statements * on the same expression. * According to a value / a result of expression, a function is called with * a specific argument. Value or result expression must be a string(S). * This function is case-insensitive. * * The list contains a tuple with an integer and any object. This integer * is the expression result. * * Prototype: fun [S fun [S u0] u1 [[S u0] r1]] u1 * * \param I : a variable or an expression. * \param fun [I u0] u1 : the function to call * \param [[I u0] r1] : a list with the result of the condition and the * user parameters * * \return u1 : the value returned by the called function **/ fun std_switchStri (cond, cbfun, list)= let switchstri list cond -> value in if value != nil then exec cbfun with [cond value] else let switch list nil -> default in exec cbfun with [cond default];; fun std_forcheck (start, end, current, flag) = if flag > 0 then // increment (start <= current) && (current <= end) else // decrement (start >= current) && (current >= end);; fun std_forfcheck (start, end, current, flag) = if flag >. 0.0 then // increment (start <=. current) && (current <=. end) else // decrement (start >=. current) && (current >=. end);; fun std_loopcheckfnull (f)= std_fIsZero f;; fun std_forreflexive (start, end, inc, cbfun, current, lastResult)= if !std_forcheck start end current inc then lastResult else std_forreflexive start end inc cbfun current+inc exec cbfun with [current];; fun std_forfreflexive (start, end, inc, cbfun, current, lastResult)= if !std_forfcheck start end current inc then lastResult else std_forfreflexive start end inc cbfun current+.inc exec cbfun with [current];; /*! \brief Perform a for-like loop, as some another languages. * * \ingroup std_loop * \details As in C, std_for has the following internal behavior : *
	for (expr1; expr2; expr3)
		statement
    
* * The first expression (expr1) is evaluated (executed) once unconditionally * at the beginning of the loop. * * In the beginning of each iteration, expr2 is evaluated. If it evaluates * to TRUE, the loop continues and statement is executed. * If it evaluates to FALSE, the execution of the loop ends. * * At the end of each iteration, expr3 is evaluated. * * However, expr1,2 or 3 can not be nil (in this case, std_for stops and * returns nil). There is no 'break'. * * * According to a value / a result of expression, a function is called with * a specific argument. Value or result expression must be a string(S). * This function is case-insensitive. * * The list contains a tuple with an integer and any object. This integer * is the expression result. * * Prototype: fun [I I I fun [I] u0] u0 * * \param I : a starting value. * \param I : an ending value. * \param I : an increment (or decrement) like 2 or -5 ... * \param fun [I] u0 : the function to call to each iteration * * \return u0 : the last value returned by the called function * * See too : http://www.scolring.org/files/doc_html/forI.html * * See too : http://www.scolring.org/files/doc_html/forList.html * * See too : http://www.scolring.org/files/doc_html/forTab.html **/ fun std_for (start, end, inc, cbfun)= if ((start > end) && (inc > 0)) then nil else if ((start < end) && (inc < 0)) then nil else if ((start == nil) || (end == nil) || (inc == nil) || (inc == 0)) then nil else std_forreflexive start end inc cbfun start nil;; /*! \brief Perform a for-like loop, as some another languages. * * \ingroup std_loop * \details As in C, std_for has the following internal behavior : *
	for (expr1; expr2; expr3)
		statement
    
* * The first expression (expr1) is evaluated (executed) once unconditionally * at the beginning of the loop. * * In the beginning of each iteration, expr2 is evaluated. If it evaluates * to TRUE, the loop continues and statement is executed. * If it evaluates to FALSE, the execution of the loop ends. * * At the end of each iteration, expr3 is evaluated. * * However, expr1,2 or 3 can not be nil (in this case, std_for stops and * returns nil). There is no 'break'. * * * According to a value / a result of expression, a function is called with * a specific argument. Value or result expression must be a string(S). * This function is case-insensitive. * * The list contains a tuple with an integer and any object. This integer * is the expression result. * * Prototype: fun [F F F fun [F] u0] u0 * * \param F : a starting value. * \param F : an ending value. * \param F : an increment (or decrement) like 2.2 or -5.54 ... * \param fun [F] u0 : the function to call to each iteration * * \return u0 : the last value returned by the called function **/ fun std_forF (start, end, inc, cbfun)= if ((start >. end) && (inc >. 0.0)) then nil else if ((start <. end) && (inc <. 0.0)) then nil else if ((start == nil) || (end == nil) || (inc == nil) || (std_loopcheckfnull inc)) then nil else std_forfreflexive start end inc cbfun start nil;; /*! \brief Perform a do while-like loop, as some another languages. * * It is similar then while do but the statment is always executed once time. * * The function loops while the 'cond' is not equal at 1. * * \ingroup std_loop * Prototype : fun [fun [] I fun [u0] u1 u0] u1 * * \param fun [] I : the "cond" to ends the loop. If this function can never return 1, * the loop will be infinite. If the function is nil, std_doWhile does nothing and return nil * \param fun [u0] u1 : the function "called" to each loop * \param u0 : a parameter at your convenience for the called function * * \return u1 : the last result of the called function * * If needed, you can use mkfunX function to add parameters to the "called" function. \see std_if **/ fun std_doWhile (cond, cbfun, param)= if cond == nil then nil else ( exec cbfun with [param]; while !exec cond with [] do exec cbfun with [param]; );; /*! \brief Perform a IF-like, as some another languages. * * This is a conveniance function to avoid write an "else" statment. * *
 var a = 5;;
 
 fun cbIfCond () = a == 5;;
 
 fun cbIf2 (param, param2)= set a = 0; _fooS param: param2;;
 
 fun cbIf (param)= param;;

 fun main ()=
	_showconsole;
	_fooS std_if @cbIfCond mkfun2 @cbIf2 "END !" "BEGIN";	// END !
	_fooS std_if @cbIfCond @cbIf "NOT POSSIBLE !";	// NIL
	0;;
 
* * \ingroup std_loop * Prototype : fun [fun [] I fun [u0] u1 u0] u1 * * \param fun [] I : the "if" expression/condition * \param fun [u0] u1 : function to call if the condition is true * \param u0 : a parameter at your convenience for the called function * * \return u1 : the result of the called function. **/ fun std_if (cond, cbfun, param)= if exec cond with [] then exec cbfun with [param] else nil;;