Project

General

Profile

Creation of a new type for Scol » History » Version 3

ModularMix, 10/18/2011 10:27 AM

1 3 ModularMix
h1. Creation of a new type for Scol
2 1 ModularMix
3 2 ModularMix
Similarly with Scol functions, it's also possible to extend Scol language by creating new data types using the integration of C/C++ plugins.
4 1 ModularMix
5 2 ModularMix
h2. Definition of *Bloc* data type
6 1 ModularMix
7 2 ModularMix
In this tutorial, we will create a basic data type which will store a name and an integer value. We'll also define the getters and setters for each of the properties.
8 2 ModularMix
As we will implement this new data type using a standard C++ class, we'll also define default constructor and destructor.
9 2 ModularMix
Now, let's create a new C++ header file named *Bloc.h*. Copy/paste the following explicit code into it :
10 1 ModularMix
<pre>
11 1 ModularMix
 // Include providing MAX_PATH define
12 1 ModularMix
 #include <windows.h>
13 1 ModularMix
 
14 1 ModularMix
 /*!
15 1 ModularMix
  * Bloc class. A simple class that has a name and a value associated with it.
16 1 ModularMix
  * It allows simple operations like getting and setting its attributes.
17 1 ModularMix
  *
18 1 ModularMix
  **/
19 1 ModularMix
 class Bloc
20 1 ModularMix
 {
21 1 ModularMix
 private:
22 1 ModularMix
    int value;	            //!< The value of the bloc
23 1 ModularMix
    char name[MAX_PATH];    //!< The name of the bloc
24 1 ModularMix
 
25 1 ModularMix
 public:
26 1 ModularMix
    int getValue();
27 1 ModularMix
    char* getName();
28 1 ModularMix
    void setName(char*);
29 1 ModularMix
    void setValue(int);
30 1 ModularMix
    Bloc(void);
31 1 ModularMix
    ~Bloc(void);
32 1 ModularMix
 };
33 1 ModularMix
</pre>
34 1 ModularMix
35 2 ModularMix
36 2 ModularMix
Then, let's create the C++ source file (*Bloc.cpp*) in which we will implement the different functions.
37 2 ModularMix
The source code is still very explicit, our object will act as a property container that we can get or set using getters and setters.
38 1 ModularMix
<pre>
39 1 ModularMix
 #include "Bloc.h"
40 1 ModularMix
 #include <string.h>
41 1 ModularMix
 #include <stdio.h>
42 1 ModularMix
 
43 1 ModularMix
 /*!
44 1 ModularMix
 * \brief Bloc constructor
45 1 ModularMix
 * 
46 1 ModularMix
 */
47 1 ModularMix
 Bloc::Bloc(void)
48 1 ModularMix
 {
49 1 ModularMix
    value=0;
50 1 ModularMix
    strcpy_s(name,"SuperBloc");
51 1 ModularMix
 }
52 1 ModularMix
 
53 1 ModularMix
 /*!
54 1 ModularMix
 * \brief Bloc destructor
55 1 ModularMix
 * 
56 1 ModularMix
 */
57 1 ModularMix
 Bloc::~Bloc(void)
58 1 ModularMix
 {
59 1 ModularMix
 }
60 1 ModularMix
 
61 1 ModularMix
 /*!
62 1 ModularMix
 * \brief Gives the bloc value
63 1 ModularMix
 * \return The bloc value 
64 1 ModularMix
 */
65 1 ModularMix
 int Bloc::getValue()
66 1 ModularMix
 {
67 1 ModularMix
    return value;
68 1 ModularMix
 }
69 1 ModularMix
 
70 1 ModularMix
 /*!
71 1 ModularMix
 * \brief Gives the bloc name
72 1 ModularMix
 * \return The bloc name
73 1 ModularMix
 * 
74 1 ModularMix
 */
75 1 ModularMix
 char * Bloc::getName()
76 1 ModularMix
 {
77 1 ModularMix
    return name;
78 1 ModularMix
 }
79 1 ModularMix
 
80 1 ModularMix
 /*!
81 1 ModularMix
 * \brief Set the bloc value
82 1 ModularMix
 * \param myValue : The new value 
83 1 ModularMix
 */
84 1 ModularMix
 void Bloc::setValue(int myValue)
85 1 ModularMix
 {
86 1 ModularMix
    value = myValue;
87 1 ModularMix
 }
88 1 ModularMix
 
