Add dump
Some checks failed
CMake / ubuntu-latest - shared=OFF, pthread=OFF, posix=OFF (push) Failing after 13s
CMake / ubuntu-latest - shared=ON, pthread=OFF, posix=OFF (push) Successful in 16s
CMake / ubuntu-latest - shared=OFF, pthread=OFF, posix=ON (push) Failing after 14s
CMake / ubuntu-latest - shared=ON, pthread=OFF, posix=ON (push) Successful in 17s
CMake / ubuntu-latest - shared=OFF, pthread=ON, posix=ON (push) Failing after 18s
CMake / ubuntu-latest - shared=ON, pthread=ON, posix=ON (push) Successful in 15s
Some checks failed
CMake / ubuntu-latest - shared=OFF, pthread=OFF, posix=OFF (push) Failing after 13s
CMake / ubuntu-latest - shared=ON, pthread=OFF, posix=OFF (push) Successful in 16s
CMake / ubuntu-latest - shared=OFF, pthread=OFF, posix=ON (push) Failing after 14s
CMake / ubuntu-latest - shared=ON, pthread=OFF, posix=ON (push) Successful in 17s
CMake / ubuntu-latest - shared=OFF, pthread=ON, posix=ON (push) Failing after 18s
CMake / ubuntu-latest - shared=ON, pthread=ON, posix=ON (push) Successful in 15s
Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
222
src/dcfg.c
222
src/dcfg.c
@@ -343,8 +343,18 @@ static inline int32_t decode_cp(StringView src, int pos, int *len)
|
||||
*len = 0;
|
||||
return -1;
|
||||
}
|
||||
return (int32_t)utf8proc_iterate(
|
||||
(uint8_t const *)src.data + pos, (int)(src.size - pos), len);
|
||||
|
||||
int32_t cp;
|
||||
int bytes = utf8proc_iterate(
|
||||
(uint8_t const *)src.data + pos, (int)(src.size - pos), &cp);
|
||||
|
||||
if (bytes < 0) {
|
||||
*len = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*len = bytes;
|
||||
return cp;
|
||||
}
|
||||
|
||||
static inline bool is_space_cp(int32_t cp)
|
||||
@@ -625,13 +635,18 @@ typedef struct {
|
||||
AST **argv;
|
||||
} ASTFunctionCall;
|
||||
|
||||
typedef struct {
|
||||
bool is_str;
|
||||
StringView s;
|
||||
} ASTKey;
|
||||
|
||||
struct AST {
|
||||
ASTKind kind;
|
||||
SourceLocation location;
|
||||
union {
|
||||
int64_t i;
|
||||
double r;
|
||||
StringView s;
|
||||
ASTKey s;
|
||||
StringView p;
|
||||
bool b;
|
||||
ASTFunction f;
|
||||
@@ -653,20 +668,18 @@ bool Parser_next(Parser *parser)
|
||||
{
|
||||
parser->cur = parser->next;
|
||||
parser->next = Lexer_next(parser->lexer);
|
||||
bool ret = parser->next.type != TokenType_Error;
|
||||
if (!ret) {
|
||||
if (parser->next.type == TokenType_Error) {
|
||||
strcpy(parser->instance->last_error, "Failed to get parser token");
|
||||
}
|
||||
return ret;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Parser_init(Parser *out_parser, Lexer *lexer, Instance *instance)
|
||||
{
|
||||
memset(out_parser, 0, sizeof(*out_parser));
|
||||
out_parser->lexer = lexer;
|
||||
out_parser->instance = instance;
|
||||
if (!Parser_next(out_parser)) {
|
||||
return false;
|
||||
}
|
||||
out_parser->next = Lexer_next(lexer);
|
||||
if (!Parser_next(out_parser)) {
|
||||
return false;
|
||||
}
|
||||
@@ -781,7 +794,7 @@ AST *parser_parse_dot_access(Parser *parser, StringView *current)
|
||||
|
||||
if (vector_size(accessv) == 1) {
|
||||
ast->kind = ASTKind_Key;
|
||||
ast->v.s = accessv[0];
|
||||
ast->v.s.s = accessv[0];
|
||||
vector_free(accessv);
|
||||
}
|
||||
return ast;
|
||||
@@ -800,13 +813,14 @@ AST *parser_parse_value(Parser *parser)
|
||||
} else if (parser->cur.type == TokenType_String
|
||||
|| parser->cur.type == TokenType_Identifier) {
|
||||
ast->kind = ASTKind_Key;
|
||||
ast->v.s = parser->cur.v.s;
|
||||
ast->v.s.s = parser->cur.v.s;
|
||||
ast->v.s.is_str = parser->cur.type == TokenType_String;
|
||||
|
||||
if (parser->next.type == TokenType_Dot) {
|
||||
FREE(ast);
|
||||
return parser_parse_dot_access(parser, NULL);
|
||||
} else if (parser->cur.type == TokenType_Identifier) {
|
||||
if (sv_eq(ast->v.s, SV("fn"))) {
|
||||
if (sv_eq(ast->v.s.s, SV("fn"))) {
|
||||
if (!Parser_next(parser)) {
|
||||
strcpy(parser->instance->last_error,
|
||||
"Failed to advance fn keyword");
|
||||
@@ -837,6 +851,11 @@ AST *parser_parse_value(Parser *parser)
|
||||
}
|
||||
|
||||
vector_add(&ast->v.f.argv, parser->cur.v.s);
|
||||
if (!Parser_next(parser)) {
|
||||
vector_free(ast->v.f.argv);
|
||||
FREE(ast);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ast->v.f.body = parser_parse_value(parser);
|
||||
@@ -847,12 +866,12 @@ AST *parser_parse_value(Parser *parser)
|
||||
}
|
||||
ast->location.range.end = ast->v.f.body->location.range.end;
|
||||
return ast;
|
||||
} else if (sv_eq(ast->v.s, SV("on"))
|
||||
|| sv_eq(ast->v.s, SV("true"))) {
|
||||
} else if (sv_eq(ast->v.s.s, SV("on"))
|
||||
|| sv_eq(ast->v.s.s, SV("true"))) {
|
||||
ast->kind = ASTKind_Boolean;
|
||||
ast->v.b = true;
|
||||
} else if (sv_eq(ast->v.s, SV("off"))
|
||||
|| sv_eq(ast->v.s, SV("false"))) {
|
||||
} else if (sv_eq(ast->v.s.s, SV("off"))
|
||||
|| sv_eq(ast->v.s.s, SV("false"))) {
|
||||
ast->kind = ASTKind_Boolean;
|
||||
ast->v.b = false;
|
||||
}
|
||||
@@ -1000,9 +1019,14 @@ Value *ast_to_value(dcfg_Instance *instance, AST *root)
|
||||
Value *value = ALLOC(sizeof(*value));
|
||||
value->instance = instance;
|
||||
if (root->kind == ASTKind_Key) {
|
||||
// FIXME: Implement
|
||||
FREE(value);
|
||||
return NULL;
|
||||
if (root->v.s.is_str) {
|
||||
value->type = dcfg_ValueType_String;
|
||||
value->v.s = root->v.s.s;
|
||||
} else {
|
||||
// FIXME: Implement
|
||||
FREE(value);
|
||||
return NULL;
|
||||
}
|
||||
} else if (root->kind == ASTKind_Path) {
|
||||
value->type = dcfg_ValueType_Path;
|
||||
value->v.p = root->v.p;
|
||||
@@ -1089,6 +1113,7 @@ dcfg_Value *dcfg_parse(dcfg_Instance *instance, dcfg_StringView const file_path)
|
||||
if (!abs) {
|
||||
snprintf(instance->last_error, sizeof(instance->last_error) - 1,
|
||||
"realpath: %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
StringView abs_sv = SV(abs);
|
||||
|
||||
@@ -1146,25 +1171,33 @@ dcfg_Value *dcfg_parse(dcfg_Instance *instance, dcfg_StringView const file_path)
|
||||
|
||||
AST *ast = Parser_parse(&parser);
|
||||
if (!ast) {
|
||||
if (!*instance->last_error) {
|
||||
strcpy(instance->last_error, "Could not parse file");
|
||||
}
|
||||
FREE(abs);
|
||||
FREE((void *)str.data);
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
instance->last_error[0] = '\0';
|
||||
|
||||
Value *v = ast_to_value(instance, ast);
|
||||
if (!v) {
|
||||
if (!*instance->last_error) {
|
||||
strcpy(instance->last_error, "Could not get Value tree from AST");
|
||||
}
|
||||
dcfg_destroy(v);
|
||||
FREE(abs);
|
||||
FREE((void *)str.data);
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
instance->last_error[0] = '\0';
|
||||
|
||||
vector_add(&instance->sourcev, str);
|
||||
vector_add(&instance->source_pathv, abs_sv);
|
||||
|
||||
v->i_sourcev_idx = vector_size(instance->sourcev) - 1;
|
||||
|
||||
vector_add(&instance->source_pathv, abs_sv);
|
||||
v->i_source_pathv_idx = vector_size(instance->source_pathv) - 1;
|
||||
|
||||
return v;
|
||||
@@ -1176,6 +1209,153 @@ void dcfg_destroy(dcfg_Value *value)
|
||||
// FIXME: Implement
|
||||
}
|
||||
|
||||
dcfg_ValueType dcfg_Value_type_ex(dcfg_Value *value, bool evaluate)
|
||||
{
|
||||
if (!value)
|
||||
return dcfg_ValueType_Nil;
|
||||
(void)evaluate; /* eval ignored for now */
|
||||
return value->type;
|
||||
}
|
||||
|
||||
bool dcfg_Value_get_object_field_ex(dcfg_Value *value, dcfg_StringView key,
|
||||
dcfg_Value **out_value, bool evaluate)
|
||||
{
|
||||
if (!value || value->type != dcfg_ValueType_Object)
|
||||
return false;
|
||||
|
||||
ValueObject *obj = &value->v.o;
|
||||
for (size_t i = 0; i < vector_size(obj->entryv); ++i) {
|
||||
ValueObjectEntry *entry = &obj->entryv[i];
|
||||
if (sv_eq(entry->k, key)) {
|
||||
*out_value = entry->v;
|
||||
if (evaluate)
|
||||
dcfg_Value_evaluate(*out_value, out_value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool dcfg_Value_get_array_item_ex(
|
||||
dcfg_Value *value, size_t index, dcfg_Value **out_value, bool evaluate)
|
||||
{
|
||||
if (!value || value->type != dcfg_ValueType_Array)
|
||||
return false;
|
||||
|
||||
ValueArray *arr = &value->v.a;
|
||||
if (index >= vector_size(arr->valuev))
|
||||
return false;
|
||||
|
||||
*out_value = arr->valuev[index];
|
||||
if (evaluate)
|
||||
dcfg_Value_evaluate(*out_value, out_value);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dcfg_Value_get_function_body_ex(
|
||||
dcfg_Value *value, dcfg_Value **out_value, bool evaluate)
|
||||
{
|
||||
if (!value || value->type != dcfg_ValueType_Function
|
||||
|| value->v.f.is_builtin)
|
||||
return false;
|
||||
|
||||
if (out_value)
|
||||
*out_value = value->v.f.v.f.body;
|
||||
|
||||
if (evaluate && out_value && *out_value)
|
||||
dcfg_Value_evaluate(*out_value, out_value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dcfg_Value_get_boolean(dcfg_Value *value, bool *out_value)
|
||||
{
|
||||
if (!value || value->type != dcfg_ValueType_Boolean)
|
||||
return false;
|
||||
if (out_value)
|
||||
*out_value = value->v.b;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dcfg_Value_get_integer(dcfg_Value *value, int64_t *out_value)
|
||||
{
|
||||
if (!value || value->type != dcfg_ValueType_Integer)
|
||||
return false;
|
||||
if (out_value)
|
||||
*out_value = value->v.i;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dcfg_Value_get_real(dcfg_Value *value, double *out_value)
|
||||
{
|
||||
if (!value || value->type != dcfg_ValueType_Real)
|
||||
return false;
|
||||
if (out_value)
|
||||
*out_value = value->v.r;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dcfg_Value_get_string(dcfg_Value *value, dcfg_StringView *out_sv)
|
||||
{
|
||||
if (!value || value->type != dcfg_ValueType_String)
|
||||
return false;
|
||||
if (out_sv)
|
||||
*out_sv = value->v.s;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dcfg_Value_get_path(dcfg_Value *value, dcfg_StringView *out_sv)
|
||||
{
|
||||
if (!value || value->type != dcfg_ValueType_Path)
|
||||
return false;
|
||||
if (out_sv)
|
||||
*out_sv = value->v.p;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dcfg_Value_get_object_keys(dcfg_Value *value, size_t capacity,
|
||||
size_t *out_count, dcfg_StringView *out_keys)
|
||||
{
|
||||
if (!value || value->type != dcfg_ValueType_Object)
|
||||
return false;
|
||||
|
||||
ValueObject *obj = &value->v.o;
|
||||
size_t count = vector_size(obj->entryv);
|
||||
if (out_count)
|
||||
*out_count = count;
|
||||
|
||||
if (out_keys) {
|
||||
size_t n = capacity < count ? capacity : count;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
out_keys[i] = obj->entryv[i].k;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dcfg_Value_get_array_size(dcfg_Value *value, size_t *out_size)
|
||||
{
|
||||
if (!value || value->type != dcfg_ValueType_Array)
|
||||
return false;
|
||||
if (out_size)
|
||||
*out_size = vector_size(value->v.a.valuev);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dcfg_call_function(dcfg_Value *function, dcfg_Value **args,
|
||||
size_t arg_count, dcfg_Value **out_value)
|
||||
{
|
||||
(void)function, (void)args, (void)arg_count, (void)out_value;
|
||||
// FIXME: Implement
|
||||
return false;
|
||||
}
|
||||
|
||||
bool dcfg_Value_evaluate(dcfg_Value *value, dcfg_Value **out_value)
|
||||
{
|
||||
(void)value, (void)out_value;
|
||||
// FIXME: Implement
|
||||
return false;
|
||||
}
|
||||
|
||||
// Libraries
|
||||
#include "vendor/utf8proc.c"
|
||||
#include "vendor/vec.c"
|
||||
|
Reference in New Issue
Block a user