/* ********************************************************************* 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 Scol * See http://redmine.scolring.org/projects/tutorials/wiki/Scol_usage * for more informations */ /*! \file stdlib.pkg * \author Scol team * \version 0.1 * \copyright GNU Lesser General Public License 2.0 or later * \brief Scol Standard Library API * **/ /* prototype : used function from another package */ //proto std_fCmp = fun [F F] I;; /* Set some prototypes to avoid some errors of compilation (inappropriate given types) or logical programming errors */ proto std_cmpI = fun [I I] I;; proto std_ncmpI = fun [I I] I;; proto std_tupleCmp = fun [u0 u0 fun [u1 u1] I] I;; proto std_objIsEqual = fun [u0 u0] I;; proto std_clampT = fun [I u0 I] I;; proto std_vectorIsEqual = fun [[I I I] [I I I]] I;; /*! \brief Get if an Scol object is nil * * \ingroup std_lib * Prototype : fun [u0] I * * \param u0 : any Scol object * \return I : 1 if object is nil **/ fun std_objIsNil (obj)= obj == nil;; /*! \brief Returns if two Scol objects are equal * * \ingroup std_lib * Prototype : fun [u0 u0] I * * \param u0 : any Scol object * \param u0 : another Scol object * \return I : 1 if objects are equals * \remark : It could be useful by calling from an other function, to compare two elements. **/ fun std_objIsEqual (obj1, obj2)= obj1 == obj2;; /*! \brief Returns if two integers are equals or not * * \ingroup std_lib * Prototype : fun [I I] I * * \param I : any integer * \param I : another integer * \return I : 1 if integers are equals * \remark : It could be useful by calling from an other function, to compare two elements. **/ fun std_cmpI (a, b)= a == b;; /*! \brief Returns if two float numbers are equals or not * * \ingroup std_lib * Prototype : fun [F F] I * * \param F : any float number * \param F : another float number * \return I : 1 if float numbers are equals * \remark : It could be useful by calling from an other function, to compare two elements. * \warning This function has been removed. See std_fCmp in float.pkg **/ /*fun std_cmpF (f, g)= std_fCmp f g;;*/ /*! \brief Returns if two string are equals or not- Case-sensitive. * * \ingroup std_lib * Prototype : fun [S S] I * * \param S : any string * \param S : another string * \return I : 1 if string are equals * \remark : It could be useful by calling from an other function, to compare two elements. **/ fun std_cmpS (s, t)= !strcmp s t;; /*! \brief Returns if two string are equals. Case-insensitive. * * \ingroup std_lib * Prototype : fun [S S] I * * \param S : any string * \param S : another string * \return I : 1 if strings are equals * \remark : It could be useful by calling from an other function, to compare two elements. **/ fun std_cmpSi (s, t)= !strcmpi s t;; /*! \brief Returns if two integers are not equals * * \ingroup std_lib * Prototype : fun [I I] I * * \param I : any integer * \param I : another integer * \return I : 1 if integers are not equals * \remark : It could be useful by calling from an other function, to compare two elements. **/ fun std_ncmpI (a, b)= a != b;; /*! \brief Returns if two float numbers are not equals * * \ingroup std_lib * Prototype : fun [F F] I * * \param F : any float number * \param F : another float number * \return I : 1 if float numbers are not equals * \remark : It could be useful by calling from an other function, to compare two elements. * * \warning This function has been removed. See std_fCmp in float.pkg **/ /*fun std_ncmpF (f, g)= !std_fCmp f g;;*/ /*! \brief Returns if two string are not equals. Case-sensitive. * * \ingroup std_lib * Prototype : fun [S S] I * * \param S : any string * \param S : another string * \return I : 1 if strings are not equals * \remark : It could be useful by calling from an other function, to compare two elements. **/ fun std_ncmpS (s, t)= if !strcmp s t then 0 else 1;; /*! \brief Returns if two string are not equals. Case-insensitive. * * \ingroup std_lib * Prototype : fun [S S] I * * \param S : any string * \param S : another string * \return I : 1 if strings are not equals * \remark : It could be useful by calling from an other function, to compare two elements. **/ fun std_ncmpSi (s, t)= if !strcmpi s t then 0 else 1;; /*! \brief Perform an entire division. * * \ingroup std_lib * Prototype : fun [I I] I * * \param I : a * \param I : b (if is equal to 0, the result will be nil) * \return I : the integral quotient or nil if b = 0 **/ fun std_divide (a, b)= if (b == 0) || (a == nil) || (b == nil) then nil else a / b;; /*! \brief Return some infos about the operating system. See 'osInfos'. * * \ingroup std_lib * Prototype : fun [] S * * \return S : a formatted string **/ fun std_os ()= sprintf "%s\n%s\n%s\n%s\n" osInfos;; /*! \brief Return some infos about the operating system. See 'memoryInfos' * for more informations about the memory. * * \ingroup std_lib * Prototype : fun [] [I I I] * * \return [I I I] : * - the approximate percentage of physical memory that is in use * - the amount of actual physical memory * - the amount of physical memory currently available **/ fun std_memory ()= let memoryInfos -> [a b c _ _ _ _ _] in [a b c];; /*! \brief Perform a pause * * \ingroup std_lib * * Prototype : fun [I] I * * \param I : the number of second * \return I : the "real" pause done, in milliseconds. **/ fun std_sleep (second)= let second*1000 -> ms in let _tickcount -> start in let start -> n in ( while ms >= n-start do set n = _tickcount; n-start );; /*! \brief Return a random integer * * \ingroup std_lib * * Prototype : fun [I] I * * \param I : the maximum, the number will be between 0 and this maximum (it should * not be greater than 32767). * \return I : a random integer **/ fun std_random (max)= srand time; mod rand max;; fun std_starterscriptparse (list)= let nil -> pkgs in let nil -> funs in ( while list != nil do let strfind "_load \"" hd list 0 -> pos in let strfind "\"" hd list pos+7 -> pos2 in ( if pos != nil then ( set pkgs = (strtrim substr hd list pos+7 pos2-pos-7) :: pkgs; nil ) else let strfind "#" hd list 0 -> pos in let strextr if pos == nil then strtrim hd list else strtrim substr hd list 0 pos -> words in if words != nil then set funs = [hd hd words tl hd words] :: funs else nil; set list = tl list ); [pkgs funs] );; /*! \brief Parse the launcher script of the current application * * \ingroup std_lib * * Prototype : fun [] [[S r1] [[S [S r1]] r1]] * * \return [[S r1] [[S [S r1]] r1]] : a tuple : * - [S r1] : the list of packages * - [[S [S r1]] r1] : a list of tuples. For each tuple : * -# S : a function name (called from the launcher), such as "main" * -# [S r1] : a list of its arguments **/ fun std_starterScriptParse ()= std_starterscriptparse lineextr _starterScript;; // _getpack _checkpack "tests/lib/lib.scol";; /*! \brief Parse a launcher script * * \ingroup std_lib * * Prototype : fun [P] [[S r1] [[S [S r1]] r1]] * * \param P : a script read reference file * * \return [[S r1] [[S [S r1]] r1]] : a tuple (or nil if error) : * - [S r1] : the list of packages * - [[S [S r1]] r1] : a list of tuples. For each tuple : * -# S : a function name (called from the launcher), such as "main" * -# [S r1] : a list of its arguments **/ fun std_starterScriptParseP (pFile)= if pFile == nil then nil else std_starterscriptparse lineextr _getpack pFile;; fun std_getloadedpackages (env)= if env == nil then nil else (_envfirstname env) :: std_getloadedpackages _removepkg env;; /*! \brief Returns the list of all loaded packages in a given channel. * * \ingroup std_lib * Prototype : fun [Chn] [S r1] * * \param Chn : a channel, like _channel * * \return [S r1] : a list of all loaded packages in the channel or nil if an error occurs **/ fun std_getLoadedPackages (chn)= let _envchannel chn -> env in std_getloadedpackages env;; fun std_tuplesortcmp (a, b, flag)= if flag then a > b else a < b;; fun std_tuplesortcmpf (a, b, flag)= if flag then a >. b else a <. b;; fun std_tuplesort (tuple, f, flag)= let tupleSize tuple -> iSize in let 1 -> i in while i < iSize do let tupleGet tuple i nil -> a in let i -> j in ( // while (j > 0) && (std_tuplesortcmp a tupleGet tuple j-1 nil flag) do while (j > 0) && (exec f with [a tupleGet tuple j-1 nil flag]) do ( set tuple = tupleSet tuple j tupleGet tuple j-1 nil; set j = j-1 ); set tuple = tupleSet tuple j a; set i = i+1; ); tuple;; /*! \brief Sort the values of an integer tuple. * * \warning If the values are not integers, the result can be undefined. * * \ingroup std_lib * * Prototype: fun [u0] u0 * * \param u0 : a tuple of integers * \return u0 : the sorted tuple **/ fun std_tupleSort (tuple)= std_tuplesort tuple @std_tuplesortcmp 0;; /*! \brief Sort the values of an integer tuple (reverse). * * \warning If the values are not integers, the result can be undefined. * * \ingroup std_lib * * Prototype: fun [u0] u0 * * \param u0 : a tuple of integers * \return u0 : the sorted tuple **/ fun std_tupleSortR (tuple)= std_tuplesort tuple @std_tuplesortcmp 1;; /*! \brief Sort the values of a float tuple. * * \warning If the values are not float, the result can be undefined. * * \ingroup std_lib * * Prototype: fun [u0] u0 * * \param u0 : a tuple of float numbers * \return u0 : the sorted tuple **/ fun std_tupleSortF (tuple)= std_tuplesort tuple @std_tuplesortcmpf 0;; /*! \brief Sort the values of a float tuple (reverse). * * \warning If the values are not float, the result can be undefined. * * \ingroup std_lib * * Prototype: fun [u0] u0 * * \param u0 : a tuple of float numbers * \return u0 : the sorted tuple **/ fun std_tupleSortFR (tuple)= std_tuplesort tuple @std_tuplesortcmpf 1;; /*! \brief Clamp a value between two values * * \ingroup std_lib * * Prototype: fun [I I I] I * * \param I : an integer to clamp * \param I : the minimum * \param I : the maximum (if it is lesser than the minimum, the function will return nil) * * \return I : the clamped value or nil if error * \see std_fClamp **/ fun std_clamp (v, m, M)= if m > M then nil else if v < m then m else if v > M then M else v;; /*! \brief Clamp a value to a tuple * * \ingroup std_lib * * Prototype: fun [I u0 I] I * * \param I : an integer to clamp * \param u0 : a tuple * \param I : a default value to set if not found in the tuple * * \return I : the clamped value or nil if error * \remark this function works too with the float numbers (value, tuple and default) **/ fun std_clampT (v, tuple, default)= if std_objIsNil tuple then nil else let tupleSize tuple -> iSize in let 0 -> res in let 0 -> i in ( while (i < iSize) && (!res) do let tupleGet tuple i nil -> a in if a == v then set res = 1 else set i = i+1; if res then v else default );; fun std_clampenum (v, tuple, f)= if std_objIsNil tuple then nil else let tupleSize tuple -> iSize in let tupleGet tuple 0 nil -> a in let tupleGet tuple iSize-1 nil -> b in let exec f with [a v 1] -> r in if r then a else let exec f with [v b 1] -> r in if r then b else v;; /*! \brief Clamp an integer like an enum. The tuple should be * sorted : only the first and the last element are compared. * * \ingroup std_lib * * Prototype: fun [I u0] I * * \param I : an integer to clamp * \param u0 : any integer tuple * * \return I : the clamped value or nil if error **/ fun std_enumClamp (v, tuple)= std_clampenum v tuple @std_tuplesortcmp;; /*! \brief Clamp a float number like an enum. The tuple should be * sorted : only the first and the last element are compared. * * \ingroup std_lib * * Prototype: fun [F u0] F * * \param F : a float to clamp * \param u0 : any float tuple * * \return F : the clamped value or nil if error **/ fun std_enumClampF (v, tuple)= std_clampenum v tuple @std_tuplesortcmpf;; /*! \brief Return the size of a tuple * * \ingroup std_lib * * Prototype: fun [u0] I * * \param u0 : any tuple * * \return I : the size or nil if error **/ fun std_tupleSize (tuple)= if std_objIsNil tuple then nil else tupleSize tuple;; /*! \brief Compare two tuples * * \ingroup std_lib * * Prototype: fun [u0 u0 fun [u0 u0] I] I * * \param u0 : any tuple * \param u0 : another tuple * \param fun [u0 u0] I : function called to compare two elements. * It should return 1 if these two elements are equals. * * \return I : 1 if equals, else 0 * \remark the two tuples must have the same type, otherwise an error * will occur during the compilation. **/ fun std_tupleCmp (tuple1, tuple2, fCmp)= if (std_objIsNil tuple1) && (std_objIsNil tuple2) then 1 else if (std_objIsNil tuple1) || (std_objIsNil tuple2) then 0 else /* With prototype in the head of this file, the two types are the same type, so they are the same size. Thus, it is useless to compare their size ! */ /*let std_tupleSize tuple1 -> size1 in let std_tupleSize tuple2 -> size2 in if size1 != size2 then 0 else*/ let std_tupleSize tuple1 -> size1 in let 1 -> res in let 0 -> i in ( while (i < size1) && (res) do let tupleGet tuple1 i nil -> t1 in let tupleGet tuple2 i nil -> t2 in if exec fCmp with [t1 t2] then set i = i+1 else set res = 0; res );; /*! \brief Return if a value is found in a tuple. * * \ingroup std_lib * * Prototype: fun [u0 u1] I * * \param u0 : any tuple * \param u1 : a value * * \return I : 1 if found, 0 if not found or nil if error * \see std_tupleIsFoundS * \see std_tupleIsFoundSi **/ fun std_tupleIsFound (tuple, v)= if std_objIsNil tuple then nil else let tupleSize tuple -> iSize in let 0 -> res in let 0 -> i in ( while (i < iSize) && (!res) do if v == tupleGet tuple i nil then set res = 1 else set i = i+1; res );; fun std_tupleisfounds (tuple, s, isSensitive)= let tupleSize tuple -> iSize in let 0 -> res in let 0 -> i in ( while (i < iSize) && (!res) do if isSensitive then if !strcmp s tupleGet tuple i nil then set res = 1 else set i = i+1 else if !strcmpi s tupleGet tuple i nil then set res = 1 else set i = i+1; res );; /*! \brief Return if a string is found in a tuple. Case sensitive. * * \ingroup std_lib * * Prototype: fun [u0 S] I * * \param u0 : any string tuple * \param u1 : a value * * \return I : 1 if found, 0 if not found or nil if error * \see std_tupleIsFound * \see std_tupleIsFoundSi **/ fun std_tupleIsFoundS (tuple, s)= std_tupleisfounds tuple s 1;; /*! \brief Return if a string is found in a tuple. Case insensitive. * * \ingroup std_lib * * Prototype: fun [u0 S] I * * \param u0 : any tuple * \param u1 : a value * * \return I : 1 if found, 0 if not found or nil if error * \see std_tupleIsFound * \see std_tupleIsFoundS **/ fun std_tupleIsFoundSi (tuple, s)= std_tupleisfounds tuple s 0;; /*! \brief Create a tuple. * * \ingroup std_lib * * Prototype: fun [I [u0 r1] u1] u1 * * \param I : the size of the new tuple (1 or +) * \param [u0 r1] : a list to set the tuple elements. Initially, * each element is set to nil, this list is a convenience to set another * values. If the list is bigger than the size, its last elements will be * ignored. If it is smaller than the size, another elements will keep * at nil. * \param u1 : should be always nil. * * \return u1 : the new tuple or nil if error **/ fun std_tupleNew (size, values, tuple)= if (size == nil) || (size < 1) then nil else if values == nil then set tuple = tupleNew size nil nil else ( set tuple = tupleNew size nil nil; let 0 -> i in while (i < size) && (values != nil) do ( set tuple = tupleSet tuple i hd values; set values = tl values; set i = i+1; ); tuple );; /*! \brief Return if a tuple is nil or each item is nil * * \ingroup std_lib * * Prototype: fun [u0] I * * \param u0 : any tuple * * \return I : 1 if nil else 0 **/ fun std_tupleIsNil (tuple)= if std_objIsNil tuple then 1 else let tupleSize tuple -> iSize in let 0 -> i in let 1 -> res in ( while (i < iSize) && (res) do if std_objIsNil tupleGet tuple i nil then set i = i+1 else set res = 0; res );; /*! \brief Return if a tuple has an (or more) item at nil * * \ingroup std_lib * * Prototype: fun [u0] I * * \param u0 : any tuple * * \return I : 1 if yes else 0 **/ fun std_tupleHasNil (tuple)= if std_objIsNil tuple then 1 else let tupleSize tuple -> iSize in let 0 -> i in let 0 -> res in ( while (i < iSize) && (!res) do if std_objIsNil tupleGet tuple i nil then set res = 1 else set i = i+1; res );; /*! \brief Return if a vector is null or not * * \ingroup std_lib * * Prototype: fun [[I I I]] I * * \param [I I I] : integer vector * * \return I : 1 if equal at 0 else 0 **/ fun std_vectorIsNullI (v)= let v -> [x y z] in (x == 0) && (y == 0) && (z == 0);; /*! * \brief Return if a vector is null or not * * \ingroup std_lib * * * Prototype: fun [[F F F]] I * * \param [F F F] : float vector * * \return I : 1 if equal at 0 else 0 **/ fun std_vectorIsNullF (v)= let v -> [x y z] in (x == 0.0) && (y == 0.0) && (z == 0.0);; /*! \brief Return if a vector is "" or not * * \ingroup std_lib * * * Prototype: fun [[S S S]] I * * \param [S S S] : string vector * * \return I : 1 yes 1 no 0 **/ fun std_vectorIsNullS (v)= let v -> [x y z] in (!strcmp x "") && (!strcmp y "") && (!strcmp z "");; /*! \brief Return if a vector is nil or not * * \ingroup std_lib * * * Prototype: fun [[u0 u1 u2]] I * * \param [u0 u1 u2] : a vector * * \return I : 1 if equal at nil else 0 **/ fun std_vectorIsNil (v)= let v -> [x y z] in (x == nil) && (y == nil) && (z == nil);; /*! \brief Return if two integer vectors are equals * * \ingroup std_lib * * * Prototype: fun [[I I I] [I I I]] I * * \param [I I I] : first integer vector * \param [I I I] : second integer vector * * \return I : 1 if are equuals else 0 * * \see std_vectorIsEqualF in lib/std/float.pkg with floating number. **/ fun std_vectorIsEqual (v1, v2)= let v1 -> [x1 y1 z1] in let v2 -> [x2 y2 z2] in (x1 == x2) && (y1 == y2) && (z1 == z2);; /*! \brief Return if two string vectors are equals. Case-sensitive. * * \ingroup std_lib * * * Prototype: fun [[S S S] [S S S]] I * * \param [S S S] : first string vector * \param [S S S] : second string vector * * \return I : 1 if are equuals else 0 **/ fun std_vectorIsEqualS (v1, v2)= let v1 -> [x1 y1 z1] in let v2 -> [x2 y2 z2] in (!strcmp x1 x2) && (!strcmp y1 y2) && (!strcmp z1 z2);; /*! \brief Return if two string vectors are equals. Case-insensitive. * * \ingroup std_lib * * * Prototype: fun [[S S S] [S S S]] I * * \param [S S S] : first string vector * \param [S S S] : second string vector * * \return I : 1 if are equuals else 0 **/ fun std_vectorIsEqualSi (v1, v2)= let v1 -> [x1 y1 z1] in let v2 -> [x2 y2 z2] in (!strcmpi x1 x2) && (!strcmpi y1 y2) && (!strcmpi z1 z2);; /*! \brief Return if two vectors are equals * * \ingroup std_lib * * * Prototype: fun [[u0 u1 u2] [u0 u1 u2]] I * * \param [u0 u1 u2] : first vector * \param [u0 u1 u2] : second vector * * \return I : 1 if are equuals else 0 * \remark You should use the specific comparaison vectors function if * the elements are I, F or S. **/ fun std_vectorIsEqualAny (v1, v2)= std_vectorIsEqual v1 v2;; /*! \brief Add two vectors (integer) * * \ingroup std_lib * * * Prototype: fun [[I I I] [I I I]] [I I I] * * \param [I I I] : first integer vector * \param [I I I] : second integer vector * * \return [I I I] : vector result **/ fun std_vectorAddI (iV1, iV2)= let iV1 -> [iX1 iY1 iZ1] in let iV2 -> [iX2 iY2 iZ2] in [add iX1 iX2 add iY1 iY2 add iZ1 iZ2];; /*! \brief Add two vectors (float number) * * \ingroup std_lib * * * Prototype: fun [[F F F] [F F F]] [F F F] * * \param [F F F] : first float vector * \param [F F F] : second float vector * * \return [F F F] : vector result **/ fun std_vectorAddF (fV1, fV2)= let fV1 -> [fX1 fY1 fZ1] in let fV2 -> [fX2 fY2 fZ2] in [addf fX1 fX2 addf fY1 fY2 addf fZ1 fZ2];; /*! \brief Add two vectors (string element) * * \ingroup std_lib * * * Prototype: fun [[S S S] [S S S]] [S S S] * * \param [S S S] : first string vector * \param [S S S] : second string vector * * \return [S S S] : vector result **/ fun std_vectorAddS (szV1, szV2)= let szV1 -> [szX1 szY1 szZ1] in let szV2 -> [szX2 szY2 szZ2] in [strcat szX1 szX2 strcat szY1 szY2 strcat szZ1 szZ2];; /*! \brief Sub two vectors (integer) * * \ingroup std_lib * * * Prototype: fun [[I I I] [I I I]] [I I I] * * \param [I I I] : first integer vector * \param [I I I] : second integer vector * * \return [I I I] : vector result **/ fun std_vectorSubI (iV1, iV2)= let iV1 -> [iX1 iY1 iZ1] in let iV2 -> [iX2 iY2 iZ2] in [sub iX1 iX2 sub iY1 iY2 sub iZ1 iZ2];; /*! \brief Sub two vectors (float number) * * \ingroup std_lib * * * Prototype: fun [[F F F] [F F F]] [F F F] * * \param [F F F] : first float vector * \param [F F F] : second float vector * * \return [F F F] : vector result **/ fun std_vectorSubF (fV1, fV2)= let fV1 -> [fX1 fY1 fZ1] in let fV2 -> [fX2 fY2 fZ2] in [subf fX1 fX2 subf fY1 fY2 subf fZ1 fZ2];; /*! \brief multiply two vectors (integer) * * \ingroup std_lib * * * Prototype: fun [[I I I] [I I I]] [I I I] * * \param [I I I] : first integer vector * \param [I I I] : second integer vector * * \return [I I I] : vector result **/ fun std_vectorMultiplyI (iV1, iV2)= let iV1 -> [iX1 iY1 iZ1] in let iV2 -> [iX2 iY2 iZ2] in [mul iX1 iX2 mul iY1 iY2 mul iZ1 iZ2];; /*! \brief Multiply two vectors (float number) * * \ingroup std_lib * * * Prototype: fun [[F F F] [F F F]] [F F F] * * \param [F F F] : first float vector * \param [F F F] : second float vector * * \return [F F F] : vector result **/ fun std_vectorMultiplyF (fV1, fV2)= let fV1 -> [fX1 fY1 fZ1] in let fV2 -> [fX2 fY2 fZ2] in [mulf fX1 fX2 mulf fY1 fY2 mulf fZ1 fZ2];; /*! \brief Divide two vectors (integer) * * \ingroup std_lib * * * Prototype: fun [[I I I] [I I I]] [I I I] * * \param [I I I] : first integer vector * \param [I I I] : second integer vector * * \return [I I I] : vector result **/ fun std_vectorDivideI (iV1, iV2)= if std_vectorIsNullI iV2 then nil else let iV1 -> [iX1 iY1 iZ1] in let iV2 -> [iX2 iY2 iZ2] in [div iX1 iX2 div iY1 iY2 div iZ1 iZ2];; /*! \brief Divide two vectors (float number) * * \ingroup std_lib * * * Prototype: fun [[F F F] [F F F]] [F F F] * * \param [F F F] : first float vector * \param [F F F] : second float vector * * \return [F F F] : vector result **/ fun std_vectorDivideF (fV1, fV2)= if std_vectorIsNullF fV2 then nil else let fV1 -> [fX1 fY1 fZ1] in let fV2 -> [fX2 fY2 fZ2] in [divf fX1 fX2 divf fY1 fY2 divf fZ1 fZ2];; /*! \brief Create a vector in duplicating a same given value * * \ingroup std_lib * * * Prototype: fun [u0] [u0 u0 u0] * * \param u0 : any value * * \return [u0 u0 u0] : vector result **/ fun std_vectorSet (v)= [v v v];; /*! \brief Check if a flag is in a flags combination, like 'WN_MENU|WN_SIZEBOX|WN_MINBOX' * * \ingroup std_lib * Prototype : fun [I I] I * * \param I : a flags combination * \param I : a flag to check * \return I : 1 if present else 0 **/ fun std_isFlagPresent (flags, flag)= if flags & flag then 1 else 0;; /*! \brief Remove a flag in a flags combination, like 'WN_MENU|WN_SIZEBOX|WN_MINBOX' * * \ingroup std_lib * Prototype : fun [I I] I * * \param I : a flags combination * \param I : a flag to remove * \return I : a new combination **/ fun std_removeFlag (flags, flag)= flags & (~flag);; /*! \brief Add a flag in a flags combination, like 'WN_MENU|WN_SIZEBOX|WN_MINBOX' * * \ingroup std_lib * Prototype : fun [I I] I * * \param I : a flags combination * \param I : a flag to add * \return I : a new combination **/ fun std_addFlag (flags, flag)= if std_isFlagPresent flags flag then // useful ? flags | flag else flags;; proto std_sameType = fun [u0 u0] I;; /*! \brief Check if two objects have the same type. * * This function should be NEVER used in production ! * * In development or debug mode, this function causes a runtime error * if the two objects have a different type. * * \ingroup std_lib * Prototype : fun [u0 u0] I * * \param u0 : any object * \param u0 : any object * \return I : always 0 **/ fun std_sameType (o1, o2)= 0;; /*! \brief ... */ fun std_addFifo (x, f)= let x :: nil -> l in if f == nil then [l l] else let f->[a b] in ( mutate b<-[_ l]; [a l] );; /*! \brief ... */ fun std_getFifo (f)= if f == nil then [nil nil] else let f -> [a b] in if a == b then [hd a nil] else [hd a [tl a b]];; /*! \brief ... */ fun std_sizeFifo (f)= if f == nil then 0 else let f -> [a _] in sizelist a;; /*! \brief ... */ fun std_concFifo (f, g)= if f == nil then g else if g == nil then f else let f -> [a b] in let g -> [c d] in ( mutate b <- [_ c]; [a d] );; /*! \brief Create a new unplugged channel with the minimal * environment. * * \ingroup std_lib * Prototype : fun [S] Chn * * \param S : a script to execute immediately in the new channel. * \return Chn : the new channel or nil if error (unable to create the new channel) * \remark Don't use this function at this time ! **/ fun std_newUnChn (szScript)= _openchannel nil szScript nil;; /*! \brief Create a new unplugged channel with the current * environment. * * \ingroup std_lib * Prototype : fun [S] Chn * * \param S : a script to execute immediately in the new channel. * \return Chn : the new channel or nil if error (unable to create the new channel) * \remark Don't use this function at this time ! **/ fun std_newUnCurChn (szScript)= _openchannel nil szScript _envchannel _channel;; /*! \brief Create a new unplugged channel with the current * environment. * * \ingroup std_lib * Prototype : fun [S S S] Chn * * \param S : a script to execute immediately in the new channel. * \param S : the function name to call when a connection is received. * \param S : the function name to call when a connection is closed. * \return Chn : the new channel or nil if error (unable to create the new channel) * \remark These two functions must be known in the new channel environnement. * * \remark Don't use this function at this time ! **/ fun std_newUnCurChnEx (szScript, funCon, funClo)= let sprintf "fun _connected ()=exec @%s with [];;\nfun _closed ()=exec @%s with [];;\n\n%s" [funCon funClo szScript] -> szScriptUpt in _openchannel nil szScriptUpt nil;; /*! \brief Create a new unplugged channel with the minimal * environment. * * \ingroup std_lib * Prototype : fun [S S S] Chn * * \param S : a script to execute immediately in the new channel. * \param S : the function name to call when a connection is received. * \param S : the function name to call when a connection is closed. * \return Chn : the new channel or nil if error (unable to create the new channel) * \remark These two functions must be known in the new channel environnement. * * \remark Don't use this function at this time ! * \see std_newUnChnExP **/ fun std_newUnChnEx (szScript, funCon, funClo)= let sprintf "%s\n_loadS \"fun _connected ()=%s;;\nfun _closed ()=%s;;\"\nmain" [szScript funCon funClo] -> szScriptUpt in let _fooS szScriptUpt -> _ in _openchannel nil szScriptUpt nil;; /*! \brief Create a new unplugged channel with the minimal * environment. * * \ingroup std_lib * Prototype : fun [[S r1] S S] Chn * * \param [S r1] : a list of files to load immediately in the new channel. * \param S : the function name to call when a connection is received. * \param S : the function name to call when a connection is closed. * \return Chn : the new channel or nil if error (unable to create the new channel) * \remark These two functions must be known in the new channel environnement. * \remark Don't use this function at this time ! **/ fun std_newUnChnExP (pFiles, funCon, funClo)= let "_loadS \"" -> szScript in let 0 -> res in ( while (pFiles != nil) do let _checkpack hd pFiles -> pFile in if pFile == nil then ( set pFiles = nil; set res = 1; ) else ( set szScript = sprintf "%s%s\n" [szScript _getpack pFile]; set pFiles = tl pFiles; 0 ); if (!res) then ( set szScript = sprintf "%sfun _connected ()=%s;;\nfun _closed ()=%s;;%s" [szScript funCon funClo "\""]; _openchannel nil szScript nil ) else nil; );;