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_Object,
|
||||||
dcfg_ValueType_Array,
|
dcfg_ValueType_Array,
|
||||||
dcfg_ValueType_Function,
|
dcfg_ValueType_Function,
|
||||||
|
dcfg_ValueType_MemberAccess,
|
||||||
dcfg_ValueType_FunctionCall,
|
dcfg_ValueType_FunctionCall,
|
||||||
} dcfg_ValueType;
|
} 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);
|
dcfg_Instance *dcfg_make_instance(dcfg_InstanceCreateInfo const *create_info);
|
||||||
void dcfg_destroy_instance(dcfg_Instance *instance);
|
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);
|
return dcfg_Value_get_function_body_ex(value, out_value, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allocates new values
|
||||||
bool dcfg_call_function(dcfg_Value *function, dcfg_Value **args,
|
bool dcfg_call_function(dcfg_Value *function, dcfg_Value **args,
|
||||||
size_t arg_count, dcfg_Value **out_value);
|
size_t arg_count, dcfg_Value **out_value);
|
||||||
|
// Allocates new values
|
||||||
bool dcfg_Value_evaluate(dcfg_Value *value, dcfg_Value **out_value);
|
bool dcfg_Value_evaluate(dcfg_Value *value, dcfg_Value **out_value);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
156
src/dcfg.c
156
src/dcfg.c
@@ -1,6 +1,8 @@
|
|||||||
#include <dcfg.h>
|
#include <dcfg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "meta.h"
|
||||||
|
|
||||||
#include "vendor/utf8proc.h"
|
#include "vendor/utf8proc.h"
|
||||||
#include "vendor/vec.h"
|
#include "vendor/vec.h"
|
||||||
|
|
||||||
@@ -137,6 +139,7 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
StringView k;
|
StringView k;
|
||||||
Value *v;
|
Value *v;
|
||||||
|
bool key_allocated;
|
||||||
} ValueObjectEntry;
|
} ValueObjectEntry;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -165,12 +168,17 @@ typedef struct {
|
|||||||
Value **argv;
|
Value **argv;
|
||||||
} ValueFunctionCall;
|
} ValueFunctionCall;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
StringView **accessv;
|
||||||
|
} ValueMemberAccess;
|
||||||
|
|
||||||
struct dcfg_Value {
|
struct dcfg_Value {
|
||||||
Instance *instance;
|
Instance *instance;
|
||||||
dcfg_ValueType type;
|
dcfg_ValueType type;
|
||||||
SourceLocation location;
|
SourceLocation location;
|
||||||
int i_sourcev_idx;
|
int i_sourcev_idx;
|
||||||
int i_source_pathv_idx;
|
int i_source_pathv_idx;
|
||||||
|
int i_environment_idx;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
int64_t i;
|
int64_t i;
|
||||||
@@ -181,10 +189,34 @@ struct dcfg_Value {
|
|||||||
ValueObject o;
|
ValueObject o;
|
||||||
ValueArray a;
|
ValueArray a;
|
||||||
ValueFunction f;
|
ValueFunction f;
|
||||||
|
ValueMemberAccess ma;
|
||||||
ValueFunctionCall c;
|
ValueFunctionCall c;
|
||||||
} v;
|
} 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 {
|
struct dcfg_Instance {
|
||||||
pthread_mutex_t mtx;
|
pthread_mutex_t mtx;
|
||||||
|
|
||||||
@@ -199,6 +231,8 @@ struct dcfg_Instance {
|
|||||||
|
|
||||||
StringView *sourcev; // Strings should be freed.
|
StringView *sourcev; // Strings should be freed.
|
||||||
StringView *source_pathv; // Strings should be freed.
|
StringView *source_pathv; // Strings should be freed.
|
||||||
|
Environment *environmentv;
|
||||||
|
int *environment_referencesv;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ALLOC(sz) (instance->alloc((sz)))
|
#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); }
|
long ftell_(void *f) { return ftell(f); }
|
||||||
#endif
|
#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)
|
dcfg_Instance *dcfg_make_instance(dcfg_InstanceCreateInfo const *create_info)
|
||||||
{
|
{
|
||||||
assert(create_info);
|
assert(create_info);
|
||||||
@@ -255,6 +299,8 @@ dcfg_Instance *dcfg_make_instance(dcfg_InstanceCreateInfo const *create_info)
|
|||||||
|
|
||||||
instance->sourcev = vector_create();
|
instance->sourcev = vector_create();
|
||||||
instance->source_pathv = vector_create();
|
instance->source_pathv = vector_create();
|
||||||
|
instance->environmentv = vector_create();
|
||||||
|
instance->environment_referencesv = vector_create();
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
@@ -263,6 +309,17 @@ void dcfg_destroy_instance(dcfg_Instance *instance)
|
|||||||
{
|
{
|
||||||
assert(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++) {
|
for (size_t i = 0; i < vector_size(instance->source_pathv); i++) {
|
||||||
free((void *)instance->source_pathv[i].data);
|
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->type = dcfg_ValueType_Object;
|
||||||
child->v.o.entryv = vector_create();
|
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);
|
vector_add(&obj->entryv, ValueObjectEntry, e);
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
@@ -1149,7 +1206,8 @@ Value *ast_to_value(dcfg_Instance *instance, AST *root)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!replaced) {
|
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);
|
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;
|
value->v.f.v.f.body = v;
|
||||||
} else if (root->kind == ASTKind_MemberAccess) {
|
} else if (root->kind == ASTKind_MemberAccess) {
|
||||||
|
value->type = dcfg_ValueType_MemberAccess;
|
||||||
// FIXME: Implement
|
// FIXME: Implement
|
||||||
FREE(value);
|
FREE(value);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1331,6 +1390,9 @@ void dcfg_destroy(dcfg_Value *value)
|
|||||||
case dcfg_ValueType_Object:
|
case dcfg_ValueType_Object:
|
||||||
for (size_t i = 0; i < vector_size(value->v.o.entryv); i++) {
|
for (size_t i = 0; i < vector_size(value->v.o.entryv); i++) {
|
||||||
dcfg_destroy(value->v.o.entryv[i].v);
|
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);
|
vector_free(value->v.o.entryv);
|
||||||
break;
|
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)
|
bool dcfg_Value_evaluate(dcfg_Value *value, dcfg_Value **out_value)
|
||||||
{
|
{
|
||||||
(void)value, (void)out_value;
|
assert(value);
|
||||||
// FIXME: Implement
|
assert(out_value);
|
||||||
return false;
|
|
||||||
|
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
|
// 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