13e12c5d1SDavid du Colombier %{ 23e12c5d1SDavid du Colombier #include "hoc.h" 33e12c5d1SDavid du Colombier #define code2(c1,c2) code(c1); code(c2) 43e12c5d1SDavid du Colombier #define code3(c1,c2,c3) code(c1); code(c2); code(c3) 53e12c5d1SDavid du Colombier %} 63e12c5d1SDavid du Colombier %union { 73e12c5d1SDavid du Colombier Symbol *sym; /* symbol table pointer */ 83e12c5d1SDavid du Colombier Inst *inst; /* machine instruction */ 93e12c5d1SDavid du Colombier int narg; /* number of arguments */ 107dd7cddfSDavid du Colombier Formal *formals; /* list of formal parameters */ 113e12c5d1SDavid du Colombier } 123e12c5d1SDavid du Colombier %token <sym> NUMBER STRING PRINT VAR BLTIN UNDEF WHILE FOR IF ELSE 133e12c5d1SDavid du Colombier %token <sym> FUNCTION PROCEDURE RETURN FUNC PROC READ 147dd7cddfSDavid du Colombier %type <formals> formals 153e12c5d1SDavid du Colombier %type <inst> expr stmt asgn prlist stmtlist 163e12c5d1SDavid du Colombier %type <inst> cond while for if begin end 173e12c5d1SDavid du Colombier %type <sym> procname 183e12c5d1SDavid du Colombier %type <narg> arglist 193e12c5d1SDavid du Colombier %right '=' ADDEQ SUBEQ MULEQ DIVEQ MODEQ 203e12c5d1SDavid du Colombier %left OR 213e12c5d1SDavid du Colombier %left AND 223e12c5d1SDavid du Colombier %left GT GE LT LE EQ NE 233e12c5d1SDavid du Colombier %left '+' '-' 243e12c5d1SDavid du Colombier %left '*' '/' '%' 253e12c5d1SDavid du Colombier %left UNARYMINUS NOT INC DEC 263e12c5d1SDavid du Colombier %right '^' 273e12c5d1SDavid du Colombier %% 283e12c5d1SDavid du Colombier list: /* nothing */ 293e12c5d1SDavid du Colombier | list '\n' 303e12c5d1SDavid du Colombier | list defn '\n' 313e12c5d1SDavid du Colombier | list asgn '\n' { code2(xpop, STOP); return 1; } 323e12c5d1SDavid du Colombier | list stmt '\n' { code(STOP); return 1; } 333e12c5d1SDavid du Colombier | list expr '\n' { code2(printtop, STOP); return 1; } 343e12c5d1SDavid du Colombier | list error '\n' { yyerrok; } 353e12c5d1SDavid du Colombier ; 363e12c5d1SDavid du Colombier asgn: VAR '=' expr { code3(varpush,(Inst)$1,assign); $$=$3; } 373e12c5d1SDavid du Colombier | VAR ADDEQ expr { code3(varpush,(Inst)$1,addeq); $$=$3; } 383e12c5d1SDavid du Colombier | VAR SUBEQ expr { code3(varpush,(Inst)$1,subeq); $$=$3; } 393e12c5d1SDavid du Colombier | VAR MULEQ expr { code3(varpush,(Inst)$1,muleq); $$=$3; } 403e12c5d1SDavid du Colombier | VAR DIVEQ expr { code3(varpush,(Inst)$1,diveq); $$=$3; } 413e12c5d1SDavid du Colombier | VAR MODEQ expr { code3(varpush,(Inst)$1,modeq); $$=$3; } 423e12c5d1SDavid du Colombier ; 433e12c5d1SDavid du Colombier stmt: expr { code(xpop); } 443e12c5d1SDavid du Colombier | RETURN { defnonly("return"); code(procret); } 453e12c5d1SDavid du Colombier | RETURN expr 463e12c5d1SDavid du Colombier { defnonly("return"); $$=$2; code(funcret); } 473e12c5d1SDavid du Colombier | PROCEDURE begin '(' arglist ')' 483e12c5d1SDavid du Colombier { $$ = $2; code3(call, (Inst)$1, (Inst)$4); } 493e12c5d1SDavid du Colombier | PRINT prlist { $$ = $2; } 503e12c5d1SDavid du Colombier | while '(' cond ')' stmt end { 513e12c5d1SDavid du Colombier ($1)[1] = (Inst)$5; /* body of loop */ 523e12c5d1SDavid du Colombier ($1)[2] = (Inst)$6; } /* end, if cond fails */ 533e12c5d1SDavid du Colombier | for '(' cond ';' cond ';' cond ')' stmt end { 543e12c5d1SDavid du Colombier ($1)[1] = (Inst)$5; /* condition */ 553e12c5d1SDavid du Colombier ($1)[2] = (Inst)$7; /* post loop */ 563e12c5d1SDavid du Colombier ($1)[3] = (Inst)$9; /* body of loop */ 573e12c5d1SDavid du Colombier ($1)[4] = (Inst)$10; } /* end, if cond fails */ 583e12c5d1SDavid du Colombier | if '(' cond ')' stmt end { /* else-less if */ 593e12c5d1SDavid du Colombier ($1)[1] = (Inst)$5; /* thenpart */ 603e12c5d1SDavid du Colombier ($1)[3] = (Inst)$6; } /* end, if cond fails */ 613e12c5d1SDavid du Colombier | if '(' cond ')' stmt end ELSE stmt end { /* if with else */ 623e12c5d1SDavid du Colombier ($1)[1] = (Inst)$5; /* thenpart */ 633e12c5d1SDavid du Colombier ($1)[2] = (Inst)$8; /* elsepart */ 643e12c5d1SDavid du Colombier ($1)[3] = (Inst)$9; } /* end, if cond fails */ 653e12c5d1SDavid du Colombier | '{' stmtlist '}' { $$ = $2; } 663e12c5d1SDavid du Colombier ; 673e12c5d1SDavid du Colombier cond: expr { code(STOP); } 683e12c5d1SDavid du Colombier ; 693e12c5d1SDavid du Colombier while: WHILE { $$ = code3(whilecode,STOP,STOP); } 703e12c5d1SDavid du Colombier ; 713e12c5d1SDavid du Colombier for: FOR { $$ = code(forcode); code3(STOP,STOP,STOP); code(STOP); } 723e12c5d1SDavid du Colombier ; 733e12c5d1SDavid du Colombier if: IF { $$ = code(ifcode); code3(STOP,STOP,STOP); } 743e12c5d1SDavid du Colombier ; 753e12c5d1SDavid du Colombier begin: /* nothing */ { $$ = progp; } 763e12c5d1SDavid du Colombier ; 773e12c5d1SDavid du Colombier end: /* nothing */ { code(STOP); $$ = progp; } 783e12c5d1SDavid du Colombier ; 793e12c5d1SDavid du Colombier stmtlist: /* nothing */ { $$ = progp; } 803e12c5d1SDavid du Colombier | stmtlist '\n' 813e12c5d1SDavid du Colombier | stmtlist stmt 823e12c5d1SDavid du Colombier ; 833e12c5d1SDavid du Colombier expr: NUMBER { $$ = code2(constpush, (Inst)$1); } 843e12c5d1SDavid du Colombier | VAR { $$ = code3(varpush, (Inst)$1, eval); } 853e12c5d1SDavid du Colombier | asgn 863e12c5d1SDavid du Colombier | FUNCTION begin '(' arglist ')' 873e12c5d1SDavid du Colombier { $$ = $2; code3(call,(Inst)$1,(Inst)$4); } 883e12c5d1SDavid du Colombier | READ '(' VAR ')' { $$ = code2(varread, (Inst)$3); } 893e12c5d1SDavid du Colombier | BLTIN '(' expr ')' { $$=$3; code2(bltin, (Inst)$1->u.ptr); } 903e12c5d1SDavid du Colombier | '(' expr ')' { $$ = $2; } 913e12c5d1SDavid du Colombier | expr '+' expr { code(add); } 923e12c5d1SDavid du Colombier | expr '-' expr { code(sub); } 933e12c5d1SDavid du Colombier | expr '*' expr { code(mul); } 943e12c5d1SDavid du Colombier | expr '/' expr { code(div); } 953e12c5d1SDavid du Colombier | expr '%' expr { code(mod); } 963e12c5d1SDavid du Colombier | expr '^' expr { code (power); } 973e12c5d1SDavid du Colombier | '-' expr %prec UNARYMINUS { $$=$2; code(negate); } 983e12c5d1SDavid du Colombier | expr GT expr { code(gt); } 993e12c5d1SDavid du Colombier | expr GE expr { code(ge); } 1003e12c5d1SDavid du Colombier | expr LT expr { code(lt); } 1013e12c5d1SDavid du Colombier | expr LE expr { code(le); } 1023e12c5d1SDavid du Colombier | expr EQ expr { code(eq); } 1033e12c5d1SDavid du Colombier | expr NE expr { code(ne); } 1043e12c5d1SDavid du Colombier | expr AND expr { code(and); } 1053e12c5d1SDavid du Colombier | expr OR expr { code(or); } 1063e12c5d1SDavid du Colombier | NOT expr { $$ = $2; code(not); } 1073e12c5d1SDavid du Colombier | INC VAR { $$ = code2(preinc,(Inst)$2); } 1083e12c5d1SDavid du Colombier | DEC VAR { $$ = code2(predec,(Inst)$2); } 1093e12c5d1SDavid du Colombier | VAR INC { $$ = code2(postinc,(Inst)$1); } 1103e12c5d1SDavid du Colombier | VAR DEC { $$ = code2(postdec,(Inst)$1); } 1113e12c5d1SDavid du Colombier ; 1123e12c5d1SDavid du Colombier prlist: expr { code(prexpr); } 1133e12c5d1SDavid du Colombier | STRING { $$ = code2(prstr, (Inst)$1); } 1143e12c5d1SDavid du Colombier | prlist ',' expr { code(prexpr); } 1153e12c5d1SDavid du Colombier | prlist ',' STRING { code2(prstr, (Inst)$3); } 1163e12c5d1SDavid du Colombier ; 1173e12c5d1SDavid du Colombier defn: FUNC procname { $2->type=FUNCTION; indef=1; } 1187dd7cddfSDavid du Colombier '(' formals ')' stmt { code(procret); define($2, $5); indef=0; } 1193e12c5d1SDavid du Colombier | PROC procname { $2->type=PROCEDURE; indef=1; } 1207dd7cddfSDavid du Colombier '(' formals ')' stmt { code(procret); define($2, $5); indef=0; } 1217dd7cddfSDavid du Colombier ; 1227dd7cddfSDavid du Colombier formals: { $$ = 0; } 1237dd7cddfSDavid du Colombier | VAR { $$ = formallist($1, 0); } 1247dd7cddfSDavid du Colombier | VAR ',' formals { $$ = formallist($1, $3); } 1253e12c5d1SDavid du Colombier ; 1263e12c5d1SDavid du Colombier procname: VAR 1273e12c5d1SDavid du Colombier | FUNCTION 1283e12c5d1SDavid du Colombier | PROCEDURE 1293e12c5d1SDavid du Colombier ; 1303e12c5d1SDavid du Colombier arglist: /* nothing */ { $$ = 0; } 1313e12c5d1SDavid du Colombier | expr { $$ = 1; } 1323e12c5d1SDavid du Colombier | arglist ',' expr { $$ = $1 + 1; } 1333e12c5d1SDavid du Colombier ; 1343e12c5d1SDavid du Colombier %% 1353e12c5d1SDavid du Colombier /* end of grammar */ 1363e12c5d1SDavid du Colombier #include <u.h> 1373e12c5d1SDavid du Colombier #include <libc.h> 1383e12c5d1SDavid du Colombier #include <bio.h> 1393e12c5d1SDavid du Colombier #include <ctype.h> 1403e12c5d1SDavid du Colombier char *progname; 1413e12c5d1SDavid du Colombier int lineno = 1; 1423e12c5d1SDavid du Colombier jmp_buf begin; 1433e12c5d1SDavid du Colombier int indef; 1443e12c5d1SDavid du Colombier char *infile; /* input file name */ 1453e12c5d1SDavid du Colombier Biobuf *bin; /* input file descriptor */ 1463e12c5d1SDavid du Colombier Biobuf binbuf; 1473e12c5d1SDavid du Colombier char **gargv; /* global argument list */ 1483e12c5d1SDavid du Colombier int gargc; 1493e12c5d1SDavid du Colombier 1503e12c5d1SDavid du Colombier int c = '\n'; /* global for use by warning() */ 1513e12c5d1SDavid du Colombier 1523e12c5d1SDavid du Colombier int backslash(int), follow(int, int, int); 1533e12c5d1SDavid du Colombier void defnonly(char*), run(void); 1543e12c5d1SDavid du Colombier void warning(char*, char*); 1553e12c5d1SDavid du Colombier 1563e12c5d1SDavid du Colombier yylex(void) /* hoc6 */ 1573e12c5d1SDavid du Colombier { 1583e12c5d1SDavid du Colombier while ((c=Bgetc(bin)) == ' ' || c == '\t') 1593e12c5d1SDavid du Colombier ; 1603e12c5d1SDavid du Colombier if (c < 0) 1613e12c5d1SDavid du Colombier return 0; 1623e12c5d1SDavid du Colombier if (c == '\\') { 1633e12c5d1SDavid du Colombier c = Bgetc(bin); 1643e12c5d1SDavid du Colombier if (c == '\n') { 1653e12c5d1SDavid du Colombier lineno++; 1663e12c5d1SDavid du Colombier return yylex(); 1673e12c5d1SDavid du Colombier } 1683e12c5d1SDavid du Colombier } 1693e12c5d1SDavid du Colombier if (c == '#') { /* comment */ 1703e12c5d1SDavid du Colombier while ((c=Bgetc(bin)) != '\n' && c >= 0) 1713e12c5d1SDavid du Colombier ; 1723e12c5d1SDavid du Colombier if (c == '\n') 1733e12c5d1SDavid du Colombier lineno++; 1743e12c5d1SDavid du Colombier return c; 1753e12c5d1SDavid du Colombier } 1763e12c5d1SDavid du Colombier if (c == '.' || isdigit(c)) { /* number */ 1773e12c5d1SDavid du Colombier double d; 1783e12c5d1SDavid du Colombier Bungetc(bin); 1793e12c5d1SDavid du Colombier Bgetd(bin, &d); 1803e12c5d1SDavid du Colombier yylval.sym = install("", NUMBER, d); 1813e12c5d1SDavid du Colombier return NUMBER; 1823e12c5d1SDavid du Colombier } 183*1066d6deSDavid du Colombier if (isalpha(c) || c == '_' || c >= 0x80) { 1843e12c5d1SDavid du Colombier Symbol *s; 1853e12c5d1SDavid du Colombier char sbuf[100], *p = sbuf; 1863e12c5d1SDavid du Colombier do { 1873e12c5d1SDavid du Colombier if (p >= sbuf + sizeof(sbuf) - 1) { 1883e12c5d1SDavid du Colombier *p = '\0'; 1893e12c5d1SDavid du Colombier execerror("name too long", sbuf); 1903e12c5d1SDavid du Colombier } 1913e12c5d1SDavid du Colombier *p++ = c; 192*1066d6deSDavid du Colombier } while ((c=Bgetc(bin)) >= 0 && (isalnum(c) || c == '_' || c >= 0x80)); 1933e12c5d1SDavid du Colombier Bungetc(bin); 1943e12c5d1SDavid du Colombier *p = '\0'; 1953e12c5d1SDavid du Colombier if ((s=lookup(sbuf)) == 0) 1963e12c5d1SDavid du Colombier s = install(sbuf, UNDEF, 0.0); 1973e12c5d1SDavid du Colombier yylval.sym = s; 1983e12c5d1SDavid du Colombier return s->type == UNDEF ? VAR : s->type; 1993e12c5d1SDavid du Colombier } 2003e12c5d1SDavid du Colombier if (c == '"') { /* quoted string */ 2013e12c5d1SDavid du Colombier char sbuf[100], *p; 2023e12c5d1SDavid du Colombier for (p = sbuf; (c=Bgetc(bin)) != '"'; p++) { 2033e12c5d1SDavid du Colombier if (c == '\n' || c == Beof) 2043e12c5d1SDavid du Colombier execerror("missing quote", ""); 2053e12c5d1SDavid du Colombier if (p >= sbuf + sizeof(sbuf) - 1) { 2063e12c5d1SDavid du Colombier *p = '\0'; 2073e12c5d1SDavid du Colombier execerror("string too long", sbuf); 2083e12c5d1SDavid du Colombier } 2093e12c5d1SDavid du Colombier *p = backslash(c); 2103e12c5d1SDavid du Colombier } 2113e12c5d1SDavid du Colombier *p = 0; 2123e12c5d1SDavid du Colombier yylval.sym = (Symbol *)emalloc(strlen(sbuf)+1); 2133e12c5d1SDavid du Colombier strcpy((char*)yylval.sym, sbuf); 2143e12c5d1SDavid du Colombier return STRING; 2153e12c5d1SDavid du Colombier } 2163e12c5d1SDavid du Colombier switch (c) { 2173e12c5d1SDavid du Colombier case '+': return follow('+', INC, follow('=', ADDEQ, '+')); 2183e12c5d1SDavid du Colombier case '-': return follow('-', DEC, follow('=', SUBEQ, '-')); 2193e12c5d1SDavid du Colombier case '*': return follow('=', MULEQ, '*'); 2203e12c5d1SDavid du Colombier case '/': return follow('=', DIVEQ, '/'); 2213e12c5d1SDavid du Colombier case '%': return follow('=', MODEQ, '%'); 2223e12c5d1SDavid du Colombier case '>': return follow('=', GE, GT); 2233e12c5d1SDavid du Colombier case '<': return follow('=', LE, LT); 2243e12c5d1SDavid du Colombier case '=': return follow('=', EQ, '='); 2253e12c5d1SDavid du Colombier case '!': return follow('=', NE, NOT); 2263e12c5d1SDavid du Colombier case '|': return follow('|', OR, '|'); 2273e12c5d1SDavid du Colombier case '&': return follow('&', AND, '&'); 2283e12c5d1SDavid du Colombier case '\n': lineno++; return '\n'; 2293e12c5d1SDavid du Colombier default: return c; 2303e12c5d1SDavid du Colombier } 2313e12c5d1SDavid du Colombier } 2323e12c5d1SDavid du Colombier 2333e12c5d1SDavid du Colombier backslash(int c) /* get next char with \'s interpreted */ 2343e12c5d1SDavid du Colombier { 2353e12c5d1SDavid du Colombier static char transtab[] = "b\bf\fn\nr\rt\t"; 2363e12c5d1SDavid du Colombier if (c != '\\') 2373e12c5d1SDavid du Colombier return c; 2383e12c5d1SDavid du Colombier c = Bgetc(bin); 2393e12c5d1SDavid du Colombier if (islower(c) && strchr(transtab, c)) 2403e12c5d1SDavid du Colombier return strchr(transtab, c)[1]; 2413e12c5d1SDavid du Colombier return c; 2423e12c5d1SDavid du Colombier } 2433e12c5d1SDavid du Colombier 2443e12c5d1SDavid du Colombier follow(int expect, int ifyes, int ifno) /* look ahead for >=, etc. */ 2453e12c5d1SDavid du Colombier { 2463e12c5d1SDavid du Colombier int c = Bgetc(bin); 2473e12c5d1SDavid du Colombier 2483e12c5d1SDavid du Colombier if (c == expect) 2493e12c5d1SDavid du Colombier return ifyes; 2503e12c5d1SDavid du Colombier Bungetc(bin); 2513e12c5d1SDavid du Colombier return ifno; 2523e12c5d1SDavid du Colombier } 2533e12c5d1SDavid du Colombier 2543e12c5d1SDavid du Colombier void 2553e12c5d1SDavid du Colombier yyerror(char* s) /* report compile-time error */ 2563e12c5d1SDavid du Colombier { 2573e12c5d1SDavid du Colombier /*rob 2583e12c5d1SDavid du Colombier warning(s, (char *)0); 2593e12c5d1SDavid du Colombier longjmp(begin, 0); 2603e12c5d1SDavid du Colombier rob*/ 2613e12c5d1SDavid du Colombier execerror(s, (char *)0); 2623e12c5d1SDavid du Colombier } 2633e12c5d1SDavid du Colombier 2643e12c5d1SDavid du Colombier void 2653e12c5d1SDavid du Colombier execerror(char* s, char* t) /* recover from run-time error */ 2663e12c5d1SDavid du Colombier { 2673e12c5d1SDavid du Colombier warning(s, t); 2683e12c5d1SDavid du Colombier Bseek(bin, 0L, 2); /* flush rest of file */ 2697dd7cddfSDavid du Colombier restoreall(); 2703e12c5d1SDavid du Colombier longjmp(begin, 0); 2713e12c5d1SDavid du Colombier } 2723e12c5d1SDavid du Colombier 2733e12c5d1SDavid du Colombier void 2743e12c5d1SDavid du Colombier fpecatch(void) /* catch floating point exceptions */ 2753e12c5d1SDavid du Colombier { 2763e12c5d1SDavid du Colombier execerror("floating point exception", (char *) 0); 2773e12c5d1SDavid du Colombier } 2783e12c5d1SDavid du Colombier 2793e12c5d1SDavid du Colombier void 2803e12c5d1SDavid du Colombier intcatch(void) /* catch interrupts */ 2813e12c5d1SDavid du Colombier { 2823e12c5d1SDavid du Colombier execerror("interrupt", 0); 2833e12c5d1SDavid du Colombier } 2843e12c5d1SDavid du Colombier 2853e12c5d1SDavid du Colombier void 2863e12c5d1SDavid du Colombier run(void) /* execute until EOF */ 2873e12c5d1SDavid du Colombier { 2883e12c5d1SDavid du Colombier setjmp(begin); 2893e12c5d1SDavid du Colombier for (initcode(); yyparse(); initcode()) 2903e12c5d1SDavid du Colombier execute(progbase); 2913e12c5d1SDavid du Colombier } 2923e12c5d1SDavid du Colombier 2933e12c5d1SDavid du Colombier void 2943e12c5d1SDavid du Colombier main(int argc, char* argv[]) /* hoc6 */ 2953e12c5d1SDavid du Colombier { 2963e12c5d1SDavid du Colombier static int first = 1; 2973e12c5d1SDavid du Colombier #ifdef YYDEBUG 2983e12c5d1SDavid du Colombier extern int yydebug; 2993e12c5d1SDavid du Colombier yydebug=3; 3003e12c5d1SDavid du Colombier #endif 3013e12c5d1SDavid du Colombier progname = argv[0]; 3023e12c5d1SDavid du Colombier init(); 3033e12c5d1SDavid du Colombier if (argc == 1) { /* fake an argument list */ 3043e12c5d1SDavid du Colombier static char *stdinonly[] = { "-" }; 3053e12c5d1SDavid du Colombier 3063e12c5d1SDavid du Colombier gargv = stdinonly; 3073e12c5d1SDavid du Colombier gargc = 1; 3083e12c5d1SDavid du Colombier } else if (first) { /* for interrupts */ 3093e12c5d1SDavid du Colombier first = 0; 3103e12c5d1SDavid du Colombier gargv = argv+1; 3113e12c5d1SDavid du Colombier gargc = argc-1; 3123e12c5d1SDavid du Colombier } 3133e12c5d1SDavid du Colombier Binit(&binbuf, 0, OREAD); 3143e12c5d1SDavid du Colombier bin = &binbuf; 3153e12c5d1SDavid du Colombier while (moreinput()) 3163e12c5d1SDavid du Colombier run(); 3173e12c5d1SDavid du Colombier exits(0); 3183e12c5d1SDavid du Colombier } 3193e12c5d1SDavid du Colombier 3203e12c5d1SDavid du Colombier moreinput(void) 3213e12c5d1SDavid du Colombier { 32280ee5cbfSDavid du Colombier char *expr; 32380ee5cbfSDavid du Colombier static char buf[64]; 3247dd7cddfSDavid du Colombier int fd; 3257dd7cddfSDavid du Colombier static Biobuf b; 3267dd7cddfSDavid du Colombier 3273e12c5d1SDavid du Colombier if (gargc-- <= 0) 3283e12c5d1SDavid du Colombier return 0; 3297dd7cddfSDavid du Colombier if (bin && bin != &binbuf) 330219b2ee8SDavid du Colombier Bterm(bin); 3313e12c5d1SDavid du Colombier infile = *gargv++; 3323e12c5d1SDavid du Colombier lineno = 1; 3333e12c5d1SDavid du Colombier if (strcmp(infile, "-") == 0) { 3343e12c5d1SDavid du Colombier bin = &binbuf; 3353e12c5d1SDavid du Colombier infile = 0; 3367dd7cddfSDavid du Colombier return 1; 3377dd7cddfSDavid du Colombier } 3387dd7cddfSDavid du Colombier if(strncmp(infile, "-e", 2) == 0) { 3397dd7cddfSDavid du Colombier if(infile[2]==0){ 3407dd7cddfSDavid du Colombier if(gargc == 0){ 3417dd7cddfSDavid du Colombier fprint(2, "%s: no argument for -e\n", progname); 3427dd7cddfSDavid du Colombier return 0; 3437dd7cddfSDavid du Colombier } 3447dd7cddfSDavid du Colombier gargc--; 3457dd7cddfSDavid du Colombier expr = *gargv++; 3467dd7cddfSDavid du Colombier }else 3477dd7cddfSDavid du Colombier expr = infile+2; 3487dd7cddfSDavid du Colombier sprint(buf, "/tmp/hocXXXXXXX"); 3497dd7cddfSDavid du Colombier infile = mktemp(buf); 3507dd7cddfSDavid du Colombier fd = create(infile, ORDWR|ORCLOSE, 0600); 3517dd7cddfSDavid du Colombier if(fd < 0){ 3527dd7cddfSDavid du Colombier fprint(2, "%s: can't create temp. file: %r\n", progname); 3537dd7cddfSDavid du Colombier return 0; 3547dd7cddfSDavid du Colombier } 3557dd7cddfSDavid du Colombier fprint(fd, "%s\n", expr); 3567dd7cddfSDavid du Colombier /* leave fd around; file will be removed on exit */ 35780ee5cbfSDavid du Colombier /* the following looks weird but is required for unix version */ 3587dd7cddfSDavid du Colombier bin = &b; 3597dd7cddfSDavid du Colombier seek(fd, 0, 0); 3607dd7cddfSDavid du Colombier Binit(bin, fd, OREAD); 3617dd7cddfSDavid du Colombier } else { 3627dd7cddfSDavid du Colombier bin=Bopen(infile, OREAD); 3637dd7cddfSDavid du Colombier if (bin == 0) { 3643e12c5d1SDavid du Colombier fprint(2, "%s: can't open %s\n", progname, infile); 3653e12c5d1SDavid du Colombier return moreinput(); 3663e12c5d1SDavid du Colombier } 3677dd7cddfSDavid du Colombier } 3683e12c5d1SDavid du Colombier return 1; 3693e12c5d1SDavid du Colombier } 3703e12c5d1SDavid du Colombier 3713e12c5d1SDavid du Colombier void 3723e12c5d1SDavid du Colombier warning(char* s, char* t) /* print warning message */ 3733e12c5d1SDavid du Colombier { 3743e12c5d1SDavid du Colombier fprint(2, "%s: %s", progname, s); 3753e12c5d1SDavid du Colombier if (t) 3763e12c5d1SDavid du Colombier fprint(2, " %s", t); 3773e12c5d1SDavid du Colombier if (infile) 3783e12c5d1SDavid du Colombier fprint(2, " in %s", infile); 3793e12c5d1SDavid du Colombier fprint(2, " near line %d\n", lineno); 3803e12c5d1SDavid du Colombier while (c != '\n' && c != Beof) 3813e12c5d1SDavid du Colombier if((c = Bgetc(bin)) == '\n') /* flush rest of input line */ 3823e12c5d1SDavid du Colombier lineno++; 3833e12c5d1SDavid du Colombier } 3843e12c5d1SDavid du Colombier 3853e12c5d1SDavid du Colombier void 3863e12c5d1SDavid du Colombier defnonly(char *s) /* warn if illegal definition */ 3873e12c5d1SDavid du Colombier { 3883e12c5d1SDavid du Colombier if (!indef) 3893e12c5d1SDavid du Colombier execerror(s, "used outside definition"); 3903e12c5d1SDavid du Colombier } 391