harec

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

commit c0407a431c1c2d1fb1878f40fbecd61b357aa35c
parent bceb9b405ce4076fe27d316d9084d518f3eef971
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sat, 19 Dec 2020 20:41:22 -0500

Initial riggings for gen

Diffstat:
Mconfigure | 1+
Ainclude/gen.h | 9+++++++++
Minclude/trace.h | 1+
Asrc/gen.c | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/main.c | 6+++---
Msrc/trace.c | 2++
6 files changed, 100 insertions(+), 3 deletions(-)

diff --git a/configure b/configure @@ -5,6 +5,7 @@ eval ". $srcdir/config.sh" harec() { genrules harec \ src/check.c \ + src/gen.c \ src/identifier.c \ src/lex.c \ src/main.c \ diff --git a/include/gen.h b/include/gen.h @@ -0,0 +1,9 @@ +#ifndef HAREC_GEN_H +#define HAREC_GEN_H +#include <stdio.h> + +struct unit; + +void gen(const struct unit *unit, FILE *out); + +#endif diff --git a/include/trace.h b/include/trace.h @@ -6,6 +6,7 @@ enum trace_sys { TR_PARSE, TR_SCAN, TR_CHECK, + TR_GEN, TR_MAX, }; diff --git a/src/gen.c b/src/gen.c @@ -0,0 +1,84 @@ +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "check.h" +#include "expr.h" +#include "gen.h" +#include "identifier.h" +#include "trace.h" +#include "types.h" + +struct gen_context { + FILE *out; + struct identifier *ns; +}; + +static char * +ident_to_sym(const struct identifier *ident) +{ + if (ident->ns) { + char *ns = ident_to_sym(ident->ns); + if (!ns) { + return NULL; + } + int n = snprintf(NULL, 0, "%s.%s", ns, ident->name); + char *str = calloc(1, n + 1); + assert(str); + snprintf(str, n + 1, "%s.%s", ns, ident->name); + free(ns); + return str; + } + return strdup(ident->name); +} + +static void +gen_function_decl(struct gen_context *ctx, const struct declaration *decl) +{ + assert(decl->type == DECL_FUNC); + const struct function_decl *func = &decl->func; + const struct type *fntype = func->type; + // TODO: All of these cases: + assert(func->flags == 0); + assert(func->symbol == NULL); + assert(fntype->func.result == &builtin_type_void); + assert(fntype->func.params == NULL); + + char *sym = ident_to_sym(&decl->ident); + fprintf(ctx->out, "%sfunction $%s() {\n", + decl->exported ? "export " : "", sym); + fprintf(ctx->out, "\t# TODO: Emit function body\n"); + fprintf(ctx->out, "}\n\n"); + free(sym); +} + +static void +gen_decl(struct gen_context *ctx, const struct declaration *decl) +{ + switch (decl->type) { + case DECL_FUNC: + gen_function_decl(ctx, decl); + break; + case DECL_TYPE: + case DECL_GLOBAL: + case DECL_CONSTANT: + assert(0); // TODO + } +} + +void +gen(const struct unit *unit, FILE *out) +{ + struct gen_context ctx = { + .out = out, + .ns = unit->ns, + }; + const struct declarations *decls = unit->declarations; + assert(decls); // At least one is required + trenter(TR_GEN, "gen"); + while (decls) { + gen_decl(&ctx, &decls->decl); + decls = decls->next; + } + trleave(TR_GEN, NULL); +} diff --git a/src/main.c b/src/main.c @@ -5,13 +5,13 @@ #include "check.h" #include "lex.h" #include "parse.h" +#include "gen.h" enum stage { STAGE_LEX, STAGE_PARSE, STAGE_CHECK, STAGE_GEN, - STAGE_EMIT, }; enum stage @@ -27,8 +27,6 @@ parse_stage(const char *s) return STAGE_CHECK; } else if (strcmp(s, "gen") == 0) { return STAGE_GEN; - } else if (strcmp(s, "emit") == 0) { - return STAGE_EMIT; } else { fprintf(stderr, "Unknown HA_STAGE value '%s'\n", s); exit(1); @@ -61,5 +59,7 @@ main(int argc, char *argv[]) if (stage == STAGE_CHECK) { return 0; } + + gen(&unit, stdout); return 0; } diff --git a/src/trace.c b/src/trace.c @@ -10,6 +10,7 @@ static const char *sysname[] = { [TR_PARSE] = "parse", [TR_SCAN] = "scan", [TR_CHECK] = "check", + [TR_GEN] = "gen", }; static int depth[] = { @@ -17,6 +18,7 @@ static int depth[] = { [TR_PARSE] = 0, [TR_SCAN] = 0, [TR_CHECK] = 0, + [TR_GEN] = 0, }; static void