shithub: hammer

Download patch

ref: 469b6871283ee08925584726368cd100c4275fef
parent: dd9a8551019ff0bfb4c5af583dc60419d28c4bb1
author: Jacob Moody <moody@posixcafe.org>
date: Fri Nov 17 14:07:16 EST 2023

structs, type decls, decl fixup, refactor

--- a/n.y
+++ b/n.y
@@ -10,6 +10,36 @@
 int yyparse(void);
 void yyerror(char*);
 
+struct {
+	char *s;
+	/* todo */
+} typetab[1000] = {
+	"byte",
+	"int",
+	"long",
+	"vlong",
+	"uint",
+	"ulong",
+	"uvlong",
+	"float32",
+	"float64",
+
+	nil,
+};
+
+void
+addtype(char *s)
+{
+	int i;
+
+	for(i = 0; i < nelem(typetab)-1; i++){
+		if(typetab[i].s != nil)
+			continue;
+		typetab[i].s = s;
+		typetab[i+1].s = nil;
+	}
+}
+
 %}
 
 %union
@@ -18,7 +48,8 @@
 	long ival;
 }
 
-%token FUNC DEF IF FOR STRUCT MOD USE TYPE NAME NUM OR AND NOTEQ SHIFTL SHIFTR
+%token FUNC DEF IF FOR MOD USE OR AND NOTEQ SHIFTL SHIFTR STRUCT
+%token TYPE NAME NUM
 
 %token	<sval>	NAME TYPE;
 %token	<ival>	NUM
@@ -29,16 +60,28 @@
 :	prog top
 |	top
 
-sem
-:	';'
-
 top
-:	FUNC NAME '(' args ')' '-' '>' return '{' stmts '}'
-|	MOD NAME sem
-|	USE NAME sem
+:	FUNC NAME '(' args ')' return '{' stmts '}'
+|	MOD NAME ';'
+|	USE NAME ';'
+|	def ';'
 
+sdecls
+:
+|	sdecls NAME ':' TYPE ';'
+
+def
+:	DEF NAME TYPE
+	{
+		addtype($2);
+	}
+|	DEF NAME STRUCT '{' sdecls '}'
+	{
+		addtype($2);
+	}
+
 return
-:	TYPE
+:	'-' '>' TYPE
 |
 
 unary
@@ -79,18 +122,42 @@
 |	stmts stmt
 
 decl
-:	NAME ':' expr
+:	NAME ':' TYPE
+|	NAME ':' '=' expr
 
 stmt
-:	expr sem
+:	expr ';'
 |	'{' stmts '}'
-|	decl sem
+|	decl ';'
 
+arg
+:	NAME TYPE
+
 args
-:	NAME
+:	
+|	arg
+|	args ',' arg
 
 %%
 
+struct {
+	char *s;
+	int type;
+} keytab[] = {
+	"fn", FUNC,
+	"type", DEF,
+	"if", IF,
+	"for", FOR,
+	"mod", MOD,
+	"use", USE,
+	"&&", AND,
+	"||", OR,
+	"!=", NOTEQ,
+	"<<", SHIFTR,
+	">>", SHIFTL,
+	"struct", STRUCT,
+};
+
 Biobuf *bin;
 
 int
@@ -180,20 +247,28 @@
 	case '(': case ')':
 	case '+': case '-':
 	case '*': case '/':
-	case '%':
+	case '%': case ':':
 	case '>': case '<':
+	case ',':
 		return c;
 	}
 	ungetc();
 	wordlex(buf, sizeof buf);
 
-	if(strcmp(buf, "fn") == 0)
-		return FUNC;
-	if(strcmp(buf, "||") == 0)
-		return OR;
-	if(strcmp(buf, "&&") == 0)
-		return AND;
+	for(i = 0; i < nelem(keytab); i++)
+		if(strcmp(keytab[i].s, buf) == 0)
+			return keytab[i].type;
 
+	for(i = 0; i < nelem(typetab); i++){
+		if(typetab[i].s == nil)
+			break;
+		if(strcmp(typetab[i].s, buf) == 0){
+			yylval.sval = strdup(buf);
+			return TYPE;
+		}
+	}
+			
+
 	if(isdigit(buf[0])){
 		yylval.ival = atoi(buf);
 		return NUM;
@@ -203,6 +278,8 @@
 	return NAME;
 }
 
+int debug;
+
 int
 yylex(void)
 {
@@ -209,6 +286,16 @@
 	int c;
 
 	c = yylex2();
+	if(!debug)
+		return c;
+	if(c < Runeself)
+		fprint(2, "%c\n", c);
+	else if(c == NAME)
+		fprint(2, "NAME %s\n", yylval.sval);
+	else if(c == TYPE)
+		fprint(2, "TYPE %s\n", yylval.sval);
+	else if(c == NUM)
+		fprint(2, "NUM %ld\n", yylval.ival);
 	return c;
 }
 
@@ -215,7 +302,7 @@
 void
 usage(void)
 {
-	fprint(2, "usage: %s\n", argv0);
+	fprint(2, "usage: [-d] %s\n", argv0);
 	exits("usage");
 }
 
@@ -223,6 +310,9 @@
 main(int argc, char **argv)
 {
 	ARGBEGIN{
+	case 'd':
+		debug++;
+		break;
 	default:
 		usage();
 		break;