diff options
| author | Nakidai <nakidai@disroot.org> | 2026-04-05 19:51:14 +0300 |
|---|---|---|
| committer | Nakidai <nakidai@disroot.org> | 2026-04-05 20:01:32 +0300 |
| commit | 8afa976e073c7bc29c878230eead6dddfdcc08a1 (patch) | |
| tree | 044b8ddf87b9a3c8b5a229b27e84e870468fb950 /var.c | |
| download | thac-5e9fb4d28f49aa4a17b38f436a63b5a7a764457b.tar.gz thac-5e9fb4d28f49aa4a17b38f436a63b5a7a764457b.zip | |
Add code v0.1.0
Diffstat (limited to 'var.c')
| -rw-r--r-- | var.c | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/var.c b/var.c new file mode 100644 index 0000000..658f00b --- /dev/null +++ b/var.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2026 Nakidai Perumenei <nakidai at disroot dot org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "thac.h" + +#include <ctype.h> +#include <stdlib.h> +#include <string.h> + + +long +findvar(char *name, struct scope **scope) +{ + struct var *var; + ulong i; + + for (; *scope; *scope = (*scope)->parent) for (i = 0; i < (*scope)->len; ++i) + { + var = &(*scope)->vars[i]; + if (!strcmp(var->name, name)) + return i; + } + + return -1; +} + +ulong +assignvar(char *name, struct val val, struct scope **scope) +{ + struct scope *lscope; + long i; + + lscope = *scope; + i = findvar(name, &lscope); + if (i < 0) + { + /* TODO: add cap and increment like in lex.c */ + (*scope)->vars = realloc( + (*scope)->vars, + sizeof(*(*scope)->vars) * ++(*scope)->len + ); + if (!(*scope)->vars) + dieno(1, "realloc()"); + i = (*scope)->len - 1; + } else + { + scope = &lscope; + } + (*scope)->vars[i].name = name; + (*scope)->vars[i].val = val; + return i; +} + +int +varnextchar(struct scope *scope) +{ + struct var *var; + ulong i; + int c; + + for (c = -1; scope; scope = scope->parent) for (i = 0; i < scope->len; ++i) + { + var = &scope->vars[i]; + if (var->name[0] == '@' && islower(var->name[1])) + c = max(c, var->name[1]); + + if (c == -1) + continue; + + if (c == 'z') + return -1; + return var->name[1] + 1; + } + + return 'a'; +} + +ulong +varnextnum(struct scope *scope) +{ + struct var *var; + ulong i; + + for (; scope; scope = scope->parent) for (i = 0; i < scope->len; ++i) + { + var = &scope->vars[i]; + if (var->name[0] == '@' && isdigit(var->name[1])) + return atoll(&var->name[1]) + 1; + } + + return 0; +} + +void +delvarscope(struct scope *scope, ulong i) +{ + freeval(scope->vars[i].val); + scope->vars[i] = scope->vars[--scope->len]; +} |