~ubuntu-branches/ubuntu/precise/dicelab/precise

« back to all changes in this revision

Viewing changes to roll.tc

  • Committer: Bazaar Package Importer
  • Author(s): Robert Lemmen
  • Date: 2007-12-10 17:06:15 UTC
  • Revision ID: james.westby@ubuntu.com-20071210170615-q1av8grz0vjiv397
Tags: upstream-0.5
ImportĀ upstreamĀ versionĀ 0.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
%operation %virtual struct roll_value *roll(expression *this)
 
2
 
 
3
roll(elist)
 
4
{
 
5
        struct roll_value *rv = new_roll_single(0);
 
6
        rv->count = 0;
 
7
        return rv;
 
8
}
 
9
 
 
10
roll(number)
 
11
{
 
12
        struct roll_value *rv = new_roll_single(this->num);
 
13
        return rv;
 
14
}
 
15
 
 
16
roll(mathop)
 
17
{
 
18
        struct roll_value *rv1 = roll(this->expr1);
 
19
        struct roll_value *rv2 = roll(this->expr2);
 
20
        if (rv1->count != 1) {
 
21
                yyerror("Argument 1 to math op isn't scalar");
 
22
                free_roll(rv2);
 
23
                rv1->count = 1;
 
24
                rv1->values[0] = 0;
 
25
                return rv1;
 
26
        }
 
27
        if (rv2->count != 1) {
 
28
                yyerror("Argument 2 to math op isn't scalar");
 
29
                free_roll(rv2);
 
30
                rv1->count = 1;
 
31
                rv1->values[0] = 0;
 
32
                return rv1;
 
33
        }
 
34
        switch (yykind(this)) {
 
35
                case plus_kind:
 
36
                        rv1->values[0] += rv2->values[0];
 
37
                        break;
 
38
                case minus_kind:
 
39
                        rv1->values[0] -= rv2->values[0];
 
40
                        break;
 
41
                case multi_kind:
 
42
                        rv1->values[0] *= rv2->values[0];
 
43
                        break;
 
44
                case divi_kind:
 
45
                        rv1->values[0] /= rv2->values[0];
 
46
                        break;
 
47
                case mod_kind:
 
48
                        rv1->values[0] %= rv2->values[0];
 
49
                        break;
 
50
                case expo_kind:
 
51
                        rv1->values[0] = (int) pow(rv1->values[0], rv2->values[0]);
 
52
                        break;
 
53
                default:
 
54
                        yyerror("Unknown math op");
 
55
                        
 
56
        }
 
57
 
 
58
        free_roll(rv2);
 
59
        return rv1;
 
60
}
 
61
 
 
62
/* XXX scat could also be a math op */
 
63
roll(scat)
 
64
{
 
65
        struct roll_value *rv1 = roll(this->expr1);
 
66
        struct roll_value *rv2 = roll(this->expr2);
 
67
        if (rv1->count != 1) {
 
68
                yyerror("Argument 1 to scat (.) isn't scalar");
 
69
                free_roll(rv2);
 
70
                rv1->count = 1;
 
71
                rv1->values[0] = 0;
 
72
                return rv1;
 
73
        }
 
74
        if (rv2->count != 1) {
 
75
                yyerror("Argument 2 to scat (.) isn't scalar");
 
76
                free_roll(rv2);
 
77
                rv1->count = 1;
 
78
                rv1->values[0] = 0;
 
79
                return rv1;
 
80
        }
 
81
        int i = 10;
 
82
        while (i < rv2->values[0]) {
 
83
                i *= 10;
 
84
        }
 
85
        rv1->values[0] *= i;
 
86
        rv1->values[0] += rv2->values[0];
 
87
        free_roll(rv2);
 
88
        return rv1;
 
89
}
 
90
 
 
91
roll(range)
 
