unoidl2.c (9250B)
1 /* 2 This file is part of unoidl2. 3 4 unoidl2 is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation, either version 3 of the License, or 7 (at your option) any later version. 8 9 unoidl2 is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with unoidl2. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include "unoidl2.h" 19 #include "parse.c.h" 20 21 #include <stdlib.h> 22 #include <stdio.h> 23 #include <string.h> 24 25 #define HSIZE 1100000 26 27 #define NCHARA 256 28 29 struct any { 30 enum {CONS, TOKEN, INUM, CHARA, SYM1, SYM2} tag; 31 union { 32 struct { 33 struct any *car; 34 struct any *cdr; 35 } c; 36 struct { 37 Kind kind; 38 struct any *sym1; 39 } t; 40 int inum; 41 } u; 42 }; 43 44 Any heap; 45 int ncells = 0; 46 47 Any xalloc() { 48 Any x = &heap[ncells]; 49 ncells++; 50 if(HSIZE <= ncells) { 51 fprintf(stderr, "Error: heap exhausted\n"); 52 exit(-1); 53 } 54 return x; 55 } 56 57 Any NIL; 58 Any T; 59 60 Any set(Any x, Any v) {return x->u.c.car = v;} 61 Any con(Any x, Any v) {return x->u.c.cdr = v;} 62 63 Any cons(Any car, Any cdr) { 64 Any x = xalloc(); 65 x->tag = CONS; 66 set(x, car); 67 con(x, cdr); 68 return x; 69 } 70 71 static Any chara_from; 72 static Any root1; 73 74 static Any chara(int x) {return &chara_from[x];} 75 76 Any intern1(char *x) { 77 Any p = root1; 78 for(; *x; x++) { 79 Any k = chara(*x); 80 Any r = find(k, cdr(p), equal, caar); 81 if(NIL == r) { 82 con(p, cons(r = list1(cons(k, p)), cdr(p))); 83 r->tag = SYM1; 84 } 85 p = r; 86 } 87 return p; 88 } 89 90 Any mk(Kind kind, char *token) { 91 Any x = xalloc(); 92 x->tag = TOKEN; 93 x->u.t.kind = kind; 94 x->u.t.sym1 = intern1(token); 95 return x; 96 } 97 98 Any mkinum(int n) { 99 Any x = xalloc(); 100 x->tag = INUM; 101 x->u.inum = n; 102 return x; 103 } 104 105 int consp(Any x) {return CONS == x->tag;} 106 Any car(Any x) {return x->u.c.car;} 107 Any cdr(Any x) {return x->u.c.cdr;} 108 Kind kind(Any x) {return x->u.t.kind;} 109 Any sym1(Any x) {return x->u.t.sym1;} 110 int inum(Any x) {return x->u.inum;} 111 Any cons3(Any a, Any b, Any c) {return cons(a, cons(b, c));} 112 Any cons4(Any a, Any b, Any c, Any d) {return cons(a, cons(b, cons(c, d)));} 113 114 Any cons5(Any a, Any b, Any c, Any d, Any e) { 115 return cons(a, cons(b, cons(c, cons(d, e)))); 116 } 117 118 Any cons6(Any a, Any b, Any c, Any d, Any e, Any f) { 119 return cons(a, cons(b, cons(c, cons(d, cons(e, f))))); 120 } 121 122 Any cons7(Any a, Any b, Any c, Any d, Any e, Any f, Any g) { 123 return cons(a, cons(b, cons(c, cons(d, cons(e, cons(f, g)))))); 124 } 125 126 Any list1(Any a) {return cons(a, NIL);} 127 Any list2(Any a, Any b) {return cons3(a, b, NIL);} 128 Any list3(Any a, Any b, Any c) {return cons4(a, b, c, NIL);} 129 Any list4(Any a, Any b, Any c, Any d) {return cons5(a, b, c, d, NIL);} 130 Any list5(Any a, Any b, Any c, Any d, Any e) {return cons6(a, b, c, d, e, NIL);} 131 132 Any list6(Any a, Any b, Any c, Any d, Any e, Any f) { 133 return cons7(a, b, c, d, e, f, NIL); 134 } 135 136 Any nconc2(Any a, Any b) { 137 if(NIL == a) 138 return b; 139 Any x, d; 140 for(x = a, d = cdr(x); NIL != d; x = d, d = cdr(x)); 141 con(x, b); 142 return a; 143 } 144 145 Any cadr(Any x) {return car(cdr(x));} 146 Any cddr(Any x) {return cdr(cdr(x));} 147 Any caddr(Any x) {return car(cdr(cdr(x)));} 148 Any cdddr(Any x) {return cdr(cdr(cdr(x)));} 149 Any cadddr(Any x) {return car(cdr(cdr(cdr(x))));} 150 Any cddddr(Any x) {return cdr(cdr(cdr(cdr(x))));} 151 Any caddddr(Any x) {return car(cdr(cdr(cdr(cdr(x)))));} 152 Any cdddddr(Any x) {return cdr(cdr(cdr(cdr(cdr(x)))));} 153 154 Any caar(Any x) {return car(car(x));} 155 156 int equal_(Any x, Any y) { 157 if(x == y) return 1; 158 if(NIL == x) return NIL == y; 159 switch(x->tag) { 160 case CONS: 161 for(; NIL != x && NIL != y; x = cdr(x), y = cdr(y)) 162 if(!equal_(car(x), car(y))) return 0; 163 return NIL == x && NIL == y; 164 case TOKEN: 165 return TOKEN == y->tag && kind(x) == kind(y) && sym1(x) == sym1(y); 166 case INUM: 167 return INUM == y->tag && inum(x) == inum(y); 168 } 169 return 0; 170 } 171 172 Any equal(Any x, Any y) {return equal_(x, y) ? T : NIL;} 173 174 void print_sym1(Any x) { 175 Any kp = car(x); 176 if(NIL != kp) { 177 Any k = car(kp); 178 Any p = cdr(kp); 179 print_sym1(p); 180 print(k); 181 } 182 } 183 184 static char *print_sym2_sep = "."; 185 186 static void print_sym2(Any x) { 187 Any kpv = car(x); 188 if(NIL != kpv) { 189 Any k = car(kpv); 190 Any p = cadr(kpv); 191 print_sym2(p); 192 if(NIL != car(p)) printf("%s", print_sym2_sep); 193 print_sym1(k); 194 } 195 } 196 197 void print_sym2_custom(Any x, char *sep) { 198 char *s = print_sym2_sep; 199 print_sym2_sep = sep; 200 print_sym2(x); 201 print_sym2_sep = s; 202 } 203 204 Any print(Any x) { 205 if(NIL == x) 206 printf("NIL"); 207 else 208 switch(x->tag) { 209 case CONS: 210 printf("("); 211 print(car(x)); 212 for(Any d = cdr(x); NIL != d; d = cdr(d)) { 213 printf(" "); 214 if(consp(d)) 215 print(car(d)); 216 else { 217 printf(". "); 218 print(d); 219 break; 220 } 221 } 222 printf(")"); 223 break; 224 case TOKEN: 225 print_sym1(sym1(x)); 226 break; 227 case INUM: 228 printf("%d", x->u.inum); 229 break; 230 case CHARA: 231 printf("%c", x->u.inum); 232 break; 233 case SYM1: 234 print_sym1(x); 235 break; 236 case SYM2: 237 print_sym2(x); 238 break; 239 /* default: error? */ 240 } 241 return x; 242 } 243 244 Any some(Fn1 test, Any lst) { 245 for(; NIL != lst; lst = cdr(lst)) { 246 Any x = test(car(lst)); 247 if(NIL != x) return x; 248 } 249 return NIL; 250 } 251 252 Any mapc(Fn1 fn, Any x) { 253 Any z = NIL; 254 for(Any y = x; NIL != y; y = cdr(y)) 255 z = fn(car(y)); 256 return z; 257 } 258 259 Any mapcx(void *env, Any (*fn)(void *env, Any e), Any x) { 260 Any z = NIL; 261 for(Any y = x; NIL != y; y = cdr(y)) 262 z = fn(env, car(y)); 263 return z; 264 } 265 266 Any find(Any elt, Any lst, Fn2 cmp, Fn1 key) { 267 for(; NIL != lst; lst = cdr(lst)) { 268 Any x = car(lst); 269 if(NIL != cmp(elt, key(x))) return x; 270 } 271 return NIL; 272 } 273 274 Any reverse(Any x, Any a) { 275 return NIL == x ? a : reverse(cdr(x), cons(car(x), a)); 276 } 277 278 Any id(Any x) {return x;} 279 280 Any mk_relative(Any x) { 281 Any h = NIL != cdr(x) ? mk(ABSOLUTE, "absolute") : mk(RELATIVE, "relative"); 282 return cons(h, x); 283 //return cons(mk(RELATIVE, "relative"), $1); 284 } 285 286 Any intern2rel(Any k, Any p) { 287 Any r = find(k, cdr(p), equal, caar); 288 if(NIL == r) { 289 con(p, cons(r = list1(list2(k, p)), cdr(p))); 290 r->tag = SYM2; 291 } 292 return r; 293 } 294 295 Any root2; 296 297 Any intern2abs(Any x) { 298 Any p = root2; 299 for(; NIL != x; x = cdr(x)) 300 p = intern2rel(sym1(car(x)), p); 301 return p; 302 } 303 304 Any get2(Any x) {return cddr(car(x));} 305 static Any set2(Any x, Any v) {return con(cdr(car(x)), v);} 306 Any sym2p(Any x) {return cadr(car(x));} 307 Any sym2k(Any x) {return caar(x);} 308 309 310 static Any module2; 311 Any subst2_x; 312 313 static Any subst2(Any v) { 314 Any w; 315 if(consp(v)) { 316 switch(kind(car(v))) { 317 case CONST: 318 w = module2; 319 module2 = sym2p(module2); 320 subst2(caddr(v)); 321 module2 = w; 322 mapc(subst2, cdddr(v)); 323 break; 324 case RELATIVE: //(relative XInterface) 325 w = cdr(v); 326 set(w, intern2rel(sym1(car(w)), module2)); 327 break; 328 case ABSOLUTE: //(absolute com sun star uno XInterface) 329 w = cdr(v); 330 set(w, intern2abs(w)); 331 con(w, NIL); 332 break; 333 default: 334 mapc(subst2, v); 335 } 336 } 337 return v; 338 } 339 340 Any build2(Any x) { 341 Any p, z; 342 switch(kind(car(x))) { 343 case MODULE: 344 p = module2; 345 z = intern2rel(sym1(cadr(x)), p); 346 module2 = z; 347 Any v = get2(z); 348 if(NIL == v) set2(z, car(x)); 349 mapc(build2, cddr(x)); 350 module2 = p; 351 break; 352 case CONSTANTS: 353 p = module2; 354 z = intern2rel(sym1(cadr(x)), p); 355 module2 = z; 356 if(NIL != get2(z)) printf("@@@ build2 error: duplicate "); 357 set(cdr(x), z); 358 set2(z, x); 359 mapc(build2, cdddr(x)); 360 module2 = p; 361 break; 362 case DEFINTERFACE: 363 case EXCEPTION: 364 case ENUM: 365 case SERVICE: 366 case STRUCT: 367 case CONST: 368 case SINGLETON: 369 case TYPEDEF: 370 case DEFTEMPLATE: 371 z = intern2rel(sym1(cadr(x)), module2); 372 if(NIL != get2(z)) printf("@@@ build2 error: duplicate "); 373 set(cdr(x), z); 374 subst2_x = z; 375 set2(z, subst2(x)); 376 break; 377 case INTERFACE: break; // TODO eg XMultiComponentFactory? 378 default: 379 printf("@@@ build2 error: "); 380 print(x); 381 printf("\n"); 382 } 383 return z; 384 } 385 386 Fn1 walk2_fn; 387 388 Any walk2(Any x) { 389 Any c = cdr(x); 390 Any kpv = car(x); 391 Any k = car(kpv); 392 Any p = cadr(kpv); 393 Any v = cddr(kpv); 394 if(NIL == v) { 395 mapc(walk2, c); 396 } else if(MODULE == kind(v)) { 397 mapc(walk2, c); 398 } else if(NIL == c) { 399 walk2_fn(v); 400 } else { 401 if(CONSTANTS != kind(car(v))) { 402 printf("@@@ walk2 error: unexpected children "); 403 print(x); 404 printf("\n"); 405 } 406 walk2_fn(v); 407 } 408 return x; 409 } 410 411 void init() { 412 heap = calloc(HSIZE, sizeof(struct any)); 413 NIL = xalloc(); 414 NIL->tag = CONS; 415 set(NIL, NIL); 416 con(NIL, NIL); 417 for(int i = 0; i < NCHARA; i++) { 418 Any x = mkinum(i); 419 x->tag = CHARA; 420 if(0 == i) chara_from = x; 421 } 422 root1 = list1(NIL); 423 T = xalloc(); 424 T->tag = TOKEN; 425 T->u.t.kind = 0; 426 T->u.t.sym1 = intern1("T"); 427 root2 = list1(NIL); 428 module2 = root2; 429 }