/* * SPDX-FileCopyrightText: 2025 William Bell * * SPDX-License-Identifier: GPL-3.0-or-later */ #include "dowrap.h" #include "../../lexer/token.h" #include "../../memory.h" #include "../parser.h" #include #include #include #include #include char *repeat_space(size_t x) { char *str = checked_malloc(x + 1); // +1 for the null terminator memset(str, ' ', x); str[x] = '\0'; return str; } void free_string_dowrap(void *ptr) { // `ptr` is a pointer to a char* char *str = *(char **)ptr; free(str); } ParsedValueReturn parse_dowrap(char *file, DArray *tokens, size_t *index) { ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue)); parsedValue->type = AST_DOWRAP; DArray *dowrap_parsed = checked_malloc(sizeof(DArray)); darray_init(dowrap_parsed, sizeof(ParsedValue)); parsedValue->data = dowrap_parsed; (*index)++; if ((*index) >= tokens->size) return (ParsedValueReturn){no_err, parsedValue}; Token *token = darray_get(tokens, *index); if (token->type != TOKEN_NEW_LINE) { free_parsed(parsedValue); free(parsedValue); return (ParsedValueReturn){create_err(token->line, token->column, token->length, file, "Syntax Error", "expected body"), NULL}; } size_t indent_depth = 0; bool temp_indent_depth_toggle = false; size_t temp_indent_depth = 0; bool pass = false; DArray dowrap_tokens; darray_init(&dowrap_tokens, sizeof(Token)); DArray to_free; darray_init(&to_free, sizeof(char *)); size_t temp_index_count = 0; while (!pass && ++(*index) < tokens->size) { token = darray_get(tokens, *index); switch (token->type) { case TOKEN_INDENT: temp_indent_depth_toggle = true; if (dowrap_tokens.size == 0) { indent_depth = strlen(token->value); temp_indent_depth = indent_depth; } else { temp_indent_depth = strlen(token->value); } break; case TOKEN_NEW_LINE: temp_indent_depth = 0; temp_indent_depth_toggle = true; darray_push(&dowrap_tokens, token); temp_index_count++; break; default: if (temp_indent_depth < indent_depth && temp_indent_depth_toggle) { pass = true; break; } if (temp_indent_depth > indent_depth) { size_t indent_amount = temp_indent_depth - indent_depth; Token indent_token; indent_token.line = token->line; indent_token.column = token->column; indent_token.type = TOKEN_INDENT; indent_token.value = repeat_space(indent_amount); darray_push(&dowrap_tokens, &indent_token); darray_push(&to_free, &indent_token.value); } temp_indent_depth_toggle = false; temp_indent_depth = 0; temp_index_count = 0; darray_push(&dowrap_tokens, token); } } (*index) -= temp_index_count; for (size_t i = 0; i < temp_index_count; i++) { darray_pop(&dowrap_tokens, NULL); } ArErr err = parser(file, dowrap_parsed, &dowrap_tokens, false); darray_free(&dowrap_tokens, NULL); darray_free(&to_free, free_string_dowrap); if (err.exists) { free_parsed(parsedValue); free(parsedValue); return (ParsedValueReturn){err, NULL}; } return (ParsedValueReturn){no_err, parsedValue}; } void free_dowrap(void *ptr) { ParsedValue *parsedValue = ptr; DArray *parsed = parsedValue->data; darray_free(parsed, free_parsed); free(parsed); }