Commit 79647c59789a6223f3b67a0b120b023eb459af59

Authored by Alain Prouté
1 parent 24815e98

fixed a bug on Opaque(...) and in replace.c

anubis_dev/compiler/src/a2a.c
... ... @@ -118,9 +118,18 @@ static void a2a_type(FILE *fp,
118 118 }
119 119 break;
120 120  
121   - case type_struct_ptr: /* (type_struct_ptr . <C struct id>) */
  121 + case type_struct_ptr:
122 122 {
123   - fprintf(fp,"(AnubisType)primitive(_StructPtr(\"%s\"))",name_of_StructPtr[integer_value(cdr(type))]);
  123 + if (consp(cdr(type)))
  124 + { /* (type_struct_ptr <Opaque id> . <name>) */
  125 + fprintf(fp,"(AnubisType)primitive(_StructPtr(_Opaque(\"%s\")))",
  126 + string_content(cdr2(type)));
  127 + }
  128 + else
  129 + { /* (type_struct_ptr . <C struct id>) */
  130 + fprintf(fp,"(AnubisType)primitive(_StructPtr(\"%s\"))",
  131 + name_of_StructPtr[integer_value(cdr(type))]);
  132 + }
124 133 }
125 134 break;
126 135  
... ... @@ -267,7 +276,10 @@ static char * display_string(char * s)
267 276 /* count the characters to replace */
268 277 for (i = 0; i < l; i++)
269 278 {
270   - if (s[i] == '\n' || s[i] == '\r' || s[i] == '\"') n++;
  279 + if ( s[i] == '\n'
  280 + || s[i] == '\r'
  281 + || s[i] == '\"'
  282 + || s[i] == '\\') n++;
271 283 }
272 284 result = (char *)mallocz(l+n+1);
273 285 j = 0;
... ... @@ -276,6 +288,7 @@ static char * display_string(char * s)
276 288 if (s[i] == '\n') { result[i+j] = '\\'; result[i+j+1] = 'n'; j++; }
277 289 else if (s[i] == '\r') { result[i+j] = '\\'; result[i+j+1] = 'r'; j++; }
278 290 else if (s[i] == '\"') { result[i+j] = '\\'; result[i+j+1] = '\"'; j++; }
  291 + else if (s[i] == '\\') { result[i+j] = '\\'; result[i+j+1] = '\\'; j++; }
