Project

General

Profile

Scol Language particular syntax » History » Revision 3

Revision 2 (arkeon, 04/29/2011 07:01 PM) → Revision 3/7 (iri, 08/09/2011 05:14 PM)

h1. Scol Language particular syntax 

 Scol is a functional language, with static types and polymorphic. 

 {{toc}} 

 h2. Syntax 

 Scol determine independently the expected types. 

 The basic types are: 
 <pre> 
 I         : integer 
 S         : string 
 F         : float 
 Chn       : SCOL channel 
 Srv       : SCOL server 
 Env       : SCOL environment 
 Comm      : communication 
 [u0 u1] : Tuples where u0, u1 are Scol types 
 [u0 r1] : List where u0 is a Scol type 
 </pre> 

 Types can be declared by the addition of Scol plugins (dll) or by the use of "typedef" or structures "struct". "nil" can claim any of these types, for example it will be used to change the value of a variable to null or test if a variable has been initialized. 

 h2. Data Structures 

 h3. With _struct_ : 

 The data structures are declared as follows: 
 <pre> 
 struct MYDATA [ MD_sName : S, MD_iValue : I] mkMYDATA;; 
 </pre> 

 You can access an element of a structure by ".MD_sName" for example: 
 <pre> 
 struct MYDATA [ MD_sName : S, MD_iValue : I] mkMYDATA;; 
 fun crData(name, value)= 
   mkMYDATA [name value] 
 ;; 

 fun getDataName(mydatastr)= 
   mydatastr.MD_sName 
 ;; 

 fun main()= 
   let crData "name" 1 -> mydatastr in 
     _fooS strcat ">>> nom : " (getDataName mydatastr); 
  0;; 
 </pre> 

 Note : you *must initialize* your structure *before* use it ! 

 h3. With _typedef_ : 

 Definition : 
 <pre> 
 typedef NewType = 
 T1 type1 
 | T2 type2 
 | T3 type3 
 | Tn;; 
 </pre> 

 To access it, use _match_    : 
 <pre>fun maFonction (X)= 
	 match X with 
	 (T1 e -> instruction1) 
	 | (T2 e -> instruction2) 
	 | (T3 e -> instruction3) 
	 | (TN e -> instructionN) 
	 | (_ -> instructionDefault);; 
 </pre> 

 For example : 
 <pre>typedef NewType = 	 /* New scol type named 'NewType'. It can set by a "subtype" (in fact in function) T1, T2, ... */ 
 T1 I 
 | T2 F 
 | T3 S 
 | Tn;; 

 typeof X = NewType;; 	 /* Global variable declaration (see below) */ 

 fun maFonction ()= 
	 match X with 
	 (T1 e -> (_fooS "X is an integer"; 0) 
	 | (T2 e -> (_fooS "X is a float"; 0) 
	 | (T3 e -> (_fooS "X is a string"; 0) 
	 | (_ -> (_fooS "X is another thing"; 0);; 
 </pre> 

 h2. Operators 

 In Scol, standard operators are supported, it is also possible to use masks (&, |, ~) and bit shifts (>>, <<). The only truly special case concern the float, it will use the standard operators followed by a "." 
 <pre> 
 fun addfloat(v1, v2)= 
   v1 +. v2    
 ;; 

 fun addint(v1, v2)= 
   v1 + v2    
 ;; 
 </pre> 

 For the string, you could use this : 
 <pre> 
 fun addString (s1, s2)= 
   strcat s1 s2;; 
 </pre> 

 h2. Global variables 

 There are different ways to declare global variables, the first by the type of the variable and the second by an initial value. 
 <pre> 
 // Declaring a variable by value, here a Int type (because the given value is an integer) 
 var iMyVar = 0;; 

 // Declaring a variable by value, here a String type (because the given value is an string) 
 var sMyVar = "Hello World";; 

 // Declaring a variable by a type 
 typeof iMyVar = I;; 
 typeof sMyVar = S;; 
 </pre> 

 To set a value to these varaible, use *set* function (it's a function even if the return is ignored usually) : 
 <pre>set sMyVar = "Hello World"; 
 set iMyVar = 0;</pre> 

 h2. Variables locales 

 A local variable declared with "let value -> varname in ", has a lifetime limited to the following statement. The Scol language set this limit by ";" or end of a bracket or brace. 
 <pre> 
 fun main()= 
   let "Hello World" -> text in 
   { 
     _fooS ">>> local variable";    //Without the brace the "text" variable would not be known at the next line 
     _fooS strcat ">>> value : " text; 
   }; 
   0;; 
 </pre> 

 h2. If logic 

 When using the "if" test, Scol has the distinction of require to write the complete test. "if" without the "else" or without the "then " will not compile. Another special case, the return value in "then" and "else" should contain the same type. 
 <pre> 
 fun main()= 
   let 1 -> i in 
   if (i == 1) then 
      set i = 0 
   else nil; 
  
   let 1 -> i in 
   if (i >= 1) then 
   { 
      if (i == 1) then nil else 
        set i = i - 1; 
   } 
   else nil; 
   0;; 
 </pre> 

 h2. While loop 

 The syntax of the loop is composed of "while" followed by "do": 
 <pre> 
 fun main()= 
   let 0 -> i in 
   while (i <= 10) do 
   { 
     _fooS strcat ">>> i value : " (itoa i); 
     set i = i + 1; 
   }; 
  0;; 
 </pre> 

 h2. Lists 

 The use of the lists is very common in Scol, it can, unlike arrays, change its size dynamically. In scol lists are nested tuples, this means that we can treat a list as a tuple of two components, the first will contain the first item in the list and the second then rest of the list without the first element. A list can contain any type and always ends with "nil". 
 <pre> 
 var lMyList = "elem1"::"elem2"::"elem3"::nil;; 
 typeof lMyList2 = [S r1];; 

 fun main()= 
   // parsing, we copy the list into a local variable to avoid modifying the global list 
   let lMyList -> l in 
   while (l != nil) do 
   { 
     // we get the first element 
     let hd l -> elem in 
     { 
       _fooS strcat ">>> elem : " elem; 

       // we add "elem" to lMyList2 
       set lMyList2 = elem::lMyList2; 
     }; 
     // we remove the first element of l 
     set l = tl l; 
   }; 

   // another method for the same result 
   let lMyList -> l in 
   while (l != nil) do 
   { 
     // we get the first element 
     let l -> [elem next] in 
     { 
       _fooS strcat ">>> elem : " elem; 

       // we add "elem" to lMyList2 
       set lMyList2 = elem::lMyList2; 

       // we remove the first element of l 
       set l = next; 
     }; 
   }; 

   // another method for the same result 
   let sizelist lMyList -> size in 
   let 0 -> i in 
   while (i < size) do 
   { 
     // we get the first element at the i position in the list 
     let nth_list lMyList i -> elem in 
     { 
       _fooS strcat ">>> elem : " elem; 
       // we add "elem" to lMyList2 
       set lMyList2 = elem::lMyList2; 
     } 
     // increment i 
     set i = i + 1; 
   }; 
   0;; 
 </pre> 

 Note : to test if a list is ended, compare it with nil : 
 <pre> 
 if myList == nil then 
   // to do something when the list is empty 
 else 
   // to do another thing when the list is not empty 
 </pre> 

 h2. Recursive functions 

 Recursive functions can avoid the use of intensive loops execution time. Here is an example of a recursive function to process the items in a list based on the previous example. The recursive function is very often used and this is natural in Scol. 
 <pre> 
 var lMyList = "elem1"::"elem2"::"elem3"::nil;; 
 typeof lMyList2 = [S r1];; 

 fun recursiveParse(l)= 
   if l == nil then nil else 
   let l -> [elem next] in 
   { 
     _fooS strcat ">>> elem : " elem; 

     // we add "elem" to lMyList2 
     set lMyList2 = elem::lMyList2; 

     // we recall the function with the following data to be processed 
     recursiveParse next; 
   };; 

 fun main()= 
   recursiveParse lMyList; 
   0;; 
 </pre> 

 h2. Callbacks 

 Callbacks allow a call to a function defined in a variable. A window object (ObjWin) for example can call a function when it is closed or being moved. It is also possible to define a variable of function type. 
 <pre> 
 typeof cbMyfun = fun [S] I;; 

 fun cbTest1(svalue)= 
   _fooS strcat ">>> value : " svalue; 
   0;; 

 fun main()= 
   set cbMyFun = @cbTest1; 
   exec cbMyFun with ["Hello world !"]; 
   0;; 
 </pre> 

 h2. Prototype 

 A function must be defined before use it. Sometimes, we can not do it. In this case, the function must be prototyped before use it (but it must be defined in the current environment ! Otherwise error "empty prototype" !) 

 <pre> 
 proto myFunctionPrototyped = fun [u0] u1;; 
 </pre>