ref: 25913255578877c5cdc9389168ca7f69a714f6ea
parent: af410eb53e3a4e3d134e480c8e669c5bbcca8eaa
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Nov 13 06:25:17 EST 2011
More parsing work. We are now closer to parsing the whole language.
--- a/parse/dump.c
+++ b/parse/dump.c
@@ -54,10 +54,12 @@
dumpnode(n->decl.init, fd, depth + 1);
break;
case Nblock:
+ fprintf(fd, "\n");
for (i = 0; i < n->block.nstmts; i++)
dumpnode(n->block.stmts[i], fd, depth+1);
break;
case Nifstmt:
+ fprintf(fd, "\n");
dumpnode(n->ifstmt.cond, fd, depth+1);
dumpnode(n->ifstmt.iftrue, fd, depth+1);
dumpnode(n->ifstmt.iffalse, fd, depth+1);
@@ -80,7 +82,7 @@
switch (n->lit.littype) {
case Lchr: fprintf(fd, " Lchr %c\n", n->lit.chrval); break;
case Lbool: fprintf(fd, " Lbool %s\n", n->lit.boolval ? "true" : "false"); break;
- case Lint: fprintf(fd, " Lint %ld\n", n->lit.intval); break;
+ case Lint: fprintf(fd, " Lint %llu\n", n->lit.intval); break;
case Lflt: fprintf(fd, " Lflt %lf\n", n->lit.fltval); break;
case Lfunc:
fprintf(fd, " Lfunc\n");
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -76,11 +76,11 @@
%token<tok> TDefault /* default */
%token<tok> TGoto /* goto */
-%token<tok><tok> TIntlit
-%token<tok><tok> TStrlit
-%token<tok><tok> TFloatlit
-%token<tok><tok> TChrlit
-%token<tok><tok> TBoollit
+%token<tok> TIntlit
+%token<tok> TStrlit
+%token<tok> TFloatlit
+%token<tok> TChrlit
+%token<tok> TBoollit
%token<tok> TEnum /* enum */
%token<tok> TStruct /* struct */
@@ -102,7 +102,7 @@
%token<tok> TRet /* -> */
%token<tok> TUse /* use */
%token<tok> TPkg /* pkg */
-%token<tok><tok> TSizeof /* sizeof */
+%token<tok> TSizeof /* sizeof */
%token<tok> TIdent
%token<tok> TEof
@@ -117,7 +117,7 @@
%type <node> bandexpr cmpexpr addexpr mulexpr shiftexpr prefixexpr postfixexpr
%type <node> funclit arraylit name block blockbody stmt label
%type <node> decl declvariants declbody declcore structelt enumelt unionelt
-%type <node> ifstmt falsebranch
+%type <node> ifstmt forstmt whilestmt elifs optexprln
%type <nodelist> arglist argdefs structbody enumbody unionbody params
@@ -401,29 +401,44 @@
stmt : retexpr
| label
| ifstmt
+ | forstmt
+ | whilestmt
+ | TEndln {$$ = NULL;}
;
-ifstmt : TIf exprln blockbody falsebranch {$$ = mkif($1->line, $2, $3, $4);}
+forstmt : TFor optexprln optexprln optexprln block
+ {$$ = mkloop($1->line, $2, $3, $4, $5);}
+ | TFor decl optexprln optexprln block
+ {$$ = mkloop($1->line, $2, $3, $4, $5);}
;
-falsebranch
- : elifblocks TEndblk {$$ = NULL;}
- | elifblocks TElse block {$$ = NULL;}
- | TElse block {$$ = $2;}
- | TEndblk {$$ = NULL;}
+optexprln: exprln {$$ = $1;}
+ | TEndln {$$ = NULL;}
+ ;
+
+whilestmt
+ : TWhile exprln block
+ {$$ = mkloop($1->line, NULL, $2, NULL, $3);}
;
-
-elifblocks
- : TElif exprln blockbody
- | elifblocks TElif exprln blockbody
+ifstmt : TIf exprln blockbody elifs
+ {$$ = mkif($1->line, $2, $3, $4);}
;
+elifs : TElif exprln blockbody elifs
+ {$$ = mkif($1->line, $2, $3, $4);}
+ | TElse blockbody TEndblk
+ {$$ = $2;}
+ | TEndblk
+ {$$ = NULL;}
+ ;
+
block : blockbody TEndblk
;
blockbody
- : stmt {$$ = mkblock(line, NULL); nlappend(&$$->block.stmts, &$$->block.nstmts, $1);}
+ : stmt {$$ = mkblock(line, NULL);
+ nlappend(&$$->block.stmts, &$$->block.nstmts, $1);}
| blockbody stmt {nlappend(&$$->block.stmts, &$$->block.nstmts, $2);}
;
--- a/parse/main.c
+++ b/parse/main.c
@@ -13,6 +13,7 @@
Node *file;
char *outfile;
+int debug;
static void usage(char *prog)
{
@@ -26,12 +27,15 @@
int opt;
int i;
- while ((opt = getopt(argc, argv, "ho:")) != -1) {
+ while ((opt = getopt(argc, argv, "dho:")) != -1) {
switch (opt) {
case 'o':
outfile = optarg;
break;
case 'h':
+ case 'd':
+ debug++;
+ break;
default:
usage(argv[0]);
exit(0);
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -1,5 +1,6 @@
-
-typedef unsigned char uchar;
+typedef uint32_t unichar;
+typedef long long vlong;
+typedef unsigned long long uvlong;
typedef struct Tok Tok;
typedef struct Node Node;
typedef struct Type Type;
@@ -52,6 +53,7 @@
struct Type {
Ty type;
int tid;
+ size_t nsub; /* type sub-parts. For fnsub, tusub, sdecls, udecls, edecls. */
union {
Node *name; /* Tyname: unresolved name */
Type **fnsub; /* Tyfunc: return, args */
@@ -101,9 +103,9 @@
Littype littype;
Type *type;
union {
- uint64_t intval;
+ uvlong intval;
double fltval;
- uint32_t chrval;
+ unichar chrval;
char *strval;
int boolval;
Node *fnval;
@@ -150,6 +152,7 @@
};
/* globals */
+extern int debug;
extern char *filename;
extern int line;
extern int ignorenl;
@@ -162,6 +165,7 @@
void *xrealloc(void *p, size_t size);
void die(char *msg, ...);
void fatal(int line, char *fmt, ...);
+char *strdupn(char *s, size_t len);
/* parsing etc */
void tokinit(char *file);
--- a/parse/tok.c
+++ b/parse/tok.c
@@ -13,7 +13,7 @@
#include "parse.h"
-#include "y.tab.h"
+#include "gram.h"
char *filename;
int line;
@@ -200,7 +200,7 @@
fatal(line, "Newlines not allowed in strings");
};
t = mktok(TStrlit);
- t->str = strndup(&fbuf[sstart], fidx - sstart);
+ t->str = strdupn(&fbuf[sstart], fidx - sstart);
return t;
}
@@ -227,7 +227,7 @@
fatal(line, "Newlines not allowed in char lit");
};
t = mktok(TStrlit);
- t->str = strndup(&fbuf[sstart], fidx - sstart);
+ t->str = strdupn(&fbuf[sstart], fidx - sstart);
return t;
}
@@ -274,7 +274,7 @@
case '-':
if (match('='))
tt = TSubeq;
- else if (match('+'))
+ else if (match('-'))
tt = TDec;
else if (match('>'))
tt = TRet;
@@ -388,13 +388,13 @@
strtod(&fbuf[start], &endp);
if (endp == &fbuf[fidx]) {
t = mktok(TFloatlit);
- t->str = strndup(&fbuf[start], fidx - start);
+ t->str = strdupn(&fbuf[start], fidx - start);
}
} else {
strtol(&fbuf[start], &endp, base);
if (endp == &fbuf[fidx]) {
t = mktok(TIntlit);
- t->str = strndup(&fbuf[start], fidx - start);
+ t->str = strdupn(&fbuf[start], fidx - start);
}
}
--- a/parse/type.c
+++ b/parse/type.c
@@ -158,65 +158,74 @@
int tybfmt(char *buf, size_t len, Type *t)
{
- size_t n;
char *p;
+ char *end;
+ //Type *sub;
- n = 0;
p = buf;
+ end = p + len;
switch (t->type) {
- case Tybad: n += snprintf(p, len - n, "BAD"); break;
- case Tyvoid: n += snprintf(p, len - n, "void"); break;
- case Tybool: n += snprintf(p, len - n, "bool"); break;
- case Tychar: n += snprintf(p, len - n, "char"); break;
- case Tyint8: n += snprintf(p, len - n, "int8"); break;
- case Tyint16: n += snprintf(p, len - n, "int16"); break;
- case Tyint: n += snprintf(p, len - n, "int"); break;
- case Tyint32: n += snprintf(p, len - n, "int32"); break;
- case Tyint64: n += snprintf(p, len - n, "int64"); break;
- case Tylong: n += snprintf(p, len - n, "long"); break;
- case Tybyte: n += snprintf(p, len - n, "byte"); break;
- case Tyuint8: n += snprintf(p, len - n, "uint8"); break;
- case Tyuint16: n += snprintf(p, len - n, "uint16"); break;
- case Tyuint: n += snprintf(p, len - n, "uint"); break;
- case Tyuint32: n += snprintf(p, len - n, "uint32"); break;
- case Tyuint64: n += snprintf(p, len - n, "uint64"); break;
- case Tyulong: n += snprintf(p, len - n, "ulong"); break;
- case Tyfloat32: n += snprintf(p, len - n, "float32"); break;
- case Tyfloat64: n += snprintf(p, len - n, "float64"); break;
- case Tyvalist: n += snprintf(p, len - n, "..."); break;
+ case Tybad: p += snprintf(p, end - p, "BAD"); break;
+ case Tyvoid: p += snprintf(p, end - p, "void"); break;
+ case Tybool: p += snprintf(p, end - p, "bool"); break;
+ case Tychar: p += snprintf(p, end - p, "char"); break;
+ case Tyint8: p += snprintf(p, end - p, "int8"); break;
+ case Tyint16: p += snprintf(p, end - p, "int16"); break;
+ case Tyint: p += snprintf(p, end - p, "int"); break;
+ case Tyint32: p += snprintf(p, end - p, "int32"); break;
+ case Tyint64: p += snprintf(p, end - p, "int64"); break;
+ case Tylong: p += snprintf(p, end - p, "long"); break;
+ case Tybyte: p += snprintf(p, end - p, "byte"); break;
+ case Tyuint8: p += snprintf(p, end - p, "uint8"); break;
+ case Tyuint16: p += snprintf(p, end - p, "uint16"); break;
+ case Tyuint: p += snprintf(p, end - p, "uint"); break;
+ case Tyuint32: p += snprintf(p, end - p, "uint32"); break;
+ case Tyuint64: p += snprintf(p, end - p, "uint64"); break;
+ case Tyulong: p += snprintf(p, end - p, "ulong"); break;
+ case Tyfloat32: p += snprintf(p, end - p, "float32"); break;
+ case Tyfloat64: p += snprintf(p, end - p, "float64"); break;
+ case Tyvalist: p += snprintf(p, end - p, "..."); break;
case Typtr:
- n += tybfmt(p, len - n, t->pbase);
- n += snprintf(p, len - n, "*");
+ p += tybfmt(p, end - p, t->pbase);
+ p += snprintf(p, end - p, "*");
break;
case Tyslice:
- n += tybfmt(p, len - n, t->sbase);
- p = &buf[n];
- n += snprintf(p, len - n, "[,]");
+ p += tybfmt(p, end - p, t->sbase);
+ p += snprintf(p, end - p, "[,]");
break;
case Tyarray:
- n += tybfmt(p, len - n, t->abase);
- p = &buf[n];
- n += snprintf(p, len - n, "[LEN]");
+ p += tybfmt(p, end - p, t->abase);
+ p += snprintf(p, end - p, "[LEN]");
break;
case Tyfunc:
+ p += snprintf(p, end - p, "(");
+ p += snprintf(p, end - p, ")");
+ break;
case Tytuple:
+ p += snprintf(p, end - p, "[");
+ p += snprintf(p, end - p, "]");
+ break;
case Tyvar:
+ p += snprintf(p, end - p, "@.%d", t->tid);
+ break;
case Typaram:
+ p += snprintf(p, end - p, "@%s", t->pname);
+ break;
case Tyname:
case Tystruct:
case Tyunion:
case Tyenum:
- snprintf(p, len - n, "TYPE ?");
+ snprintf(p, end - p, "TYPE ?");
break;
}
- return n;
+ return end - p;
}
char *tyfmt(char *buf, size_t len, Type *t)
{
- tyfmt(buf, len, t);
+ tybfmt(buf, len, t);
return buf;
}
--- a/parse/util.c
+++ b/parse/util.c
@@ -64,3 +64,13 @@
va_end(ap);
exit(1);
}
+
+/* Some systems don't have strndup. */
+char *strdupn(char *s, size_t len)
+{
+ char *ret;
+
+ ret = xalloc(len);
+ memcpy(ret, s, len);
+ return ret;
+}