92
{
 
93
        int i;
 
94
        int c = 0;
 
95
        struct roll_value *rv1 = roll(this->expr1);
 
96
        struct roll_value *rv2 = roll(this->expr2);
 
97
        if (rv1->count != 1) {
 
98
                yyerror("Argument 1 to range (..) isn't scalar");
 
99
                free_roll(rv2);
 
100
                rv1->count = 1;
 
101
                rv1->values[0] = 0;
 
102
                return rv1;
 
103
        }
 
104
        if (rv2->count != 1) {
 
105
                yyerror("Argument 2 to range (..) isn't scalar");
 
106
                free_roll(rv2);
 
107
                rv1->count = 1;
 
108
                rv1->values[0] = 0;
 
109
                return rv1;
 
110
        }
 
111
        struct roll_value *rv;
 
112
        if (rv1->values[0] <= rv2->values[0]) {
 
113
                rv = new_roll_multi(
 
114
                        abs(rv1->values[0] - rv2->values[0]) + 1);
 
115
                for (i = rv1->values[0]; i != rv2->values[0]; 
 
116
                        rv1->values[0] < rv2->values[0] ? i++ : i--) {
 
117
                        rv->values[c] = i;
 
118
                        c++;
 
119
                }
 
120
                rv->values[c] = rv2->values[0];
 
121
        }
 
122
        else {
 
123
                rv = new_roll_single(0);
 
124
                rv->count = 0;
 
125
        }
 
126
        free_roll(rv1);
 
127
        free_roll(rv2);
 
128
        return rv;
 
129
}
 
130
 
 
131
roll(rep)
 
132
{
 
133
        struct roll_value *rep = roll(this->expr1);
 
134
        if (rep->count != 1) {
 
135
                yyerror("Argument 1 to rep (#) isn't scalar");
 
136
                rep->count = 1;
 
137
                rep->values[0] = 0;
 
138
                return rep;
 
139
        }
 
140
        struct roll_value *rv = new_roll_single(rep->values[0]);
 
141
        rv->count = 0;
 
142
        int i;
 
143
        for (i = 0; i < rep->values[0]; i++) {
 
144
                struct roll_value *roll = roll(this->expr2);
 
145
                rv->values = (int*)realloc(rv->values, 
 
146
                        sizeof(int) * (rv->count + roll->count));
 
147
                memcpy(&rv->values[rv->count], roll->values, 
 
148
                        roll->count * sizeof(int));             
 
149
                rv->count += roll->count;
 
150
                free_roll(roll);
 
151
        }
 
152
        free_roll(rep);
 
153
 
 
154
        return rv;
 
155
}
 
156
 
 
157
roll(lcat)
 
158
{
 
159
        struct roll_value *rv1 = roll(this->expr1);
 
160
        struct roll_value *rv2 = roll(this->expr2);
 
161
        rv1->values = (int*)realloc(rv1->values, 
 
162
                sizeof(int) * (rv1->count + rv2->count));
 
163
        memcpy(&rv1->values[rv1->count], rv2->values, 
 
164
                rv2->count * sizeof(int));              
 
165
        rv1->count += rv2->count;
 
166
        free_roll(rv2);
 
167
        return rv1;
 
168
}
 
169
 
 
170
roll(negate)
 
171
{
 
172
        struct roll_value *rv = roll(this->expr);
 
173
        if (rv->count != 1) {
 
174
                yyerror("Argument 1 to negate (-) isn't scalar");
 
175
                rv->count = 1;
 
176
                rv->values[0] = 0;
 
177
                return rv;
 
178
        }
 
179
        rv->values[0] *= -1;
 
180
        return rv;
 
181
}
 
182
 
 
183
roll(dice)
 
184
{
 
185
        struct roll_value *rv = roll(this->expr);
 
186
        if (rv->count != 1) {
 
187
                yyerror("Argument 1 to dice (d) isn't scalar");
 
188
                rv->count = 1;
 
189
                rv->values[0] = 0;
 
190
                return rv;
 
191
        }
 
192
        if (rv->values[0] < 1) {
 
193
                yyerror("Argument 1 to dice (d) isn't >= 1");
 
194
                rv->count = 1;
 
195
                rv->values[0] = 0;
 
196
                return rv;
 
197
        }
 
198
        rv->values[0] = 1 + (int) (rv->values[0] * (rand() / (RAND_MAX + 1.0)));
 
199
        return rv;
 
200
}
 
201
 
 
202
roll(sum)
 
