Commit 79647c59789a6223f3b67a0b120b023eb459af59
1 parent
24815e98
fixed a bug on Opaque(...) and in replace.c
Showing
9 changed files
with
399 additions
and
230 deletions
Show diff stats
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
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} | ... | ... |