/* * SPDX-FileCopyrightText: 2025 William Bell * * SPDX-License-Identifier: GPL-3.0-or-later */ #include "operations.h" #include "../../memory.h" #include "../parser.h" #include #include #include #include ParsedValue convert_to_operation(DArray *to_operate_on, DArray *operations) { if (to_operate_on->size == 1) { return *((ParsedValue *)darray_get(to_operate_on, 0)); } ArTokenType operation_type = 0; Token operation = {}; DArray positions; for (size_t i = 0; i < operations->size; i++) { Token *current_operation = darray_get(operations, i); if (operation_type < current_operation->type) { if (operation_type != 0) { darray_free(&positions, NULL); } operation_type = current_operation->type; operation = *current_operation; darray_init(&positions, sizeof(size_t)); } if (operation_type == current_operation->type) { darray_push(&positions, &i); } } ParsedValue parsedValue; parsedValue.type = AST_OPERATION; ParsedOperation *operationStruct = checked_malloc(sizeof(ParsedOperation)); parsedValue.data = operationStruct; operationStruct->operation = operation_type; operationStruct->line = operation.line; operationStruct->column = operation.column; operationStruct->length = operation.length; darray_init(&operationStruct->to_operate_on, sizeof(ParsedValue)); size_t to_operate_on_last_position = 0; for (size_t i = 0; i < positions.size; i++) { size_t *position = darray_get(&positions, i); DArray to_operate_on_slice = darray_slice( to_operate_on, to_operate_on_last_position, (*position) + 1); DArray operations_slice = darray_slice(operations, to_operate_on_last_position, (*position)); ParsedValue result = convert_to_operation(&to_operate_on_slice, &operations_slice); darray_push(&operationStruct->to_operate_on, &result); to_operate_on_last_position = (*position) + 1; } DArray to_operate_on_slice = darray_slice( to_operate_on, to_operate_on_last_position, to_operate_on->size); DArray operations_slice = darray_slice(operations, to_operate_on_last_position, operations->size); ParsedValue result = convert_to_operation(&to_operate_on_slice, &operations_slice); darray_push(&operationStruct->to_operate_on, &result); darray_free(&positions, NULL); return parsedValue; } ParsedValueReturn parse_operations(char *file, DArray *tokens, size_t *index, ParsedValue *first_parsed_value) { DArray to_operate_on; darray_init(&to_operate_on, sizeof(ParsedValue)); darray_push(&to_operate_on, first_parsed_value); free(first_parsed_value); DArray operations; darray_init(&operations, sizeof(Token)); while (tokens->size > *index) { bool to_break = false; Token *token = darray_get(tokens, *index); switch (token->type) { SWITCH_OPERATIONS break; default: to_break = true; } if (to_break) break; darray_push(&operations, token); (*index)++; ArErr err = error_if_finished(file, tokens, index); if (err.exists) { darray_free(&to_operate_on, free_parsed); darray_free(&operations, NULL); return (ParsedValueReturn){err, NULL}; } ParsedValueReturn parsedValue = parse_token_full(file, tokens, index, true, false); if (parsedValue.err.exists) { darray_free(&to_operate_on, free_parsed); darray_free(&operations, NULL); return parsedValue; } else if (!parsedValue.value) { darray_free(&to_operate_on, free_parsed); darray_free(&operations, NULL); return (ParsedValueReturn){create_err(token->line, token->column, token->length, file, "Syntax Error", "expected value"), NULL}; } darray_push(&to_operate_on, parsedValue.value); free(parsedValue.value); } ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue)); ParsedValue output = convert_to_operation(&to_operate_on, &operations); memcpy(parsedValue, &output, sizeof(ParsedValue)); darray_free(&to_operate_on, NULL); darray_free(&operations, NULL); return (ParsedValueReturn){no_err, parsedValue}; } void free_operation(void *ptr) { ParsedValue *parsedValue = ptr; ParsedOperation *parsed_operation = parsedValue->data; darray_free(&parsed_operation->to_operate_on, free_parsed); free(parsed_operation); }