203
{
 
204
        int s = 0;
 
205
        int i;
 
206
        struct roll_value *rv = roll(this->expr);
 
207
        for (i = 0; i < rv->count; i++) {
 
208
                s += rv->values[i];
 
209
        }
 
210
        rv->count = 1;
 
211
        rv->values = (int*)realloc(rv->values, sizeof(int) * rv->count);
 
212
        rv->values[0] = s;
 
213
        return rv;
 
214
}
 
215
 
 
216
roll(prod)
 
217
{
 
218
        int s = 1;
 
219
        int i;
 
220
        struct roll_value *rv = roll(this->expr);
 
221
        for (i = 0; i < rv->count; i++) {
 
222
                s *= rv->values[i];
 
223
        }
 
224
        rv->values[0] = s;
 
225
        rv->count = 1;
 
226
        return rv;
 
227
}
 
228
 
 
229
roll(perm)
 
230
{
 
231
        struct roll_value *rv = roll(this->expr);
 
232
        permute(rv->values, rv->count);
 
233
        return rv;
 
234
}
 
235
 
 
236
roll(sort)
 
237
{
 
238
        struct roll_value *rv = roll(this->expr);
 
239
        /* sortiere */
 
240
        quicksort(rv->values, 0, rv->count - 1);
 
241
        return rv;
 
242
}
 
243
 
 
244
roll(rev)
 
245
{
 
246
        int i;
 
247
        struct roll_value *rv = roll(this->expr);
 
248
        for (i = 0; i < rv->count/2; i++) {
 
249
                rv->values[i] ^= rv->values[rv->count-1-i];
 
250
                rv->values[rv->count-1-i] ^= rv->values[i];
 
251
                rv->values[i] ^= rv->values[rv->count-1-i];
 
252
        }
 
253
        return rv;
 
254
}
 
255
 
 
256
roll(count)
 
257
{
 
258
        struct roll_value *rv = roll(this->expr);
 
259
        rv->values = realloc(rv->values, sizeof(int));
 
260
        rv->values[0] = rv->count;
 
261
        rv->count = 1;
 
262
        return rv;
 
263
}
 
264
 
 
265
/* XXX first <-> last and high <-> low could be done in one method per pair */
 
266
roll(first) {
 
267
        struct roll_value *num = roll(this->expr1);
 
268
        struct roll_value *exp = roll(this->expr2);
 
269
        if (num->count != 1) {
 
270
                yyerror("Argument 1 to first isn't scalar");
 
271
                free_roll(num);
 
272
                exp->count = 1;
 
273
                exp->values[0] = 0;
 
274
                return exp;
 
275
        }
 
276
        if (this->type == drop) {
 
277
                int i = exp->count - num->values[0];
 
278
                if (i <= 0) {
 
279
                        i = 0;
 
280
                        exp->count = 0;
 
281
                }
 
282
                else {
 
283
                        memcpy(&exp->values[0], &exp->values[exp->count - i], 
 
284
                                i * sizeof(int));
 
285
                        exp->count = i;
 
286
                }
 
287
        }
 
288
        else {
 
289
                exp->count = min(exp->count, num->values[0]);
 
290
        }
 
291
        free_roll(num);
 
292
        return exp;
 
293
}
 
294
 
 
295
roll(last) {
 
296
        struct roll_value *num = roll(this->expr1);
 
297
        struct roll_value *exp = roll(this->expr2);
 
298
        if (num->count != 1) {
 
299
                yyerror("Argument 1 to last isn't scalar");
 
300
                free_roll(num);
 
301
                exp->count = 1;
 
302
                exp->values[0] = 0;
 
303
                return exp;
 
304
        }
 
305
        if (this->type == drop) {
 
306
                exp->count -= num->values[0];
 
307
                if (exp->count < 0) {
 
308
                        exp->count = 0;
 
309
                }
 
310
        }
 
311
        else {
 
312
                if (num->values[0] < exp->count) {
 
313
                        memcpy(&exp->values[0], &exp->values[exp->count - num->values[0]],
 
314
                                num->values[0] * sizeof(int));
 
315
                        exp->count = num->values[0];
 
316
                }
 
317
        }
 
318
        free_roll(num);
 
319
        return exp;
 
320
}
 
