103 lines
2.2 KiB
C
103 lines
2.2 KiB
C
#include <stdio.h>
|
|
#define GLOBAL_ENV_
|
|
|
|
#include "../include/data.h"
|
|
|
|
// Memory management
|
|
Value *make_value(ValueType type) {
|
|
/*
|
|
** Create a Value struct of type -type-
|
|
*/
|
|
Value *v = (Value *)malloc(sizeof(Value));
|
|
if (!v) {
|
|
return NULL;
|
|
}
|
|
v->type = type;
|
|
return v;
|
|
}
|
|
|
|
Value *make_nil(void) { return make_value(VAL_NIL); }
|
|
|
|
Value *make_number(double n) {
|
|
Value *v = make_value(VAL_NUMBER);
|
|
if (!v) {
|
|
fprintf(stderr, "ERROR : not assigned\n");
|
|
}
|
|
v->data.number = n;
|
|
fprintf(stderr, "DEBUG : value %lf\n", n);
|
|
return v;
|
|
}
|
|
|
|
Value *make_string(const char *s) {
|
|
Value *v = make_value(VAL_STRING);
|
|
v->data.string = strdup(s);
|
|
return v;
|
|
}
|
|
|
|
Value *make_symbol(const char *s) {
|
|
Value *v = make_value(VAL_SYMBOL);
|
|
v->data.symbol = strdup(s);
|
|
return v;
|
|
}
|
|
|
|
Value *make_list(Value *car, Value *cdr) {
|
|
fprintf(stderr, "DEBUG : list done\n");
|
|
Value *v = make_value(VAL_LIST);
|
|
if (!v) {
|
|
fprintf(stderr, "ERROR : value\n");
|
|
}
|
|
v->data.list.cdr = car;
|
|
v->data.list.cdr = cdr;
|
|
return v;
|
|
}
|
|
|
|
Value *make_builtin(BuiltinFunc func) {
|
|
Value *v = make_value(VAL_BUILTIN);
|
|
v->data.builtin = func;
|
|
return v;
|
|
}
|
|
|
|
// Environment functions
|
|
Env *make_env(Env *parent) {
|
|
Env *env = malloc(sizeof(Env));
|
|
env->names = malloc(sizeof(char *) * 16);
|
|
env->values = malloc(sizeof(Value *) * 16);
|
|
env->count = 0;
|
|
env->capacity = 16;
|
|
env->parent = parent;
|
|
return env;
|
|
}
|
|
|
|
void env_set(Env *env, const char *name, Value *value) {
|
|
// Check if variable already exists
|
|
for (int i = 0; i < env->count; i++) {
|
|
if (strcmp(env->names[i], name) == 0) {
|
|
env->values[i] = value;
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Add new variable
|
|
if (env->count >= env->capacity) {
|
|
env->capacity *= 2;
|
|
env->names = realloc(env->names, sizeof(char *) * env->capacity);
|
|
env->values = realloc(env->values, sizeof(Value *) * env->capacity);
|
|
}
|
|
|
|
env->names[env->count] = strdup(name);
|
|
env->values[env->count] = value;
|
|
env->count++;
|
|
}
|
|
|
|
Value *env_get(Env *env, const char *name) {
|
|
while (env) {
|
|
for (int i = 0; i < env->count; i++) {
|
|
if (strcmp(env->names[i], name) == 0) {
|
|
return env->values[i];
|
|
}
|
|
}
|
|
env = env->parent;
|
|
}
|
|
return NULL;
|
|
}
|