89 1 ModularMix
 /*!
90 1 ModularMix
 * \brief Set the bloc name
91 1 ModularMix
 * \param myValue : The new name 
92 1 ModularMix
 */
93 1 ModularMix
 void Bloc::setName(char* myName)
94 1 ModularMix
 {
95 1 ModularMix
    strncpy_s(name, myName, MAX_PATH-1);
96 1 ModularMix
 }
97 2 ModularMix
</pre>
98 2 ModularMix
99 2 ModularMix
100 2 ModularMix
h2. Binding between C and Scol
101 2 ModularMix
102 2 ModularMix
Now we'll see how to be able to use *Bloc* object in Scol language, by integrating it into our plugin Template.
103 2 ModularMix
104 2 ModularMix
h3. Creation and destruction of *Bloc* object
105 2 ModularMix
106 2 ModularMix
The first step is to make available the definition of *Bloc* object in *template.cpp*, by including the file *Bloc.h* :
107 2 ModularMix
<pre>
108 2 ModularMix
 #include "Bloc.h"
109 2 ModularMix
</pre>
110 2 ModularMix
111 2 ModularMix
112 2 ModularMix
*OBJBLOCSCOL* enables to store the unique ID linked to the new Scol type. This ID is allocated by Scol virtual machine during the registration of this new type (we will explain this later in this document). 
113 2 ModularMix
<pre>
114 2 ModularMix
 //! Bloc Object in Scol
115 2 ModularMix
 int OBJBLOCSCOL;
116 2 ModularMix
 
117 2 ModularMix
 //! BlocObj is set here as a type (an int) for doxygen documentation
118 2 ModularMix
 typedef int BlocObj;
119 2 ModularMix
</pre>
120 2 ModularMix
121 2 ModularMix
The first function to be defined is the one which will allow to create the object and add it to the Scol stack.
122 2 ModularMix
This one will correspond to the followin Scol prototype : *fun [Chn] BlocObj*. We have to check that the first element on the Scol stack is a valid channel.
123 2 ModularMix
Once the input parameters have been checked, the creation of the *Bloc* object is done in two steps :
124 2 ModularMix
* The memory allocation ad the creation of the object in C++
125 2 ModularMix
* The allocation of a space in Scol stack, and the call to the function *OBJcreate* which will create the object in Scol 
126 2 ModularMix
<pre>
127 2 ModularMix
 /*! @ingroup group1
128 2 ModularMix
  * \brief _CRbloc : Open, initialize Bloc object
129 2 ModularMix
  *
130 2 ModularMix
  * <b>Prototype:</b> fun [Chn] BlocObj
131 2 ModularMix
  *
132 2 ModularMix
  * \param Chn : current channel
133 2 ModularMix
  *
134 2 ModularMix
  * \return BlocObj : Bloc object if success, NIL otherwise 
135 2 ModularMix
  **/
136 2 ModularMix
 int _CRbloc(mmachine m)
