commit 851ae9124493230ca2ca1f9ab767747701d615d2
parent 45d8d43dbefc75ce4b5d979a190071ea78527924
Author: Nihal Jere <nihal@nihaljere.xyz>
Date: Fri, 28 Jan 2022 23:33:06 -0600
more cleanup
hide blockstack internals, remove lex.h and parse.h, move finddecl to
blockstack, improve names, remove unused headers
Diffstat:
11 files changed, 69 insertions(+), 89 deletions(-)
diff --git a/blockstack.c b/blockstack.c
@@ -9,6 +9,21 @@
const struct block *blockstack[BLOCKSTACKSIZE];
size_t blocki;
+struct decl *
+finddecl(const struct slice s)
+{
+ for (int j = blocki - 1; j >= 0; j--) {
+ for (int i = 0; i < blockstack[j]->decls.len; i++) {
+ struct decl *decl = &blockstack[j]->decls.data[i];
+ if (slice_cmp(&s, &decl->s) == 0) {
+ return decl;
+ }
+ }
+ }
+
+ return NULL;
+}
+
void
blockpush(const struct block *const block)
{
@@ -33,7 +48,7 @@ const struct block *const
blockpeek()
{
if (blocki == 0)
- die("blockpop: cannot peek empty stack!");
+ return NULL;
return blockstack[blocki - 1];
}
diff --git a/blockstack.h b/blockstack.h
@@ -1,6 +1,4 @@
void blockpush(const struct block *const block);
struct block *blockpop();
struct block *blockpeek();
-
-extern const struct block *blockstack[BLOCKSTACKSIZE];
-extern size_t blocki;
+struct decl *finddecl(struct slice s);
diff --git a/ir.c b/ir.c
@@ -4,11 +4,9 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
-#include <strings.h>
#include "array.h"
#include "nooc.h"
-#include "parse.h"
#include "ir.h"
#include "util.h"
#include "blockstack.h"
diff --git a/lex.c b/lex.c
@@ -6,7 +6,6 @@
#include "nooc.h"
#include "ir.h"
#include "util.h"
-#include "lex.h"
#define ADVANCE(n) \
start.data += (n) ; \
@@ -18,9 +17,7 @@ lex(struct slice start)
{
size_t line = 1;
size_t col = 1;
- struct token *const head = calloc(1, sizeof(struct token));
- if (!head)
- return NULL;
+ struct token *const head = xcalloc(1, sizeof(struct token));
struct token *cur = head;
while (start.len) {
@@ -125,10 +122,7 @@ lex(struct slice start)
error(line, col, "invalid token");
}
- cur->next = calloc(1, sizeof(struct token));
-
- if (!cur->next)
- die("lex: failed to allocate next token");
+ cur->next = xcalloc(1, sizeof(struct token));
cur = cur->next;
}
diff --git a/lex.h b/lex.h
@@ -1 +0,0 @@
-struct token *lex(struct slice start);
diff --git a/main.c b/main.c
@@ -4,7 +4,6 @@
#include <string.h>
#include <stdint.h>
#include <stdio.h>
-#include <stdlib.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
@@ -14,8 +13,6 @@
#include "ir.h"
#include "util.h"
#include "elf.h"
-#include "lex.h"
-#include "parse.h"
#include "type.h"
#include "map.h"
#include "blockstack.h"
@@ -28,6 +25,9 @@ struct toplevel toplevel;
struct map *typesmap;
char *infile;
+struct block parse(const struct token *const start);
+struct token *lex(struct slice start);
+
uint64_t
data_push(const char *const ptr, const size_t len)
{
diff --git a/parse.c b/parse.c
@@ -4,7 +4,6 @@
#include <stdlib.h>
#include "nooc.h"
-#include "parse.h"
#include "ir.h"
#include "util.h"
#include "array.h"
@@ -12,26 +11,10 @@
#include "map.h"
#include "blockstack.h"
-const struct token *tok;
-
+static const struct token *tok;
static void parsenametypes(struct nametypes *const nametypes);
static size_t parsetype();
-struct decl *
-finddecl(const struct slice s)
-{
- for (int j = blocki - 1; j >= 0; j--) {
- for (int i = 0; i < blockstack[j]->decls.len; i++) {
- struct decl *decl = &(blockstack[j]->decls.data[i]);
- if (slice_cmp(&s, &decl->s) == 0) {
- return decl;
- }
- }
- }
-
- return NULL;
-}
-
static void
expect(const enum tokentype type)
{
@@ -49,7 +32,7 @@ parsestring(struct expr *const expr)
expr->kind = EXPR_LIT;
expr->class = C_STR;
expr->d.v.v.s = (struct slice){ 0 };
- struct slice str = tok->slice;
+ const struct slice str = tok->slice;
for (size_t i = 0; i < str.len; i++) {
switch (str.data[i]) {
case '\\':
@@ -99,7 +82,7 @@ parsenum(struct expr *const expr)
tok = tok->next;
}
-enum class
+static enum class
typetoclass(const struct type *const type)
{
switch (type->class) {
@@ -122,6 +105,8 @@ static size_t
parseexpr(struct block *const block)
{
struct expr expr = { 0 };
+ const struct type *type;
+ const struct decl *decl;
switch (tok->type) {
case TOK_LOOP:
expr.start = tok;
@@ -148,13 +133,11 @@ parseexpr(struct block *const block)
expect(TOK_RPAREN);
tok = tok->next;
return ret;
- break;
case TOK_NAME:
expr.start = tok;
// a procedure definition
if (slice_cmplit(&tok->slice, "proc") == 0) {
- struct decl decl = { 0 };
- struct type *type;
+ struct decl param = { 0 };
int8_t offset = 0;
expr.kind = EXPR_PROC;
expr.class = C_PROC;
@@ -164,46 +147,46 @@ parseexpr(struct block *const block)
parsenametypes(&expr.d.proc.out);
for (int i = expr.d.proc.in.len - 1; i >= 0; i--) {
- decl.s = expr.d.proc.in.data[i].name;
- decl.type = expr.d.proc.in.data[i].type;
- decl.in = true;
- type = &types.data[decl.type];
+ param.s = expr.d.proc.in.data[i].name;
+ param.type = expr.d.proc.in.data[i].type;
+ param.in = true;
+ type = &types.data[param.type];
offset += type->size;
- array_add((&expr.d.proc.block.decls), decl);
+ array_add((&expr.d.proc.block.decls), param);
}
for (size_t i = 0; i < expr.d.proc.out.len; i++) {
- decl.s = expr.d.proc.out.data[i].name;
- decl.type = typeref(expr.d.proc.out.data[i].type);
- decl.in = decl.out = true;
- type = &types.data[decl.type];
+ param.s = expr.d.proc.out.data[i].name;
+ param.type = typeref(expr.d.proc.out.data[i].type);
+ param.in = param.out = true;
+ type = &types.data[param.type];
offset += type->size;
- array_add((&expr.d.proc.block.decls), decl);
+ array_add((&expr.d.proc.block.decls), param);
}
parseblock(&expr.d.proc.block);
// a function call
} else if (tok->next && tok->next->type == TOK_LPAREN) {
- size_t pidx;
expr.d.call.name = tok->slice;
- struct decl *decl = finddecl(expr.d.call.name);
+ decl = finddecl(expr.d.call.name);
if (slice_cmplit(&expr.d.call.name, "syscall") == 0) {
expr.class = C_INT;
} else {
if (decl == NULL)
error(expr.start->line, expr.start->col, "undeclared procedure '%.*s'", expr.d.s.len, expr.d.s.data);
- struct type *proctype = &types.data[decl->type];
- if (proctype->d.params.out.len == 1) {
- struct type *rettype = &types.data[*proctype->d.params.out.data];
+ type = &types.data[decl->type];
+ if (type->d.params.out.len == 1) {
+ struct type *rettype = &types.data[*type->d.params.out.data];
expr.class = typetoclass(rettype);
- }
+ } else if (type->d.params.out.len > 1)
+ error(tok->line, tok->col, "only one return supported");
}
tok = tok->next->next;
expr.kind = EXPR_FCALL;
while (tok->type != TOK_RPAREN) {
- pidx = parseexpr(block);
+ size_t pidx = parseexpr(block);
array_add((&expr.d.call.params), pidx);
if (tok->type == TOK_RPAREN)
break;
@@ -217,7 +200,7 @@ parseexpr(struct block *const block)
expr.kind = EXPR_IDENT;
expr.d.s = tok->slice;
- struct decl *decl = finddecl(expr.d.s);
+ decl = finddecl(expr.d.s);
if (decl == NULL)
error(expr.start->line, expr.start->col, "undeclared identifier '%.*s'", expr.d.s.len, expr.d.s.data);
expr.class = typetoclass(&types.data[decl->type]);
@@ -289,7 +272,7 @@ binary_common:
return exprs.len - 1;
}
-void
+static void
parsetypelist(struct typelist *const list)
{
expect(TOK_LPAREN);
@@ -391,7 +374,7 @@ static void
parseblock(struct block *const block)
{
struct statement statement;
- bool curlies = false;
+ bool curlies = false, toplevel_decl = blockpeek() == NULL;
blockpush(block);
if (tok->type == TOK_LCURLY) {
@@ -404,7 +387,7 @@ parseblock(struct block *const block)
statement.start = tok;
if (tok->type == TOK_LET) {
struct decl decl = { 0 };
- decl.toplevel = !(blocki - 1);
+ decl.toplevel = toplevel_decl;
decl.start = tok;
statement.kind = STMT_DECL;
tok = tok->next;
@@ -417,15 +400,14 @@ parseblock(struct block *const block)
expect(TOK_EQUAL);
tok = tok->next;
- if (finddecl(decl.s)) {
+ if (finddecl(decl.s))
error(tok->line, tok->col, "repeat declaration!");
- }
decl.val = parseexpr(block);
array_add((&block->decls), decl);
statement.idx = block->decls.len - 1;
- array_add((block), statement);
+ array_add(block, statement);
} else if (tok->type == TOK_RETURN) {
statement.kind = STMT_RETURN;
tok = tok->next;
diff --git a/parse.h b/parse.h
@@ -1,3 +0,0 @@
-struct block parse(const struct token *const tok);
-struct nametype *findparam(struct nametypes *params, struct slice s);
-struct decl *finddecl(struct slice s);
diff --git a/type.c b/type.c
@@ -5,13 +5,13 @@
#include <string.h>
#include "nooc.h"
-#include "parse.h"
#include "ir.h"
#include "util.h"
#include "type.h"
#include "map.h"
#include "blake3.h"
#include "array.h"
+#include "blockstack.h"
// hashtable based on cproc's map.c
@@ -165,8 +165,8 @@ type_put(const struct type *const type)
void
typecompat(const size_t typei, const size_t expri)
{
- struct type *type = &types.data[typei];
- struct expr *expr = &exprs.data[expri];
+ const struct type *const type = &types.data[typei];
+ const struct expr *const expr = &exprs.data[expri];
switch (type->class) {
case TYPE_INT:
@@ -201,7 +201,7 @@ typecompat(const size_t typei, const size_t expri)
const size_t
typeref(const size_t typei)
{
- struct type ref = {
+ const struct type ref = {
.class = TYPE_REF,
.size = 8,
.d.subtype = typei
@@ -214,30 +214,28 @@ static void
typecheckcall(const struct expr *const expr)
{
assert(expr->kind == EXPR_FCALL);
- struct decl *fdecl = finddecl(expr->d.call.name);
+ const struct decl *const decl = finddecl(expr->d.call.name);
- if (fdecl == NULL) {
- if (slice_cmplit(&expr->d.call.name, "syscall") == 0) {
+ if (decl == NULL) {
+ if (slice_cmplit(&expr->d.call.name, "syscall") == 0)
return;
- } else {
+ else
error(expr->start->line, expr->start->col, "unknown function '%.*s'", expr->d.call.name.len, expr->d.call.name.data);
- }
}
- struct type *ftype = &types.data[fdecl->type];
- assert(ftype->class == TYPE_PROC);
+ const struct type *const type = &types.data[decl->type];
+ assert(type->class == TYPE_PROC);
// should this throw an error instead and we move the check out of parsing?
- assert(expr->d.call.params.len == ftype->d.params.in.len);
- for (int i = 0; i < ftype->d.params.in.len; i++) {
- typecompat(ftype->d.params.in.data[i], expr->d.call.params.data[i]);
- }
+ assert(expr->d.call.params.len == type->d.params.in.len);
+ for (int i = 0; i < type->d.params.in.len; i++)
+ typecompat(type->d.params.in.data[i], expr->d.call.params.data[i]);
}
static void
typecheckexpr(const size_t expri)
{
- struct expr *expr = &exprs.data[expri];
+ const struct expr *const expr = &exprs.data[expri];
switch (expr->kind) {
case EXPR_BINARY:
typecheckexpr(expr->d.bop.left);
@@ -267,8 +265,8 @@ typecheck(const struct block *const block)
{
for (size_t i = 0; i < block->len; i++) {
const struct statement *const statement = &block->data[i];
- struct decl *decl;
- struct assgn *assgn;
+ const struct decl *decl;
+ const struct assgn *assgn;
switch (block->data[i].kind) {
case STMT_ASSGN:
assgn = &assgns.data[statement->idx];
@@ -278,7 +276,7 @@ typecheck(const struct block *const block)
typecheckexpr(assgn->val);
if (decl->out) {
- struct type *type = &types.data[decl->type];
+ const struct type *const type = &types.data[decl->type];
typecompat(type->d.subtype, assgn->val);
} else {
typecompat(decl->type, assgn->val);
diff --git a/util.c b/util.c
@@ -240,7 +240,7 @@ slice_cmp(const struct slice *const s1, const struct slice *const s2)
int
slice_cmplit(const struct slice *const s1, const char *const s2)
{
- size_t len = strlen(s2);
+ const size_t len = strlen(s2);
if (s1->len < len)
return 1;
diff --git a/x64.c b/x64.c
@@ -2,7 +2,6 @@
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
-#include <strings.h>
#include "nooc.h"
#include "ir.h"