From 29f2af205aefe3820fdb1f72589a6bec719e1e5f Mon Sep 17 00:00:00 2001 From: gtheler Date: Sun, 11 Aug 2024 19:15:19 -0300 Subject: [PATCH] implemented vector assignment --- src/feenox.h | 2 +- src/math/assignment.c | 68 +++++++++++++++++++++++++++++++++++------- src/math/expressions.c | 4 +-- src/parser/parser.c | 2 +- tests/vector.sh | 3 ++ tests/vector_init.fee | 6 ++++ 6 files changed, 70 insertions(+), 15 deletions(-) create mode 100644 tests/vector_init.fee diff --git a/src/feenox.h b/src/feenox.h index fefbe4df..f556d2a8 100644 --- a/src/feenox.h +++ b/src/feenox.h @@ -2053,7 +2053,7 @@ extern int feenox_parse_main_input_file(const char *filepath); extern char *feenox_ends_in_init(const char *name); extern char *feenox_ends_in_zero(const char *name); extern int feenox_count_arguments(char *string, size_t *); -extern int feenox_read_arguments(char *string, unsigned int n_arguments, char ***arg, size_t *n_chars); +extern int feenox_read_arguments(char *string, int n_arguments, char ***arg, size_t *n_chars); // file.c diff --git a/src/math/assignment.c b/src/math/assignment.c index 09b743c0..55a6a063 100644 --- a/src/math/assignment.c +++ b/src/math/assignment.c @@ -152,19 +152,65 @@ int feenox_add_assignment(const char *left_hand, const char *right_hand) { } } - // the right-hand side is easy! - feenox_call(feenox_expression_parse(&assignment->rhs, right_hand)); + if (assignment->vector == NULL || bracket != NULL || index_range != NULL) { + // the right-hand side is easy ( + feenox_call(feenox_expression_parse(&assignment->rhs, right_hand)); - LL_APPEND(feenox.assignments, assignment); - if (assignment->variable != NULL) { - feenox_call(feenox_add_instruction(feenox_instruction_assignment_scalar, assignment)); - } else if (assignment->vector != NULL) { - feenox_call(feenox_add_instruction(feenox_instruction_assignment_vector, assignment)); - } else if (assignment->matrix != NULL) { - feenox_call(feenox_add_instruction(feenox_instruction_assignment_matrix, assignment)); + LL_APPEND(feenox.assignments, assignment); + if (assignment->variable != NULL) { + feenox_call(feenox_add_instruction(feenox_instruction_assignment_scalar, assignment)); + } else if (assignment->vector != NULL) { + feenox_call(feenox_add_instruction(feenox_instruction_assignment_vector, assignment)); + } else if (assignment->matrix != NULL) { + feenox_call(feenox_add_instruction(feenox_instruction_assignment_matrix, assignment)); + } else { + feenox_push_error_message("invalid assignment"); + return FEENOX_ERROR; + } } else { - feenox_push_error_message("invalid assignment"); - return FEENOX_ERROR; + // this block handles the vector initialization + vector_t *vector = assignment->vector; + feenox_free(assignment); + char *non_const_rhs = strdup(right_hand); + char *rhs_starting_with_bracket = non_const_rhs; + while (*rhs_starting_with_bracket != '(') { + if (*rhs_starting_with_bracket == '\0') { + feenox_push_error_message("right hand side for vector initialization has to be inside brackets '(' and ')'"); + return FEENOX_ERROR; + } + *rhs_starting_with_bracket++; + } + size_t n_chars_count = 0; + int n_expressions = 0; + if ((n_expressions = feenox_count_arguments(rhs_starting_with_bracket, &n_chars_count)) <= 0) { + feenox_push_error_message("invalid initialization expression"); + return FEENOX_ERROR; + } + + if (vector->size != 0 && n_expressions > vector->size) { + feenox_push_error_message("more expressions (%d) than vector size (%d)", n_expressions, vector->size); + return FEENOX_ERROR; + } + + char **expr = NULL; + feenox_call(feenox_read_arguments(rhs_starting_with_bracket, n_expressions, &expr, &n_chars_count)); + for (int i = 0; i < n_expressions; i++) { + feenox_check_alloc(assignment = calloc(1, sizeof(assignment_t))); + assignment->vector = vector; + assignment->scalar = 1; + + char *i_str = NULL; + feenox_check_minusone(asprintf(&i_str, "%d", i+1)); + feenox_call(feenox_expression_parse(&assignment->row, i_str)); + feenox_call(feenox_expression_parse(&assignment->rhs, expr[i])); + feenox_call(feenox_add_instruction(feenox_instruction_assignment_vector, assignment)); + LL_APPEND(feenox.assignments, assignment); + feenox_free(i_str); + feenox_free(expr[i]); + } + feenox_free(expr); + + feenox_free(non_const_rhs); } return FEENOX_OK; diff --git a/src/math/expressions.c b/src/math/expressions.c index 6141c8ea..7be3c5e1 100644 --- a/src/math/expressions.c +++ b/src/math/expressions.c @@ -103,7 +103,7 @@ int feenox_count_arguments(char *string, size_t *n_chars) { } -int feenox_read_arguments(char *string, unsigned int n_arguments, char ***arg, size_t *n_chars) { +int feenox_read_arguments(char *string, int n_arguments, char ***arg, size_t *n_chars) { if (string[0] != '(' && string[0] != '[') { feenox_push_error_message("arguments must start with a parenthesis for functions and with a bracket for vectors or matrices"); @@ -413,7 +413,7 @@ expr_item_t *feenox_expression_parse_item(const char *string) { (builtin_vectorfunction = feenox_get_builtin_vectorfunction_ptr(token)) != NULL || (builtin_functional = feenox_get_builtin_functional_ptr(token)) != NULL) { - // copy into argument whatever is after the nam + // copy into argument whatever is after the name char *argument = NULL; feenox_check_alloc_null(argument = strdup(string+strlen(token))); diff --git a/src/parser/parser.c b/src/parser/parser.c index b3e5160c..5f8ce659 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -1,7 +1,7 @@ /*------------ -------------- -------- --- ----- --- -- - - * FeenoX parser * - * Copyright (C) 2009--2023 jeremy theler + * Copyright (C) 2009--2024 jeremy theler * * This file is part of FeenoX. * diff --git a/tests/vector.sh b/tests/vector.sh index 22d25c66..195095fa 100755 --- a/tests/vector.sh +++ b/tests/vector.sh @@ -12,5 +12,8 @@ fi answer vector.fee "196" exitifwrong $? +answer vector_init.fee "1 2 3 4" +exitifwrong $? + answerdiff fibo_vector.fee exitifwrong $? diff --git a/tests/vector_init.fee b/tests/vector_init.fee new file mode 100644 index 00000000..4c928f6f --- /dev/null +++ b/tests/vector_init.fee @@ -0,0 +1,6 @@ +VECTOR x1[2] DATA 1 2 +VECTOR x2[2] + +x2 = (3, 4) + +PRINT x1 x2 SEP " "