279 292 else result[i+j] = s[i];
280 293 }
281 294 result[i+j] = 0;
... ...
anubis_dev/compiler/src/compile.c
... ... @@ -1726,14 +1726,22 @@ Expr compile_term(Expr head,
1726 1726 Warning: <i> is not significant and should be removed from 'local'
1727 1727 */
1728 1728 {
1729   - int i = 0;
1730   - while (!(car(car(ctxt)) == second(head)) &&
1731   - !(car(car(ctxt)) == f_micro_ctxt && second(car(ctxt)) == second(head))
  1729 + int i = 0;
  1730 + Expr aux = ctxt;
  1731 + while (!(car(car(aux)) == second(head)) &&
  1732 + !(car(car(aux)) == f_micro_ctxt && second(car(aux)) == second(head))
1732 1733 )
1733   - {
1734   - ctxt = cdr(ctxt);
  1734 + {
  1735 + aux = cdr(aux);
1735 1736 i++;
  1737 + if (aux == nil)
  1738 + {
  1739 + fprintf(errfile,"The symbol '%s' was not found in the context: ",string_content(second(head)));
  1740 + debug(ctxt);
  1741 + anb_exit(1);
  1742 + }
1736 1743 }
  1744 +
1737 1745 //assert(i == integer_value(third(head)));
1738 1746  
1739 1747 code = mcons3(mcons3(peek,second(head),new_integer(i)),
... ...
anubis_dev/compiler/src/interp.c
... ... @@ -2704,7 +2704,12 @@ Expr lambda_interpretations (Expr lc,
2704 2704 return nil;
2705 2705 }
2706 2706  
2707   - result = cons(cons(mcons5(closure,lc,mctxt,lctxt,car(aux)),new_env),
  2707 + result = cons(cons(mcons5(closure,
  2708 + lc,
  2709 + mctxt,
  2710 + lctxt,
  2711 + car(aux)),
  2712 + new_env),
2708 2713 result);
2709 2714 }
2710 2715  
... ... @@ -2951,6 +2956,8 @@ Expr app_interpretations_1(Expr lc,
2951 2956 Expr body = operations[opid].definition;
2952 2957 Expr body_type = operations[opid].target_type;
2953 2958  
  2959 + //debug(body);
  2960 +
2954 2961 /* We also need the list of types which are the values
2955 2962 (found so far) of the parameters, and the list of original
2956 2963 parameters */
... ... @@ -3042,6 +3049,8 @@ Expr app_interpretations_1(Expr lc,
3042 3049 body),
3043 3050 new_env),
3044 3051 result);
  3052 +
  3053 + //debug(result);
3045 3054 }
3046 3055 else
3047 3056 #endif
... ...
anubis_dev/compiler/src/lexer.l
... ... @@ -1233,7 +1233,7 @@ void end_of_par(void)
1233 1233 if (incorrect_pars >= stop_after) anb_exit(1);
1234 1234 }
1235 1235 errors = 0;
1236   - bound_var_count = 0;
  1236 + //bound_var_count = 0;
1237 1237 clean_up_pairs();
1238 1238 more = 0;
1239 1239 ext_com_index = 0;
... ...
anubis_dev/compiler/src/opdef.c
... ... @@ -795,8 +795,8 @@ void check_operation(int opid)
795 795 fprintf(a2a_file," (the type 'AnubisInstance' and related types are defined in section 17 of\n"
796 796 " 'library/predefined.anubis').\n\n");
797 797 fprintf(a2a_file," The purpose of this file is to let you produce anything you want from your program\n"
798   - " (for example, a translation into another language). The root of the module is the\n"
799   - " first element in the list.\n\n");
  798 + " (for example, a translation into another language). The root of the module is\n"
  799 + " described by the first paragraph below.\n\n");
800 800  
801 801  
802 802 collected_type_ids = nil;
... ...
anubis_dev/compiler/src/replace.c
... ... @@ -28,60 +28,104 @@ static Expr fresh_bound_var(void)
28 28 }
29 29  
30 30  
31   - /* Renaming bound variables.
32   - Given an interpretation head, rename_bound all bound variables with fresh system names.
  31 + /**********************************************************************************
  32 + rename_bound_in_decs takes:
  33 +
  34 + decs = ((x . T) (y . U) (z . V) ...) declarations of variables
  35 + dict = ((y . y1) (u . u1) ...) dictionary for changing the names of some variables
  36 +
  37 + and returns:
  38 +
  39 + ((x . T) (y1 . U) (z . V) ...)
  40 +
  41 + i.e. it replaces the names of declared variables according to the dictionary
  42 + */
  43 +static Expr rename_bound_in_decs(Expr decs,
  44 + Expr dict)
  45 +{
  46 + Expr result = nil;
  47 + while (consp(decs))
  48 + {
  49 + Expr dec = car(decs); /* dec = (sym . type) */
  50 + Expr new_name = assoc(car(dec),dict); /* get a remplacement name */
  51 + if (new_name == key_not_found)
  52 + result = cons(dec,result); /* this entry is unchanged */
  53 + else
  54 + result = cons(cons(new_name,cdr(dec)),result); /* this entry is updated: (y . U) becomes (y1 . U) */
  55 + decs = cdr(decs);
  56 + }
  57 + result = reverse(result); /* put them back in the original order */
  58 + return result;
  59 +}
  60 +
  61 +
  62 +
  63 + /******************************************************************************************
  64 + Renaming bound variables.
  65 + Given an interpretation head, rename_bound renames all bound variables with fresh system names.
  66 +
  67 + The dictionary 'dict' gives the correspondance between old names and new names:
  68 +
  69 + dict = ((old_name . new_name) ...)
  70 +
  71 + where each old name was bound in a surrounding expression (but is free in 'head', and must be
  72 + replaced).
33 73 */
34 74 static Expr rename_bound(Expr head, /* the expression within which bound variables must be rename_boundd */
35 75 Expr dict) /* a alist giving the correspondance between old names and new names */
36 76 {
  77 + Expr result = nil;
  78 +
  79 + //debug(head);
  80 +
37 81 switch(car(head))
38 82 {
39 83 case alt_number:
40 84 /* (alt_number <lc> . <head>) */
41 85 {
42   - return mcons3(car(head),second(head),rename_bound(cdr2(head),dict));
  86 + result = mcons3(car(head),second(head),rename_bound(cdr2(head),dict));
43 87 }
44 88 break;
45 89  
46 90 case protect:
47 91 /* (protect <lc> . <head>) */
48 92 {
49   - return mcons3(car(head),second(head),rename_bound(cdr2(head),dict));
  93 + result = mcons3(car(head),second(head),rename_bound(cdr2(head),dict));
50 94 }
51 95 break;
52 96  
53 97 case lock:
54 98 /* (lock <lc> <filename> . <term>) */
55 99 {
56   - return mcons4(car(head),second(head),third(head),rename_bound(cdr3(head),dict));
  100 + result = mcons4(car(head),second(head),third(head),rename_bound(cdr3(head),dict));
57 101 }
58 102 break;
59 103  
60 104 case avm:
61 105 /* (avm <lc> <instr> ...) */
62 106 {
63   - return head;
  107 + result = head;
64 108 }
65 109 break;
66 110  
67 111 case debug_avm:
68 112 /* (debug_avm <lc> . <head>) */
69 113 {
70   - return mcons3(car(head),second(head),rename_bound(cdr2(head),dict));
  114 + result = mcons3(car(head),second(head),rename_bound(cdr2(head),dict));
71 115 }
72 116 break;
73 117  
74 118 case terminal:
75 119 /* (terminal <lc> . <head>) */
76 120 {
77   - return mcons3(car(head),second(head),rename_bound(cdr2(head),dict));
  121 + result = mcons3(car(head),second(head),rename_bound(cdr2(head),dict));
78 122 }
79 123 break;
80 124  
81 125 case operation:
82 126 /* (operation <lc> <opid> <name> <parms> <type> . <types>) */
83 127 {
84   - return head;
  128 + result = head;
85 129 }
86 130 break;
87 131  
... ... @@ -90,91 +134,118 @@ static Expr rename_bound(Expr head, /* the expression within which bound
90 134 <line of macro definition>
91 135 . <head>) */
92 136 {
93   - return head; /* no need to rename_bound here (names are already unique) */
  137 + result = mcons5(macro,
  138 + second(head),
  139 + third(head),
  140 + forth(head),
  141 + rename_bound(cdr4(head),dict));
94 142 }
95 143 break;
96 144  
97 145 case string:
98 146 /* (string <lc> . <string>) */
99 147 {
100   - return head;
  148 + result = head;
101 149 }
102 150 break;
103 151  
104 152 case anb_int32:
105 153 /* (int32 <lc> . <Cint>) */
106 154 {
107   - return head;
  155 + result = head;
108 156 }
109 157 break;
110 158  
111 159 case anb_int_10:
112 160 /* (anb_int_10 <lc> bigit ... bigit) */
113 161 {
114   - return head;
  162 + result= head;
115 163 }
116 164 break;
117 165  
118 166 case anb_int_16:
119 167 /* (anb_int_16 <lc> bigit ... bigit) */
120 168 {
121   - return head;
  169 + result = head;
122 170 }
123 171 break;
124 172  
125 173 case small_datum:
126 174 /* (small_datum <type> . <Cint>) */
127 175 {
128   - return head;
  176 + result = head;
129 177 }
130 178 break;
131 179  
132 180 case word_64:
133 181 /* (word_64 word1 . word0) */
134 182 {
135   - return head;
  183 + result = head;
136 184 }
137 185 break;
138 186  
139 187 case word_128:
140 188 /* (word_128 word3 word2 word1 . word0) */
141 189 {
142   - return head;
  190 + result = head;
143 191 }
144 192 break;
145 193  
146 194 case fpnum:
147 195 /* (fpnum <lc> <int32 mantissa> . <int32 exponent>) */
148 196 {
149   - return head;
  197 + result = head;
150 198 }
151 199 break;
152 200  
153 201 case local:
154   - /* (local <name> <not used> . <type>) */
  202 + /* (local <name> <not used> . <type>)
  203 +
  204 + if name has an entry in dict, we must replace the above by:
  205 +
  206 + (local <new name> <not used> . <type>)
  207 + */
155 208 {
156 209 Expr new_name = assoc(second(head),dict);
157 210 if (new_name == key_not_found)
158   - return head;
  211 + result = head;
159 212 else
160   - return mcons4(local,new_name,third(head),cdr3(head));
  213 + result = mcons4(local,new_name,third(head),cdr3(head));
161 214 }
162 215 break;
163 216  
164 217 case micro_local:
165   - /* (micro_local <name> <not used> <not used> . <type>) */
  218 + /* (micro_local <name> <not used> <not used> . <type>)
  219 + same method as for 'local'
  220 + */
166 221 {
167 222 Expr new_name = assoc(second(head),dict);
168 223 if (new_name == key_not_found)
169   - return head;
  224 + result = head;
170 225 else
171   - return mcons5(micro_local,new_name,third(head),forth(head),cdr4(head));
  226 + result = mcons5(micro_local,new_name,third(head),forth(head),cdr4(head));
172 227 }
173 228 break;
174 229  
175 230 case closure:
176   - /* (closure <lc> (f_micro_ctxt fname ftype (sym . type)...) <args> . <body>)
177   - where <args> is ((sym . type) ...)
  231 + /* (closure <lc> (f_micro_ctxt fname ftype . <micro decs>) <args> . <body>)
  232 + where <micro decs> = ((sym . type) ...)
  233 + where <args> = ((sym . type) ...)
  234 +
  235 + <args> declares the arguments of the function.
  236 +
  237 + The symbols declared in <micro decs> are those which occur in the body of the fonction,
  238 + which are not arguments of the function, and which are present in the evaluation
  239 + context of the function (i.e. they are not global symbols aka. operation names)
  240 +
  241 + When renaming bound variables in this interpretation head we must
  242 +
  243 + (1) replace the symbols in the heads of pairs in <micro decs> using dict.
  244 + (2) create a new name for the name of the function if there is one
  245 + (3) create new names for the arguments of the function
  246 + (4) enlarge dict with the pairs corresponding to the name of the function and the arguments
  247 + (5) replace locals in the body of the function using this enlarged dict
  248 +
178 249 */
179 250 {
180 251 /* Here 'fname' is declared as a variable if not nil and
... ... @@ -185,27 +256,28 @@ static Expr rename_bound(Expr head, /* the expression within which bound
185 256 Expr fname = second(mctxt); /* fname */
186 257 Expr fname1 = nil; /* new fname (if not nil) */
187 258 Expr args1 = nil; /* new <args> */
  259 + Expr dict1 = dict;
188 260  
189 261 if (fname != nil)
190 262 {
191 263 fname1 = fresh_bound_var();
192   - dict = cons(cons(fname,fname1),dict);
  264 + dict1 = cons(cons(fname,fname1),dict1);
193 265 }
194 266  
195 267 while (consp(args))
196 268 {
197 269 Expr new_name = fresh_bound_var();
198 270 args1 = cons(cons(new_name,cdr(car(args))),args1); /* constructing the new <args> */
199   - dict = cons(cons(car(car(args)),new_name),dict); /* enriching the dictionary */
  271 + dict1 = cons(cons(car(car(args)),new_name),dict1); /* enriching the dictionary */
200 272 args = cdr(args);
201 273 }
202 274 args1 = reverse(args1); /* put them back in the right order */
203 275  
204   - return mcons5(closure,
205   - second(head),
206   - mcons3(f_micro_ctxt,fname1,cdr2(mctxt)),
207   - args1,
208   - rename_bound(cdr4(head),dict));
  276 + result = mcons5(closure,
  277 + second(head),
  278 + mcons3(f_micro_ctxt,fname1,rename_bound_in_decs(cdr2(mctxt),dict)),
  279 + args1,
  280 + rename_bound(cdr4(head),dict1));
209 281 }
210 282 break;
211 283  
... ... @@ -219,7 +291,7 @@ static Expr rename_bound(Expr head, /* the expression within which bound
219 291 f_and_args1 = cons(rename_bound(car(f_and_args),dict),f_and_args1);
220 292 f_and_args = cdr(f_and_args);
221 293 }
222   - return mcons3(app, second(head), reverse(f_and_args1));
  294 + result = mcons3(app, second(head), reverse(f_and_args1));
223 295 }
224 296 break;
225 297  
... ... @@ -257,7 +329,7 @@ static Expr rename_bound(Expr head, /* the expression within which bound
257 329 }
258 330 cases1 = reverse(cases1); /* put the new cases in the right order */
259 331  
260   - return mcons4(cond,
  332 + result = mcons4(cond,
261 333 second(head),
262 334 rename_bound(third(head),dict),
263 335 cases1);
... ... @@ -283,13 +355,13 @@ static Expr rename_bound(Expr head, /* the expression within which bound
283 355 resurg = cdr(resurg);
284 356 }
285 357 resurg1 = reverse(resurg1);
286   - return mcons7(select_cond_interp,
287   - second(head),
288   - rename_bound(third(head),dict),
289   - forth(head),
290   - cons(car(fifth(head)),resurg1),
291   - rename_bound(sixth(head),dict1),
292   - rename_bound(cdr6(head),dict));
  358 + result = mcons7(select_cond_interp,
  359 + second(head),
  360 + rename_bound(third(head),dict),
  361 + forth(head),
  362 + cons(car(fifth(head)),resurg1),
  363 + rename_bound(sixth(head),dict1),
  364 + rename_bound(cdr6(head),dict));
293 365 }
294 366 break;
295 367  
... ... @@ -297,143 +369,151 @@ static Expr rename_bound(Expr head, /* the expression within which bound
297 369 /* (with <lc> <symbol> <int head> . <int head>) */
298 370 {
299 371 Expr new_name = fresh_bound_var();
300   - return mcons5(with,
301   - second(head),
302   - new_name,
303   - rename_bound(forth(head),dict),
304   - rename_bound(cdr4(head),cons(cons(third(head),new_name),dict)));
  372 + result = mcons5(with,
  373 + second(head),
  374 + new_name,
  375 + rename_bound(forth(head),dict),
  376 + rename_bound(cdr4(head),cons(cons(third(head),new_name),dict)));
305 377 }
306 378 break;
307 379  
308 380 case anb_read:
309 381 /* (anb_read <lc> . <conn>) */
310 382 {
311   - return mcons3(car(head),second(head),rename_bound(cdr2(head),dict));
  383 + result = mcons3(car(head),second(head),rename_bound(cdr2(head),dict));
312 384 }
313 385 break;
314 386  
315 387 case anb_write:
316 388 /* (anb_write <lc> <conn> . <value>) */
317 389 {
318   - return mcons4(anb_write,
319   - second(head),
320   - rename_bound(third(head),dict),
321   - rename_bound(cdr3(head),dict));
  390 + result = mcons4(anb_write,
  391 + second(head),
  392 + rename_bound(third(head),dict),
  393 + rename_bound(cdr3(head),dict));
322 394 }
323 395 break;
324 396  
325 397 case anb_exchange:
326 398 /* (anb_exchange <lc> <conn> . <value>) */
327 399 {
328   - return mcons4(anb_exchange,
329   - second(head),
330   - rename_bound(third(head),dict),
331   - rename_bound(cdr3(head),dict));
  400 + result = mcons4(anb_exchange,
  401 + second(head),
  402 + rename_bound(third(head),dict),
  403 + rename_bound(cdr3(head),dict));
332 404 }
333 405 break;
334 406  
335 407 case wait_for:
336 408 /* (wait_for <lc> <head (cond)> <head (msecs)> . <head (after)>) */
337 409 {
338   - return mcons5(wait_for,
339   - second(head),
340   - rename_bound(third(head),dict),
341   - rename_bound(forth(head),dict),
342   - rename_bound(cdr4(head),dict));
  410 + result = mcons5(wait_for,
  411 + second(head),
  412 + rename_bound(third(head),dict),
  413 + rename_bound(forth(head),dict),
  414 + rename_bound(cdr4(head),dict));
343 415 }
344 416 break;
345 417  
346 418 case delegate:
347 419 /* (delegate <lc> <head (delegated)> . <head (body)>) */
348 420 {
349   - return mcons4(delegate,
350   - second(head),
351   - rename_bound(third(head),dict),
352   - rename_bound(cdr3(head),dict));
  421 + result = mcons4(delegate,
  422 + second(head),
  423 + rename_bound(third(head),dict),
  424 + rename_bound(cdr3(head),dict));
353 425 }
354 426 break;
355 427  
356 428 case delegatep:
357 429 /* (delegatep <lc> <head priority> <head (delegated)> . <head (body)>) */
358 430 {
359   - return mcons5(delegatep,
360   - second(head),
361   - rename_bound(third(head),dict),
362   - rename_bound(forth(head),dict),
363   - rename_bound(cdr4(head),dict));
  431 + result = mcons5(delegatep,
  432 + second(head),
  433 + rename_bound(third(head),dict),
  434 + rename_bound(forth(head),dict),
  435 + rename_bound(cdr4(head),dict));
364 436 }
365 437 break;
366 438  
367 439 case serialize:
368 440 /* (serialize <lc> . <term>) */
369 441 {
370   - return mcons3(car(head),second(head),rename_bound(cdr2(head),dict));
  442 + result = mcons3(car(head),second(head),rename_bound(cdr2(head),dict));
371 443 }
372 444 break;
373 445  
374 446 case tempserialize:
375 447 /* (tempserialize <lc> . <term>) */
376 448 {
377   - return mcons3(car(head),second(head),rename_bound(cdr2(head),dict));
  449 + result = mcons3(car(head),second(head),rename_bound(cdr2(head),dict));
378 450 }
379 451 break;
380 452  
381 453 case unserialize:
382 454 /* (unserialize <lc> <type> . <head>) */
383 455 {
384   - return mcons4(unserialize,second(head),third(head),rename_bound(cdr3(head),dict));
  456 + result = mcons4(unserialize,second(head),third(head),rename_bound(cdr3(head),dict));
385 457 }
386 458 break;
387 459  
388 460 case tempunserialize:
389 461 /* (tempunserialize <lc> <type> . <head>) */
390 462 {
391   - return mcons4(tempunserialize,second(head),third(head),rename_bound(cdr3(head),dict));
  463 + result = mcons4(tempunserialize,second(head),third(head),rename_bound(cdr3(head),dict));
392 464 }
393 465 break;
394 466  
395 467 case bit_width:
396 468 /* (bit_width . <type>) */
397 469 {
398   - return head;
  470 + result = head;
399 471 }
400 472 break;
401 473  
402 474 case indirect_type:
403 475 /* (indirect_type . <type>) */
404 476 {
405   - return head;
  477 + result = head;
406 478 }
407 479 break;
408 480  
409 481 case vcopy:
410 482 /* (vcopy n . v) */
411 483 {
412   - return mcons3(vcopy,rename_bound(second(head),dict),rename_bound(cdr2(head),dict));
  484 + result = mcons3(vcopy,rename_bound(second(head),dict),rename_bound(cdr2(head),dict));
413 485 }
414 486 break;
415 487  
416 488 case type_desc_interp:
417 489 /* (type_desc_interp <lc> . <type>) */
418 490 {
419   - return head;
  491 + result = head;
420 492 }
421 493 break;
422 494  
423 495 case byte_array:
424 496 /* (byte_array <lc> <byte> ...) */
425 497 {
426   - return head;
  498 + result = head;
427 499 }
428 500 break;
429 501  
430 502 default: assert(0);
431 503 }
  504 +
  505 + //debug(result);
  506 +
  507 + return result;
432 508 }
433 509  
434 510  
435 511  
436   - /* The replacement auxiliary function */
  512 + /********************************************************************************************************
  513 +
  514 + The replacement auxiliary function
  515 +
  516 + */
437 517  
438 518 static Expr replace_aux(Expr head, /* where bound variables are already renamed */
439 519 Expr alist) /* ((sym . value) ...) replace sym by value ... */
... ...
anubis_dev/library/predefined.anubis
... ... @@ -5542,10 +5542,6 @@ public type AnubisType:
5542 5542 List(AnubisType) operands). // or: Result(Error,$T)
5543 5543 // but also: Bool (with an empty list of operands)
5544 5544  
5545   -public type AnubisArg: // used for components of alternatives, resurgent symbols and arguments of functions
5546   - arg (AnubisType type,
5547   - String name).
5548   -
5549 5545 public type AnubisComponent:
5550 5546 comp (AnubisType type), // anonymous component
5551 5547 comp (AnubisType type,
... ... @@ -5564,6 +5560,10 @@ public type AnubisAlternative:
5564 5560  
5565 5561 public type AnubisTerm:... // defined below
5566 5562  
  5563 +public type AnubisArg:
  5564 + arg (AnubisType type,
  5565 + String name).
  5566 +
5567 5567 public type AnubisCase: // case in a conditional
5568 5568 _case (String name,
5569 5569 List(AnubisArg) resurgent_symbols,
... ... @@ -5623,57 +5623,11 @@ public type AnubisScope:
5623 5623 private,
5624 5624 public.
5625 5625  
5626   - We also represent implementations of types as they are computed by the Anubis compiler.
5627   -
5628   -public type AnubisCompImplementation: // Implementation of a component (of an alternative)
5629   - comp (Int component_type_id, // unique id of type instance of component
5630   - Int offset, // offset of component in the memory segment
5631   - Int width). // width of component (see explanations below).
5632   -
5633   - Note: small types may have only small alternatives
5634   - mixed types may have small and mixed alternatives
5635   - large types may have only large alternatives
5636   -
5637   - For a small alternative <offset> and <width> represent:
5638   -
5639   - <offset> number of bits below argument bit field (including index field)
5640   - <width> width of bit field (in bits)
5641   -
5642   - For a mixed alternative:
5643   -
5644   - <offset> number of bytes above reference counter of data segment
5645   - <width> width of fields in bytes
5646   -
5647   - For a large alternative:
5648   -
5649   - <offset> number of bytes above index field in data segment
5650   - <width> width of field in bytes
5651   -
5652   -
5653   -public type AnubisAltImplementation: // implementation of an alternative
5654   - small_alt (List(AnubisCompImplementation) components),
5655   - mixed_alt (List(AnubisCompImplementation) components),
5656   - large_alt (List(AnubisCompImplementation) components).
5657   -
5658   -public type AnubisImplementation: // Implementation of a type as computed by the Anubis compiler
5659   - primitive_type (AnubisPrimitiveType),
5660   - // the implementation of primitive types is decribed in the documentation
5661   - small_type (Int nalt, // number of alternatives
5662   - Int index_bit_width, // bit width for storing the indexes of alternatives
5663   - List(AnubisAltImplementation) alternatives),
5664   - mixed_type (Int nalt, // number of alternatives
5665   - Int index_bit_width, // bit width for storing the indexes of alternatives
5666   - List(AnubisAltImplementation) alternatives),
5667   - large_type (Int nalt, // number of alternatives
5668   - Int index_bit_width, // bit width for storing the indexes of alternatives
5669   - List(AnubisAltImplementation) alternatives),
5670   - functional_type.
5671 5626  
5672 5627 public type AnubisTypeInstance:
5673   - type (Int id, // unique id of instance of type
5674   - AnubisType the_type, // description of type
5675   - Maybe(List(AnubisAlternative)) alternatives, // alternatives if it is a sum type
5676   - AnubisImplementation implementation). // implementation of type as computed by the by Anubis compiler
  5628 + type (Int id, // unique id of instance of type
  5629 + AnubisType the_type, // description of type
  5630 + Maybe(List(AnubisAlternative)) alternatives). // alternatives if it is a sum type
5677 5631  
5678 5632 public type AnubisDatumInstance:
5679 5633 constructor (Int id, // unique id of constructor
... ...
anubis_dev/manuals/en/Anubis-doc-1-13.pdf
No preview for this file type
anubis_dev/manuals/en/Anubis-doc-1-13.tex
... ... @@ -2837,7 +2837,7 @@ how to use a formater. The subsequent sections explain how to write down a forma
2837 2837  
2838 2838 In these explanations we assume that the target language is the language C. We also assume of course
2839 2839 that you have an Anubis project containing a ``global'' paragraph whose name is \code{my\_program}, and that
2840   -you have already produced the file \code{my\_program.a2a} by using the option \code{.a2a} of the
  2840 +you have already produced the file \code{my\_program.a2a} by using the option \code{-a2a} of the
2841 2841 Anubis compiler.
2842 2842  
2843 2843 In order to produce the file \code{my\_program.c} containing your project written in the C language,
... ... @@ -2848,19 +2848,21 @@ create an Anubis file containing this~:
2848 2848 read my_program.a2a use the data produced by the compiler
2849 2849 read a2a/C/formater.anubis use the formater for the language C
2850 2850  
2851   - Produce the module which will produce your C source file:
  2851 + Define the module which will produce your C source file:
2852 2852 global define One
2853   - make_my_C_source
  2853 + make_my_C_source // chose this name freely
2854 2854 (
2855 2855 List(String) args // not used
2856 2856 ) =
2857   - format(my_program).
  2857 + format("my_program.c",
  2858 + my_program_types,
  2859 + my_program_data).
2858 2860  
2859 2861 and execute it:
2860 2862 execute anbexec make_my_C_source
2861 2863 \end{verbatim}
2862 2864 }
2863   -That's all~!
  2865 +That's all~! The file \fn{my\_program.c} is created and contains the desired C source.
2864 2866  
2865 2867 This will not fail with the C language because the C formater is able to translate all of Anubis, but this may fail
2866 2868 for another formater (which maybe needs to be enhanced, but of course, enhancing a formater requires
... ... @@ -2888,8 +2890,7 @@ As an example, here is the definition of \code{AnubisTypeInstance}~:
2888 2890 public type AnubisTypeInstance:
2889 2891 type (Int id,
2890 2892 AnubisType the_type,
2891   - Maybe(List(AnubisAlternative)) alternatives,
2892   - AnubisImplementation implementation).
  2893 + Maybe(List(AnubisAlternative)) alternatives).
2893 2894 \end{verbatim}
2894 2895 }
2895 2896 This shows how a datum of type \code{AnubisTypeInstance} decribes an instance of an Anubis type definition.
... ... @@ -2903,9 +2904,6 @@ type \code{AnubisType}.
2903 2904 \item The component \code{alternatives} may have the value \code{failure}, meaning that the type is not defined
2904 2905 by a paragraph. It is either a primitive type or a functional type. If the value of this component is
2905 2906 \code{success(l)}, then \code{l} describes the alternatives of the type definition. See below for the details.
2906   -\item The component \code{implementation} describes how the Anubis compiler implements the type. This is more technical,
2907   -but may be useful for translating the type description into a type definition in another language. For example,
2908   -this is used by the C formater. The details of this description are given below in section \myref{sec:implementation}.
2909 2907 \end{liste}
2910 2908 For example, we have the following paragraph in \fn{library/a2a/example.a2a}~:
2911 2909 {\color{codecolor}
... ... @@ -2917,12 +2915,7 @@ define AnubisTypeInstance a2at_5 =
2917 2915 [comp((AnubisType)primitive(_String))]),
2918 2916 alt("alt2",
2919 2917 [comp((AnubisType)primitive(_Int),"x"),
2920   - comp((AnubisType)primitive(_String),"s")])]),
2921   - mixed_type((Int)002,
2922   - (Int)002,
2923   - [mixed_alt([comp((Int)0,(Int)0,(Int)4)]),
2924   - mixed_alt([comp((Int)3,(Int)0,(Int)4),
2925   - comp((Int)0,(Int)4,(Int)4)])])).
  2918 + comp((AnubisType)primitive(_String),"s")])])).