137 2 ModularMix
 {
138 2 ModularMix
      #ifdef _SCOL_DEBUG_
139 2 ModularMix
      MMechostr(MSKDEBUG,"_CRbloc\n");
140 2 ModularMix
      #endif
141 2 ModularMix
 
142 2 ModularMix
      // Declare local variables
143 2 ModularMix
      int k = 0;
144 2 ModularMix
 
145 2 ModularMix
      // Get the channel without pulling it (first element in the stack)
146 2 ModularMix
      int channel = MMget(m, 0);
147 2 ModularMix
 
148 2 ModularMix
      // Test the channel
149 2 ModularMix
      if (channel == NIL)
150 2 ModularMix
      { 
151 2 ModularMix
          MMechostr(MSKDEBUG, "Channel NIL\n");
152 2 ModularMix
          MMpull(m);                            // Pull the channel													
153 2 ModularMix
          MMpush(m, NIL);                       // Push NIL on the stack
154 2 ModularMix
          return 0;
155 2 ModularMix
      }
156 2 ModularMix
 
157 2 ModularMix
      // Create bloc instance
158 2 ModularMix
      Bloc * bloc = new Bloc();
159 2 ModularMix
 
160 2 ModularMix
      if (bloc == NULL)
161 2 ModularMix
      {
162 2 ModularMix
          MMechostr(MSKDEBUG, "_CRbloc ...initialization failed\n");
163 2 ModularMix
          SAFE_DELETE(bloc) ;
164 2 ModularMix
          MMpull(m);				// Pull the channel
165 2 ModularMix
          MMpush(m, NIL);			// Push NIL on the stack
166 2 ModularMix
          return 0;
167 2 ModularMix
      }
168 2 ModularMix
      MMechostr(MSKDEBUG,"_CRbloc ...initialization successful\n");
169 2 ModularMix
 
170 2 ModularMix
      // Allocate a space in the stack for a table of bloc objects
171 2 ModularMix
      int blocTab = MMmalloc(m, 1, TYPETAB);
172 2 ModularMix
      if (blocTab == NIL)
173 2 ModularMix
      {
174 2 ModularMix
          MMechostr(MSKDEBUG,"_CRbloc ...MMmalloc failed\n");
175 2 ModularMix
          SAFE_DELETE(bloc); 
176 2 ModularMix
          MMpull(m);				// Pull the channel
177 2 ModularMix
          return MMpush(m, NIL);		// Push NIL on the stack
178 2 ModularMix
      }
179 2 ModularMix
      MMechostr(MSKDEBUG,"_CRbloc ...MMmalloc successful\n");
180 2 ModularMix
 
181 2 ModularMix
      // Push the table of bloc objects into the stack
182 2 ModularMix
      MMstore(m, blocTab, 0, (int)bloc);
183 2 ModularMix
      MMpush(m, PTOM(blocTab));
184 2 ModularMix
 
185 2 ModularMix
      // Create a new scol bloc object
186 2 ModularMix
      k = OBJcreate(m, OBJBLOCSCOL, (int)bloc, NULL, NULL);
187 2 ModularMix
      MMechostr(MSKDEBUG,"_CRbloc ...object creation successful\n");
188 2 ModularMix
 
189 2 ModularMix
      #ifdef _SCOL_DEBUG_
190 2 ModularMix
      MMechostr(MSKDEBUG,"ok\n");
191 2 ModularMix
      #endif
192 2 ModularMix
 
193 2 ModularMix
      // Return bloc object
194 2 ModularMix
      return k;
195 2 ModularMix
 }
196 2 ModularMix
</pre>
197 2 ModularMix
198 2 ModularMix
The second function to define is the one to destroy the object on a query made by the Scol developer.
199 2 ModularMix
The singularity of this function is that we don't pop from the Scol stack the object passed as a parameter, and we don't delete the associated C++ object either.
200 2 ModularMix
Instead of this, we use the Scol Garbage Collector (GC) using the function *OBJdelTM* from the Scol API. This function needs to know the Scol type of the object we want to delete.
201 2 ModularMix
<pre>
202 2 ModularMix
 /*! @ingroup group1
203 2 ModularMix
  * \brief _DSbloc : Destroy bloc object
204 2 ModularMix
  *
205 2 ModularMix
  * <b>Prototype:</b> fun [BlocObj] I
206 2 ModularMix
  *
207 2 ModularMix
  * \param BlocObj : Bloc Object to destroy
208 2 ModularMix
  *
209 2 ModularMix
  * \return I : 0 if success, NIL otherwise 
210 2 ModularMix
  **/
211 2 ModularMix
 int _DSbloc(mmachine m)
212 2 ModularMix
 {
213 2 ModularMix
     #ifdef _SCOL_DEBUG_
214 2 ModularMix
     MMechostr(MSKDEBUG,"_DSbloc\n");
215 2 ModularMix
     #endif
216 2 ModularMix
 
217 2 ModularMix
     int bloc = MTOP( MMget(m,0) );
218 2 ModularMix
     if ( bloc == NIL ) { MMset(m,0,NIL); return 0; }
219 2 ModularMix
 
220 2 ModularMix
     OBJdelTM( m, OBJBLOCSCOL, PTOM(bloc) );
221 2 ModularMix
     MMset(m,0,0);	
222 2 ModularMix
 
223 2 ModularMix
     #ifdef _SCOL_DEBUG_
224 2 ModularMix
     MMechostr(MSKDEBUG,"ok\n");
225 2 ModularMix
     #endif
226 2 ModularMix
     return 0;
227 2 ModularMix
 }
