Skip to content

Commit fa2f76c

Browse files
listのwrapをCASTでないときにtag付きポインタに
1 parent 78414b0 commit fa2f76c

3 files changed

Lines changed: 48 additions & 27 deletions

File tree

libC/capp.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -417,16 +417,15 @@ value coerce(value v, crc *s) {
417417
*dest = 0;
418418
return retv;
419419
#else
420-
if ((lst*)v != NULL && ((lst*)v)->lstkind == WRAPPED_LIST) { // u<<[s]>><[s']>
421-
crc *c = compose_lists(((lst*)v)->lstdat.wrap_l.c, s);
420+
if ((lst*)v != NULL && (((lst*)v)->lstdat.wrap_l.c & 0b1)) { // u<<[s]>><[s']>
421+
crc *c = compose_lists((crc*)(((lst*)v)->lstdat.wrap_l.c & ~0b1), s);
422422
if (c->crckind == ID) { // u<<[s]>><[s']> -> u<id> -> u
423423
return (value)((lst*)v)->lstdat.wrap_l.w;
424424
} else { // u<<[s]>><[s']> -> u<[s;;s']> -> u<<[s;;s']>>
425425
value retv;
426426
retv = (value)GC_MALLOC(sizeof(lst));
427-
((lst*)retv)->lstkind = WRAPPED_LIST;
428427
((lst*)retv)->lstdat.wrap_l.w = ((lst*)v)->lstdat.wrap_l.w;
429-
((lst*)retv)->lstdat.wrap_l.c = c;
428+
((lst*)retv)->lstdat.wrap_l.c = (crc*)((uintptr_t)c | 0b1);
430429
return retv;
431430
}
432431
} else { // u<[s']> -> u<<[s']>>
@@ -435,9 +434,8 @@ value coerce(value v, crc *s) {
435434
#endif
436435
value retv;
437436
retv = (value)GC_MALLOC(sizeof(lst));
438-
((lst*)retv)->lstkind = WRAPPED_LIST;
439437
((lst*)retv)->lstdat.wrap_l.w = (lst*)v;
440-
((lst*)retv)->lstdat.wrap_l.c = s;
438+
((lst*)retv)->lstdat.wrap_l.c = (uintptr_t)s | 0b1;
441439
return retv;
442440
}
443441
#endif
@@ -494,16 +492,15 @@ value coerce(value v, crc *s) {
494492
#else
495493
value retv;
496494
retv = (value)GC_MALLOC(sizeof(lst));
497-
((lst*)retv)->lstkind = WRAPPED_LIST;
498-
if ((lst*)v != NULL && ((lst*)v)->lstkind == WRAPPED_LIST) { // u<<[s]>><[s'];G!>
495+
if ((lst*)v != NULL && (((lst*)v)->lstdat.wrap_l.c & 0b1)) { // u<<[s]>><[s'];G!>
499496
((lst*)retv)->lstdat.wrap_l.w = ((lst*)v)->lstdat.wrap_l.w;
500-
((lst*)retv)->lstdat.wrap_l.c = compose_lists(((lst*)v)->lstdat.wrap_l.c, mid_crc);
497+
((lst*)retv)->lstdat.wrap_l.c = (crc*)((uintptr_t)compose_lists((crc*)(((lst*)v)->lstdat.wrap_l.c & ~0b1), mid_crc) | 0b1);
501498
} else { // u<[s'];G!> -> u<<[s'];G!>>
502499
#ifdef PROFILE
503500
update_longest(1);
504501
#endif
505502
((lst*)retv)->lstdat.wrap_l.w = (lst*)v;
506-
((lst*)retv)->lstdat.wrap_l.c = mid_crc;
503+
((lst*)retv)->lstdat.wrap_l.c = (uintptr_t)mid_crc | 0b1;
507504
}
508505
return tag_value(retv, G_LI);
509506
#endif

libC/lst.c

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ __attribute__((noreturn)) void did_not_match() {
1212
#include "ty.h"
1313
#include "crc.h"
1414

15+
#ifdef CAST
1516
int is_NULL(lst *l) {
1617
while (l != NULL && l->lstkind == WRAPPED_LIST) {
1718
l = l->lstdat.wrap_l.w;
@@ -21,26 +22,44 @@ int is_NULL(lst *l) {
2122

2223
value hd(lst *l) {
2324
if (l->lstkind == WRAPPED_LIST) {
24-
#ifdef CAST
25-
return cast(hd(l->lstdat.wrap_l.w), l->lstdat.wrap_l.u1->tydat.tylist, l->lstdat.wrap_l.u2->tydat.tylist, l->rid, l->polarity);
26-
#else
27-
return coerce(l->lstdat.wrap_l.w->lstdat.unwrap_l.h, l->lstdat.wrap_l.c->crcdat.one_crc);
28-
#endif
25+
return cast(hd(l->lstdat.wrap_l.w), l->lstdat.wrap_l.u1->tydat.tylist, l->lstdat.wrap_l.u2->tydat.tylist, l->rid, l->polarity);\
2926
} else {
3027
return l->lstdat.unwrap_l.h;
3128
}
3229
}
3330

3431
value tl(lst *l) {
3532
if (l->lstkind == WRAPPED_LIST) {
36-
#ifdef CAST
3733
return cast(tl(l->lstdat.wrap_l.w), l->lstdat.wrap_l.u1, l->lstdat.wrap_l.u2, l->rid, l->polarity);
38-
#else
39-
return coerce(l->lstdat.wrap_l.w->lstdat.unwrap_l.t, l->lstdat.wrap_l.c);
40-
#endif
4134
} else {
4235
return l->lstdat.unwrap_l.t;
4336
}
4437
}
38+
#else
39+
40+
int is_NULL(lst *l) {
41+
while (l != NULL && (l->lstdat.wrap_l.c & 0b1)) {
42+
l = l->lstdat.wrap_l.w;
43+
}
44+
return (l == NULL);
45+
}
46+
47+
value hd(lst *l) {
48+
if (l->lstdat.wrap_l.c & 0b1) {
49+
return coerce(l->lstdat.wrap_l.w->lstdat.unwrap_l.h, ((crc*)(l->lstdat.wrap_l.c & ~0b1))->crcdat.one_crc);
50+
} else {
51+
return l->lstdat.unwrap_l.h;
52+
}
53+
}
54+
55+
value tl(lst *l) {
56+
if (l->lstdat.wrap_l.c & 0b1) {
57+
return coerce(l->lstdat.wrap_l.w->lstdat.unwrap_l.t, (crc*)(l->lstdat.wrap_l.c & ~0b1));
58+
} else {
59+
return l->lstdat.unwrap_l.t;
60+
}
61+
}
62+
63+
#endif
4564

4665
#endif

libC/lst.h

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,34 +7,39 @@ typedef struct lst {
77
#if defined(EAGER) || defined(STATIC)
88
value h;
99
value t;
10-
#else
10+
#elif defined(CAST)
1111
enum lstkind : uint8_t {
1212
UNWRAPPED_LIST,
1313
WRAPPED_LIST
1414
} lstkind;
15-
#ifdef CAST
1615
uint8_t polarity;
1716
uint32_t rid;
18-
#endif
1917
union lstdat {
2018
struct unwrap_l {
2119
value h;
2220
value t;
2321
} unwrap_l;
2422
struct wrap_l {
2523
lst *w;
26-
#ifdef CAST
2724
ty *u1;
2825
ty *u2;
29-
#else
30-
crc *c;
31-
#endif
26+
} wrap_l;
27+
} lstdat;
28+
#else
29+
union lstdat {
30+
struct unwrap_l {
31+
value h;
32+
value t;
33+
} unwrap_l;
34+
struct wrap_l {
35+
lst *w;
36+
uintptr_t c;
3237
} wrap_l;
3338
} lstdat;
3439
#endif
3540
} lst;
3641

37-
void did_not_match() __attribute__((noreturn));;
42+
void did_not_match() __attribute__((noreturn));
3843

3944
#if !defined(EAGER) && !defined(STATIC)
4045
value hd(lst*);

0 commit comments

Comments
 (0)