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;