228 2 ModularMix
</pre>
229 2 ModularMix
230 2 ModularMix
231 2 ModularMix
As previously stated, we have to define a callback function for the object destruction which will then be called by the GC.
232 2 ModularMix
This function will pop the object from the Scol stack and delete the C++ object from the memory.
233 2 ModularMix
<pre>
234 2 ModularMix
 /*!
235 2 ModularMix
  * \brief Scol object destroy callback
236 2 ModularMix
  *
237 2 ModularMix
  * \param mmachine : scol machine structure
238 2 ModularMix
  * \param int : scol object system handle
239 2 ModularMix
  * \param int : scol object stack handle
240 2 ModularMix
  *
241 2 ModularMix
  * \return int : 0
242 2 ModularMix
  **/
243 2 ModularMix
 int destroyBlocObj(mmachine m, int handsys, int blocTab)
244 2 ModularMix
 {
245 2 ModularMix
     // Read the first element of a TAB element (table of objects)
246 2 ModularMix
     Bloc* bloc = (Bloc*) MMfetch(m, MTOP(blocTab), 0);
247 2 ModularMix
     if (bloc == NULL)
248 2 ModularMix
     {
249 2 ModularMix
         // Write the first element in the stack, without pulling it
250 2 ModularMix
         MMset(m, 0, NIL); 
251 2 ModularMix
         return 0;
252 2 ModularMix
     }
253 2 ModularMix
 
254 2 ModularMix
     // Safely dispose of "Bloc" pointer
255 2 ModularMix
     SAFE_DELETE(bloc);
256 2 ModularMix
 
257 2 ModularMix
     // Write the first element of a TAB element
258 2 ModularMix
     MMstore(m, MTOP(blocTab), 0, NULL);
259 2 ModularMix
 
260 2 ModularMix
     // Display debug message
261 2 ModularMix
     MMechostr(MSKDEBUG,"Bloc object destroyed.\n");
262 2 ModularMix
     return 0;
263 2 ModularMix
 }
264 2 ModularMix
</pre>
265 2 ModularMix
266 2 ModularMix
267 2 ModularMix
Given that all our functions are defined, we will register the new data type for Scol.
268 2 ModularMix
It's important to notice :
269 2 ModularMix
* the binding to the callback function for the object destruction (*destroyBlocObj*),
270 2 ModularMix
* the parameter "OBJBLOCSCOL" which corresponds to the type name as it will be used in a Scol program.
271 2 ModularMix
272 2 ModularMix
Finally, the function returns an ID for the new data type, which is stored in the global variable *OBJBLOCSCOL* (we remind that this variable is used in the function *_DSBloc* to notice to the GC the object type to delete).
273 2 ModularMix
<pre>
274 2 ModularMix
 // Declare a new type of object ("OBJBLOCSCOL")
275 2 ModularMix
 OBJBLOCSCOL = OBJregister(0 /*nb of callback*/, 1/* deleted from parent */, destroyBlocObj, "OBJBLOCSCOL");
276 2 ModularMix
</pre>
277 2 ModularMix
278 2 ModularMix
279 2 ModularMix
The binding of the C++ functions enabling to create and delete a *Bloc* object in Scol is registered using *PKhardpak* function, so we have to modify the parameters of this function.
280 2 ModularMix
We notice the specific values used to bind the Scol data type, which name will be *ObjBloc*.
281 2 ModularMix
<pre>
282 2 ModularMix
 //! Nb of Scol functions or types
283 2 ModularMix
 #define NbTplPKG	4
284 2 ModularMix
 
285 2 ModularMix
 /*!
286 2 ModularMix
  * Scol function names
287 2 ModularMix
  **/
288 2 ModularMix
 char* TplName[NbTplPKG] =
289 2 ModularMix
 {
290 2 ModularMix
     "_HelloWorld",
291 2 ModularMix
     "ObjBloc",
292 2 ModularMix
     "_CRbloc",
293 2 ModularMix
     "_DSbloc"
294 2 ModularMix
 };
295 2 ModularMix
 
296 2 ModularMix
 /*!
297 2 ModularMix
  * Pointers to C functions that manipulate the VM for each scol function previously defined
298 2 ModularMix
  **/
299 2 ModularMix
 int (*TplFunc[NbTplPKG])(mmachine m)=
300 2 ModularMix
 {
301 2 ModularMix
     _HelloWorld,
302 2 ModularMix
     NULL,
303 2 ModularMix
     _CRbloc,
304 2 ModularMix
     _DSbloc
305 2 ModularMix
 };
306 2 ModularMix
 
307 2 ModularMix
 /*!
308 2 ModularMix
  * Nb of arguments of each scol function
309 2 ModularMix
  **/
310 2 ModularMix
 int TplNArg[NbTplPKG]=
