spl

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 9d60becbda4e8138e00b15b68bc0edbb53356f2b
parent 26376b868067410a95147da8549cc0a698846c2e
Author: Brian Swetland <swetland@frotz.net>
Date:   Fri, 13 Oct 2023 17:15:27 -0700

compiler0: hacky varargs for printing

just enough so we can easily wire up error(...), info(...), etc

Diffstat:
Mcompiler0.c | 44+++++++++++++++++++++++++++++++++++++++++++-
Minc/builtin.type.h | 2+-
Minc/library.impl.c | 2+-
Minc/library.impl.h | 2+-
4 files changed, 46 insertions(+), 4 deletions(-)

diff --git a/compiler0.c b/compiler0.c @@ -46,6 +46,7 @@ enum { SYMBOL_FLD, // struct field SYMBOL_PTR, // struct *field SYMBOL_DEF, // enum + SYMBOL_FN, }; struct Scope { @@ -79,6 +80,7 @@ enum { // TYPE_POINTER, TYPE_ARRAY, TYPE_SLICE, + TYPE_STR, TYPE_STRUCT, // TYPE_FUNC, TYPE_ENUM, @@ -145,6 +147,7 @@ struct Ctx { String *idn_continue; Type *type_void; // base types + Type *type_str; Type *type_u32; Type *type_i32; Type *type_u8; @@ -316,6 +319,7 @@ void ctx_init() { ctx.idn_continue = string_make("continue", 8); ctx.type_void = type_make(string_make("void", 4), TYPE_VOID, nil, nil, 0); + ctx.type_u32 = type_make(string_make("str", 3), TYPE_STR, nil, nil, 0); ctx.type_u32 = type_make(string_make("u32", 3), TYPE_U32, nil, nil, 0); ctx.type_i32 = type_make(string_make("i32", 3), TYPE_U32, nil, nil, 0); ctx.type_u8 = type_make(string_make("u8", 2), TYPE_U8, nil, nil, 0); @@ -878,6 +882,36 @@ String *parse_name(const char* what) { void parse_expr(void); +int is_type(const char* typename) { + String *name = ctx.ident; + Symbol *sym = symbol_find(name); + if (sym == nil) { + error("undefined identifier '%s'", name->text); + } + return !strcmp(sym->type->name->text, typename); +} + +// cheesy varargs for a few special purpose functions +void parse_va_call(const char* fn) { + emit_impl("({ int fd = fn_%s_begin();", fn); + while (ctx.tok != tCPAREN) { + if (ctx.tok == tSTR) { + emit_impl(" fn_writes(fd,"); + } else if (ctx.tok == tIDN) { + emit_impl(" fn_write%s(fd,", is_type("str") ? "s" : "x"); + } else { + emit_impl(" fn_writex(fd,"); + } + parse_expr(); + emit_impl(");"); + if (ctx.tok != tCPAREN) { + require(tCOMMA); + } + } + next(); + emit_impl(" fn_%s_end(); })", fn); +} + void parse_ident(void) { String *name = ctx.ident; Symbol *sym = symbol_find(name); @@ -889,6 +923,10 @@ void parse_ident(void) { if (ctx.tok == tOPAREN) { // function call next(); + if (!strcmp(name->text, "error")) { + parse_va_call("error"); + return; + } emit_impl("fn_%s(", name->text); while (ctx.tok != tCPAREN) { parse_expr(); @@ -902,7 +940,7 @@ void parse_ident(void) { } else if (ctx.tok == tDOT) { // field access next(); String *fieldname = parse_name("field name"); - Symbol *field = type_find_field(sym->type, fieldname); + //Symbol *field = type_find_field(sym->type, fieldname); emit_impl("($%s->%s)", name->text, fieldname->text); } else if (ctx.tok == tOBRACK) { // array access next(); @@ -1415,6 +1453,10 @@ void parse_function(void) { emit_decl("%s);\n", ctx.scope->first ? "" : "void"); emit_impl("%s) {\n", ctx.scope->first ? "" : "void"); + // TODO: more complete type if needed... + Symbol *sym = symbol_make_global(fname, rtype); + sym->kind = SYMBOL_FN; + require(tOBRACE); scope_push(SCOPE_BLOCK); diff --git a/inc/builtin.type.h b/inc/builtin.type.h @@ -10,4 +10,4 @@ typedef int16_t t$i16; typedef uint8_t t$u8; typedef int8_t t$i8; -typedef uint8_t *t$u8$; +typedef uint8_t *t$str; diff --git a/inc/library.impl.c b/inc/library.impl.c @@ -8,7 +8,7 @@ void fn__hexout_(int x) { printf("D %08x\n", x); } -void fn_writes(int fd, t$u8$ s) { +void fn_writes(int fd, t$str s) { write(fd, (void*)s, strlen((void*) s)); } void fn_writex(int fd, int n) { diff --git a/inc/library.impl.h b/inc/library.impl.h @@ -2,7 +2,7 @@ void fn__hexout_(t$i32 x); -void fn_writes(t$i32 fd, t$u8$ s); +void fn_writes(t$i32 fd, t$str s); void fn_writex(t$i32 fd, t$i32 n); void fn_writec(t$i32 fd, t$i32 c); t$i32 fn_readc(t$i32 fd);