summaryrefslogtreecommitdiff
path: root/s1/rhoc.y
blob: 4015fc2284f92f1823bd910af71387def83487ed (plain)
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
82
83
84
85
86
87
88
%{
#define	YYSTYPE double
%}
%token	NUMBER
%left	'+' '-'
%left	'*' '/'
%left	UNMIN
%%
list:	/* ε */
	| list '\n'
	| list expr '\n'	{ print("\t%.8g\n", $2); }
	;
expr:	  NUMBER
	| '-' expr	%prec UNMIN { $$ = -$2; }
	| expr '+' expr		{ $$ = $1 + $3; }
	| expr '-' expr 	{ $$ = $1 - $3; }
	| expr '*' expr 	{ $$ = $1 * $3; }
	| expr '/' expr 	{ $$ = $1 / $3; }
	| expr '%' expr 	{ $$ = fmod($1, $3); }
	| expr '(' expr ')'	{ $$ = $1 * $3; }
	| '(' expr ')'		{ $$ = $2; }
	;
%%
#include <u.h>
#include <libc.h>
#include <ctype.h>
#include <bio.h>

Biobuf *bin;
int lineno;
int prompt;

int yyparse(void);

void
yyerror(char *msg)
{
	fprint(2, "%s at line %d\n", msg, lineno);
}

int
yylex(void)
{
	int c;

	if(prompt){
		print("%d: ", lineno);
		prompt--;
	}
	while((c = Bgetc(bin)) == ' ' || c == '\t')
		;
	if(c == '.' || isdigit(c)){
		Bungetc(bin);
		Bgetd(bin, &yylval);
		return NUMBER;
	}
	if(c == '\n'){
		lineno++;
		prompt++;
	}
	return c;
}

void
usage(void)
{
	fprint(2, "usage: %s\n", argv0);
	exits("usage");
}

void
main(int argc, char *argv[])
{
	ARGBEGIN{
	default: usage();
	}ARGEND;
	
	if(argc > 0)
		usage();
	bin = Bfdopen(0, OREAD);
	if(bin == nil)
		sysfatal("Bfdopen: %r");
	lineno++;
	prompt++;
	yyparse();
	Bterm(bin);
	exits(0);
}