diff options
-rw-r--r-- | builtin.c | 2 | ||||
-rw-r--r-- | dat.h | 44 | ||||
-rw-r--r-- | readme.md | 10 | ||||
-rw-r--r-- | semblance.y | 268 | ||||
-rw-r--r-- | sym.c | 3 |
5 files changed, 200 insertions, 127 deletions
@@ -85,6 +85,6 @@ init(void) install(consts[i].name, CONST, consts[i].val); for(i = 0; i < nelem(builtins); i++){ s = install(builtins[i].name, BLTIN, 0); - s->u.fn = builtins[i].fn; + s->fn = builtins[i].fn; } } @@ -7,10 +7,29 @@ enum TQUAT, }; -typedef struct Var Var; -typedef struct Symbol Symbol; +enum +{ + NODENUM, + NODESYM, +}; + typedef struct Const Const; typedef struct Builtin Builtin; +typedef struct Var Var; +typedef struct Symbol Symbol; +typedef struct Node Node; + +struct Const +{ + char *name; + double val; +}; + +struct Builtin +{ + char *name; + double (*fn)(); +}; struct Var { @@ -27,21 +46,16 @@ struct Symbol char *name; int type; union { - Var var; - double val; /* constant value */ - double (*fn)(double); - } u; + Var var; /* ID */ + double dconst; /* CONST */ + double (*fn)(double); /* BLTIN */ + }; Symbol *next; }; -struct Const +struct Node { - char *name; - double val; -}; - -struct Builtin -{ - char *name; - double (*fn)(); + int type; + double num; /* NODENUM */ + Symbol *sym; /* NODESYM */ }; @@ -25,9 +25,9 @@ It's largely influenced by the [RSL][3] and [GLSL][4] languages. Point3 a, b; double s; - b = b * a; /* b = modulatept3(a, b); */ + b = b * a; /* b = modulatept3(b, a); */ b = b * s; /* b = mulpt3(b, s); */ - b = b * m; /* xform3(b, m); */ + b = b * m; /* b = xform3(b, m); */ b = b × a; /* b = crossvec3(b, a); */ b = b · a; /* b = dotvec3(b, a); */ m = m * n; /* mulm3(m, n); */ @@ -72,9 +72,9 @@ It's largely influenced by the [RSL][3] and [GLSL][4] languages. - fragment | in shader | in libgraphics | +--------------------------------+ - position → sp->v.p - color → sp->v.c - <attr> → sp->v.attrs["<attr>"] + position → sp->v->p + color → sp->v->c + <attr> → sp->v->attrs["<attr>"] - swizzles Point3 p; Color c; 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> TYPE -%token <val> NUMBER -%token <sym> VAR CONST BLTIN UNDEF -%type <val> expr exprs -%type <sym> asgn asgns +%token <node> NUMBER ID CONST BLTIN UNDEF +%type <node> expr exprs +%type <node> 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); @@ -15,7 +15,8 @@ install(char *s, int t, double v) memset(sym, 0, sizeof *sym); sym->name = estrdup(s); sym->type = t; - sym->u.val = v; + sym->dconst = v; + sym->var.type = -1; sym->next = symtab; symtab = sym; return sym; |