321
 
 
322
roll(low) {
 
323
        struct roll_value *num = roll(this->expr1);
 
324
        struct roll_value *exp = roll(this->expr2);
 
325
        if (num->count != 1) {
 
326
                yyerror("Argument 1 to last isn't scalar");
 
327
                free_roll(num);
 
328
                exp->count = 1;
 
329
                exp->values[0] = 0;
 
330
                return exp;
 
331
        }
 
332
        int *slist = (int*)malloc(sizeof(int) * exp->count);
 
333
        int *mask = (int*)malloc(sizeof(int) * exp->count);
 
334
        memcpy(slist, exp->values, sizeof(int) * exp->count);
 
335
        memset(mask, 0, sizeof(int) * exp->count);
 
336
        quicksort(slist, 0, exp->count -1);
 
337
        int p = 0, i, c = 0;
 
338
 
 
339
/*      printf("# (");
 
340
        for (i = 0; i < exp->count; i++) {
 
341
                printf("%i", exp->values[i]);
 
342
                if (i < (exp->count-1)) {
 
343
                        printf(", ");
 
344
                }
 
345
        }
 
346
        printf(") -> (");*/
 
347
 
 
348
        if (this->type == keep) {
 
349
                for (i = 0; (i < exp->count) && (c < num->values[0]); i++) {
 
350
                        int j, found = 0;
 
351
                        for (j = 0; j < num->values[0]; j++) {
 
352
                                if (exp->values[i] == slist[j]) {
 
353
                                        found = 1;
 
354
                                        break;
 
355
                                }
 
356
                        }
 
357
                        if (found) {
 
358
                                exp->values[p++] = exp->values[i];
 
359
                                c++;
 
360
                        }
 
361
                }
 
362
        }
 
363
        else {
 
364
                // XXX something wrong here
 
365
                for (i = 0; (i < exp->count) && (c < (exp->count - num->values[0])); 
 
366
                        i++) {
 
367
                        int j, found = 0;
 
368
                        for (j = exp->count - 1; j >= num->values[0]; j--) {
 
369
                                if ((exp->values[i] == slist[j]) && (!mask[j])) {
 
370
                                        found = 1;
 
371
                                        mask[j] = 1;
 
372
                                        break;
 
373
                                }
 
374
                                else {
 
375
                                }
 
376
                        }
 
377
                        if (found) {
 
378
                                exp->values[p++] = exp->values[i];
 
379
                                c++;
 
380
                        }
 
381
                }
 
382
        }
 
383
        exp->count = c;
 
384
/*      for (i = 0; i < exp->count; i++) {
 
385
                printf("%i", exp->values[i]);
 
386
                if (i < (exp->count-1)) {
 
387
                        printf(", ");
 
388
                }
 
389
        }
 
390
        printf(")\n");*/
 
391
        free(slist);
 
392
        free(mask);
 
393
        return exp;
 
394
}
 
395
 
 
396
roll(high) {
 
397
        struct roll_value *num = roll(this->expr1);
 
398
        struct roll_value *exp = roll(this->expr2);
 
399
        if (num->count != 1) {
 
400
                yyerror("Argument 1 to last isn't scalar");
 
401
                free_roll(num);
 
402
                exp->count = 1;
 
403
                exp->values[0] = 0;
 
404
                return exp;
 
405
        }
 
406
        int *slist = (int*)malloc(sizeof(int) * exp->count);
 
407
        int *mask = (int*)malloc(sizeof(int) * exp->count);
 
408
        memcpy(slist, exp->values, sizeof(int) * exp->count);
 
409
        memset(mask, 0, sizeof(int) * exp->count);
 
410
        quicksort(slist, 0, exp->count -1);
 
411
        int p = 0, i, c = 0;
 
412
 
 
413
        if (this->type == keep) {
 
414
                for (i = 0; (i < exp->count) && (c < num->values[0]); i++) {
 
415
                        int j, found = 0;
 
416
                        for (j = exp->count - 1; j >= exp->count - num->values[0]; j--) {
 
417
                                if (exp->values[i] == slist[j]) {
 
418
                                        found = 1;
 
419
                                        break;
 
420
                                }
 
421
                        }
 
422
                        if (found) {
 
423
                                exp->values[p++] = exp->values[i];
 
424
                                c++;
 
425
                        }
 
426
                }
 
427
        }
 
428
        else {
 
429
                for (i = 0; (i < exp->count) && (c < (exp->count - num->values[0])); 
 
430
                        i++) {
 
431
                        int j, found = 0;
 
432
                        for (j = 0; j < exp->count - num->values[0]; j++) {
 
433
                                if ((exp->values[i] == slist[j]) && (!mask[j])) {
 
434
                                        found = 1;
 
435
                                        mask[j] = 1;
 
436
                                        break;
 
437
                                }
 
438
                        }
 
439
                        if (found) {
 
440
                                exp->values[p++] = exp->values[i];
 
441
                                c++;
 
442
                        }
 
443
                }
 
444
        }
 
445
        exp->count = c;
 
446
        free(slist);
 
447
        free(mask);
 
448
        return exp;
 
449
}
 