311 2 ModularMix
 {
312 2 ModularMix
     0,
313 2 ModularMix
     TYPTYPE,
314 2 ModularMix
     1,
315 2 ModularMix
     1
316 2 ModularMix
 };
317 2 ModularMix
 
318 2 ModularMix
 /*!
319 2 ModularMix
  * Prototypes of the scol functions
320 2 ModularMix
  **/
321 2 ModularMix
 char* TplType[NbTplPKG]=
322 2 ModularMix
 {
323 2 ModularMix
     "fun [] I",                // _HelloWorld
324 2 ModularMix
     NULL,
325 2 ModularMix
     "fun [Chn] ObjBloc",	// _CRbloc
326 2 ModularMix
     "fun [ObjBloc] I"          // _DSbloc
327 2 ModularMix
 };
328 2 ModularMix
</pre>
329 2 ModularMix
330 2 ModularMix
h3. Access to the properties of Bloc object
331 2 ModularMix
332 2 ModularMix
To access the properties of *Bloc* object, we will define the getters and setters for each property of the object.
333 2 ModularMix
The important point here is to well observe and understand for each function the different operations updating the Scol stack, regarding the Scol prototype (retrieve Scol parameters, check all of them and return the appropriate Scol value).
334 2 ModularMix
<pre>
335 2 ModularMix
 /*! @ingroup group1
336 2 ModularMix
  * \brief _GETblocValue : Get the value of the Bloc object
337 2 ModularMix
  *
338 2 ModularMix
  * <b>Prototype:</b> fun [BlocObj] I
339 2 ModularMix
  *
340 2 ModularMix
  * \param BlocObj : bloc object
341 2 ModularMix
  *
342 2 ModularMix
  * \return I : return bloc value, nil otherwise
343 2 ModularMix
  **/
344 2 ModularMix
 int _GETblocValue(mmachine m)
345 2 ModularMix
 {
346 2 ModularMix
     #ifdef _SCOL_DEBUG_
347 2 ModularMix
     MMechostr(MSKDEBUG,"_GETblocValue\n");
348 2 ModularMix
     #endif
349 2 ModularMix
     // Get bloc table from the stack, then transform it
350 2 ModularMix
     int blocTable = MTOP( MMget(m,0) ) ;
351 2 ModularMix
     if ( blocTable == NIL ) { MMset(m,0,NIL) ; return 0 ; }
352 2 ModularMix
 
353 2 ModularMix
     // cast this bloc in a Bloc object
354 2 ModularMix
     Bloc* bloc = (Bloc*)MMfetch(m, blocTable, 0) ;
355 2 ModularMix
     if( !bloc ) { MMset(m,0,NIL) ; return 0 ; }
356 2 ModularMix
 
357 2 ModularMix
     // put the return of the function call in the stack 
358 2 ModularMix
     MMset(m,0,ITOM(bloc->getValue()));
359 2 ModularMix
 
360 2 ModularMix
     #ifdef _SCOL_DEBUG_
361 2 ModularMix
     MMechostr(MSKDEBUG,"ok\n");
362 2 ModularMix
     #endif
363 2 ModularMix
 
364 2 ModularMix
     return 0;
365 2 ModularMix
 }
366 2 ModularMix
 
367 2 ModularMix
 /*! @ingroup group1
368 2 ModularMix
  * \brief _SETblocValue : Set the value of the bloc
369 2 ModularMix
  *
370 2 ModularMix
  * <b>Prototype:</b> fun [BlocObj I] I
371 2 ModularMix
  *
372 2 ModularMix
  * \param BlocObj : bloc object
373 2 ModularMix
  * \param I : New value
374 2 ModularMix
  *
375 2 ModularMix
  * \return I : 0 if success, -1 otherwise 
376 2 ModularMix
  **/
377 2 ModularMix
 int _SETblocValue(mmachine m)
