ref: 51f3bfd0e73d5e78d9fe71e6106a2a883619e18f
author: rodri <[email protected]>
date: Sat Aug 31 12:06:55 EDT 2024
stage 1.
--- /dev/null
+++ b/readme
@@ -1,0 +1,14 @@
+Welcome to rhoc, rodri's high-order calculator. This program is
+already shipping with plan 9 so, in order to separate it from the
+original, here is my version.
+
+I'm creating a folder per stage as it is explained in tupe [1], like
+`s1', `s2', for stage one and two respectively.
+
+I also took the freedom to create the program my own way, so it's not
+exactly as shown in the book, although it's got the same features. In
+addition to UTF support (fuck you lex!)
+
+
+References:
+[1] The Unix Programming Environment, by Kernighan and Pike, 1984.
--- /dev/null
+++ b/s1/mkfile
@@ -1,0 +1,10 @@
+</$objtype/mkfile
+
+TARG=rhoc1
+OFILES=\
+ y.tab.$O
+YFILES=\
+ rhoc.y
+BIN=/$objtype/bin
+
+</sys/src/cmd/mkone
--- /dev/null
+++ b/s1/rhoc.y
@@ -1,0 +1,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);
+}