450
 
 
451
roll(comparison) {
 
452
        struct roll_value *num = roll(this->expr1);
 
453
        struct roll_value *exp = roll(this->expr2);
 
454
        if (num->count != 1) {
 
455
                yyerror("Argument 1 to comparison isn't scalar");
 
456
                free_roll(num);
 
457
                exp->count = 1;
 
458
                exp->values[0] = 0;
 
459
                return exp;
 
460
        }
 
461
        int o, n = 0;
 
462
        for (o = 0; o < exp->count; o++) {
 
463
                int c = 0;
 
464
                switch (this->comp) {
 
465
                        case eq:
 
466
                                c = exp->values[o] == num->values[0];
 
467
                                break;
 
468
                        case ne:
 
469
                                c = exp->values[o] != num->values[0];
 
470
                                break;
 
471
                        case gt:
 
472
                                c = exp->values[o] > num->values[0];
 
473
                                break;
 
474
                        case lt:
 
475
                                c = exp->values[o] < num->values[0];
 
476
                                break;
 
477
                        case ge:
 
478
                                c = exp->values[o] >= num->values[0];
 
479
                                break;
 
480
                        case le:
 
481
                                c = exp->values[o] <= num->values[0];
 
482
                                break;
 
483
                        default:
 
484
                                yyerror("Unexpected comparison (really bad)");
 
485
                }
 
486
                if (this->type == drop) {
 
487
                        c = !c;
 
488
                }
 
489
                if (c) {
 
490
                        exp->values[n++] = exp->values[o];
 
491
                }
 
492
        }
 
493
        exp->count = n;
 
494
        free_roll(num);
 
495
        return exp;
 
496
}
 
497
 
 
498
roll(ifthenelse)
 
499
{
 
500
        struct roll_value *if_expr = roll(this->if_expr);
 
501
        if (if_expr->count > 0) {
 
502
                free_roll(if_expr);
 
503
                return roll(this->then_expr);
 
504
        }
 
505
        else {
 
506
                free_roll(if_expr);
 
507
                return roll(this->else_expr);
 
508
        }
 
509
}
 
510
 
 
511
roll(let)
 
512
{
 
513
        // variable setzen und in symtab
 
514
        struct symtab *nst = (struct symtab*)malloc(sizeof(struct symtab));
 
515
        nst->name = this->varname;
 
516
        nst->rvalue = roll(this->expr1);
 
517
        nst->next = this->symtab;
 
518
        set_symtab(this->expr2, nst);
 
519
        struct roll_value *ret = roll(this->expr2);
 
520
        // variable wieder vom stack
 
521
        free_roll(nst->rvalue);
 
522
        free(nst);
 
523
        return ret;
 
524
}
 
525
 
 
526
roll(variable)
 