2926 2919 \end{verbatim}
2927 2920 }
2928 2921 which describes the type definition~:
... ... @@ -2958,94 +2951,206 @@ public type AnubisDatumInstance:
2958 2951 \begin{liste}
2959 2952 \item The alternative \code{constructor} is used for describing constructors of defined types.
2960 2953 In our example, the type \code{ExampleType} has two constuctors whose names are \code{alt1} and \code{alt2}.
2961   -\end{liste}
2962   -
2963   -\suc
2964   -
2965   -
2966   -\subsubsection{Instances of Anubis paragraphs}
2967   -An Anubis source file is mainly (as you already know) a sequence of paragraphs. Some of these
2968   -paragraphs are ``schemas'', i.e. contain types parameters (such as \code{\$T}). ``Instanciating
2969   -a schema'' means replacing the type parameters by actual types. For example, the definition of \code{List} is
2970   -a schema whose parameter represents the type of elements in the lists. This schema can be instanciated
2971   -as \code{List(String)} or as \code{List(Int)} or as \code{List(T)} where \code{T} is any type.
2972   -Similarly, the function \code{length} computing the length of a list is a schema, since it can compute
2973   -the length of a list whose elements have any possible type.
2974   -
2975   -A type parameter cannot be implemented (i.e. it cannot receive an actual representation method in computer memory) since we don't know
2976   -anything about this type. Only instances of types can be implemented. Similarly, only instances of functions (and
2977   -other data) can be compiled. A module file (\code{.adm}) contains only compilations of instances of data.
2978   -
2979   -What the \code{.a2a} file contains is an intermediary representation of the module, precisely the state
2980   -of the module when it is already checked as a correct program, and eveything is appropriately instanciated,
2981   -but not yet transformed into a sequence
2982   -of Anubis virtual machine instructions. Furthermore, these instances are presented in the \code{.a2a} file in the form
2983   -of Anubis data, hence easily usable by way of an Anubis program. In order to let you understand precisely
2984   -what I mean by ``in the form of Anubis data'', here is an example. The following is the content of the file
2985   -\fn{library/a2a/example.anubis}~:
  2954 +Again, each datum instance is identified by a unique integer. Here is the paragraph describing \code{alt1}
  2955 +in \fn{library/a2a/example.a2a}~:
  2956 +{\color{codecolor}
  2957 +\begin{verbatim}
  2958 + /* constructor 'alt1', type: ((String) -> ExampleType) */
  2959 +define AnubisDatumInstance a2ad_6 =
  2960 + constructor(6,
  2961 + "alt1",
  2962 + [(AnubisType)primitive(_String)],
  2963 + instance((Int)5,"ExampleType",[])).
  2964 +\end{verbatim}
  2965 +}
  2966 +The file \code{example.a2a} does not contain a description of \code{alt2}. This is normal, since the ``global''
  2967 +paragraph in \fn{library/a2a/example.anubis}~:
2986 2968 {\color{codecolor}
2987 2969 \begin{verbatim}
2988   - A simple type:
2989   -
2990   -type ExampleType:
2991   - alt1(String),
2992   - alt2(Int x, String s).
2993   -
2994   - A simple (secondary) module:
2995   -
2996 2970 global define ExampleType
2997 2971 example
2998 2972 =
2999 2973 alt1("Hello").
3000 2974 \end{verbatim}
3001 2975 }
3002   -We compile this file with the option \code{-a2a} and we obtain the file
3003   -\fn{library/a2a/example.a2a} which contains the unique paragraph (plus initial comments
3004   -not reproduced here)~:
  2976 +does not make use of the constructor \code{alt2}.
  2977 +
  2978 +\item The alternative \code{primitive} describes a primitive function. The only informations are the name and the type.
  2979 +The identifier may change from one version of Anubis to another one, because it depends on the design of the
  2980 +file \fn{predef.anubis}. However, it is sure that not two distinct primitive can have the same name and the same
  2981 +type, and these data are less likely to change with versions of Anubis. Hence, these informations should preferably be used
  2982 +by a formater. Anyway, if the file \fn{predef.anubis} is enhanced, it is likely that the formaters must be enhanced
  2983 +accordingly.
  2984 +
  2985 +\item The alternative \code{datum} describes an instance of a definition of datum. The informations on such an instance
  2986 +are the following~:
  2987 + \begin{liste}
  2988 + \item The unique identifier \code{id}.
  2989 + \item The name of the datum defined.
  2990 + \item The path of the file where it is defined (this informations may become a comment in the source
  2991 + file of the target language).
  2992 + \item The line at which it is defined.
  2993 + \item The scope of the definition, which can be either \code{private} or \code{public}. Notice that
  2994 + there is no information such as \code{macro} of \code{inline}. This is because since we are
  2995 + describing only instances of paragraphs, all references to a macro or an inline function are
  2996 + already replaced by the bodies of these definition. Hence, in the \code{.a2a} file (and also
  2997 + of course in the \code{.adm} file, the macros and inline functions have ``vanished''.
  2998 + \item The target type of the definition instance.
  2999 + \item The list of argument declarations, each one in the form \code{arg(\sconcept{type},\sconcept{name})}.
  3000 + \item The description of the (instanciated) body of the definition.
  3001 + \end{liste}
  3002 +
  3003 +\end{liste}
  3004 +
  3005 +
  3006 +\subsubsection{Description of types}
  3007 +The following types are used for describing Anubis types~:
3005 3008 {\color{codecolor}
3006 3009 \begin{verbatim}
3007   -public define NonEmptyList(AnubisInstance) example =
3008   - [
3009   - /* 'example' in '.../library/a2a/example.anubis' at line 10 */
3010   - (AnubisInstance)datum(1309,
3011   - "example",
3012   - ".../library/a2a/example.anubis",
3013   - 10,
3014   - _apply(_operation("alt1",1307),
3015   - [_string("Hello")])),
3016   -
3017   - /* type 'ExampleType' */
3018   - (AnubisInstance)type(5,
3019   - instance(178,"ExampleType",[]),
3020   - success([alt("alt1",
3021   - [comp(primitive(_String))]),
3022   - alt("alt2",
3023   - [comp(primitive(_Int),"x"),
3024   - comp(primitive(_String),"s")])]),
3025   - [mixed_type])
3026   - ].
  3010 +public type AnubisType:...
  3011 +
  3012 +public type AnubisPrimitiveType:
  3013 + _ByteArray,
  3014 + _Float,
  3015 + _Int,
  3016 + _Listener,
  3017 + _MVar (AnubisType),
  3018 + _RStream,
  3019 + _RWStream,
  3020 + _String,
  3021 + _StructPtr (String name),
  3022 + _Var (AnubisType),
  3023 + _WStream.
  3024 +
  3025 +public type AnubisType:
  3026 + parameter (String name),
  3027 + primitive (AnubisPrimitiveType),
  3028 + functional (List(AnubisType) sources,
  3029 + AnubisType target),
  3030 + instance (Int id,
  3031 + String name,
  3032 + List(AnubisType) operands).
  3033 +
  3034 +public type AnubisComponent:
  3035 + comp (AnubisType type),
  3036 + comp (AnubisType type,
  3037 + String name).
  3038 +
  3039 +public type AnubisAlternative:
  3040 + alt (String name,
  3041 + List(AnubisComponent) components).
3027 3042 \end{verbatim}
3028 3043 }
3029   -As you see, \code{example} is defined here as a list of two ``Anubis Instances'', i.e. instances of paragraphs.
3030   -Notice that the number of instances in the \code{.a2a} file has nothing to do
3031   -with the number of paragraphs in the source file, and this for many reasons. First of all, the \code{.a2a} file does not
3032   -represent the source file, but the module defined by the ``global'' paragraph. In particular, if the compiler encounters
3033   -several ``global'' paragraphs, it produces several \code{.a2a} files. Also, in an \code{.a2a} file, you can find
3034   -instances of paragraphs located in other files than the file the name of which is on the Anubis compiler command line,
3035   -because of the \code{read} and \code{transmit} keywords. Finally, a single paragraph may produce several instances
3036   -in a single module, hence several instances in a single \code{.a2a} file.
3037 3044  
3038   -Nevertheless, what you see above is that the \code{.a2a} file presents instances in the form which is the easiest
3039   -for doing something with them, namely as Anubis text.
3040 3045  
3041   -Now, in order to decipher the above example, we need to discuss the types used in \code{.a2a} files.
  3046 +\subsubsection{Description of data}
  3047 +The following types are used for describing Anubis terms~:
  3048 +{\color{codecolor}
  3049 +\begin{verbatim}
  3050 +public type AnubisTerm:...
  3051 +
  3052 +public type AnubisArg:
  3053 + arg (AnubisType type,
  3054 + String name).
  3055 +
  3056 +public type AnubisCase:
  3057 + _case (String name,
  3058 + List(AnubisArg) resurgent_symbols,
  3059 + AnubisTerm body).
  3060 +
  3061 +public type AnubisTerm:
  3062 + _apply (AnubisTerm function,
  3063 + List(AnubisTerm) arguments),
  3064 + _byte_array (ByteArray content),
  3065 + _cond (AnubisTerm test,
  3066 + List(AnubisCase) cases),
  3067 + _integer (Int value),
  3068 + _delegate (AnubisTerm priority,
  3069 + AnubisTerm delegated,
  3070 + AnubisTerm body),
  3071 + _float (Float value),
  3072 + _function (List(AnubisArg) arguments,
  3073 + Maybe(String) function_name,
  3074 + AnubisTerm body),
  3075 + _micro_symbol(String name),
  3076 + _of_type (AnubisType type,
  3077 + AnubisTerm term),
  3078 + _operation (String name,
  3079 + Int id),
  3080 + _protect (AnubisTerm protected),
  3081 + _read (AnubisTerm v),
  3082 + _select_cond (AnubisTerm test,
  3083 + Int index_of_selected,
  3084 + AnubisCase selected_case,
  3085 + AnubisTerm default),
  3086 + _serialize (AnubisTerm term),
  3087 + _small_datum (AnubisType type,
  3088 + Int value),
  3089 + _string (String value),
  3090 + _symbol (String name),
  3091 + _type_desc (AnubisType type),
  3092 + _unserialize (AnubisType type,
  3093 + AnubisTerm byte_array),
  3094 + _wait_for (AnubisTerm condition,
  3095 + AnubisTerm body),
  3096 + _with (String symbol,
  3097 + AnubisTerm value,
  3098 + AnubisTerm body),
  3099 + _write (AnubisTerm v,
  3100 + AnubisTerm value).
  3101 +\end{verbatim}
  3102 +}
  3103 +
  3104 +
  3105 +
3042 3106  
3043   -\subsubsection{Implementations of types}\mylabel{sec:implementation}
3044   -\suc
3045 3107  
3046 3108 \subsubsection{Primitives}
3047 3109 \suc
3048 3110  
  3111 +
  3112 +\subsubsection{Designing a formater}
  3113 +If you want to create a new formater, the easiest is probably to begin by having a look
  3114 +at the C formater in the file \fn{library/a2a/C/formater.anubis}. In parallel,
  3115 +you should read the present section.
  3116 +
  3117 +From now on, we assume that the name of the module (and of the \code{.a2a} file) is \code{my\_program}. We also
  3118 +assume in these explanations that the target language is the language C, but the principles are valid for
  3119 +any target language.
  3120 +Since we manipulate only instance of types and data, we will simply say ``type'' instead of ``instance of type'',
  3121 +and similarly for data.
  3122 +
  3123 +In the file \code{my\_program.a2a} there are only two public paragraphs, and they are defined like this~:
  3124 +{\color{codecolor}
  3125 +\begin{verbatim}
  3126 +public define List(AnubisTypeInstance) my_program_types =
  3127 + [
  3128 + ...
  3129 + ].
  3130 +
  3131 +public define List(AnubisDatumInstance) my_program_data =
  3132 + [
  3133 + ...
  3134 + ].
  3135 +\end{verbatim}
  3136 +}
  3137 +The first one gives the list of the representations of all types, and the second one the list
  3138 +of the representations of all data. These two lists, together with the name you want to give to the C file,
  3139 + are given as arguments to the function \code{format} which must be
  3140 +of type~:
  3141 +\begin{ccode}
  3142 + (String,List(AnubisTypeInstance),List(AnubisDatumInstance)) -> One
  3143 +\end{ccode}
  3144 +The role of format is to create a new file named \code{my\_program.c} and to write into it the C translation
  3145 +of the data found in the two lists.
  3146 +
  3147 +The first thing to do is to translate type descriptions into types of the target language. This is of course possible
  3148 +for C, but maybe more problematic for an untyped language. In this last case, you must decide for a format
  3149 +of data, which is mainly the same thing as defining a type, except that the compiler of the target will not check
  3150 +these types. They will be checked only at run time.
  3151 +
  3152 +
  3153 +
3049 3154 \section{The Anubis Library}
3050 3155  
3051 3156 \subsection{Overview}
... ...