#include #include #include #include #include <9p.h> #include void mathattach(Req *req) { req->ofcall.qid = (Qid) {1, 0, 0x80}; req->fid->qid = req->ofcall.qid; respond(req, nil); } char * mathwalk(Fid *fid, char *name, Qid *qid) { static int qidcount = 2; char opstack[10], *tops, tok, *p; double nstack[20], *tns; tops = opstack + nelem(opstack); tns = nstack + nelem(nstack); p = name; for(;;) { for(; *p && *p == ' '; p++); if(isdigit(*p)) { if(tns <= nstack) goto error; *--tns = strtod(p, &p); continue; } tok = *p++; switch(tok) { case '+': case '-': case '*': case '%': case ')': case 0: while(tops < opstack + nelem(opstack) && (tok != '*' && tok != '%' || *tops != '+' && *tops != '-')) { if(*tops == '(') { if(tok != ')') break; tok = -1; tops++; continue; } if(tns >= nstack + nelem(nstack) - 1) goto error; switch(*tops) { case '+': tns[1] += *tns; break; case '-': tns[1] -= *tns; break; case '*': tns[1] *= *tns; break; case '%': tns[1] /= *tns; break; } tops++; tns++; } if(tok && tok != -1 && tok != ')') { case '(': if(tops <= opstack) goto error; *--tops = tok; } if(tok == 0) goto out; break; default: goto error; } } out: if(tops != opstack + nelem(opstack)) goto error; if(tns != nstack + nelem(nstack) - 1) goto error; *qid = (Qid) {qidcount++, 0, 0}; fid->qid = *qid; fid->aux = smprint("%g\n", *tns); return nil; error: return "syntax error"; } void mathread(Req *req) { if(req->fid->aux == nil) { respond(req, nil); return; } readstr(req, (char *) req->fid->aux); respond(req, nil); } void mathdestroy(Fid *fid) { free(fid->aux); } Srv mathsrv = { .attach = mathattach, .walk1 = mathwalk, .read = mathread, .destroyfid = mathdestroy, }; void main() { postmountsrv(&mathsrv, "math", "/n/math", MREPL); }