527
{
 
528
        struct symtab *nst = this->symtab;
 
529
        struct roll_value *ret = NULL;
 
530
        while (nst != NULL) {
 
531
                if (strcmp(this->varname, nst->name) == 0) {
 
532
                        /* copy the roll value */
 
533
                        ret = (struct roll_value*)malloc(sizeof(struct roll_value));
 
534
                        ret->values = (int*)malloc(sizeof(int) * nst->rvalue->count);
 
535
                        memcpy(ret->values, nst->rvalue->values, 
 
536
                                sizeof(int) * nst->rvalue->count);
 
537
                        ret->count = nst->rvalue->count;
 
538
                        break;
 
539
                }
 
540
                nst = nst->next;
 
541
        }
 
542
        if (ret == NULL) {
 
543
                char *emsg = (char*)malloc(sizeof(char)*22+strlen(this->varname));
 
544
                sprintf(emsg, "Variable \"%s\" not found", this->varname);
 
545
                yyerror(emsg);
 
546
                free(emsg);
 
547
                ret = (struct roll_value*)malloc(sizeof(struct roll_value));
 
548
                ret->values = (int*)malloc(sizeof(int) * 1);
 
549
                ret->values[0] = 0;
 
550
                ret->count = 1;
 
551
        }
 
552
        return ret;
 
553
}
 
554
 
 
555
roll(foreach)
 
556
{
 
557
        struct roll_value *list = roll(this->expr1);
 
558
        struct roll_value *ret = (struct roll_value*)
 
559
                malloc(sizeof(struct roll_value));
 
560
        ret->count = 0;
 
561
        ret->values = NULL;
 
562
        struct symtab *nst = (struct symtab*)malloc(sizeof(struct symtab));
 
563
        nst->name = this->varname;
 
564
        nst->rvalue = (struct roll_value*)malloc(sizeof(struct roll_value));
 
565
        nst->rvalue->count = 1;
 
566
        nst->rvalue->values = (int*)malloc(sizeof(int));
 
567
        nst->next = this->symtab;
 
568
        set_symtab(this->expr2, nst);
 
569
        int i;
 
570
        for (i = 0; i < list->count; i++) {
 
571
                nst->rvalue->values[0] = list->values[i];
 
572
                struct roll_value *cur = roll(this->expr2);
 
573
                /* concat to the current solution */
 
574
                ret->values = (int*)realloc(ret->values, 
 
575
                        (ret->count + cur->count) * sizeof(int));
 
576
                memcpy(&ret->values[ret->count], cur->values, 
 
577
                        cur->count * sizeof(int));
 
578
                ret->count += cur->count;
 
579
                free_roll(cur);
 
580
        }
 
581
        free_roll(list);
 
582
        free_roll(nst->rvalue);
 
583
        free(nst);
 
584
        return ret;
 
585
}
 
586
 
 
587
roll(whiledo)
 
588
{
 
589
        struct roll_value *cur;
 
590
        struct roll_value *ret = (struct roll_value*)malloc(
 
591
                sizeof(struct roll_value));
 
592
        ret->count = 0;
 
593
        ret->values = NULL;
 
594
        struct symtab *nst = (struct symtab*)malloc(sizeof(struct symtab));
 
595
        nst->name = this->varname;
 
596
        nst->next = this->symtab;
 
597
        
 
598
        set_symtab(this->expr2, nst);
 
599
        cur = roll(this->expr1);
 
600
        nst->rvalue = cur;
 
601
        /* concat cur to ret */
 
602
        ret->values = (int*)realloc(ret->values, 
 
603
                sizeof(int) * (cur->count + ret->count));
 
604
        memcpy(&ret->values[ret->count], cur->values, sizeof(int) * cur->count);
 
605
        ret->count += cur->count;
 
606
        while (cur->count > 0)
 
607
        {
 
608
                cur = roll(this->expr2);
 
609
                free_roll(nst->rvalue);
 
610
                nst->rvalue = cur;
 
611
                /* concat cur to ret */
 
612
                ret->values = (int*)realloc(ret->values, 
 
613
                        sizeof(int) * (cur->count + ret->count));
 
614
                memcpy(&ret->values[ret->count], cur->values, 
 
615
                        sizeof(int) * cur->count);
 
616
                ret->count += cur->count;
 
617
        }
 
618
        free_roll(cur);
 
619
        free(nst);
 
620
        return ret;
 
621
}