Add some evaluation stuff + versioning
Some checks failed
CMake / ubuntu-latest - shared=OFF, pthread=OFF, posix=OFF (push) Successful in 13s
CMake / ubuntu-latest - shared=ON, pthread=OFF, posix=OFF (push) Successful in 15s
CMake / ubuntu-latest - shared=OFF, pthread=OFF, posix=ON (push) Failing after 16s
CMake / ubuntu-latest - shared=ON, pthread=OFF, posix=ON (push) Failing after 17s
CMake / ubuntu-latest - shared=OFF, pthread=ON, posix=ON (push) Failing after 16s
CMake / ubuntu-latest - shared=ON, pthread=ON, posix=ON (push) Failing after 17s
Some checks failed
CMake / ubuntu-latest - shared=OFF, pthread=OFF, posix=OFF (push) Successful in 13s
CMake / ubuntu-latest - shared=ON, pthread=OFF, posix=OFF (push) Successful in 15s
CMake / ubuntu-latest - shared=OFF, pthread=OFF, posix=ON (push) Failing after 16s
CMake / ubuntu-latest - shared=ON, pthread=OFF, posix=ON (push) Failing after 17s
CMake / ubuntu-latest - shared=OFF, pthread=ON, posix=ON (push) Failing after 16s
CMake / ubuntu-latest - shared=ON, pthread=ON, posix=ON (push) Failing after 17s
Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
@@ -49,9 +49,19 @@ typedef enum dcfg_ValueKind {
|
||||
dcfg_ValueType_Object,
|
||||
dcfg_ValueType_Array,
|
||||
dcfg_ValueType_Function,
|
||||
dcfg_ValueType_MemberAccess,
|
||||
dcfg_ValueType_FunctionCall,
|
||||
} dcfg_ValueType;
|
||||
|
||||
typedef struct dcfg_Version {
|
||||
int major;
|
||||
int minor;
|
||||
int patch;
|
||||
char const *str;
|
||||
} dcfg_Version;
|
||||
|
||||
dcfg_Version dcfg_get_version(void);
|
||||
|
||||
dcfg_Instance *dcfg_make_instance(dcfg_InstanceCreateInfo const *create_info);
|
||||
void dcfg_destroy_instance(dcfg_Instance *instance);
|
||||
|
||||
@@ -105,8 +115,10 @@ static inline bool dcfg_Value_get_function_body(
|
||||
return dcfg_Value_get_function_body_ex(value, out_value, true);
|
||||
}
|
||||
|
||||
// Allocates new values
|
||||
bool dcfg_call_function(dcfg_Value *function, dcfg_Value **args,
|
||||
size_t arg_count, dcfg_Value **out_value);
|
||||
// Allocates new values
|
||||
bool dcfg_Value_evaluate(dcfg_Value *value, dcfg_Value **out_value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
156
src/dcfg.c
156
src/dcfg.c
@@ -1,6 +1,8 @@
|
||||
#include <dcfg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "meta.h"
|
||||
|
||||
#include "vendor/utf8proc.h"
|
||||
#include "vendor/vec.h"
|
||||
|
||||
@@ -137,6 +139,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
StringView k;
|
||||
Value *v;
|
||||
bool key_allocated;
|
||||
} ValueObjectEntry;
|
||||
|
||||
typedef struct {
|
||||
@@ -165,12 +168,17 @@ typedef struct {
|
||||
Value **argv;
|
||||
} ValueFunctionCall;
|
||||
|
||||
typedef struct {
|
||||
StringView **accessv;
|
||||
} ValueMemberAccess;
|
||||
|
||||
struct dcfg_Value {
|
||||
Instance *instance;
|
||||
dcfg_ValueType type;
|
||||
SourceLocation location;
|
||||
int i_sourcev_idx;
|
||||
int i_source_pathv_idx;
|
||||
int i_environment_idx;
|
||||
|
||||
union {
|
||||
int64_t i;
|
||||
@@ -181,10 +189,34 @@ struct dcfg_Value {
|
||||
ValueObject o;
|
||||
ValueArray a;
|
||||
ValueFunction f;
|
||||
ValueMemberAccess ma;
|
||||
ValueFunctionCall c;
|
||||
} v;
|
||||
};
|
||||
|
||||
typedef struct Environment {
|
||||
struct Environment *parent;
|
||||
StringView *argv;
|
||||
Value *argvv;
|
||||
} Environment;
|
||||
|
||||
bool environment_create(Environment *out_env, Environment *parent)
|
||||
{
|
||||
out_env->argv = vector_create();
|
||||
out_env->argvv = vector_create();
|
||||
out_env->parent = parent;
|
||||
return true;
|
||||
}
|
||||
|
||||
void environment_destroy(Environment *env)
|
||||
{
|
||||
vector_free(&env->argv);
|
||||
for (size_t i = 0; i < vector_size(env->argvv); i++) {
|
||||
dcfg_destroy(&env->argvv[i]);
|
||||
}
|
||||
vector_free(&env->argvv);
|
||||
}
|
||||
|
||||
struct dcfg_Instance {
|
||||
pthread_mutex_t mtx;
|
||||
|
||||
@@ -199,6 +231,8 @@ struct dcfg_Instance {
|
||||
|
||||
StringView *sourcev; // Strings should be freed.
|
||||
StringView *source_pathv; // Strings should be freed.
|
||||
Environment *environmentv;
|
||||
int *environment_referencesv;
|
||||
};
|
||||
|
||||
#define ALLOC(sz) (instance->alloc((sz)))
|
||||
@@ -213,6 +247,16 @@ int fseek_(void *f, size_t p, int o) { return fseek(f, p, o); }
|
||||
long ftell_(void *f) { return ftell(f); }
|
||||
#endif
|
||||
|
||||
dcfg_Version dcfg_get_version(void)
|
||||
{
|
||||
return (dcfg_Version) {
|
||||
.major = VERSION_MAJOR,
|
||||
.minor = VERSION_MINOR,
|
||||
.patch = VERSION_PATCH,
|
||||
.str = VERSION_STRING,
|
||||
};
|
||||
}
|
||||
|
||||
dcfg_Instance *dcfg_make_instance(dcfg_InstanceCreateInfo const *create_info)
|
||||
{
|
||||
assert(create_info);
|
||||
@@ -255,6 +299,8 @@ dcfg_Instance *dcfg_make_instance(dcfg_InstanceCreateInfo const *create_info)
|
||||
|
||||
instance->sourcev = vector_create();
|
||||
instance->source_pathv = vector_create();
|
||||
instance->environmentv = vector_create();
|
||||
instance->environment_referencesv = vector_create();
|
||||
|
||||
return instance;
|
||||
}
|
||||
@@ -263,6 +309,17 @@ void dcfg_destroy_instance(dcfg_Instance *instance)
|
||||
{
|
||||
assert(instance);
|
||||
|
||||
for (size_t i = 0; i < vector_size(instance->environment_referencesv);
|
||||
i++) {
|
||||
if (instance->environment_referencesv[i] > 0) {
|
||||
environment_destroy(&instance->environmentv[i]);
|
||||
}
|
||||
}
|
||||
vector_free(instance->environment_referencesv);
|
||||
|
||||
for (size_t i = 0; i < vector_size(instance->environmentv); i++) { }
|
||||
vector_free(instance->environmentv);
|
||||
|
||||
for (size_t i = 0; i < vector_size(instance->source_pathv); i++) {
|
||||
free((void *)instance->source_pathv[i].data);
|
||||
}
|
||||
@@ -1068,7 +1125,7 @@ static Value *ensure_child_obj(Instance *inst, Value *parent, StringView key)
|
||||
child->type = dcfg_ValueType_Object;
|
||||
child->v.o.entryv = vector_create();
|
||||
|
||||
ValueObjectEntry e = { .k = key, .v = child };
|
||||
ValueObjectEntry e = { .k = key, .v = child, .key_allocated = false };
|
||||
vector_add(&obj->entryv, ValueObjectEntry, e);
|
||||
return child;
|
||||
}
|
||||
@@ -1149,7 +1206,8 @@ Value *ast_to_value(dcfg_Instance *instance, AST *root)
|
||||
}
|
||||
|
||||
if (!replaced) {
|
||||
ValueObjectEntry new_e = { .k = field, .v = rhs };
|
||||
ValueObjectEntry new_e
|
||||
= { .k = field, .v = rhs, .key_allocated = false };
|
||||
vector_add(&obj->entryv, ValueObjectEntry, new_e);
|
||||
}
|
||||
}
|
||||
@@ -1183,6 +1241,7 @@ Value *ast_to_value(dcfg_Instance *instance, AST *root)
|
||||
}
|
||||
value->v.f.v.f.body = v;
|
||||
} else if (root->kind == ASTKind_MemberAccess) {
|
||||
value->type = dcfg_ValueType_MemberAccess;
|
||||
// FIXME: Implement
|
||||
FREE(value);
|
||||
return NULL;
|
||||
@@ -1331,6 +1390,9 @@ void dcfg_destroy(dcfg_Value *value)
|
||||
case dcfg_ValueType_Object:
|
||||
for (size_t i = 0; i < vector_size(value->v.o.entryv); i++) {
|
||||
dcfg_destroy(value->v.o.entryv[i].v);
|
||||
if (value->v.o.entryv[i].key_allocated) {
|
||||
value->instance->free((void *)value->v.o.entryv[i].k.data);
|
||||
}
|
||||
}
|
||||
vector_free(value->v.o.entryv);
|
||||
break;
|
||||
@@ -1506,9 +1568,93 @@ bool dcfg_call_function(dcfg_Value *function, dcfg_Value **args,
|
||||
|
||||
bool dcfg_Value_evaluate(dcfg_Value *value, dcfg_Value **out_value)
|
||||
{
|
||||
(void)value, (void)out_value;
|
||||
// FIXME: Implement
|
||||
return false;
|
||||
assert(value);
|
||||
assert(out_value);
|
||||
|
||||
bool ret = true;
|
||||
value->instance->last_error[0] = '\0';
|
||||
*out_value = value->instance->alloc(sizeof(**out_value));
|
||||
Value *v = *out_value;
|
||||
|
||||
if (value->type == dcfg_ValueType_Nil) {
|
||||
v->type = dcfg_ValueType_Nil;
|
||||
} else if (value->type == dcfg_ValueType_Boolean) {
|
||||
v->type = dcfg_ValueType_Boolean;
|
||||
v->v.b = value->v.b;
|
||||
} else if (value->type == dcfg_ValueType_Integer) {
|
||||
v->type = dcfg_ValueType_Integer;
|
||||
v->v.i = value->v.i;
|
||||
} else if (value->type == dcfg_ValueType_Real) {
|
||||
v->type = dcfg_ValueType_Real;
|
||||
v->v.r = value->v.r;
|
||||
} else if (value->type == dcfg_ValueType_String) {
|
||||
v->type = dcfg_ValueType_String;
|
||||
v->v.s = value->v.s;
|
||||
} else if (value->type == dcfg_ValueType_Path) {
|
||||
v->type = dcfg_ValueType_Path;
|
||||
v->v.p = value->v.p;
|
||||
} else if (value->type == dcfg_ValueType_Object) {
|
||||
v->type = dcfg_ValueType_Object;
|
||||
v->v.o.entryv = vector_create();
|
||||
for (size_t i = 0; i < vector_size(value->v.o.entryv); i++) {
|
||||
ValueObjectEntry *e = &value->v.o.entryv[i];
|
||||
Value *new_v;
|
||||
bool res = dcfg_Value_evaluate(e->v, &new_v);
|
||||
if (!res) {
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
ValueObjectEntry ne = {
|
||||
.k = e->k,
|
||||
.v = new_v,
|
||||
};
|
||||
ne.k.data = value->instance->alloc(ne.k.size + 1);
|
||||
memcpy((void *)ne.k.data, e->k.data, ne.k.size);
|
||||
((char *)ne.k.data)[ne.k.size] = '\0';
|
||||
vector_add(&v->v.o.entryv, ValueObjectEntry, ne);
|
||||
}
|
||||
} else if (value->type == dcfg_ValueType_Array) {
|
||||
v->type = dcfg_ValueType_Array;
|
||||
v->v.a.valuev = vector_create();
|
||||
for (size_t i = 0; i < vector_size(value->v.a.valuev); i++) {
|
||||
Value *val = NULL;
|
||||
bool res = dcfg_Value_evaluate(value->v.a.valuev[i], &val);
|
||||
if (!res) {
|
||||
ret = false;
|
||||
}
|
||||
vector_add(&v->v.a.valuev, Value *, val);
|
||||
}
|
||||
} else if (value->type == dcfg_ValueType_Function) {
|
||||
Value *out_value_prev = *out_value;
|
||||
bool res = dcfg_call_function(value, NULL, 0, out_value);
|
||||
if (!res) {
|
||||
dcfg_destroy(out_value_prev);
|
||||
ret = false;
|
||||
}
|
||||
} else if (value->type == dcfg_ValueType_MemberAccess) {
|
||||
// FIXME: Implement
|
||||
ret = false;
|
||||
} else if (value->type == dcfg_ValueType_FunctionCall) {
|
||||
Value *function;
|
||||
bool res = dcfg_Value_evaluate(value->v.c.function, &function);
|
||||
if (!res || function->type != dcfg_ValueType_Function) {
|
||||
ret = false;
|
||||
} else {
|
||||
Value *out_value_prev = *out_value;
|
||||
bool res = dcfg_call_function(function, value->v.c.argv,
|
||||
vector_size(value->v.c.argv), out_value);
|
||||
if (!res) {
|
||||
dcfg_destroy(out_value_prev);
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
assert(0 && "Invalid value type");
|
||||
}
|
||||
if (!ret) {
|
||||
dcfg_destroy(*out_value);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Libraries
|
||||
|
16
src/meta.h
Normal file
16
src/meta.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef META_H
|
||||
#define META_H
|
||||
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 1
|
||||
#define VERSION_PATCH 0
|
||||
|
||||
#define STRINGIFY(x) #x
|
||||
#define TOSTRING(x) STRINGIFY(x)
|
||||
|
||||
// proper version string
|
||||
#define VERSION_STRING \
|
||||
TOSTRING(VERSION_MAJOR) \
|
||||
"." TOSTRING(VERSION_MINOR) "." TOSTRING(VERSION_PATCH)
|
||||
|
||||
#endif // META_H
|
Reference in New Issue
Block a user