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);
}
--
⑨