shithub: semblance

Download patch

ref: c56f21d2819ed6c69215124364527b5f9fba371c
parent: a89ada0279a41c1bd6664dc385044702f78fffb4
author: rodri <rgl@antares-labs.eu>
date: Fri Mar 28 20:34:41 EDT 2025

initial expression parsing

--- a/builtin.c
+++ b/builtin.c
@@ -90,6 +90,20 @@
 	return -1;
 }
 
+int
+optype(int tt)
+{
+	switch(tt){
+	case '+': return OPADD;
+	case '-': return OPSUB;
+	case '*': return OPMUL;
+	case '/': return OPDIV;
+	case L'·': return OPDOT;
+	case L'×': return OPCROSS;
+	}
+	return -1;
+}
+
 void
 initsyms(void)
 {
@@ -101,46 +115,45 @@
 }
 
 char *
-gettokenname(Token *t)
+gettokenname(int t)
 {
 	static char *tab[] = {
-	 [TDOUBLE-TDOUBLE]	"TDOUBLE",
-	 [TPT2-TDOUBLE]		"TPT2",
-	 [TPT3-TDOUBLE]		"TPT3",
-	 [TVEC2-TDOUBLE]	"TVEC2",
-	 [TVEC3-TDOUBLE]	"TVEC3",
-	 [TNORMAL2-TDOUBLE]	"TNORMAL2",
-	 [TNORMAL3-TDOUBLE]	"TNORMAL3",
-	 [TQUAT-TDOUBLE]	"TQUAT",
-	 [TMAT3-TDOUBLE]	"TMAT3",
-	 [TMAT4-TDOUBLE]	"TMAT4",
-	 [TNUM-TDOUBLE]		"TNUM",
-	 [TSTR-TDOUBLE]		"TSTR",
-	 [TPP-TDOUBLE]		"TPP",
-	 [TMM-TDOUBLE]		"TMM",
-	 [TEQ-TDOUBLE]		"TEQ",
-	 [TLAND-TDOUBLE]	"TLAND",
-	 [TLOR-TDOUBLE]		"TLOR",
-	 [TID-TDOUBLE]		"TID",
+	 [TEOF-TEOF]		"TEOF",
+	 [TDOUBLE-TEOF]		"TDOUBLE",
+	 [TPT2-TEOF]		"TPT2",
+	 [TPT3-TEOF]		"TPT3",
+	 [TVEC2-TEOF]		"TVEC2",
+	 [TVEC3-TEOF]		"TVEC3",
+	 [TNORMAL2-TEOF]	"TNORMAL2",
+	 [TNORMAL3-TEOF]	"TNORMAL3",
+	 [TQUAT-TEOF]		"TQUAT",
+	 [TMAT3-TEOF]		"TMAT3",
+	 [TMAT4-TEOF]		"TMAT4",
+	 [TNUM-TEOF]		"TNUM",
+	 [TSTR-TEOF]		"TSTR",
+	 [TPP-TEOF]		"TPP",
+	 [TMM-TEOF]		"TMM",
+	 [TEQ-TEOF]		"TEQ",
+	 [TLAND-TEOF]		"TLAND",
+	 [TLOR-TEOF]		"TLOR",
+	 [TID-TEOF]		"TID",
 	};
+	static char buf[5][8];
+	static int idx;
 
-	if(t->type < TDOUBLE || t->type >= TDOUBLE + nelem(tab))
-		return nil;
+	if(t < TEOF || t >= TEOF + nelem(tab)){
+		snprint(buf[idx], sizeof buf[idx], "%C", t);
+		idx = (idx + 1) % nelem(buf);
+		return buf[idx - 1];
+	}
 
-	return tab[t->type-TDOUBLE];
+	return tab[t - TEOF];
 }
 
 void
 printtoken(Token *t)
 {
-	char *s;
-
-	s = gettokenname(t);
-	if(s == nil){
-		print("%C\n", t->type);
-		return;
-	}
-	print("%s", s);
+	print("%s", gettokenname(t->type));
 	if(t->type == TNUM)
 		print(" (%g)", t->v);
 	else if(t->type == TSTR || t->type == TID)
--- a/dat.h
+++ b/dat.h
@@ -1,5 +1,6 @@
 enum {
 	TEOF = 1<<24,
+	/* types */
 	TDOUBLE,
 	TPT2,
 	TPT3,
@@ -10,13 +11,16 @@
 	TQUAT,
 	TMAT3,
 	TMAT4,
+	/* literals */
 	TNUM,
 	TSTR,
+	/* ops */
 	TPP,
 	TMM,
 	TEQ,
 	TLAND,
 	TLOR,
+	/* syms */
 	TID,
 };
 
@@ -46,17 +50,6 @@
 };
 
 enum {
-	NODENUM,
-	NODESYM,
-};
-
-enum {
-	SYMVAR,
-	SYMCONST,
-	SYMTYPE,
-};
-
-enum {
 	TYPDOUBLE,
 	TYPPT2,
 	TYPPT3,
@@ -69,8 +62,31 @@
 	TYPMAT4,
 };
 
