Minor cleanup, print_stack.
This commit is contained in:
parent
8b4d265ed9
commit
62ed15d17a
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue