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 <dcfg.h>
|
||||||
|
|
||||||
|
#include <alloca.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.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[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@@ -28,21 +36,16 @@ int main(int argc, char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
walk_value(value, false, 0);
|
WALK(value, false, 0);
|
||||||
|
|
||||||
dcfg_destroy(value);
|
dcfg_destroy(value);
|
||||||
dcfg_destroy_instance(instance);
|
dcfg_destroy_instance(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_indent(int indent)
|
void walk_value(dcfg_Value *value, bool evaluate, int indent, bool first)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < indent; ++i)
|
if (first)
|
||||||
putchar('\t');
|
print_indent(indent);
|
||||||
}
|
|
||||||
|
|
||||||
void walk_value(dcfg_Value *value, bool evaluate, int indent)
|
|
||||||
{
|
|
||||||
print_indent(indent);
|
|
||||||
|
|
||||||
dcfg_ValueType type = dcfg_Value_type_ex(value, evaluate);
|
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);
|
print_indent(indent + 1);
|
||||||
printf("\"%.*s\": ", (int)keys[i].size, keys[i].data);
|
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)
|
if (i + 1 < n)
|
||||||
printf(",");
|
printf(",");
|
||||||
printf("\n");
|
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))
|
if (!dcfg_Value_get_array_item_ex(value, i, &item, evaluate))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
walk_value(item, evaluate, indent + 1);
|
print_indent(indent + 1);
|
||||||
|
walk_value(item, evaluate, indent + 1, false);
|
||||||
if (i + 1 < sz)
|
if (i + 1 < sz)
|
||||||
printf(",");
|
printf(",");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
@@ -129,8 +133,8 @@ void walk_value(dcfg_Value *value, bool evaluate, int indent)
|
|||||||
dcfg_Value *body = NULL;
|
dcfg_Value *body = NULL;
|
||||||
|
|
||||||
if (dcfg_Value_get_function_body_ex(value, &body, evaluate) && body) {
|
if (dcfg_Value_get_function_body_ex(value, &body, evaluate) && body) {
|
||||||
printf("<fn> ");
|
printf("<fn>\t");
|
||||||
walk_value(body, evaluate, indent + 1);
|
walk_value(body, evaluate, indent + 1, false);
|
||||||
} else {
|
} else {
|
||||||
printf("<builtin-fn>");
|
printf("<builtin-fn>");
|
||||||
}
|
}
|
||||||
@@ -140,7 +144,7 @@ void walk_value(dcfg_Value *value, bool evaluate, int indent)
|
|||||||
if (evaluate) {
|
if (evaluate) {
|
||||||
dcfg_Value *res;
|
dcfg_Value *res;
|
||||||
if (dcfg_Value_evaluate(value, &res))
|
if (dcfg_Value_evaluate(value, &res))
|
||||||
walk_value(res, evaluate, indent);
|
walk_value(res, evaluate, indent, first);
|
||||||
else
|
else
|
||||||
printf("<error-evaluating-call>");
|
printf("<error-evaluating-call>");
|
||||||
} else {
|
} 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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
62
src/dcfg.c
62
src/dcfg.c
@@ -1014,6 +1014,26 @@ AST *Parser_parse(Parser *parser) { return parser_parse_value(parser); }
|
|||||||
#define ALLOC(sz) (instance->alloc((sz)))
|
#define ALLOC(sz) (instance->alloc((sz)))
|
||||||
#define FREE(ptr) (instance->free((ptr)))
|
#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 *ast_to_value(dcfg_Instance *instance, AST *root)
|
||||||
{
|
{
|
||||||
Value *value = ALLOC(sizeof(*value));
|
Value *value = ALLOC(sizeof(*value));
|
||||||
@@ -1040,9 +1060,45 @@ Value *ast_to_value(dcfg_Instance *instance, AST *root)
|
|||||||
value->type = dcfg_ValueType_Real;
|
value->type = dcfg_ValueType_Real;
|
||||||
value->v.r = root->v.r;
|
value->v.r = root->v.r;
|
||||||
} else if (root->kind == ASTKind_Block) {
|
} else if (root->kind == ASTKind_Block) {
|
||||||
// FIXME: Implement
|
value->type = dcfg_ValueType_Object;
|
||||||
FREE(value);
|
value->v.o.entryv = vector_create();
|
||||||
return NULL;
|
|
||||||
|
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) {
|
} else if (root->kind == ASTKind_Array) {
|
||||||
value->type = dcfg_ValueType_Array;
|
value->type = dcfg_ValueType_Array;
|
||||||
value->v.a.valuev = vector_create();
|
value->v.a.valuev = vector_create();
|
||||||
|
Reference in New Issue
Block a user