378 2 ModularMix
 {
379 2 ModularMix
     #ifdef _SCOL_DEBUG_
380 2 ModularMix
     MMechostr(MSKDEBUG,"_SETblocValue\n");
381 2 ModularMix
     #endif
382 2 ModularMix
     // Get param
383 2 ModularMix
     int value = MTOI( MMpull(m) ) ;
384 2 ModularMix
 
385 2 ModularMix
     // Get Bloc table
386 2 ModularMix
     int blocTable = MTOP( MMget(m,0) ) ;
387 2 ModularMix
     if ( blocTable == NIL ) { MMset(m,0,-1) ; return 0 ; }
388 2 ModularMix
 
389 2 ModularMix
     // Cast the content of bloc table to Bloc*
390 2 ModularMix
     Bloc* bloc = (Bloc*)MMfetch(m, blocTable, 0) ;
391 2 ModularMix
     bloc->setValue(value);
392 2 ModularMix
     MMset(m,0,0);
393 2 ModularMix
 
394 2 ModularMix
     #ifdef _SCOL_DEBUG_
395 2 ModularMix
     MMechostr(MSKDEBUG,"ok\n");
396 2 ModularMix
     #endif
397 2 ModularMix
 
398 2 ModularMix
     return 0;
399 2 ModularMix
 }
400 2 ModularMix
 
401 2 ModularMix
 /*! @ingroup group1
402 2 ModularMix
  * \brief _GETblocName : Get the name of the bloc
403 2 ModularMix
  *
404 2 ModularMix
  * <b>Prototype:</b> fun [BlocObj] S
405 2 ModularMix
  *
406 2 ModularMix
  * \param BlocObj : bloc object
407 2 ModularMix
  *
408 2 ModularMix
  * \return S : The name of the bloc if success, NIL otherwise 
409 2 ModularMix
  **/
410 2 ModularMix
 int _GETblocName(mmachine m)
411 2 ModularMix
 {
412 2 ModularMix
     #ifdef _SCOL_DEBUG_
413 2 ModularMix
     MMechostr(MSKDEBUG,"_GETblocName\n");
414 2 ModularMix
     #endif
415 2 ModularMix
     // Get bloc table in the stack, then transform it in system pointer
416 2 ModularMix
     int blocTable = MTOP( MMget(m,0) ) ;
417 2 ModularMix
     if ( blocTable == NIL ) { MMset(m,0,NIL) ; return 0 ; }
418 2 ModularMix
 
419 2 ModularMix
     // cast this bloc in a Bloc object
420 2 ModularMix
     Bloc* bloc = (Bloc*)MMfetch(m, blocTable, 0) ;
421 2 ModularMix
     if( !bloc ) { MMset(m,0,NIL) ; return 0 ; }
422 2 ModularMix
 
423 2 ModularMix
     // remove param from stack
424 2 ModularMix
     MMpull(m);
425 2 ModularMix
 
426 2 ModularMix
     // put in the stack the return of the function call  
427 2 ModularMix
     Mpushstrbloc(m, bloc->getName());
428 2 ModularMix
 
429 2 ModularMix
     #ifdef _SCOL_DEBUG_
430 2 ModularMix
     MMechostr(MSKDEBUG,"ok\n");
431 2 ModularMix
     #endif
432 2 ModularMix
 
433 2 ModularMix
     return 0;
434 2 ModularMix
 }
435 2 ModularMix
 
436 2 ModularMix
 /*! @ingroup group1
437 2 ModularMix
  * \brief _SETblocName : Set the name of the bloc
438 2 ModularMix
  *
439 2 ModularMix
  * <b>Prototype:</b> fun [BlocObj S] I
440 2 ModularMix
  *
441 2 ModularMix
  * \param BlocObj : bloc object
442 2 ModularMix
  * \param S : New name
443 2 ModularMix
  *
444 2 ModularMix
  * \return I : 0 if success, -1 otherwise 
445 2 ModularMix
  **/
446 2 ModularMix
 int _SETblocName(mmachine m)
447 2 ModularMix
 {
448 2 ModularMix
     #ifdef _SCOL_DEBUG_
449 2 ModularMix
     MMechostr(MSKDEBUG,"_SETblocName\n");
450 2 ModularMix
     #endif
451 2 ModularMix
     // Get param
452 2 ModularMix
     int name = MTOP( MMpull(m) ) ;
453 2 ModularMix
 
454 2 ModularMix
     // Get Bloc table
455 2 ModularMix
     int blocTable = MTOP( MMget(m,0) ) ;
456 2 ModularMix
     if ( blocTable == NIL ) { MMset(m,0,-1) ; return 0 ; }
457 2 ModularMix
 
458 2 ModularMix
     // Cast the content of bloc table to Bloc*
459 2 ModularMix
     Bloc* bloc = (Bloc*)MMfetch(m, blocTable, 0) ;
460 2 ModularMix
 
461 2 ModularMix
     char * sname = MMstartstr(m, name);
462 2 ModularMix
     bloc->setName(sname);
463 2 ModularMix
 
464 2 ModularMix
     MMset(m,0,0);
465 2 ModularMix
     
466 2 ModularMix
     #ifdef _SCOL_DEBUG_
467 2 ModularMix
     MMechostr(MSKDEBUG,"ok\n");
468 2 ModularMix
     #endif
469 2 ModularMix
 
470 2 ModularMix
     return 0;
471 2 ModularMix
 }
