all repos — hex @ db6d1e57174cde1d625a24b446f0dbabcde53465

A tiny, minimalist, slightly-esoteric concatenative programming lannguage.

Improved quotation parsing.
h3rald h3rald@h3rald.com
Tue, 19 Nov 2024 15:35:19 +0100
commit

db6d1e57174cde1d625a24b446f0dbabcde53465

parent

2d177b3e7522bbbdccd2d7ba1fd703a84f123203

1 files changed, 105 insertions(+), 4 deletions(-)

jump to
M hex.chex.c

@@ -26,6 +26,7 @@ char **HEX_ARGV;

int HEX_ARGC = 0; volatile sig_atomic_t HEX_KEEP_RUNNING = 1; int HEX_ERRORS = 1; +int HEX_QUOTATION_BALANCE = 0; void hex_error(const char *format, ...) {

@@ -451,11 +452,19 @@ token->type = HEX_TOKEN_NUMBER;

} else if (*ptr == '(') { + HEX_QUOTATION_BALANCE++; token->type = HEX_TOKEN_QUOTATION_START; ptr++; } else if (*ptr == ')') { + HEX_QUOTATION_BALANCE--; + if (HEX_QUOTATION_BALANCE < 0) + { + hex_error("Unexpected quotation end"); + token->type = HEX_TOKEN_INVALID; + return token; + } token->type = HEX_TOKEN_QUOTATION_END; ptr++; }

@@ -487,8 +496,89 @@ free(token);

} } +int hex_parse_quotation(const char **input, HEX_StackElement *result) +{ + HEX_StackElement **quotation = NULL; + size_t capacity = 2; + size_t size = 0; + + quotation = (HEX_StackElement **)malloc(capacity * sizeof(HEX_StackElement *)); + if (!quotation) + { + hex_error("Memory allocation failed"); + return 1; + } + + HEX_Token *token; + while ((token = hex_next_token(input)) != NULL) + { + if (token->type == HEX_TOKEN_QUOTATION_END) + { + hex_free_token(token); + break; + } + + if (size >= capacity) + { + capacity *= 2; + quotation = (HEX_StackElement **)realloc(quotation, capacity * sizeof(HEX_StackElement *)); + if (!quotation) + { + hex_error("Memory allocation failed"); + return 1; + } + } + + HEX_StackElement *element = (HEX_StackElement *)malloc(sizeof(HEX_StackElement)); + if (token->type == HEX_TOKEN_NUMBER) + { + element->type = HEX_TYPE_INTEGER; + element->data.intValue = (int)strtol(token->value, NULL, 16); + } + else if (token->type == HEX_TOKEN_STRING) + { + element->type = HEX_TYPE_STRING; + element->data.strValue = strdup(token->value); + } + else if (token->type == HEX_TOKEN_SYMBOL) + { + element->type = HEX_TYPE_USER_SYMBOL; + element->symbolName = strdup(token->value); + } + else if (token->type == HEX_TOKEN_QUOTATION_START) + { + element->type = HEX_TYPE_QUOTATION; + if (hex_parse_quotation(input, element) != 0) + { + hex_free_token(token); + return 1; + } + } + else + { + hex_error("Unexpected token in quotation"); + hex_free_token(token); + return 1; + } + + quotation[size] = element; + size++; + hex_free_token(token); + } + + if (HEX_QUOTATION_BALANCE != 0) + { + hex_error("Unbalanced quotation"); + return 1; + } + + result->type = HEX_TYPE_QUOTATION; + result->data.quotationValue = quotation; + result->quotationSize = size; + return 0; +} // Recursive quotation parsing -HEX_StackElement **hex_parse_quotation(const char **input, size_t *size) +HEX_StackElement **hex___parse_quotation(const char **input, size_t *size) { HEX_StackElement **quotation = NULL; size_t capacity = 2;

@@ -539,7 +629,7 @@ }

else if (token->type == HEX_TOKEN_QUOTATION_START) { element->type = HEX_TYPE_QUOTATION; - element->data.quotationValue = hex_parse_quotation(input, &element->quotationSize); + element->data.quotationValue = hex___parse_quotation(input, &element->quotationSize); } else {

@@ -549,6 +639,10 @@

quotation[*size] = element; (*size)++; hex_free_token(token); + } + if (HEX_QUOTATION_BALANCE != 0) + { + hex_error("Unbalanced quotation"); } return quotation;

@@ -3105,8 +3199,15 @@ }

} else if (token->type == HEX_TOKEN_QUOTATION_START) { - size_t quotationSize; - HEX_StackElement **quotation = hex_parse_quotation(&input, &quotationSize); + HEX_StackElement quotationElement; + if (hex_parse_quotation(&input, &quotationElement) != 0) + { + hex_free_token(token); + return 1; + } + HEX_StackElement **quotation = quotationElement.data.quotationValue; + size_t quotationSize = quotationElement.quotationSize; + // HEX_StackElement **quotation = hex_parse_quotation(&input, &quotationSize); if (hex_push_quotation(quotation, quotationSize) != 0) { hex_free_token(token);