commit 5ebdcce90ba41520880d8e5270f1ca4275c0103a
parent c46ccba8c2ad085e053b47b694551a1a6b1b7744
Author: erai <erai@omiltem.net>
Date: Wed, 20 Nov 2024 23:23:39 -0500
add nil
Diffstat:
6 files changed, 32 insertions(+), 4 deletions(-)
diff --git a/cc1.om b/cc1.om
@@ -266,7 +266,7 @@ func mark_expr_used(c: *compiler, d: *decl, n: *node) {
mark_expr_used(c, d, n.a);
return;
} else if kind == N_SIZEOF || kind == N_STR || kind == N_NUM
- || kind == N_CHAR {
+ || kind == N_CHAR || kind == N_NIL {
return;
} else {
cdie(c, "not an expression");
@@ -647,6 +647,12 @@ func typecheck_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
}
n.t = mktype1(c, TY_PTR, mktype0(c, TY_BYTE));
+ } else if (kind == N_NIL) {
+ if (!rhs) {
+ cdie(c, "nil is not an lexpr");
+ }
+
+ n.t = mktype0(c, TY_NIL);
} else if (kind == N_NUM) {
if (!rhs) {
cdie(c, "num is not an lexpr");
@@ -1334,6 +1340,8 @@ func compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
kind = n.kind;
if (kind == N_STR) {
emit_str(c.s, n.s);
+ } else if (kind == N_NIL) {
+ emit_num(c.s, 0);
} else if (kind == N_NUM) {
emit_num(c.s, n.n);
} else if (kind == N_CHAR) {
@@ -1635,7 +1643,7 @@ func call_check(c: *compiler, n: *node): int {
// Possible side effect in the first position
result = call_check(c, n.a);
} else if n.kind == N_STR || n.kind == N_NUM || n.kind == N_CHAR
- || n.kind == N_IDENT || n.kind == N_SIZEOF {
+ || n.kind == N_IDENT || n.kind == N_SIZEOF || n.kind == N_NIL {
// No side effects
} else {
fdputd(2, n.kind);
diff --git a/cc3.peg b/cc3.peg
@@ -93,7 +93,7 @@ cast_expr <- 'as' sp type
post_expr <- primary (index_expr / call_expr / member_expr / cast_expr)*
primary <- ident sp / hex sp / dec sp / str sp / char sp
- / sizeof_expr / '(' sp expr ')' sp
+ / sizeof_expr / nil sp / '(' sp expr ')' sp
sizeof_expr <- sizeof sp '(' sp expr ')' sp
@@ -103,7 +103,7 @@ str <- ["] ([\\] . / !["] .)* ["]
char <- ['] ([\\] . / !['] .)+ [']
reserved <- return / break / sizeof / if / else / loop / continue / goto
- / var / enum / struct / union / byte / int / void / func / as
+ / var / enum / struct / union / byte / int / void / func / as / nil
return <- 'return' ![a-zA-Z0-9_]
break <- 'break' ![a-zA-Z0-9_]
diff --git a/cout.om b/cout.om
@@ -317,6 +317,8 @@ func ctranslate_expr(c: *compiler, n: *node) {
} else if n.kind == N_NUM {
fputd(c.cout, n.n);
fputs(c.cout, "UL");
+ } else if n.kind == N_NIL {
+ fputs(c.cout, "(void *)0");
} else if n.kind == N_CHAR {
fputd(c.cout, n.n);
} else if n.kind == N_CALL {
diff --git a/node.om b/node.om
@@ -15,6 +15,7 @@ enum {
N_NUM,
N_CHAR,
N_STR,
+ N_NIL,
N_STMTLIST,
N_EXPRLIST,
N_CALL,
@@ -126,6 +127,7 @@ func node_to_str(kind: int): *byte {
if kind == N_NUM { return "N_NUM"; }
if kind == N_CHAR { return "N_CHAR"; }
if kind == N_STR { return "N_STR"; }
+ if kind == N_NIL { return "N_NIL"; }
if kind == N_STMTLIST { return "N_STMTLIST"; }
if kind == N_EXPRLIST { return "N_EXPRLIST"; }
if kind == N_CALL { return "N_CALL"; }
diff --git a/parse2.om b/parse2.om
@@ -610,6 +610,8 @@ func reconstruct_primary(c: *parser, pn: *peg_node): *node {
return reconstruct_char(c, pn);
} else if pn.tag == P_sizeof_expr {
return reconstruct_sizeof(c, pn);
+ } else if pn.tag == P_nil {
+ return reconstruct_nil(c, pn);
} else if pn.tag == P_expr {
return reconstruct_expr(c, pn);
} else {
@@ -694,6 +696,15 @@ func reconstruct_char(c: *parser, pn: *peg_node): *node {
n.n = x;
return n;
}
+
+func reconstruct_nil(c: *parser, pn: *peg_node): *node {
+ var n: *node;
+ assert(pn.tag == P_nil, "nil");
+ n = mknode0(c, N_NIL);
+ copypos(n, pn);
+ return n;
+}
+
func reconstruct_sizeof(c: *parser, pn: *peg_node): *node {
var n: *node;
var a: *node;
diff --git a/type.om b/type.om
@@ -6,6 +6,7 @@ struct type {
}
enum {
+ TY_NIL,
TY_VOID,
TY_INT,
TY_BYTE,
@@ -47,6 +48,10 @@ func unify(c: *compiler, a: *type, b: *type) {
return;
}
+ if a && b && ((a.kind == TY_NIL && b.kind == TY_PTR) || (a.kind == TY_PTR && b.kind == TY_NIL)) {
+ return;
+ }
+
if ((a && !b) || (b && !a) || a.kind != b.kind) {
cdie(c, "type error");
}