os

An operating system
git clone https://erai.gay/code/os/
Log | Files | Refs | README | LICENSE

commit 5ebdcce90ba41520880d8e5270f1ca4275c0103a
parent c46ccba8c2ad085e053b47b694551a1a6b1b7744
Author: erai <erai@omiltem.net>
Date:   Wed, 20 Nov 2024 23:23:39 -0500

add nil

Diffstat:
Mcc1.om | 12++++++++++--
Mcc3.peg | 4++--
Mcout.om | 2++
Mnode.om | 2++
Mparse2.om | 11+++++++++++
Mtype.om | 5+++++
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"); }