shithub: semblance

Download patch

ref: 97bc549d4b8bf638946ac4ff3b066941bca9a03b
parent: 11087295a24b0a8d08897824c7ee9676026fa159
author: rodri <[email protected]>
date: Thu Sep 5 11:45:27 EDT 2024

initial compiler work.

--- /dev/null
+++ b/alloc.c
@@ -1,0 +1,43 @@
+#include <u.h>
+#include <libc.h>
+
+void *
+emalloc(ulong n)
+{
+	void *p;
+
+	p = malloc(n);
+	if(p == nil)
+		sysfatal("malloc: %r");
+	setmalloctag(p, getcallerpc(&n));
+	return p;
+}
+
+void *
+erealloc(void *p, ulong n)
+{
+	void *np;
+
+	np = realloc(p, n);
+	if(np == nil){
+		if(n == 0)
+			return nil;
+		sysfatal("realloc: %r");
+	}
+	if(p == nil)
+		setmalloctag(np, getcallerpc(&p));
+	else
+		setrealloctag(np, getcallerpc(&p));
+	return np;
+}
+
+char *
+estrdup(char *s)
+{
+	char *ns;
+
+	ns = strdup(s);
+	if(ns == nil)
+		sysfatal("strdup: %r");
+	return ns;
+}
--- /dev/null
+++ b/builtin.c
@@ -1,0 +1,90 @@
+#include <u.h>
+#include <libc.h>
+#include <geometry.h>
+#include "dat.h"
+#include "fns.h"
+#include "y.tab.h"
+
+static char *types[] = {
+	"double",
+	"point",
+	"vector",
+	"normal",
+	"quat",
+};
+
+static char *ctypes[] = {
+	"double",
+	"Point3",
+	"Point3",
+	"Point3",
+	"Quaternion",
+};
+
+static Const consts[] = {
+	"π",	3.14159265358979323846,
+	"e",	2.71828182845904523536,
+	"γ",	0.57721566490153286060,
+	"DEG",	57.29577951308232087680,
+	"Φ",	1.61803398874989484820,
+};
+
+static Builtin builtins[] = {
+	"sin",		sin,
+	"cos",		cos,
+	"atan",		atan,
+	"atan2",	atan2,
+	"log",		log,
+	"log10",	log10,
+	"exp",		exp,
+	"sqrt",		sqrt,
+	"int",		round,
+	"abs",		fabs,
+};
+
+double
+round(double n)
+{
+	return floor(n + 0.5);
+}
+
+int
+lookuptype(char *s)
+{
+	int i;
+
+	for(i = 0; i < nelem(types); i++)
+		if(strcmp(s, types[i]) == 0)
+			return i;
+	return -1;
+}
+
+char *
+typename(int t)
+{
+	if(t >= 0 && t < nelem(types))
+		return types[t];
+	return nil;
+}
+
+char *
+ctypename(int t)
+{
+	if(t >= 0 && t < nelem(ctypes))
+		return ctypes[t];
+	return nil;
+}
+
+void
+init(void)
+{
+	Symbol *s;
+	int i;
+
+	for(i = 0; i < nelem(consts); i++)
+		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;
+	}
+}
--- /dev/null
+++ b/dat.h
@@ -1,0 +1,47 @@
+enum
+{
+	TDOUBLE,
+	TPOINT,
+	TVECTOR,
+	TNORMAL,
+	TQUAT,
+};
+
+typedef struct Var Var;
+typedef struct Symbol Symbol;
+typedef struct Const Const;
+typedef struct Builtin Builtin;
+
+struct Var
+{
+	int type;
+	union {
+		double dval;
+		Point3 pval;
+		Quaternion qval;
+	};
+};
+
+struct Symbol
+{
+	char *name;
+	int type;
+	union {
+		Var var;
+		double val;		/* constant value */
+		double (*fn)(double);
+	} u;
+	Symbol *next;
+};
+
+struct Const
+{
+	char *name;
+	double val;
+};
+
+struct Builtin
+{
+	char *name;
+	double (*fn)();
+};
--- /dev/null
+++ b/fns.h
@@ -1,0 +1,12 @@
+Symbol *install(char*, int, double);
+Symbol *lookup(char*);
+double round(double);
+int lookuptype(char*);
+char* typename(int);
+char* ctypename(int);
+void init(void);
+void *emalloc(ulong);
+void *erealloc(void*, ulong);
+char *estrdup(char*);
+
+int yyparse(void);
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,17 @@
+</$objtype/mkfile
+
+BIN=/$objtype/bin
+TARG=sslc
+OFILES=\
+	alloc.$O\
+	sym.$O\
+	builtin.$O\
+	y.tab.$O
+YFILES=\
+	semblance.y
+HFILES=\
+	dat.h\
+	fns.h\
+	y.tab.h
+
+</sys/src/cmd/mkone
--- /dev/null
+++ b/semblance.y
@@ -1,0 +1,213 @@
+%{
+#include <u.h>
+#include <libc.h>
+#include <ctype.h>
+#include <bio.h>
+#include <geometry.h>
+#include "dat.h"
+#include "fns.h"
+%}
+%union {
+	int type;
+	double val;
+	Symbol *sym;
+}
+%token	<type> TYPE
+%token	<val> NUMBER
+%token	<sym> VAR CONST BLTIN UNDEF
+%type	<val> expr exprs
+%type	<sym> asgn asgns
+%right	'='
+%%
+top:	/* ε */
+	| list
+	;
+list:	  prog
+	| list prog
+	;
+prog:	'\n'
+	| decls
+	| asgns
+	| exprs			{ print("\t%.8g\n", $1); }
+	;
+decls:	  decls decl
+	| decl
+	;
+decl:	  TYPE { decltype = $1; } vars ';'
+	;
+vars:	  VAR
+	{
+		if($1->type != UNDEF)
+			rterror("variable already exists");
+
+		$1->type = VAR;
+		$1->u.var.type = decltype;
+		print("%s %s;\n", ctypename(decltype), $1->name);
+	}
+	| vars ',' VAR
+	{
+		if($3->type != UNDEF)
+			rterror("variable already exists");
+
+		$3->type = VAR;
+		$3->u.var.type = decltype;
+		print("%s %s;\n", ctypename(decltype), $3->name);
+	}
+	;
+asgns:	  asgns asgn ';'
+	| asgn ';'
+	;
+asgn:	 VAR '=' NUMBER
+	{
+		if($1->type != VAR || $1->u.var.type != TDOUBLE)
+			rterror("illegal assignment");
+
+		$1->u.var.dval = $3;
+		$$ = $1;
+	}
+	| VAR '=' VAR
+	{
+		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;
+			break;
+		}
+	}
+	;
+exprs:	  exprs expr ';'
+	| expr ';'
+	;
+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;
+		}
+	}
+	;
+%%
+
+int decltype;
+Biobuf *bin;
+int lineno;
+
+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);
+}
+
+int
+yylex(void)
+{
+	Symbol *s;
+	char sname[256], *p;
+	Rune r;
+	int t;
+
+	while((r = Bgetrune(bin)) == ' ' || r == '\t')
+		;
+
+	if(r == Beof)
+		return 0;
+
+	if(r == '.' || isdigitrune(r)){
+		Bungetrune(bin);
+		Bgetd(bin, &yylval.val);
+		return NUMBER;
+	}
+
+	if(isalpharune(r)){
+		p = sname;
+
+		do{
+			if(p+runelen(r) - sname >= sizeof(sname))
+				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){
+			yylval.type = t;
+			return TYPE;
+		}
+
+		if((s = lookup(sname)) == nil)
+			s = install(sname, UNDEF, 0);
+		yylval.sym = s;
+
+		return s->type == UNDEF || s->type == CONST ? VAR : s->type;
+	}
+
+	if(r == '\n')
+		lineno++;
+
+	return r;
+}
+
+void
+usage(void)
+{
+	fprint(2, "usage: %s\n", argv0);
+	exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+	ARGBEGIN{
+	default: usage();
+	}ARGEND;
+	if(argc > 0)
+		usage();
+
+	bin = Bfdopen(0, OREAD);
+	if(bin == nil)
+		sysfatal("Bfdopen: %r");
+
+	lineno++;
+	init();
+
+	yyparse();
+
+	Bterm(bin);
+	exits(nil);
+}
--- /dev/null
+++ b/sym.c
@@ -1,0 +1,33 @@
+#include <u.h>
+#include <libc.h>
+#include <geometry.h>
+#include "dat.h"
+#include "fns.h"
+
+static Symbol *symtab;
+
+Symbol *
+install(char *s, int t, double v)
+{
+	Symbol *sym;
+
+	sym = emalloc(sizeof(Symbol));
+	memset(sym, 0, sizeof *sym);
+	sym->name = estrdup(s);
+	sym->type = t;
+	sym->u.val = v;
+	sym->next = symtab;
+	symtab = sym;
+	return sym;
+}
+
+Symbol *
+lookup(char *s)
+{
+	Symbol *sym;
+
+	for(sym = symtab; sym != nil; sym = sym->next)
+		if(strcmp(sym->name, s) == 0)
+			return sym;
+	return nil;
+}
--- /dev/null
+++ b/test.shader
@@ -1,0 +1,10 @@
+point a, b;
+double n;
+
+n = 1;
+n;
+
+a + b;
+a * n;
+n * b;
+n * n;