Minor cleanup, print_stack.

This commit is contained in:
Simon Forman 2023-02-04 18:51:58 -08:00
parent 8b4d265ed9
commit 62ed15d17a
2 changed files with 211 additions and 130 deletions

View File

@ -1,4 +1,12 @@
/* /*
Copyright © 2023 Simon Forman Copyright © 2023 Simon Forman
This file is part of Thun This file is part of Thun
@ -55,6 +63,16 @@ my_callback(GC_PTR void_obj, __attribute__((unused)) GC_PTR void_environment) {
} }
/*
*/
JoyList JoyList
push_integer_from_str(char *str, JoyList tail) push_integer_from_str(char *str, JoyList tail)
{ {
@ -68,51 +86,6 @@ push_integer_from_str(char *str, JoyList tail)
} }
/* Pre-declare so we can use it in print_node(). */
void
print_list(JoyList el);
void
print_node(JoyType j)
{
switch (j.kind) {
case joyInt:
gmp_printf("%Zd", j.value.i);
break;
case joySymbol:
printf("%s", j.value.symbol);
break;
case joyTrue:
printf("true");
break;
case joyFalse:
printf("false");
break;
case joyList:
printf("[");
print_list(j.value.el);
printf("]");
break;
default:
printf("wtf");
}
}
void
print_list(JoyList el)
{
while (NULL != el) {
print_node(*(el->head));
el = el->tail;
if (NULL != el) {
printf(" ");
}
}
}
char * char *
trim_leading_blanks(char *str) trim_leading_blanks(char *str)
{ {
@ -161,6 +134,7 @@ make_non_list_node(char *text, size_t size)
return node; return node;
} }
/* Create a new list_node with a joyList head. */ /* Create a new list_node with a joyList head. */
JoyList JoyList
make_list_node(JoyList el) make_list_node(JoyList el)
@ -173,6 +147,160 @@ make_list_node(JoyList el)
} }
JoyList
pop_any(JoyListPtr stack)
{
JoyList result;
if (!(*stack)) {
printf("Not enough values on stack.\n");
exit(1);
}
result = *stack;
*stack = (*stack)->tail;
return result;
}
mpz_t *
pop_int(JoyListPtr stack)
{
JoyList node;
node = pop_any(stack);
switch (node->head->kind) {
case joyInt:
return &(node->head->value.i);
default:
printf("Not an integer.\n");
exit(1);
}
}
JoyList
pop_list(JoyListPtr stack)
{
JoyList node;
node = pop_any(stack);
switch (node->head->kind) {
case joyList:
return node;
default:
printf("Not a list.\n");
exit(1);
}
}
JoyList
pop_list_node(JoyListPtr stack)
{
return pop_list(stack)->head->value.el;
}
void
push_quote(JoyList el, JoyListPtr expression)
{
JoyList node;
if (!el) return;
node = newJoyList;
node->head = newJoyType;
node->head->kind = joyList;
node->head->value.el = el;
node->tail = *expression;
*expression = node;
}
JoyList
newIntNode(void) {
JoyList node = newJoyList;
node->head = newJoyType;
node->head->kind = joyInt;
mpz_init(node->head->value.i);
GC_register_finalizer(node->head->value.i, my_callback, NULL, NULL, NULL);
return node;
}
void
push_thing(JoyTypePtr term, JoyListPtr stack) {
JoyList node = newJoyList;
node->head = term;
node->tail = *stack;
*stack = node;
}
/*
*/
/* Pre-declare so we can use it in print_node(). */
void
print_list(JoyList el);
void
print_node(JoyType j)
{
switch (j.kind) {
case joyInt:
gmp_printf("%Zd", j.value.i);
break;
case joySymbol:
printf("%s", j.value.symbol);
break;
case joyTrue:
printf("true");
break;
case joyFalse:
printf("false");
break;
case joyList:
printf("[");
print_list(j.value.el);
printf("]");
break;
default:
printf("wtf");
}
}
void
print_list(JoyList el)
{
while (NULL != el) {
print_node(*(el->head));
el = el->tail;
if (NULL != el) {
printf(" ");
}
}
}
void
print_stack(JoyList el)
{
if (el) {
if (el->tail) {
print_stack(el->tail);
printf(" ");
}
print_node(*(el->head));
}
}
/* /*
@ -236,6 +364,7 @@ Extract terms from the text until a closing bracket is found.
return result; return result;
} }
/* /*
Get the next node from the text, updating text Get the next node from the text, updating text
to point to the rest of the, uh, text. to point to the rest of the, uh, text.
@ -307,78 +436,31 @@ text_to_expression(char *text)
} }
JoyList
pop_any(JoyListPtr stack)
{
JoyList result;
if (!(*stack)) {
printf("Not enough values on stack.\n");
exit(1);
}
result = *stack;
*stack = (*stack)->tail;
return result;
}
mpz_t *
pop_int(JoyListPtr stack)
{
JoyList node;
node = pop_any(stack);
switch (node->head->kind) {
case joyInt:
return &(node->head->value.i);
default:
printf("Not an integer.\n");
exit(1);
}
}
JoyList
pop_list(JoyListPtr stack)
{
JoyList node;
node = pop_any(stack);
switch (node->head->kind) {
case joyList:
return node;
default:
printf("Not a list.\n");
exit(1);
}
}
JoyList
pop_list_node(JoyListPtr stack)
{
return pop_list(stack)->head->value.el;
}
void
push_quote(JoyList el, JoyListPtr expression)
{
JoyList node;
if (!el) return;
node = newJoyList;
node->head = newJoyType;
node->head->kind = joyList;
node->head->value.el = el;
node->tail = *expression;
*expression = node;
}
/* /*
As elegant as it is to model the expression as a stack, it's not very
efficient, as concatenating definitions and other quoted programs to
the expression is a common and expensive operation.
Instead, let's keep a stack of sub-expressions, reading from them
one-by-one, and prepending new sub-expressions to the stack rather than
concatenating them.
Return the next term from the expression and the new expression. Return the next term from the expression and the new expression.
(item, quote), expression = expression (item, quote), expression = expression
return item, push_quote(quote, expression) return item, push_quote(quote, expression)
*/ */
JoyTypePtr JoyTypePtr
next_term(JoyListPtr expression) next_term(JoyListPtr expression)
{ {
@ -398,21 +480,19 @@ next_term(JoyListPtr expression)
if (quote) { if (quote) {
push_quote(quote, expression); push_quote(quote, expression);
} }
print_list(*expression);
printf(" <--\n");
return term; return term;
} }
JoyList /*
newIntNode(void) {
JoyList node = newJoyList;
node->head = newJoyType;
node->head->kind = joyInt;
mpz_init(node->head->value.i);
GC_register_finalizer(node->head->value.i, my_callback, NULL, NULL, NULL);
return node; */
}
#define BINARY_MATH_OP(name) \ #define BINARY_MATH_OP(name) \
void \ void \
@ -473,13 +553,14 @@ void mod(JoyListPtr stack, JoyListPtr expression) {stack = expression;}
void truthy(JoyListPtr stack, JoyListPtr expression) {stack = expression;} void truthy(JoyListPtr stack, JoyListPtr expression) {stack = expression;}
void /*
push_thing(JoyTypePtr term, JoyListPtr stack) {
JoyList node = newJoyList;
node->head = term;
node->tail = *stack;
*stack = node;
}
*/
void void
@ -565,7 +646,7 @@ main(void)
} }
expression = text_to_expression(line); expression = text_to_expression(line);
joy(&stack, &expression); joy(&stack, &expression);
print_list(stack); print_stack(stack);
printf("\n"); printf("\n");
} }
return 0; return 0;

View File

@ -35,4 +35,4 @@ the comparison functions as definitions:
lt [false] [false] [true] cmp lt [false] [false] [true] cmp
neq [true] [false] [true] cmp neq [true] [false] [true] cmp
le [false] [true] [true] cmp le [false] [true] [true] cmp
ge [true] [true] [false] cmp ge [true] [true] [false] cmp