do not abort when meet a compilation error

This commit is contained in:
Yuichi Nishiwaki 2013-10-20 18:17:12 +09:00
parent 4f8aa03b24
commit 05eb62cc4d
5 changed files with 42 additions and 8 deletions

View File

@ -3,6 +3,7 @@
#include <stddef.h> #include <stddef.h>
#include <stdbool.h> #include <stdbool.h>
#include <setjmp.h>
#include "picconf.h" #include "picconf.h"
#include "picrin/value.h" #include "picrin/value.h"
@ -34,6 +35,9 @@ typedef struct {
struct pic_irep **irep; struct pic_irep **irep;
size_t ilen, icapa; size_t ilen, icapa;
jmp_buf *jmp;
const char *errmsg;
struct heap_page *heap; struct heap_page *heap;
struct pic_object *arena[PIC_ARENA_SIZE]; struct pic_object *arena[PIC_ARENA_SIZE];
int arena_idx; int arena_idx;
@ -68,7 +72,7 @@ struct pic_proc *pic_codegen(pic_state *, pic_value, struct pic_env *);
void pic_abort(pic_state *, const char *); void pic_abort(pic_state *, const char *);
void pic_raise(pic_state *, pic_value); void pic_raise(pic_state *, pic_value);
void pic_error(pic_state *, const char *, ...); void pic_error(pic_state *, const char *);
void pic_debug(pic_state *, pic_value); void pic_debug(pic_state *, pic_value);

View File

@ -204,7 +204,7 @@ pic_gen(pic_state *pic, struct pic_irep *irep, pic_value obj, struct pic_env *en
b = env_lookup(pic, obj, env, &depth, &idx); b = env_lookup(pic, obj, env, &depth, &idx);
if (! b) { if (! b) {
pic_abort(pic, "unbound variable"); pic_error(pic, "unbound variable");
} }
if (depth == -1) { /* global */ if (depth == -1) { /* global */
@ -218,7 +218,7 @@ pic_gen(pic_state *pic, struct pic_irep *irep, pic_value obj, struct pic_env *en
irep->clen++; irep->clen++;
} }
else { /* nonlocal */ else { /* nonlocal */
pic_abort(pic, "reference to closed variable not supported"); pic_error(pic, "reference to closed variable not supported");
} }
break; break;
} }
@ -362,7 +362,7 @@ pic_gen(pic_state *pic, struct pic_irep *irep, pic_value obj, struct pic_env *en
case PIC_TT_PROC: case PIC_TT_PROC:
case PIC_TT_UNDEF: case PIC_TT_UNDEF:
case PIC_TT_PORT: { case PIC_TT_PORT: {
pic_abort(pic, "invalid expression given"); pic_error(pic, "invalid expression given");
} }
} }
} }
@ -438,6 +438,17 @@ pic_codegen(pic_state *pic, pic_value obj, struct pic_env *env)
proc->cfunc_p = false; proc->cfunc_p = false;
proc->u.irep = irep = new_irep(pic); proc->u.irep = irep = new_irep(pic);
if (! pic->jmp) {
jmp_buf jmp;
pic->jmp = &jmp;
if (setjmp(*pic->jmp) != 0) {
/* error occured */
pic->jmp = NULL;
return NULL;
}
}
pic_gen(pic, irep, obj, env); pic_gen(pic, irep, obj, env);
irep->code[irep->clen].insn = OP_STOP; irep->code[irep->clen].insn = OP_STOP;
irep->clen++; irep->clen++;

View File

@ -3,6 +3,17 @@
#include "picrin.h" #include "picrin.h"
void
pic_error(pic_state *pic, const char *msg)
{
pic->errmsg = msg;
if (! pic->jmp) {
puts(msg);
abort();
}
longjmp(*pic->jmp, 1);
}
void void
pic_abort(pic_state *pic, const char *msg) pic_abort(pic_state *pic, const char *msg)
{ {

View File

@ -66,13 +66,11 @@ main()
/* read */ /* read */
r = pic_parse(pic, code, &v); r = pic_parse(pic, code, &v);
if (! r) { /* wait for more input */ if (! r) { /* wait for more input */
pic_gc_arena_restore(pic, ai); goto next;
continue;
} }
code[0] = '\0'; code[0] = '\0';
if (pic_undef_p(v)) { /* parse error */ if (pic_undef_p(v)) { /* parse error */
pic_gc_arena_restore(pic, ai); goto next;
continue;
} }
#if DEBUG #if DEBUG
@ -83,6 +81,11 @@ main()
/* eval */ /* eval */
proc = pic_codegen(pic, v, pic->global_env); proc = pic_codegen(pic, v, pic->global_env);
if (proc == NULL) {
printf("compilation error: %s\n", pic->errmsg);
pic->errmsg = NULL;
goto next;
}
v = pic_run(pic, proc, pic_nil_value()); v = pic_run(pic, proc, pic_nil_value());
/* print */ /* print */
@ -90,6 +93,7 @@ main()
pic_debug(pic, v); pic_debug(pic, v);
printf("\n"); printf("\n");
next:
pic_gc_arena_restore(pic, ai); pic_gc_arena_restore(pic, ai);
} }

View File

@ -51,6 +51,10 @@ pic_open()
pic->glen = 0; pic->glen = 0;
pic->gcapa = PIC_GLOBALS_SIZE; pic->gcapa = PIC_GLOBALS_SIZE;
/* error handling */
pic->jmp = NULL;
pic->errmsg = NULL;
/* GC arena */ /* GC arena */
pic->arena_idx = 0; pic->arena_idx = 0;