shithub: spirva

Download patch

ref: cbbb6280961fd5a120d2a5a765bd483fbfc86af7
author: sirjofri <[email protected]>
date: Sat Feb 3 17:59:18 EST 2024

adds files

--- /dev/null
+++ b/asm.c
@@ -1,0 +1,195 @@
+#include <u.h>
+#include <libc.h>
+#include "sym.h"
+#include "asm.h"
+#include "y.tab.h"
+#include "ops.h"
+
+#define NIL 0
+
+#define BUF4(x) ((x)%4 ? ((x)/4 + 1)*4 : (x))
+
+Inst res;
+Inst op;
+Inst args[10];
+int argptr = 0;
+
+void
+a_init()
+{
+	res.type = NIL;
+	op.type = NIL;
+	
+	for (int i = 0; i < argptr; i++) {
+		if (args[i].type == STR) {
+			free(args[i].str);
+		}
+	}
+	argptr = 0;
+}
+
+void
+assemble(void)
+{
+	u32int output[128];
+	u32int* optr;
+	u32int numwords = 0;
+	
+	int slen;
+	Inst in;
+	
+	if (res.type == SYM) {
+		numwords++;
+	}
+	
+	if (op.type == OP) {
+		numwords++;
+	} else {
+		fprint(2, "error: no Op to assemble!\n");
+	}
+	
+	for (int i = 0; i < argptr; i++) {
+		in = args[i];
+		switch (in.type) {
+		case NIL:
+		case OP:
+			fprint(2, "warning: strange situation!\n");
+			break;
+		case SYM:
+		case FLOAT:
+		case INT:
+			numwords++;
+			break;
+		case STR:
+			slen = strlen(in.str) + 1;
+			slen = BUF4(slen);
+			numwords += slen;
+		}
+	}
+	
+	if (debug) {
+		fprint(2, "%d: ", numwords);
+		fprint(2, " %10s =", res.type ? res.var->name : "");
+		fprint(2, " %s", op.type ? o_find(op.op) : nil);
+		
+		for (int i = 0; i < argptr; i++) {
+			in = args[i];
+			switch (in.type) {
+			case NIL:
+			case OP:
+				fprint(2, " X");
+				break;
+			case SYM:
+				fprint(2, " %s", in.var->name);
+				break;
+			case FLOAT:
+				fprint(2, " %f", in.f);
+				break;
+			case INT:
+				fprint(2, " %d", in.i);
+				break;
+			case STR:
+				fprint(2, " \"%s\"", in.str);
+				break;
+			}
+		}
+		fprint(2, "\n");
+	}
+	
+	optr = output;
+	*optr = (u32int)(numwords<<16 | op.op);
+	optr++;
+	
+	if (res.type == SYM) {
+		*optr = (u32int)res.var->id;
+		optr++;
+	}
+	
+	for (int i = 0; i < argptr; i++) {
+		in = args[i];
+		switch (in.type) {
+		case SYM:
+			*optr = (u32int)in.var->id;
+			optr++;
+			break;
+		case FLOAT:
+			*optr = (u32int)in.f;
+			optr++;
+			break;
+		case INT:
+			*optr = (u32int)in.i;
+			optr++;
+			break;
+		case STR:
+			slen = strlen(in.str);
+			memset(optr, 0, BUF4(slen));
+			memcpy(optr, in.str, slen);
+			optr += slen/4+1;
+			break;
+		}
+	}
+	
+	slen = optr - output;
+	write(1, output, slen*sizeof(u32int));
+	
+	a_init();
+}
+
+void
+arg(Inst s)
+{
+	if (argptr >= 10) {
+		sysfatal("error: too many arguments!\n");
+	}
+	args[argptr++] = s;
+}
+
+void
+a_result(Symbol *var)
+{
+	res.type = SYM;
+	res.var = var;
+}
+
+void
+a_op(uint inop)
+{
+	op.type = OP;
+	op.op = inop;
+}
+
+void
+a_var(Symbol *sym)
+{
+	Inst a;
+	a.type = SYM;
+	a.var = sym;
+	arg(a);
+}
+
+void
+a_float(double f)
+{
+	Inst a;
+	a.type = FLOAT;
+	a.f = f;
+	arg(a);
+}
+
+void
+a_int(int i)
+{
+	Inst a;
+	a.type = INT;
+	a.i = i;
+	arg(a);
+}
+
+void
+a_str(char *str)
+{
+	Inst a;
+	a.type = STR;
+	a.str = str;
+	arg(a);
+}
--- /dev/null
+++ b/asm.h
@@ -1,0 +1,23 @@
+typedef struct Inst Inst;
+struct Inst {
+	int type;
+	union {
+		Symbol *var;
+		uint op;
+		double f;
+		int i;
+		char *str;
+	};
+};
+
+extern int debug;
+
+void a_result(Symbol *var);
+void a_op(uint op);
+void a_var(Symbol *var);
+void a_float(double f);
+void a_int(int i);
+void a_str(char *str);
+
+void a_init(void);
+void assemble(void);
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,21 @@
+</$objtype/mkfile
+
+LFLAGS=-9
+
+TARG=\
+	spirva\
+
+OFILES=\
+	y.tab.$O\
+	lex.yy.$O\
+	sym.$O\
+	asm.$O\
+	ops.$O\
+
+YFILES=\
+	spirva.y\
+
+LFILES=\
+	spirva.l\
+
+</sys/src/cmd/mkone
--- /dev/null
+++ b/ops.c
@@ -1,0 +1,34 @@
+#include <u.h>
+#include <libc.h>
+#include "ops.h"
+
+Ops ops[] = {
+	{ "OpNop", 0 },
+	{ nil, nil },
+};
+
+uint
+o_lookup(char *n)
+{
+	Ops *o;
+	
+	for (o = ops; o->opname; o++) {
+		if (strcmp(o->opname, n) == 0) {
+			return o->op;
+		}
+	}
+	return 0;
+}
+
+char*
+o_find(uint op)
+{
+	Ops *o;
+	
+	for (o = ops; o->opname; o++) {
+		if (o->op == op) {
+			return o->opname;
+		}
+	}
+	return nil;
+}
--- /dev/null
+++ b/ops.h
@@ -1,0 +1,8 @@
+typedef struct Ops Ops;
+struct Ops {
+	char *opname;
+	uint op;
+};
+
+uint o_lookup(char *n);
+char *o_find(uint op);
--- /dev/null
+++ b/spirva.l
@@ -1,0 +1,48 @@
+%{
+#include "sym.h"
+#include "y.tab.h"
+#include "ops.h"
+%}
+
+WS	[ \t]
+ANUM	[A-Za-z0-9_]
+INT	-?[0-9]+
+FLOAT	-?([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)
+
+%%
+
+\;.*$ {}
+
+Op[A-Za-z0-9]+ {
+	yylval.op = o_lookup(yytext);
+	return OP;
+}
+
+\${ANUM}+ {
+	yylval.sym = symfind(strdup(yytext));
+	return SYM;
+}
+
+{INT} {
+	yylval.i = atoi(yytext);
+	return INT;
+}
+
+{FLOAT} {
+	yylval.f = atof(yytext);
+	return FLOAT;
+}
+
+{ANUM}+ {
+	yylval.str = strdup(yytext);
+	return STR;
+}
+
+\" { return '"'; }
+
+=|\n { return yytext[0]; }
+
+{WS}	{ }
+
+%%
+/* code */
--- /dev/null
+++ b/spirva.y
@@ -1,0 +1,80 @@
+%{
+#include <u.h>
+#include "sym.h"
+#include "asm.h"
+
+int debug;
+
+extern int yylex(void);
+extern int yyparse(void);
+%}
+%union {
+	uint op;
+	double f;
+	int i;
+	Symbol *sym;
+	char *str;
+}
+%token <sym> SYM
+%token <op> OP
+%token <f> FLOAT
+%token <i> INT
+%token <str> STR
+%right '='
+%%
+list: /* nothing */
+	| list '\n'
+	| list SYM '=' oplist '\n' { a_result($2); asm(); }
+	| list oplist '\n' { asm(); }
+	;
+
+oplist: OP arglist { a_op($1); }
+	;
+
+arglist: /* nothing */
+	| arglist arg
+	;
+
+arg: SYM { a_var($1); }
+	| INT { a_int($1); }
+	| FLOAT { a_float($1); }
+	| str
+	;
+
+str: '"' STR '"' { a_str($2); }
+%%
+	/* end of grammar */
+#include <libc.h>
+#include <bio.h>
+
+void
+init(void) {
+	a_init();
+}
+
+void
+asm(void) {
+	assemble();
+}
+
+void
+main(int argc, char **argv)
+{
+	ARGBEGIN{
+	case 'd':
+		debug++;
+		break;
+	}ARGEND;
+	
+	u32int magic = 0x07230203;
+	write(1, &magic, sizeof(u32int));
+	
+	for (init(); yyparse(); init())
+		asm();
+}
+
+void
+yyerror(char *s)
+{
+	fprint(2, "error: %s\n", s);
+}
--- /dev/null
+++ b/sym.c
@@ -1,0 +1,46 @@
+#include <u.h>
+#include <libc.h>
+#include "sym.h"
+
+Symbol* syms = nil;
+uint id;
+
+Symbol*
+symfind(char *name)
+{
+	Symbol *s;
+	
+	if (!syms) {
+		syms = malloc(sizeof(Symbol));
+		syms->name = name;
+		syms->next = nil;
+		syms->id = id = 0;
+		return syms;
+	}
+	
+	s = syms;
+	while (s) {
+		if (strcmp(s->name, name) == 0) {
+			return s;
+		}
+		if (!s->next) {
+			s->next = malloc(sizeof(Symbol));
+			s = s->next;
+			s->next = nil;
+			s->name = name;
+			s->id = ++id;
+			return s;
+		}
+		s = s->next;
+	}
+	return nil;
+}
+
+void
+printsyms()
+{
+	Symbol *s;
+	for (s = syms; s; s = s->next) {
+		print("symbol: %s (%d)\n", s->name, s->id);
+	}
+}
--- /dev/null
+++ b/sym.h
@@ -1,0 +1,9 @@
+typedef struct Symbol Symbol;
+struct Symbol {
+	char *name;
+	uint id;
+	Symbol *next;
+};
+
+Symbol *symfind(char *name);
+void printsyms(void);