Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 3.26)
set(CMAKE_COMPILE_WARNING_AS_ERROR ON)
project(akoc
LANGUAGES C
VERSION 0.1.0
Expand Down
4 changes: 2 additions & 2 deletions src/elem.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ void ako_elem_set_type(ako_elem_t* elem, ako_type_t new_type){
if(elem_is_table_array && !new_type_is_table_array){
//new type wont make use of the dyn array
dyn_array_destroy(&elem->a);
memset(&elem->a, '\0', sizeof(dyn_array_t));
elem->a = (dyn_array_t){0};
}
else if (!elem_is_table_array && new_type_is_table_array){
//elem isnt a table or array
Expand Down Expand Up @@ -269,7 +269,7 @@ void ako_elem_set_float(ako_elem_t* elem, ako_float value){
void ako_elem_set_shorttype(ako_elem_t* elem, const char* str){
assert(elem != NULL);
ako_elem_set_type(elem, AT_SHORTTYPE);
elem->str = str;
elem->str = string_cpy(str);
}

void ako_elem_set_bool(ako_elem_t* elem, bool value){
Expand Down
41 changes: 40 additions & 1 deletion src/lex/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
#include "../private.h"

#include <assert.h>
#include <string.h>

#include "../mem/dyn_string.h"
#include "ako/ako.h"

typedef struct
{
Expand Down Expand Up @@ -53,6 +57,8 @@ static ako_elem_t* _parse_value(state_t* state)
{
token_t* peeked = peek(state, 0);
location_t start_loc;
dyn_string_t str; //Used in short type
ako_elem_t* ret;
switch (peeked->type)
{
case AKO_TT_OPEN_D_BRACE:
Expand Down Expand Up @@ -127,13 +133,46 @@ static ako_elem_t* _parse_value(state_t* state)
case AKO_TT_STRING:
_consume(state);
return ako_elem_create_string(peeked->value_string);
case AKO_TT_AND:
//need identifier next
if (!CHECK_TYPE(peek(state, 1), AKO_TT_IDENT))
{
//Invalid start
return ako_elem_create_errorf("ShortType needs to start with an Identifier, error at %zu:%zu",
peeked->start.line,
peeked->start.column);
}

_consume(state);
peeked = peek(state, 0);
str = dyn_string_create(strlen(peeked->value_string));

while (CHECK_TYPE(peek(state, 0), AKO_TT_IDENT))
{
dyn_string_append(&str, _consume(state)->value_string);
peeked = peek(state, 0);
if (peeked == NULL || peeked->type != AKO_TT_DOT)
{
break;
}
//consume dot
_consume(state);
dyn_string_append(&str, ".");
}

ret = ako_elem_create_shorttype(str.data);
ako_free(str.data);
return ret;

default:
return ako_elem_create_errorf("Unsupported type at %zu:%zu -> %zu:%zu",
peeked->start.line,
peeked->start.column,
peeked->end.line,
peeked->end.column);
}

return ako_elem_create_errorf("Unexpected escape from switch statement.");
}

static ako_elem_t* _parse_table_element(state_t* state, ako_elem_t* table)
Expand Down Expand Up @@ -239,7 +278,7 @@ static ako_elem_t* _parse_table_element(state_t* state, ako_elem_t* table)
if (ako_elem_is_error(value))
{
//Uh oh, just return the error
ako_elem_destroy(current_table);
//Don't destroy any tables as who ever called this function will destroy the tree anyway.
return value;
}

Expand Down
56 changes: 56 additions & 0 deletions test/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,66 @@ int parse_string_esc()
return 0;
}

int parse_short_type()
{
ako_elem_t* egg = ako_parse("mi &ku window.width 55");
ASSERT_ELEM(egg);

ako_elem_t* mi = ako_elem_table_get(egg, "mi");
ASSERT_ELEM(mi);

if (ako_elem_get_type(mi) != AT_SHORTTYPE)
{
printf("Given mi is not a short type\n");
ako_elem_destroy(egg);
return 1;
}

const char* value = ako_elem_get_shorttype(mi);
if (strcmp(value, "ku") != 0)
{
printf("Expected ku got %s\n", value);
ako_elem_destroy(egg);
return 1;
}

ako_elem_destroy(egg);
return 0;
}

int parse_multi_short_type()
{
ako_elem_t* egg = ako_parse("viva &viva.happy window.width 55");
ASSERT_ELEM(egg);

ako_elem_t* viva = ako_elem_table_get(egg, "viva");
ASSERT_ELEM(viva);

if (ako_elem_get_type(viva) != AT_SHORTTYPE)
{
printf("Given viva is not a short type\n");
ako_elem_destroy(egg);
return 1;
}

const char* value = ako_elem_get_shorttype(viva);
if (strcmp(value, "viva.happy") != 0)
{
printf("Expected viva.happy got %s\n", value);
ako_elem_destroy(egg);
return 1;
}

ako_elem_destroy(egg);
return 0;
}

static test_t tests[] = {
{"Basic parsing", &basic_parse},
{"Float parsing", &parse_float},
{"String escape parsing", &parse_string_esc},
{"Short type parsing", &parse_short_type},
{"Multi short type parsing", &parse_multi_short_type},
{NULL, NULL} // Null terminator
};

Expand Down