Skip to content

Commit de2f965

Browse files
Factor out some reused code in allocation routines
1 parent 1517777 commit de2f965

File tree

1 file changed

+47
-186
lines changed

1 file changed

+47
-186
lines changed

src/runtime.h

Lines changed: 47 additions & 186 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,8 @@ static ANY pop(void);
271271
static ANY peek(void);
272272
static int stack_length(void);
273273

274+
static TABLE mktable(ANY, ANY, TABLE, TABLE, size_t);
275+
274276
// Builtin functions needed by compiled source file defined in functions.c
275277
static TABLE ___insert(ANY, ANY, TABLE);
276278
static LIST ___empty(void);
@@ -418,15 +420,7 @@ int main(int argc, char** argv)
418420
}
419421
srand(ts.tv_nsec ^ ts.tv_sec); // TODO make random more random.
420422
// Load parameters
421-
while (argc --> 1)
422-
{
423-
cognate_list* const tmp = gc_malloc (sizeof *tmp);
424-
tmp->object = box_STRING(argv[argc]);
425-
tmp->next = cmdline_parameters;
426-
gc_mark_any(&tmp->object);
427-
gc_mark_ptr((void*)&tmp->next);
428-
cmdline_parameters = tmp;
429-
}
423+
while (argc --> 1) cmdline_parameters = ___push(box_STRING(argv[argc]), cmdline_parameters);
430424
// Bind error signals.
431425
struct sigaction error_signal_action;
432426
error_signal_action.sa_sigaction = handle_error_signal;
@@ -719,29 +713,10 @@ TABLE table_skew(TABLE T)
719713
if (!T) return NULL;
720714
else if (!T->left) return T;
721715
else if (T->left->level == T->level)
722-
{
723-
TABLE T2 = gc_malloc(sizeof *T2);
724-
T2->key = T->key;
725-
T2->value = T->value;
726-
T2->level = T->level;
727-
T2->left = T->left->right;
728-
T2->right = T->right;
729-
gc_mark_ptr((void*)&T2->left);
730-
gc_mark_ptr((void*)&T2->right);
731-
gc_mark_any(&T2->key);
732-
gc_mark_any(&T2->value);
733-
TABLE L2 = gc_malloc(sizeof *L2);
734-
L2->key = T->left->key;
735-
L2->value = T->left->value;
736-
L2->level = T->left->level;
737-
L2->left = T->left->left;
738-
L2->right = T2;
739-
gc_mark_ptr((void*)&L2->left);
740-
gc_mark_ptr((void*)&L2->right);
741-
gc_mark_any(&L2->key);
742-
gc_mark_any(&L2->value);
743-
return L2;
744-
}
716+
return
717+
mktable(T->left->key, T->left->value, T->left->left,
718+
mktable(T->key, T->value, T->left->right, T->right, T->level),
719+
T->left->level);
745720
/*
746721
else if (T->right && T->right->left && T->right && T->right->left->level == T->right->level)
747722
{
@@ -759,27 +734,10 @@ TABLE table_split(TABLE T)
759734
if (!T) return NULL;
760735
else if (!T->right || !T->right->right) return T;
761736
else if (T->level == T->right->right->level)
762-
{
763-
TABLE T2 = gc_malloc(sizeof *T2);
764-
T2->left = T->left;
765-
T2->right = T->right->left;
766-
T2->key = T->key;
767-
T2->value = T->value;
768-
gc_mark_ptr((void*)&T2->left);
769-
gc_mark_ptr((void*)&T2->right);
770-
gc_mark_any(&T2->key);
771-
gc_mark_any(&T2->value);
772-
TABLE R2 = gc_malloc(sizeof *R2);
773-
R2->left = T2;
774-
R2->right = T->right->right;
775-
R2->key = T->right->key;
776-
R2->value = T->right->value;
777-
gc_mark_ptr((void*)&R2->left);
778-
gc_mark_ptr((void*)&R2->right);
779-
gc_mark_any(&R2->key);
780-
gc_mark_any(&R2->value);
781-
return R2;
782-
}
737+
return
738+
mktable(T->right->key, T->right->value,
739+
mktable(T->key, T->value, T->left, T->right->left, T->level),
740+
T->right->right, T->right->level);
783741
else return T;
784742
}
785743

@@ -1793,17 +1751,10 @@ static LIST ___list(BLOCK expr)
17931751
// Eval expr
17941752
call_block(expr);
17951753
// Move to a list.
1796-
cognate_list* lst = NULL;
1754+
LIST lst = NULL;
17971755
size_t len = stack_length();
17981756
for (size_t i = 0; i < len; ++i)
1799-
{
1800-
cognate_list* l = gc_malloc(sizeof *l);
1801-
l->object = stack.start[i];
1802-
l->next = lst;
1803-
lst = l;
1804-
gc_mark_any(&l->object);
1805-
gc_mark_ptr((void*)&l->next);
1806-
}
1757+
lst = ___push(stack.start[i], lst);
18071758
stack.top = stack.start;
18081759
stack.start = tmp_stack_start;
18091760
return lst;
@@ -2388,77 +2339,35 @@ static TABLE ___table (BLOCK expr)
23882339
return d;
23892340
}
23902341

2342+
static TABLE mktable(ANY key, ANY value, TABLE left, TABLE right, size_t level)
2343+
{
2344+
TABLE t = gc_malloc(sizeof *t);
2345+
t->key = key;
2346+
t->value = value;
2347+
t->left = left;
2348+
t->right = right;
2349+
t->level = level;
2350+
gc_mark_ptr((void*)&t->left);
2351+
gc_mark_ptr((void*)&t->right);
2352+
gc_mark_any(&t->key);
2353+
gc_mark_any(&t->value);
2354+
return t;
2355+
}
2356+
23912357
static TABLE ___insert(ANY key, ANY value, TABLE d)
23922358
{
23932359
if unlikely(key.type == io || key.type == block || key.type == box) throw_error_fmt("Can't index a table with %s", ___show(key));
2394-
if (!d)
2395-
{
2396-
TABLE D = gc_malloc(sizeof *D);
2397-
D->left = NULL;
2398-
D->right = NULL;
2399-
D->key = key;
2400-
D->value = value;
2401-
gc_mark_ptr((void*)&D->left);
2402-
gc_mark_ptr((void*)&D->right);
2403-
gc_mark_any(&D->key);
2404-
gc_mark_any(&D->value);
2405-
D->level = 1;
2406-
return D;
2407-
}
2360+
if (!d) return mktable(key, value, NULL, NULL, 1);
24082361
ptrdiff_t diff = compare_objects(d->key, key);
2409-
if (diff == 0)
2410-
{
2411-
TABLE D = gc_malloc(sizeof *D);
2412-
D->left = d->left;
2413-
D->right = d->right;
2414-
D->key = key;
2415-
D->value = value;
2416-
D->level = d->level;
2417-
gc_mark_ptr((void*)&D->left);
2418-
gc_mark_ptr((void*)&D->right);
2419-
gc_mark_any(&D->key);
2420-
gc_mark_any(&D->value);
2421-
return D;
2422-
}
2423-
2424-
TABLE D = NULL;
2425-
2362+
if (diff == 0) return mktable(key, value, d->left, d->right, d->level);
24262363
if (diff > 0)
2427-
{
2428-
TABLE left = ___insert(key, value, d->left);
2429-
D = gc_malloc(sizeof *D);
2430-
D->key = d->key;
2431-
D->value = d->value;
2432-
D->level = d->level;
2433-
D->right = d->right;
2434-
D->left = left;
2435-
gc_mark_ptr((void*)&D->left);
2436-
gc_mark_ptr((void*)&D->right);
2437-
gc_mark_any(&D->key);
2438-
gc_mark_any(&D->value);
2439-
}
2364+
return
2365+
table_split(table_skew(
2366+
mktable(d->key, d->value, ___insert(key, value, d->left), d->right, d->level)));
24402367
else //if (diff < 0)
2441-
{
2442-
TABLE right = ___insert(key, value, d->right);
2443-
D = gc_malloc(sizeof *D);
2444-
D->key = d->key;
2445-
D->value = d->value;
2446-
D->level = d->level;
2447-
D->left = d->left;
2448-
D->right = right;
2449-
gc_mark_ptr((void*)&D->left);
2450-
gc_mark_ptr((void*)&D->right);
2451-
gc_mark_any(&D->key);
2452-
gc_mark_any(&D->value);
2453-
}
2454-
2455-
// Perform skew and then split. The conditionals that determine whether or
2456-
// not a rotation will occur or not are inside of the procedures, as given
2457-
// above.
2458-
D = table_skew(D);
2459-
D = table_split(D);
2460-
2461-
return D;
2368+
return
2369+
table_split(table_skew(
2370+
mktable(d->key, d->value, d->left, ___insert(key, value, d->right), d->level)));
24622371
}
24632372

24642373
static ANY ___D(ANY key, TABLE d)
@@ -2502,69 +2411,21 @@ static TABLE ___remove(ANY key, TABLE T)
25022411
TABLE T2 = NULL;
25032412
// This part is fairly intuitive - if this breaks it's probably not here:
25042413
if (diff < 0)
2505-
{
2506-
TABLE right = ___remove(key, T->right);
2507-
T2 = gc_malloc(sizeof *T2);
2508-
T2->left = T->left;
2509-
T2->right = right;
2510-
T2->value = T->value;
2511-
T2->key = T->key;
2512-
T2->level = T->level;
2513-
gc_mark_ptr((void*)&T2->left);
2514-
gc_mark_ptr((void*)&T2->right);
2515-
gc_mark_any(&T2->key);
2516-
gc_mark_any(&T2->value);
2517-
2518-
}
2414+
T2 = mktable(T->key, T->value, T->left, ___remove(key, T->right), T->level);
25192415
else if (diff > 0)
2416+
T2 = mktable(T->key, T->value, ___remove(key, T->left), T->right, T->level);
2417+
else if (!T->left && !T->right) return NULL;
2418+
else if (!T->left) // T->right not null
25202419
{
2521-
TABLE left = ___remove(key, T->left);
2522-
T2 = gc_malloc(sizeof *T2);
2523-
T2->left = left;
2524-
T2->right = T->right;
2525-
T2->value = T->value;
2526-
T2->key = T->key;
2527-
T2->level = T->level;
2528-
gc_mark_ptr((void*)&T2->left);
2529-
gc_mark_ptr((void*)&T2->right);
2530-
gc_mark_any(&T2->key);
2531-
gc_mark_any(&T2->value);
2420+
TABLE L = T->right;
2421+
while (L->left) L = L->left; // successor
2422+
T2 = mktable(L->key, L->value, T->left, ___remove(L->key, T->right), L->level);
25322423
}
2533-
else // if (diff == 0
2424+
else // left and right not null
25342425
{
2535-
if (!T->left && !T->right) return NULL;
2536-
else if (!T->left) // T->right not null
2537-
{
2538-
TABLE L = T->right;
2539-
while (L->left) L = L->left; // successor
2540-
TABLE right = ___remove(L->key, T->right);
2541-
T2 = gc_malloc(sizeof *T2);
2542-
T2->right = right;
2543-
T2->left = T->left;
2544-
T2->key = L->key;
2545-
T2->value = L->value;
2546-
T2->level = L->level;
2547-
gc_mark_ptr((void*)&T2->left);
2548-
gc_mark_ptr((void*)&T2->right);
2549-
gc_mark_any(&T2->key);
2550-
gc_mark_any(&T2->value);
2551-
}
2552-
else // left and right not null
2553-
{
2554-
TABLE L = T->left;
2555-
while (L->right) L = L->right; // predecessor
2556-
TABLE left = ___remove(L->key, T->left);
2557-
T2 = gc_malloc(sizeof *T2);
2558-
T2->left = left;
2559-
T2->right = T->right;
2560-
T2->key = L->key;
2561-
T2->value = L->value;
2562-
T2->level = L->level;
2563-
gc_mark_ptr((void*)&T2->left);
2564-
gc_mark_ptr((void*)&T2->right);
2565-
gc_mark_any(&T2->key);
2566-
gc_mark_any(&T2->value);
2567-
}
2426+
TABLE L = T->left;
2427+
while (L->right) L = L->right; // predecessor
2428+
T2 = mktable(L->key, L->value, ___remove(L->key, T->left), T->right, L->level);
25682429
}
25692430

25702431
// below here idk really what's going on, but it seems to work:

0 commit comments

Comments
 (0)