aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2012-04-24 18:59:06 +0000
committerDimitri Sokolyuk <demon@dim13.org>2012-04-24 18:59:06 +0000
commit1dcd0406c621511610cfd2b110a4d35ad6d5d4f6 (patch)
treeec9c69e9681bb563f451bd7b8bc76e6cec41f659
parentd28be64a53c8436359406cd73775f41216155a7d (diff)
add rudimentary error handling
-rw-r--r--gramar.y34
-rw-r--r--main.c2
2 files changed, 29 insertions, 7 deletions
diff --git a/gramar.y b/gramar.y
index 7d952d2..b546729 100644
--- a/gramar.y
+++ b/gramar.y
@@ -43,6 +43,7 @@ struct pair {
static int sp = 0;
static int rp = 0;
static int pc = 0;
+static int haserrors = 0;
unsigned short *buffer;
char **label;
@@ -64,7 +65,7 @@ char **label;
%token <ival> NUMBER
%token <sval> STRING QSTRING
-%type <ival> register opcode extended value expr
+%type <ival> register opcode extended operand expr
%left PLUS MINUS
%left MULT
@@ -77,12 +78,12 @@ prog
;
statement
- : opcode value COMMA value
+ : opcode operand comma operand
{
popop(($4 << 10) | ($2 << 4) | $1);
popall();
}
- | opcode value
+ | opcode operand
{
popop(($2 << 10) | $1);
popall();
@@ -91,20 +92,32 @@ statement
| DP STRING { addref($2); }
| DAT data { popall(); }
| ORG expr { pc = $2; }
+ | error { yyerror("statement"); }
;
data
: /* empty */
| data block
- | data COMMA block
+ | data comma block
+ ;
+
+comma
+ : COMMA
+ | error { yyerror("comma"); }
;
expr
- : NUMBER { $$ = $1; }
+ : NUMBER
+ {
+ if ($1 > 0xFFFF)
+ yyerror("integer too big");
+ $$ = $1;
+ }
| expr PLUS expr { $$ = $1 + $3; }
| expr MINUS expr { $$ = $1 - $3; }
| expr MULT expr { $$ = $1 * $3; }
| LPAR expr RPAR { $$ = $2; }
+ | error { yyerror("expr"); }
;
block
@@ -118,7 +131,7 @@ block
| expr { push($1, NULL); }
;
-value
+operand
: register { $$ = $1; }
| LBR register RBR { $$ = 0x08 + $2; }
| POP { $$ = 0x18; }
@@ -182,6 +195,7 @@ register
| Z { $$ = 0x05; }
| I { $$ = 0x06; }
| J { $$ = 0x07; }
+ | error { yyerror("register"); }
;
opcode
@@ -201,6 +215,7 @@ opcode
| IFN { $$ = 0x0d; }
| IFG { $$ = 0x0e; }
| IFB { $$ = 0x0f; }
+ | error { yyerror("opcode"); }
;
extended
@@ -216,7 +231,7 @@ void
yyerror(const char *s)
{
fprintf(stderr, "Line %d: %s\n", yylineno, s);
- exit(1);
+ haserrors = 1;
}
void
@@ -292,5 +307,10 @@ compile(FILE *fd, size_t sz)
free(stack);
free(label);
+ if (haserrors) {
+ free(buffer);
+ buffer = NULL;
+ }
+
return buffer;
}
diff --git a/main.c b/main.c
index 70634d1..7f43556 100644
--- a/main.c
+++ b/main.c
@@ -85,6 +85,8 @@ main(int argc, char **argv)
m = compile(fd, MEMSZ);
fclose(fd);
+ if (!m)
+ errx(1, "compilation errors");
emu(m, r);