aboutsummaryrefslogtreecommitdiff
path: root/minic
diff options
context:
space:
mode:
authorQuentin Carbonneaux <[email protected]>2015-10-13 14:30:16 -0400
committerQuentin Carbonneaux <[email protected]>2015-10-13 14:30:16 -0400
commit0c7bf521b38a1bfc3b608d135f458d777699772a (patch)
tree6b2e3943514fe058ab56449b190e591652b485a9 /minic
parent48cc2559298732a1e527e6494b9f16b94f78970e (diff)
add void type
Diffstat (limited to 'minic')
-rw-r--r--minic/minic.y43
1 files changed, 24 insertions, 19 deletions
diff --git a/minic/minic.y b/minic/minic.y
index 4087e9d..b73e043 100644
--- a/minic/minic.y
+++ b/minic/minic.y
@@ -13,17 +13,20 @@ enum {
};
enum { /* minic types */
- INT = 0,
- LNG = 1,
- PTR = 2,
- FUN = 3,
+ NIL,
+ INT,
+ LNG,
+ PTR,
+ FUN,
};
-#define IDIR(x) (((x) << 2) + PTR)
-#define FUNC(x) (((x) << 2) + FUN)
-#define DREF(x) ((x) >> 2)
-#define KIND(x) ((x) & 3)
-#define SIZE(x) (KIND(x) == INT ? 4 : 8)
+#define IDIR(x) (((x) << 3) + PTR)
+#define FUNC(x) (((x) << 3) + FUN)
+#define DREF(x) ((x) >> 3)
+#define KIND(x) ((x) & 7)
+#define SIZE(x) \
+ (x == NIL ? (die("void has no size"), 0) : \
+ x == INT ? 4 : 8)
typedef struct Node Node;
typedef struct Symb Symb;
@@ -163,15 +166,7 @@ varget(char *v)
char
irtyp(unsigned ctyp)
{
- switch (KIND(ctyp)) {
- default:
- die("internal error");
- case INT:
- return 'w';
- case PTR:
- case LNG:
- return 'l';
- }
+ return SIZE(ctyp) == 8 ? 'l' : 'w';
}
void
@@ -369,6 +364,8 @@ expr(Node *n)
sr = s0;
if (s1.ctyp == LNG && s0.ctyp == INT)
sext(&s0);
+ if (s0.ctyp != IDIR(NIL) || KIND(s1.ctyp) != PTR)
+ if (s1.ctyp != IDIR(NIL) || KIND(s0.ctyp) != PTR)
if (s1.ctyp != s0.ctyp)
die("invalid assignment");
fprintf(of, "\tstore%c ", irtyp(s1.ctyp));
@@ -559,6 +556,8 @@ param(char *v, unsigned ctyp, Node *pl)
{
Node *n;
+ if (ctyp == NIL)
+ die("invalid void declaration");
n = mknode(0, 0, pl);
varadd(v, 0, ctyp);
strcpy(n->u.v, v);
@@ -603,7 +602,7 @@ mkfor(Node *ini, Node *tst, Node *inc, Stmt *s)
%token <n> IDENT
%token PP MM LE GE SIZEOF
-%token TINT TLNG
+%token TVOID TINT TLNG
%token IF ELSE WHILE FOR BREAK RETURN
%right '='
@@ -628,6 +627,8 @@ fdcl: type IDENT '(' ')' ';'
idcl: type IDENT ';'
{
+ if ($1 == NIL)
+ die("invalid void declaration");
if (nglo == NGlo)
die("too many string literals");
ini[nglo] = alloc(sizeof "{ x 0 }");
@@ -692,6 +693,8 @@ dcls: | dcls type IDENT ';'
int s;
char *v;
+ if ($2 == NIL)
+ die("invalid void declaration");
v = $3->u.v;
s = SIZE($2);
varadd(v, 0, $2);
@@ -701,6 +704,7 @@ dcls: | dcls type IDENT ';'
type: type '*' { $$ = IDIR($1); }
| TINT { $$ = INT; }
| TLNG { $$ = LNG; }
+ | TVOID { $$ = NIL; }
;
stmt: ';' { $$ = 0; }
@@ -772,6 +776,7 @@ yylex()
char *s;
int t;
} kwds[] = {
+ { "void", TVOID },
{ "int", TINT },
{ "long", TLNG },
{ "if", IF },