+enum {
+	OPADD,
+	OPSUB,
+	OPMUL,
+	OPDIV,
+	OPDOT,
+	OPCROSS,
+	OPUPLUS,
+	OPUMINUS,
+};
+
+enum {
+	SYMVAR,
+	SYMCONST,
+	SYMTYPE,
+};
+
+enum {
+	NODENUM,
+	NODESYM,
+};
+
 typedef struct Keyword Keyword;
 typedef struct Type Type;
+typedef struct Op Op;
 typedef struct Const Const;
 typedef struct Var Var;
 typedef struct Symbol Symbol;
@@ -85,6 +101,12 @@
 struct Type
 {
 	int type;
+};
+
+struct Op
+{
+	int type;
+	Rune tok;
 };
 
 struct Const
--- a/fns.h
+++ b/fns.h
@@ -13,8 +13,9 @@
 int opstart(int);
 int findop(char*);
 int vartype(int);
+int optype(int);
 void initsyms(void);
-char *gettokenname(Token*);
+char *gettokenname(int);
 void printtoken(Token*);
 
 /* lexer */
@@ -21,4 +22,6 @@
 int lex(Lexer*);
 int peek(Lexer*);
 int expect(Lexer*, int);
+int expectany(Lexer*, ...);
+int gotany(Lexer*, ...);
 int gottype(Lexer*);
--- a/lexer.c
+++ b/lexer.c
@@ -5,6 +5,8 @@
 #include "dat.h"
 #include "fns.h"
 
+extern int debuglexer;
+
 static Token Teof = {TEOF};
 static Token Terr = {-1};
 
@@ -17,9 +19,9 @@
 	case 8:
 		return r >= '0' && r <= '7';
 	case 16:
-		return isdigitrune(r) ||
-		(r >= 'a' && r <= 'f') ||
-		(r >= 'A' && r <= 'F');
+		return isdigitrune(r)
+		|| (r >= 'a' && r <= 'f')
+		|| (r >= 'A' && r <= 'F');
 	}
 	return isdigitrune(r);
 }
@@ -112,8 +114,8 @@
 				return Terr;
 			}
 			p += runetochar(p, &r);
-		}while((r = Bgetrune(l->in)) != Beof &&
-			(isalpharune(r) || isdigitrune(r) || r == '_'));
+		}while((r = Bgetrune(l->in)) != Beof
+			&& (isalpharune(r) || isdigitrune(r) || r == '_'));
 		Bungetrune(l->in);
 		*p = 0;
 
@@ -168,6 +170,8 @@
 		memset(&l->peektok, 0, sizeof(Token));
 	}else
 		l->tok = scan(l);
+	if(debuglexer)
+		fprint(2, "lex: '%s'\n", gettokenname(l->tok.type));
 	return l->tok.type;
 }
 
@@ -176,6 +180,8 @@
 {
 	if(l->peektok.type <= 0)
 		l->peektok = scan(l);
+	if(debuglexer)
+		fprint(2, "peek: '%s'\n", gettokenname(l->peektok.type));
 	return l->peektok.type;
 }
 
@@ -183,8 +189,8 @@
 expect(Lexer *l, int t)
 {
 	if(lex(l) != t){
-		werrstr("expected '%C', got '%C' (%s)",
-			t, l->tok.type, gettokenname(&l->tok));
+		werrstr("expected '%s', got '%s'",
+			gettokenname(t), gettokenname(l->tok.type));
 		return 0;
 	}
 	return 1;
@@ -191,21 +197,41 @@
 }
 
 int
-gottype(Lexer *l)
+expectany(Lexer *l, ...)
 {
-	switch(peek(l)){
-	case TDOUBLE:
-	case TPT2:
-	case TPT3:
-	case TVEC2:
-	case TVEC3:
-	case TNORMAL2:
-	case TNORMAL3:
-	case TQUAT:
-	case TMAT3:
-	case TMAT4:
-		lex(l);
-		return 1;
-	}
+	va_list a;
+	int t, e;
+
+	va_start(a, l);
+	t = lex(l);
+	while((e = va_arg(a, int)) != 0)
+		if(t == e)
+			return 1;
+	va_end(a);
+	werrstr("unexpected '%s'", gettokenname(t));
 	return 0;
+}
+
+int
+gotany(Lexer *l, ...)
+{
+	va_list a;
+	int t;
+
+	va_start(a, l);
+	while((t = va_arg(a, int)) != 0)
+		if(peek(l) == t){
+			lex(l);
+			return 1;
+		}
+	va_end(a);
+	return 0;
+}
+
+int
+gottype(Lexer *l)
+{
+	return gotany(l, TDOUBLE, TPT2, TPT3, TVEC2,
+		TVEC3, TNORMAL2, TNORMAL3, TQUAT,
+		TMAT3, TMAT4, 0);
 }
--