shithub: semblance

Download patch

ref: bfd97dce0cd0b532b0a6065fd1cf891169ebd204
parent: 97bc549d4b8bf638946ac4ff3b066941bca9a03b
author: rodri <rgl@antares-labs.eu>
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;