climp

Dirty interpreter for the limp programming language in C

git clone https://git.8pit.net/climp.git

  1#include <stdlib.h>
  2#include <string.h>
  3
  4#include "env.h"
  5#include "util.h"
  6
  7env*
  8newenv(int size)
  9{
 10	env *tbl;
 11
 12	tbl = emalloc(sizeof(env));
 13	tbl->size = size;
 14	tbl->entries = emalloc(sizeof(entry) * size);
 15
 16	for (int i = 0; i < size; i++)
 17		tbl->entries[i] = NULL;
 18
 19	return tbl;
 20}
 21
 22void
 23freeentry(entry *ent)
 24{
 25	entry *next;
 26
 27	if (!ent) return;
 28	free(ent->key);
 29
 30	for (next = ent->next; next != NULL; next = next->next)
 31		freeentry(next);
 32
 33	free(ent);
 34}
 35
 36void
 37freeenv(env *tbl)
 38{
 39	if (!tbl) return;
 40	for (int i = 0; i < tbl->size; i++)
 41		freeentry(tbl->entries[i]);
 42
 43	free(tbl->entries);
 44	free(tbl);
 45}
 46
 47int
 48hash(env *tbl, char *str)
 49{
 50	int c;
 51	unsigned long hash = 5381;
 52
 53	/**
 54	 * Borrowed from DJB http://www.cse.yorku.ca/~oz/hash.html
 55	 */
 56
 57	while ((c = *str++))
 58		 /* hash * 33 + c */
 59		hash = ((hash << 5) + hash) + c;
 60
 61	return hash % tbl->size;
 62}
 63
 64int
 65setval(env *tbl, char *key, int val)
 66{
 67	int keyh;
 68	entry *ent, *buck, *last, *next;
 69
 70	ent = emalloc(sizeof(entry));
 71	ent->key   = estrdup(key);
 72	ent->value = val;
 73	ent->next  = NULL;
 74
 75	keyh = hash(tbl, key);
 76	if (!(buck = tbl->entries[keyh])) {
 77		tbl->entries[keyh] = ent;
 78		return 0;
 79	}
 80
 81	for (next = buck; next != NULL; next = next->next) {
 82		if (!strcmp(next->key, key))
 83			return -1;
 84		last = next;
 85	}
 86
 87	last->next = ent;
 88	return 0;
 89}
 90
 91int
 92updval(env *tbl, char *key, int val)
 93{
 94	int keyh;
 95	entry *buck, *next;
 96
 97	keyh = hash(tbl, key);
 98	if (!(buck = tbl->entries[keyh]))
 99		return -1;
100
101	for (next = buck; next != NULL; next = next->next)
102		if (!strcmp(next->key, key))
103			break;
104
105	if (!next) return -1;
106	next->value = val;
107
108	return 0;
109}
110
111int
112getval(env *tbl, char *key, int *dest)
113{
114	int keyh;
115	entry *buck, *next;
116
117	keyh = hash(tbl, key);
118	if (!(buck = tbl->entries[keyh]))
119		return -1;
120
121	for (next = buck; next != NULL; next = next->next)
122		if (!strcmp(next->key, key))
123			break;
124
125	*dest = next->value;
126	return 0;
127}