Add object support
All checks were successful
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 11s
CMake / ubuntu-latest - shared=OFF, pthread=OFF, posix=ON (push) Successful in 13s
CMake / ubuntu-latest - shared=ON, pthread=OFF, posix=ON (push) Successful in 11s
CMake / ubuntu-latest - shared=OFF, pthread=ON, posix=ON (push) Successful in 11s
CMake / ubuntu-latest - shared=ON, pthread=ON, posix=ON (push) Successful in 11s
All checks were successful
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 11s
CMake / ubuntu-latest - shared=OFF, pthread=OFF, posix=ON (push) Successful in 13s
CMake / ubuntu-latest - shared=ON, pthread=OFF, posix=ON (push) Successful in 11s
CMake / ubuntu-latest - shared=OFF, pthread=ON, posix=ON (push) Successful in 11s
CMake / ubuntu-latest - shared=ON, pthread=ON, posix=ON (push) Successful in 11s
Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
@@ -1,10 +1,18 @@
|
||||
#include <dcfg.h>
|
||||
|
||||
#include <alloca.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void walk_value(dcfg_Value *value, bool evaluate, int indent);
|
||||
void walk_value(dcfg_Value *value, bool evaluate, int indent, bool first);
|
||||
#define WALK(v, e, i) walk_value((v), (e), (i), true)
|
||||
|
||||
static void print_indent(int indent)
|
||||
{
|
||||
for (int i = 0; i < indent; ++i)
|
||||
putchar('\t');
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@@ -28,20 +36,15 @@ int main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
walk_value(value, false, 0);
|
||||
WALK(value, false, 0);
|
||||
|
||||
dcfg_destroy(value);
|
||||
dcfg_destroy_instance(instance);
|
||||
}
|
||||
|
||||
static void print_indent(int indent)
|
||||
{
|
||||
for (int i = 0; i < indent; ++i)
|
||||
putchar('\t');
|
||||
}
|
||||
|
||||
void walk_value(dcfg_Value *value, bool evaluate, int indent)
|
||||
void walk_value(dcfg_Value *value, bool evaluate, int indent, bool first)
|
||||
{
|
||||
if (first)
|
||||
print_indent(indent);
|
||||
|
||||
dcfg_ValueType type = dcfg_Value_type_ex(value, evaluate);
|
||||
@@ -97,7 +100,7 @@ void walk_value(dcfg_Value *value, bool evaluate, int indent)
|
||||
|
||||
print_indent(indent + 1);
|
||||
printf("\"%.*s\": ", (int)keys[i].size, keys[i].data);
|
||||
walk_value(child, evaluate, indent + 1);
|
||||
walk_value(child, evaluate, indent + 1, false);
|
||||
if (i + 1 < n)
|
||||
printf(",");
|
||||
printf("\n");
|
||||
@@ -116,7 +119,8 @@ void walk_value(dcfg_Value *value, bool evaluate, int indent)
|
||||
if (!dcfg_Value_get_array_item_ex(value, i, &item, evaluate))
|
||||
continue;
|
||||
|
||||
walk_value(item, evaluate, indent + 1);
|
||||
print_indent(indent + 1);
|
||||
walk_value(item, evaluate, indent + 1, false);
|
||||
if (i + 1 < sz)
|
||||
printf(",");
|
||||
printf("\n");
|
||||
@@ -129,8 +133,8 @@ void walk_value(dcfg_Value *value, bool evaluate, int indent)
|
||||
dcfg_Value *body = NULL;
|
||||
|
||||
if (dcfg_Value_get_function_body_ex(value, &body, evaluate) && body) {
|
||||
printf("<fn> ");
|
||||
walk_value(body, evaluate, indent + 1);
|
||||
printf("<fn>\t");
|
||||
walk_value(body, evaluate, indent + 1, false);
|
||||
} else {
|
||||
printf("<builtin-fn>");
|
||||
}
|
||||
@@ -140,7 +144,7 @@ void walk_value(dcfg_Value *value, bool evaluate, int indent)
|
||||
if (evaluate) {
|
||||
dcfg_Value *res;
|
||||
if (dcfg_Value_evaluate(value, &res))
|
||||
walk_value(res, evaluate, indent);
|
||||
walk_value(res, evaluate, indent, first);
|
||||
else
|
||||
printf("<error-evaluating-call>");
|
||||
} else {
|
||||
|
@@ -1,2 +1,12 @@
|
||||
fn lib = [ 123 "string" ./path 80085.3 ]
|
||||
fn lib = [
|
||||
123
|
||||
"string"
|
||||
./path
|
||||
80085.3
|
||||
{
|
||||
key1 = 123
|
||||
key2.member = "str"
|
||||
key2.another_member = ./amazing
|
||||
}
|
||||
]
|
||||
|
||||
|
60
src/dcfg.c
60
src/dcfg.c
@@ -1014,6 +1014,26 @@ AST *Parser_parse(Parser *parser) { return parser_parse_value(parser); }
|
||||
#define ALLOC(sz) (instance->alloc((sz)))
|
||||
#define FREE(ptr) (instance->free((ptr)))
|
||||
|
||||
static Value *ensure_child_obj(Instance *inst, Value *parent, StringView key)
|
||||
{
|
||||
ValueObject *obj = &parent->v.o;
|
||||
|
||||
for (size_t i = 0; i < vector_size(obj->entryv); ++i) {
|
||||
if (sv_eq(obj->entryv[i].k, key)) {
|
||||
return obj->entryv[i].v;
|
||||
}
|
||||
}
|
||||
|
||||
Value *child = inst->alloc(sizeof *child);
|
||||
child->instance = inst;
|
||||
child->type = dcfg_ValueType_Object;
|
||||
child->v.o.entryv = vector_create();
|
||||
|
||||
ValueObjectEntry e = { .k = key, .v = child };
|
||||
vector_add(&obj->entryv, e);
|
||||
return child;
|
||||
}
|
||||
|
||||
Value *ast_to_value(dcfg_Instance *instance, AST *root)
|
||||
{
|
||||
Value *value = ALLOC(sizeof(*value));
|
||||
@@ -1040,9 +1060,45 @@ Value *ast_to_value(dcfg_Instance *instance, AST *root)
|
||||
value->type = dcfg_ValueType_Real;
|
||||
value->v.r = root->v.r;
|
||||
} else if (root->kind == ASTKind_Block) {
|
||||
// FIXME: Implement
|
||||
FREE(value);
|
||||
value->type = dcfg_ValueType_Object;
|
||||
value->v.o.entryv = vector_create();
|
||||
|
||||
for (size_t i = 0; i < vector_size(root->v.bl.entryv); ++i) {
|
||||
ASTBlock_Entry *e = &root->v.bl.entryv[i];
|
||||
Value *rhs = ast_to_value(instance, e->v);
|
||||
if (!rhs) {
|
||||
// FIXME: Free
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Value *target = value;
|
||||
StringView field;
|
||||
|
||||
if (e->k->kind == ASTKind_Key) {
|
||||
field = e->k->v.s.s;
|
||||
} else {
|
||||
ASTMemberAccess *ma = &e->k->v.m;
|
||||
for (size_t j = 0; j + 1 < vector_size(ma->accessv); ++j)
|
||||
target = ensure_child_obj(instance, target, ma->accessv[j]);
|
||||
field = ma->accessv[vector_size(ma->accessv) - 1];
|
||||
}
|
||||
|
||||
ValueObject *obj = &target->v.o;
|
||||
bool replaced = false;
|
||||
for (size_t j = 0; j < vector_size(obj->entryv); ++j) {
|
||||
if (sv_eq(obj->entryv[j].k, field)) {
|
||||
dcfg_destroy(obj->entryv[j].v);
|
||||
obj->entryv[j].v = rhs;
|
||||
replaced = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!replaced) {
|
||||
ValueObjectEntry new_e = { .k = field, .v = rhs };
|
||||
vector_add(&obj->entryv, new_e);
|
||||
}
|
||||
}
|
||||
} else if (root->kind == ASTKind_Array) {
|
||||
value->type = dcfg_ValueType_Array;
|
||||
value->v.a.valuev = vector_create();
|
||||
|
Reference in New Issue
Block a user