From bfd97dce0cd0b532b0a6065fd1cf891169ebd204 Mon Sep 17 00:00:00 2001 From: rodri Date: Thu, 19 Sep 2024 21:21:26 +0000 Subject: fixes and advances. --- semblance.y | 268 ++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 163 insertions(+), 105 deletions(-) (limited to 'semblance.y') diff --git a/semblance.y b/semblance.y index c6629a1..b717bed 100644 --- a/semblance.y +++ b/semblance.y @@ -9,115 +9,160 @@ %} %union { int type; - double val; - Symbol *sym; + Node node; } +%token PRINT %token TYPE -%token NUMBER -%token VAR CONST BLTIN UNDEF -%type expr exprs -%type asgn asgns +%token NUMBER ID CONST BLTIN UNDEF +%type expr exprs +%type asgn asgns %right '=' %% -top: /* ε */ - | list +list: /* ε */ { fprint(2, "list: ε\n"); } + prog { fprint(2, "list: prog\n"); } + | list prog { fprint(2, "list: list prog\n"); } ; -list: prog - | list prog - ; -prog: '\n' - | decls - | asgns - | exprs { print("\t%.8g\n", $1); } + +prog: /* ε */ { fprint(2, "prog: ε\n"); } + | decls { fprint(2, "prog: decls\n"); } + | asgns { fprint(2, "prog: asgns\n"); } + | exprs { fprint(2, "prog: exprs\n"); } + | PRINT exprs + { + fprint(2, "prog: PRINT exprs\n"); + if($2.type == NODENUM) + fprint(2, "%g\n", $2.num); + if($2.type == NODESYM){ + fprint(2, "%s = ", $2.sym->name); + switch($2.sym->type){ + case ID: + switch($2.sym->var.type){ + case TDOUBLE: fprint(2, "%g\n", $2.sym->var.dval); break; + case TPOINT: + case TVECTOR: + case TNORMAL: + case TQUAT: fprint(2, "%V\n", $2.sym->var.pval); break; + } + break; + case CONST: fprint(2, "%g\n", $2.sym->dconst); break; + case BLTIN: fprint(2, "f()\n"); break; + } + } + } ; -decls: decls decl - | decl + +decls: decl { decltype = -1; fprint(2, "decls: decl\n"); } + | decls decl { decltype = -1; fprint(2, "decls: decls decl\n"); } ; -decl: TYPE { decltype = $1; } vars ';' + +decl: TYPE { decltype = $1; } idlist ';' { fprint(2, "decl: TYPE idlist\n"); } ; -vars: VAR + +idlist: ID { - if($1->type != UNDEF) - rterror("variable already exists"); + fprint(2, "idlist: ID\n"); + + if($1.sym->type != UNDEF) + yyerror("variable already exists"); - $1->type = VAR; - $1->u.var.type = decltype; - print("%s %s;\n", ctypename(decltype), $1->name); + if(decltype < 0) + yyerror("no type specified"); + + $1.sym->type = ID; + $1.sym->var.type = decltype; + print("%s %s;\n", ctypename(decltype), $1.sym->name); } - | vars ',' VAR + | idlist ',' ID { - if($3->type != UNDEF) - rterror("variable already exists"); + fprint(2, "idlist: ID , idlist\n"); + + if($3.sym->type != UNDEF) + yyerror("variable already exists"); + + if(decltype < 0) + yyerror("no type specified"); - $3->type = VAR; - $3->u.var.type = decltype; - print("%s %s;\n", ctypename(decltype), $3->name); + $3.sym->type = ID; + $3.sym->var.type = decltype; + print("%s %s;\n", ctypename(decltype), $3.sym->name); } ; -asgns: asgns asgn ';' - | asgn ';' + +asgns: asgn ';' { fprint(2, "asgns: asgn\n"); } + | asgns asgn ';' { fprint(2, "asgns: asgns asgn\n"); } ; -asgn: VAR '=' NUMBER - { - if($1->type != VAR || $1->u.var.type != TDOUBLE) - rterror("illegal assignment"); - $1->u.var.dval = $3; - $$ = $1; - } - | VAR '=' VAR +asgn: ID '=' expr { - switch($1->type){ - default: rterror("illegal assignment"); - case VAR: - if($1->u.var.type != $3->u.var.type) - rterror("illegal assignment"); - - switch($1->u.var.type){ - case TDOUBLE: - $1->u.var.dval = $3->u.var.dval; - break; - case TPOINT: - case TVECTOR: - case TNORMAL: - case TQUAT: - $1->u.var.pval = $3->u.var.pval; - break; - } - $$ = $1; + fprint(2, "asgn: ID = expr\n"); + + print("%s = ", $1.sym->name); + switch($1.sym->var.type){ + case TDOUBLE: + if($3.type == NODENUM) + print("%g", $3.num); + else if($3.sym->type == CONST) + print("%g", $3.sym->dconst); + else if($3.sym->type == ID && $3.sym->var.type == TDOUBLE) + print("%s", $3.sym->name); + else + yyerror("illegal assignment"); + break; + case TPOINT: + case TVECTOR: + case TNORMAL: + case TQUAT: + if($3.type == NODENUM) + print("Pt3(%g,%g,%g,%g)", $3.num, $3.num, $3.num, $3.num); + else if($3.sym->type == CONST) + print("Pt3(%g,%g,%g,%g)", + $3.sym->dconst, + $3.sym->dconst, + $3.sym->dconst, + $3.sym->dconst); + else if($3.sym->type == ID) + switch($3.sym->var.type){ + case TDOUBLE: + print("Pt3(%g,%g,%g,%g)", + $3.sym->var.dval, + $3.sym->var.dval, + $3.sym->var.dval, + $3.sym->var.dval); + break; + case TPOINT: + case TVECTOR: + case TNORMAL: + print("%s", $3.sym->name); + break; + case TQUAT: + print("Pt3(%g,%g,%g,%g)", + $3.sym->var.pval.y, + $3.sym->var.pval.z, + $3.sym->var.pval.w, + $3.sym->var.pval.x); + break; + } + else + yyerror("illegal assignment"); break; } + print(";\n"); + + $$ = $1; + break; } ; -exprs: exprs expr ';' - | expr ';' + +exprs: expr ';' { fprint(2, "exprs: expr\n"); } + | exprs expr ';' { fprint(2, "exprs: exprs expr\n"); } ; -expr: NUMBER - | VAR - { - Point3 *p; - - switch($1->type){ - case UNDEF: rterror("undefined variable"); - case CONST: $$ = $1->u.val; break; - case VAR: - switch($1->u.var.type){ - case TDOUBLE: $$ = $1->u.var.dval; break; - case TPOINT: - case TVECTOR: - case TNORMAL: - $$ = -1; - p = &$1->u.var.pval; - print("[%g %g %g %g]\n", p->x, p->y, p->z, p->w); - break; - } - break; - } - } + +expr: NUMBER { fprint(2, "expr: NUMBER %g\n", $1.num); } + | ID { fprint(2, "expr: ID\n"); } ; %% -int decltype; +int decltype = -1; Biobuf *bin; int lineno; @@ -125,61 +170,60 @@ void yyerror(char *msg) { fprint(2, "%s at line %d\n", msg, lineno); -} - -void -rterror(char *msg) -{ - fprint(2, "%s at line %d\n", msg, lineno); + exits("syntax error"); } int yylex(void) { Symbol *s; - char sname[256], *p; + char buf[256], *p; Rune r; int t; - while((r = Bgetrune(bin)) == ' ' || r == '\t') - ; + do{ + r = Bgetrune(bin); + if(r == '\n') + lineno++; + }while(isspace(r)); if(r == Beof) return 0; if(r == '.' || isdigitrune(r)){ Bungetrune(bin); - Bgetd(bin, &yylval.val); + Bgetd(bin, &yylval.node.num); + yylval.node.type = NODENUM; return NUMBER; } if(isalpharune(r)){ - p = sname; - + p = buf; do{ - if(p+runelen(r) - sname >= sizeof(sname)) - return r; /* force syntax error. */ + if(p+runelen(r) - buf >= sizeof(buf)) + return r; /* force syntax error. */ p += runetochar(p, &r); }while((r = Bgetrune(bin)) != Beof && (isalpharune(r) || isdigitrune(r))); Bungetrune(bin); *p = 0; - if((t = lookuptype(sname)) >= 0){ + if(strcmp(buf, "print") == 0) + return PRINT; + + if((t = lookuptype(buf)) >= 0){ yylval.type = t; return TYPE; } - if((s = lookup(sname)) == nil) - s = install(sname, UNDEF, 0); - yylval.sym = s; + if((s = lookup(buf)) == nil) + s = install(buf, UNDEF, 0); + yylval.node.sym = s; + yylval.node.type = NODESYM; - return s->type == UNDEF || s->type == CONST ? VAR : s->type; + return s->type == UNDEF || s->type == CONST ? ID : s->type; } - if(r == '\n') - lineno++; - return r; } @@ -193,6 +237,7 @@ usage(void) void main(int argc, char *argv[]) { + GEOMfmtinstall(); ARGBEGIN{ default: usage(); }ARGEND; @@ -207,6 +252,19 @@ main(int argc, char *argv[]) init(); yyparse(); +// int n; +// char *s, *name; +// while((n = yylex())){ +// s = n == NUMBER? "NUMBER": +// n == ID? "ID": +// n == NODENUM? "NODENUM": +// n == NODESYM? "NODESYM": +// n == TYPE? "TYPE": +// n == PRINT? "PRINT": +// n == UNDEF? "UNDEF": nil; +// name = n == ID? yylval.node.sym->name: ""; +// print("%d: %s%C%s\n", lineno, s?s:"", s?' ':n, name); +// } Bterm(bin); exits(nil); -- cgit v1.2.3