472 2 ModularMix
</pre>
473 2 ModularMix
474 2 ModularMix
475 2 ModularMix
As explained earlier, we will add the binding of our new functions to the variables used during the registration of the package (when calling *PKhardpak*).
476 2 ModularMix
<pre>
477 2 ModularMix
 //! Nb of Scol functions or types
478 2 ModularMix
 #define NbTplPKG	8
479 2 ModularMix
 
480 2 ModularMix
 /*!
481 2 ModularMix
  * Scol function names
482 2 ModularMix
  **/
483 2 ModularMix
 char* TplName[NbTplPKG] =
484 2 ModularMix
 {
485 2 ModularMix
     "_HelloWorld",
486 2 ModularMix
     "ObjBloc",
487 2 ModularMix
     "_CRbloc",
488 2 ModularMix
     "_DSbloc",
489 2 ModularMix
     "_GETblocValue",
490 2 ModularMix
     "_GETblocName",
491 2 ModularMix
     "_SETblocName",
492 2 ModularMix
     "_SETblocValue"
493 2 ModularMix
 };
494 2 ModularMix
 
495 2 ModularMix
 /*!
496 2 ModularMix
  * Pointers to C functions that manipulate the VM for each scol function previously defined
497 2 ModularMix
  **/
498 2 ModularMix
 int (*TplFunc[NbTplPKG])(mmachine m)=
499 2 ModularMix
 {
500 2 ModularMix
     _HelloWorld,
501 2 ModularMix
     NULL,
502 2 ModularMix
     _CRbloc,
503 2 ModularMix
     _DSbloc,
504 2 ModularMix
     _GETblocValue,
505 2 ModularMix
     _GETblocName,
506 2 ModularMix
     _SETblocName,
507 2 ModularMix
     _SETblocValue
508 2 ModularMix
 };
509 2 ModularMix
 
510 2 ModularMix
 /*!
511 2 ModularMix
  * Nb of arguments of each scol function
512 2 ModularMix
  **/
513 2 ModularMix
 int TplNArg[NbTplPKG]=
514 2 ModularMix
 {
515 2 ModularMix
     0,
516 2 ModularMix
     TYPTYPE,
517 2 ModularMix
     1,
518 2 ModularMix
     1,
519 2 ModularMix
     1,
520 2 ModularMix
     1,
521 2 ModularMix
     2,
522 2 ModularMix
     2
523 2 ModularMix
 };
524 2 ModularMix
 
525 2 ModularMix
 /*!
526 2 ModularMix
  * Prototypes of the scol functions
527 2 ModularMix
  **/
528 2 ModularMix
 char* TplType[NbTplPKG]=
529 2 ModularMix
 {
530 2 ModularMix
     "fun [] I",                                        // _HelloWorld
531 2 ModularMix
     NULL,
532 2 ModularMix
     "fun [Chn] ObjBloc",				// _CRbloc
533 2 ModularMix
     "fun [ObjBloc] I",					// _DSbloc
534 2 ModularMix
     "fun [ObjBloc] I",                                 // _GETblocValue
535 2 ModularMix
     "fun [ObjBloc] S",                                 // _GETblocName
536 2 ModularMix
     "fun [ObjBloc S] I",                               // _SETblocName
537 2 ModularMix
     "fun [ObjBloc I] I"                                // _SETblocValue
538 2 ModularMix
 };
