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:
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);