diff options
| author | Xavier Del Campo Romero <xavi92@disroot.org> | 2026-05-09 02:56:07 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi92@disroot.org> | 2026-05-17 11:13:23 +0200 |
| commit | 527c23b73c8dae16f02cca6f450edb7d8225f60f (patch) | |
| tree | 6b2bfd9e8d814026d6d2c1839d8cfe1bcadc825c /lit.c | |
| download | slcob-master.tar.gz | |
Diffstat (limited to 'lit.c')
| -rw-r--r-- | lit.c | 102 |
1 files changed, 102 insertions, 0 deletions
@@ -0,0 +1,102 @@ +#include "lit.h" +#include "fn.h" +#include "lex.h" +#include "parse.h" +#include "prv.h" +#include <stddef.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +void lit_free(struct lit *l) +{ + free(l->name); +} + +static char *gen(struct ast *ast, struct fn *fn) +{ + static const char fmt[] = "__str_%zu"; + int n = snprintf(NULL, 0, fmt, ast->litcnt); + char *ret = NULL; + size_t sz; + + if (n < 0) + { + fprintf(stderr, "%s: snprintf(3) failed\n", __func__); + goto failure; + } + else if (!(ret = malloc((sz = n + 1)))) + { + perror("malloc(3)"); + goto failure; + } + + n = snprintf(ret, sz, fmt, ast->litcnt); + + if (n < 0 || n >= sz) + { + fprintf(stderr, "%s: snprintf(3) failed with %d\n", __func__, n); + goto failure; + } + + ast->litcnt++; + return ret; + +failure: + free(ret); + return NULL; +} + +static const struct lit *find(const struct tk *tk, const struct ast *ast) +{ + for (const struct lit *l = ast->lits; l; l = l->next) + if (!strcmp(l->tk->s, tk->s)) + return l; + + return NULL; +} + +int lit_cgen(const struct lit *l) +{ + printf("data $%s = { b \"%s\", b 0 }\n", l->name, l->tk->s); + return 0; +} + +const struct lit *lit_push(const struct tk *tk, struct prv *p) +{ + char *name = NULL; + struct fn *fn = fn_cur(p); + struct ast *ast = p->ast; + const struct lit *prev = find(tk, ast); + struct lit *l; + + if (prev) + return prev; + else if (!(name = gen(ast, fn))) + goto failure; + else if (!(l = malloc(sizeof *l))) + { + perror("malloc(3)"); + goto failure; + } + + *l = (struct lit) + { + .name = name, + .fn = fn, + .tk = tk + }; + + if (!ast->lits) + ast->lits = l; + else if (ast->lastlit) + ast->lastlit->next = l; + + ast->lastlit = l; + fprintf(stderr, "adding literal \"%s\"\n", name); + return l; + +failure: + free(name); + return NULL; +} |
