Use setjmp/longjmp to recover after errors.
Wow! That was easy!
This commit is contained in:
parent
0611aa3c05
commit
437e0af91d
|
|
@ -29,6 +29,7 @@ along with Thun. If not see <http://www.gnu.org/licenses/>.
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
|
||||||
#include <gc.h>
|
#include <gc.h>
|
||||||
#include <gmp.h>
|
#include <gmp.h>
|
||||||
|
|
@ -37,6 +38,7 @@ along with Thun. If not see <http://www.gnu.org/licenses/>.
|
||||||
#include "definitions.h"
|
#include "definitions.h"
|
||||||
|
|
||||||
|
|
||||||
|
static jmp_buf jbuf;
|
||||||
|
|
||||||
const char *BLANKS = " \t";
|
const char *BLANKS = " \t";
|
||||||
const char *FALSE = "false";
|
const char *FALSE = "false";
|
||||||
|
|
@ -166,7 +168,7 @@ pop_any(JoyListPtr stack)
|
||||||
JoyList result;
|
JoyList result;
|
||||||
if (!(*stack)) {
|
if (!(*stack)) {
|
||||||
printf("Not enough values on stack.\n");
|
printf("Not enough values on stack.\n");
|
||||||
exit(1);
|
longjmp(jbuf, 1);
|
||||||
}
|
}
|
||||||
result = *stack;
|
result = *stack;
|
||||||
*stack = (*stack)->tail;
|
*stack = (*stack)->tail;
|
||||||
|
|
@ -183,7 +185,7 @@ pop_int(JoyListPtr stack)
|
||||||
return &(node->head->value.i);
|
return &(node->head->value.i);
|
||||||
default:
|
default:
|
||||||
printf("Not an integer.\n");
|
printf("Not an integer.\n");
|
||||||
exit(1);
|
longjmp(jbuf, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -200,7 +202,7 @@ pop_bool(JoyListPtr stack)
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
printf("Not a Boolean.\n");
|
printf("Not a Boolean.\n");
|
||||||
exit(1);
|
longjmp(jbuf, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -215,7 +217,7 @@ pop_list_node(JoyListPtr stack)
|
||||||
return node;
|
return node;
|
||||||
default:
|
default:
|
||||||
printf("Not a list.\n");
|
printf("Not a list.\n");
|
||||||
exit(1);
|
longjmp(jbuf, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -372,14 +374,14 @@ Extract terms from the text until a closing bracket is found.
|
||||||
/* NULL string input? */
|
/* NULL string input? */
|
||||||
if (NULL == *text) {
|
if (NULL == *text) {
|
||||||
printf("Missing ']' bracket. A\n");
|
printf("Missing ']' bracket. A\n");
|
||||||
exit(1);
|
longjmp(jbuf, 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
*text = trim_leading_blanks(*text);
|
*text = trim_leading_blanks(*text);
|
||||||
|
|
||||||
if (NULL == *text) {
|
if (NULL == *text) {
|
||||||
printf("Missing ']' bracket. B\n");
|
printf("Missing ']' bracket. B\n");
|
||||||
exit(1);
|
longjmp(jbuf, 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Look for blanks or brackets. */
|
/* Look for blanks or brackets. */
|
||||||
|
|
@ -392,7 +394,7 @@ Extract terms from the text until a closing bracket is found.
|
||||||
*/
|
*/
|
||||||
if (NULL == rest) {
|
if (NULL == rest) {
|
||||||
printf("Missing ']' bracket. C\n");
|
printf("Missing ']' bracket. C\n");
|
||||||
exit(1);
|
longjmp(jbuf, 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* How many chars have we got? */
|
/* How many chars have we got? */
|
||||||
|
|
@ -460,7 +462,7 @@ parse_node(char **text)
|
||||||
}
|
}
|
||||||
if (']' == rest[0]) {
|
if (']' == rest[0]) {
|
||||||
printf("Extra ']' bracket.\n");
|
printf("Extra ']' bracket.\n");
|
||||||
exit(1);
|
longjmp(jbuf, 1);
|
||||||
}
|
}
|
||||||
printf("Should be unreachable.");
|
printf("Should be unreachable.");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
@ -680,7 +682,7 @@ first(JoyListPtr stack, __attribute__((unused)) JoyListPtr expression)
|
||||||
JoyList quote = pop_list(stack);
|
JoyList quote = pop_list(stack);
|
||||||
if (!quote) {
|
if (!quote) {
|
||||||
printf("Cannot take first of empty list.\n");
|
printf("Cannot take first of empty list.\n");
|
||||||
exit(1);
|
longjmp(jbuf, 1);
|
||||||
}
|
}
|
||||||
push_thing(quote->head, stack);
|
push_thing(quote->head, stack);
|
||||||
}
|
}
|
||||||
|
|
@ -692,7 +694,7 @@ rest(JoyListPtr stack, __attribute__((unused)) JoyListPtr expression)
|
||||||
JoyList quote = pop_list(stack);
|
JoyList quote = pop_list(stack);
|
||||||
if (!quote) {
|
if (!quote) {
|
||||||
printf("Cannot take rest of empty list.\n");
|
printf("Cannot take rest of empty list.\n");
|
||||||
exit(1);
|
longjmp(jbuf, 1);
|
||||||
}
|
}
|
||||||
push_quote(quote->tail, stack);
|
push_quote(quote->tail, stack);
|
||||||
}
|
}
|
||||||
|
|
@ -749,7 +751,7 @@ truthy(JoyListPtr stack, __attribute__((unused)) JoyListPtr expression)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("Cannot Boolify.\n");
|
printf("Cannot Boolify.\n");
|
||||||
exit(1);
|
longjmp(jbuf, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -790,7 +792,7 @@ joy(JoyListPtr stack, JoyListPtr expression)
|
||||||
interned = in_word_set(sym, strlen(sym));
|
interned = in_word_set(sym, strlen(sym));
|
||||||
if (!interned) {
|
if (!interned) {
|
||||||
printf("Unknown: %s\n", sym);
|
printf("Unknown: %s\n", sym);
|
||||||
exit(1);
|
longjmp(jbuf, 1);
|
||||||
}
|
}
|
||||||
interned->func(stack, expression);
|
interned->func(stack, expression);
|
||||||
}
|
}
|
||||||
|
|
@ -804,6 +806,7 @@ main(void)
|
||||||
char *status;
|
char *status;
|
||||||
JoyList stack = EMPTY_LIST;
|
JoyList stack = EMPTY_LIST;
|
||||||
JoyList expression = EMPTY_LIST;
|
JoyList expression = EMPTY_LIST;
|
||||||
|
JoyList s;
|
||||||
|
|
||||||
/* Initialize Boolean singleton values. */
|
/* Initialize Boolean singleton values. */
|
||||||
JoyTrue = newJoyType;
|
JoyTrue = newJoyType;
|
||||||
|
|
@ -847,8 +850,14 @@ main(void)
|
||||||
printf("bye\n");
|
printf("bye\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
s = stack;
|
||||||
|
if (!setjmp(jbuf)) {
|
||||||
expression = text_to_expression(line);
|
expression = text_to_expression(line);
|
||||||
joy(&stack, &expression);
|
joy(&stack, &expression);
|
||||||
|
} else {
|
||||||
|
/* err */
|
||||||
|
stack = s;
|
||||||
|
}
|
||||||
print_stack(stack);
|
print_stack(stack);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue