ref: bfd97dce0cd0b532b0a6065fd1cf891169ebd204
parent: 97bc549d4b8bf638946ac4ff3b066941bca9a03b
author: rodri <[email protected]>
date: Thu Sep 19 17:21:26 EDT 2024
fixes and advances.
--- a/builtin.c
+++ b/builtin.c
@@ -85,6 +85,6 @@
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;
}
}
--- a/dat.h
+++ b/dat.h
@@ -7,11 +7,30 @@
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
{
int type;
@@ -27,21 +46,16 @@
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 */
};
--- a/readme.md
+++ b/readme.md
@@ -25,9 +25,9 @@
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 @@
- 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;
--- 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: /* ε */ { 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;
+ }
+ }
+ }
;
-prog: '\n'
- | decls
- | asgns
- | exprs { print("\t%.8g\n", $1); }
+
+decls: decl { decltype = -1; fprint(2, "decls: decl\n"); }
+ | decls decl { decltype = -1; fprint(2, "decls: decls decl\n"); }
;
-decls: decls decl
- | decl
+
+decl: TYPE { decltype = $1; } idlist ';' { fprint(2, "decl: TYPE idlist\n"); }
;
-decl: TYPE { decltype = $1; } vars ';'
- ;
-vars: VAR
+
+idlist: ID
{
- if($1->type != UNDEF)
- rterror("variable already exists");
+ fprint(2, "idlist: ID\n");
- $1->type = VAR;
- $1->u.var.type = decltype;
- print("%s %s;\n", ctypename(decltype), $1->name);
+ if($1.sym->type != UNDEF)
+ yyerror("variable already exists");
+
+ 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");
- $3->type = VAR;
- $3->u.var.type = decltype;
- print("%s %s;\n", ctypename(decltype), $3->name);
+ if($3.sym->type != UNDEF)
+ yyerror("variable already exists");
+
+ if(decltype < 0)
+ yyerror("no type specified");
+
+ $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");
+ fprint(2, "asgn: ID = expr\n");
- 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;
+ 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,24 +170,22 @@
yyerror(char *msg)
{
fprint(2, "%s at line %d\n", msg, lineno);
+ exits("syntax error");
}
-void
-rterror(char *msg)
-{
- fprint(2, "%s at line %d\n", msg, lineno);
-}
-
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;
@@ -149,16 +192,16 @@
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)));
@@ -165,21 +208,22 @@
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 @@
void
main(int argc, char *argv[])
{
+ GEOMfmtinstall();
ARGBEGIN{
default: usage();
}ARGEND;
@@ -207,6 +252,19 @@
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);
--- a/sym.c
+++ b/sym.c
@@ -15,7 +15,8 @@
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;