-
Notifications
You must be signed in to change notification settings - Fork 0
/
hoc.y
81 lines (69 loc) · 1.54 KB
/
hoc.y
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
%{
#include <stdio.h>
#include "hoc.h"
%}
%union {
double val;
Symbol *sym;
Inst *inst;
}
%token <val> NUMBER
%token <sym> VAR BLTIN UNDEF
%right '='
%left '%'
%left '+' '-'
%left '*' '/'
%left UNAROP
%right '^'
/* expect one shift/reduce conflict: shall a standalone assignment
* (e.g., “x = 1;”) reduce to an expr and print its value,
* or shift directly to “list asgn ';'” and not print?
*/
%expect 1
%%
list
: // nothing
| list ';'
| list asgn ';' { oprcode(pop); oprcode(STOP); return 1; }
| list expr ';' { oprcode(print); oprcode(STOP); return 1; }
| list error ';' { yyerrok; }
;
asgn
: VAR '=' expr { oprcode(varpush); symcode($1); oprcode(assign); }
;
expr
: NUMBER { oprcode(constpush); valcode($1); }
| '@' { oprcode(constpush); valcode(lastval); }
| VAR { oprcode(varpush); symcode($1); oprcode(eval); }
| asgn
| expr '+' expr { oprcode(add); }
| expr '-' expr { oprcode(sub); }
| expr '*' expr { oprcode(mul); }
| expr '/' expr { oprcode(divd); }
| expr '%' expr { oprcode(mod); }
| expr '^' expr { oprcode(power); }
| '(' expr ')'
| '+' expr %prec UNAROP
| '-' expr %prec UNAROP { oprcode(negate); }
| BLTIN '(' expr ')' { oprcode(bltin); funcode($1->func); }
;
%%
#include <stdlib.h>
#include <setjmp.h>
char const *argv0;
static jmp_buf begin;
int
main(int argc, char *argv[static argc+1])
{
argv0 = argc > 0 ? argv[0] : "hoc";
init();
setjmp(begin);
for (initcode(); yyparse(); initcode())
execute(prog);
exit(EXIT_SUCCESS);
}
void
reset(void)
{
longjmp(begin, 0);
}