539 2 ModularMix
</pre>
540 2 ModularMix
541 2 ModularMix
542 2 ModularMix
We can now recompile the project and move the generated DLL file to the *plugins* folder of Scol Voyager.
543 2 ModularMix
544 2 ModularMix
545 2 ModularMix
h2. Use of the new data type in Scol
546 2 ModularMix
547 2 ModularMix
In this section, we will explain how to create a Scol program which will be using the *ObjBloc* data type that we have just created.
548 2 ModularMix
The first thing to do is to update the *template.pkg* file, which must still be located in the user partition of Scol Voyager, by adding the following function :
549 2 ModularMix
<pre>
550 2 ModularMix
 /*! \brief Sample main function that show how to use a custom C++ type in Scol.
551 2 ModularMix
  *
552 2 ModularMix
  *  The custom type is defined within a C++ plugin.
553 2 ModularMix
  *  We checks creation of a new instance of the object, setting values in,
554 2 ModularMix
  *  reading the values stored in, and then we manually deleting the instance.
555 2 ModularMix
  *
556 2 ModularMix
  *  <b>Prototype:</b> fun [S I] I
557 2 ModularMix
  *
558 2 ModularMix
  *  \param S : bloc name
559 2 ModularMix
  *  \param I : bloc value
560 2 ModularMix
  *   
561 2 ModularMix
  *  \return I : 0
562 2 ModularMix
  **/
563 2 ModularMix
 fun ObjBlocTest(nameValue, integerValue)=
564 2 ModularMix
     let _CRbloc _channel -> blocInstance in 
565 2 ModularMix
     {
566 2 ModularMix
         // Set ObjBloc properties values
567 2 ModularMix
         _SETblocName blocInstance nameValue;
568 2 ModularMix
         _SETblocValue blocInstance integerValue;    
569 2 ModularMix
 
570 2 ModularMix
         // Check if values where correctly registered and log them on the console
571 2 ModularMix
         _fooS strcatn "Bloc name:  "::(_GETblocName blocInstance)::"\nBloc value: "::(itoa (_GETblocValue blocInstance))::nil;
572 2 ModularMix
 
573 2 ModularMix
         // Manually destroying blocInstance
574 2 ModularMix
         _DSbloc blocInstance;
575 2 ModularMix
     };
576 2 ModularMix
     0;;
577 2 ModularMix
</pre>
578 2 ModularMix
579 2 ModularMix
580 2 ModularMix
Now, let's create a new file in our user partition, named *TestObjBloc.scol*. This program will load the *template.pkg* package that we have just updated, and run the function *ObjBlocTest* by passing to it 2 parameters.
581 2 ModularMix
It's important to notice that in Scol language, to pass an integer as a parameter in a *.scol* file, we must use its hexadecimal representation (in our case, 'ff' stands for '255').
582 2 ModularMix
<pre>
583 2 ModularMix
 _load "template.pkg"
584 2 ModularMix
 ObjBlocTest "newBloc" ff
585 2 ModularMix
</pre>
586 2 ModularMix
587 2 ModularMix
588 2 ModularMix
Now, we can run the Scol program *TestObjBloc.scol*. The log file (usually located in *C:\Users\MyUser\AppData\Local\Scol Voyager\Logs*) should be close to the following lines :
589 2 ModularMix
<pre>
590 2 ModularMix
 Loading C:\Users\Jeff\Documents\Scol Voyager\Partition_LocalUsr\template.pkg ...
591 2 ModularMix
 typechecking
592 2 ModularMix
 fun main : fun [] I
593 2 ModularMix
 fun ObjBlocTest : fun [S I] I
594 2 ModularMix
 Generating bytecodes for 'main'...
595 2 ModularMix
 3 bytes generated (for a total of 375 bytes)
596 2 ModularMix
 Generating bytecodes for 'ObjBlocTest'...
597 2 ModularMix
 79 bytes generated (for a total of 453 bytes)
598 2 ModularMix
 Loading complete
599 2 ModularMix
 
600 2 ModularMix
 
601 2 ModularMix
 > exec: ObjBlocTest "newBloc" ff
602 2 ModularMix
 
603 2 ModularMix
 _CRbloc
604 2 ModularMix
 _CRbloc ...initialization successful
605 2 ModularMix
 _CRbloc ...MMmalloc successful
606 2 ModularMix
 _CRbloc ...object creation successful
607 2 ModularMix
 ok
608 2 ModularMix
 _SETblocName
609 2 ModularMix
 ok
610 2 ModularMix
 _SETblocValue
611 2 ModularMix
 ok
612 2 ModularMix
 _GETblocName
613 2 ModularMix
 ok
614 2 ModularMix
 _GETblocValue
615 2 ModularMix
 ok
616 2 ModularMix
 Bloc name:  newBloc
617 2 ModularMix
 Bloc value: 255
618 2 ModularMix
 _DSbloc
619 2 ModularMix
 Bloc object destroyed.
620 2 ModularMix
 ok
621 1 ModularMix
</pre>