From f61fc6677caf0b38858816fecf00dbbd54dbc60a Mon Sep 17 00:00:00 2001 From: Mehmet Mert Yildiran Date: Wed, 22 Apr 2020 20:48:25 +0300 Subject: [PATCH] Implement variable update from function returns --- chaos.y | 4 ++ errors.c | 3 -- errors.h | 1 - functions/function.c | 25 ++++++++++ functions/function.h | 2 + symbol.c | 5 -- tests/function.kaos | 106 +++++++++++++++++++++++++++++++++++++++++ tests/function.out | 45 +++++++++++++++-- tests/modules/lib.kaos | 12 ++--- 9 files changed, 183 insertions(+), 20 deletions(-) diff --git a/chaos.y b/chaos.y index 0dd8fea6..613ea75a 100644 --- a/chaos.y +++ b/chaos.y @@ -501,6 +501,8 @@ variable: T_VAR { $$ = $1; } | variable T_EQUAL boolean_expression { updateSymbolBool($1, $3); $$ = ""; } | variable T_EQUAL arraystart { finishComplexModeWithUpdate($1); $$ = ""; free($1); } | variable T_EQUAL dictionarystart { finishComplexModeWithUpdate($1); $$ = ""; free($1); } + | variable T_EQUAL T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($3, NULL); updateSymbolByClonningFunctionReturn($1, $3, NULL); } else { free($1); free($3); } $$ = ""; } + | variable T_EQUAL T_VAR T_DOT T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($5, $3); updateSymbolByClonningFunctionReturn($1, $5, $3); } else { free($1); free($3); free($5); } $$ = ""; } | T_RETURN variable { returnSymbol($2); $$ = ""; } | variable_complex_element { if (is_interactive) { printSymbolValueEndWithNewLine(getComplexElementBySymbolId(variable_complex_element, variable_complex_element_symbol_id), false, false); $$ = ""; } else { yyerror("Syntax error"); } } | variable_complex_element T_EQUAL T_TRUE { updateComplexElementBool($3); $$ = ""; } @@ -513,6 +515,8 @@ variable: T_VAR { $$ = $1; } | variable_complex_element T_EQUAL boolean_expression { updateComplexElementBool($3); $$ = ""; } | variable_complex_element T_EQUAL arraystart { updateComplexElementComplex(); $$ = ""; } | variable_complex_element T_EQUAL dictionarystart { updateComplexElementComplex(); $$ = ""; } + | variable_complex_element T_EQUAL T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($3, NULL); updateComplexSymbolByClonningFunctionReturn($3, NULL); } else { free($3); } $$ = ""; } + | variable_complex_element T_EQUAL T_VAR T_DOT T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($5, $3); updateComplexSymbolByClonningFunctionReturn($5, $3); } else { free($3); free($5); } $$ = ""; } ; variable_complex_element: { } diff --git a/errors.c b/errors.c index 18fcca52..d396b5d7 100644 --- a/errors.c +++ b/errors.c @@ -51,9 +51,6 @@ void throw_error_base(unsigned short code, char *str1, char *str2, long long lld case E_ILLEGAL_VARIABLE_TYPE_FOR_VARIABLE: sprintf(error_msg, "Illegal variable type: %s, for variable: %s", str1, str2); break; - case E_ARRAYS_ARE_NOT_MASS_ASSIGNABLE: - sprintf(error_msg, "Arrays are not mass assignable! Target variable: %s", str1); - break; case E_VARIABLE_IS_NOT_A_DICTIONARY: sprintf(error_msg, "Variable '%s' is not a dictionary!", str1); break; diff --git a/errors.h b/errors.h index 25aff18c..5ca6af14 100644 --- a/errors.h +++ b/errors.h @@ -21,7 +21,6 @@ enum ExitCode { E_VARIABLE_IS_NOT_AN_ARRAY, E_INDEX_OUT_OF_RANGE, E_ILLEGAL_VARIABLE_TYPE_FOR_VARIABLE, - E_ARRAYS_ARE_NOT_MASS_ASSIGNABLE, E_VARIABLE_IS_NOT_A_DICTIONARY, E_UNDEFINED_KEY, E_UNRECOGNIZED_COMPLEX_DATA_TYPE, diff --git a/functions/function.c b/functions/function.c index 618ac598..5597d157 100644 --- a/functions/function.c +++ b/functions/function.c @@ -376,6 +376,31 @@ void createCloneFromFunctionReturn(char *clone_name, enum Type type, char *name, free(module); } +void updateSymbolByClonningFunctionReturn(char *clone_name, char *name, char*module) { + _Function* function = getFunction(name, module); + if (function->symbol == NULL) { + append_to_array_without_malloc(&free_string_stack, name); + throw_error(E_FUNCTION_DID_NOT_RETURN_ANYTHING, name); + return; + } + updateSymbolByClonning(clone_name, function->symbol); + free(clone_name); + free(name); + free(module); +} + +void updateComplexSymbolByClonningFunctionReturn(char *name, char*module) { + _Function* function = getFunction(name, module); + if (function->symbol == NULL) { + append_to_array_without_malloc(&free_string_stack, name); + throw_error(E_FUNCTION_DID_NOT_RETURN_ANYTHING, name); + return; + } + updateComplexElementSymbol(function->symbol); + free(name); + free(module); +} + void initMainFunction() { main_function = (struct _Function*)malloc(sizeof(_Function)); main_function->name = "main"; diff --git a/functions/function.h b/functions/function.h index b04b3bf5..ee145f7c 100644 --- a/functions/function.h +++ b/functions/function.h @@ -85,6 +85,8 @@ void addFunctionCallParameterSymbol(char *name); void returnSymbol(char *name); void printFunctionReturn(char *name, char *module, char *end, bool pretty, bool escaped); void createCloneFromFunctionReturn(char *clone_name, enum Type type, char *name, char *module, enum Type extra_type); +void updateSymbolByClonningFunctionReturn(char *clone_name, char *name, char*module); +void updateComplexSymbolByClonningFunctionReturn(char *name, char*module); void initMainFunction(); void initScopeless(); void freeFunction(_Function* function); diff --git a/symbol.c b/symbol.c index bbd49008..a762ed6f 100644 --- a/symbol.c +++ b/symbol.c @@ -650,11 +650,6 @@ Symbol* updateSymbolByClonning(char *clone_name, Symbol* symbol) { throw_error(E_ILLEGAL_VARIABLE_TYPE_FOR_VARIABLE, getTypeName(symbol->type), clone_name); } - if (clone_symbol->type == K_ARRAY) { - append_to_array_without_malloc(&free_string_stack, clone_name); - throw_error(E_ARRAYS_ARE_NOT_MASS_ASSIGNABLE, clone_name); - } - Symbol* temp_symbol = clone_symbol; if (clone_symbol->type == K_ANY) { diff --git a/tests/function.kaos b/tests/function.kaos index 31c858ea..7eb77db1 100644 --- a/tests/function.kaos +++ b/tests/function.kaos @@ -175,3 +175,109 @@ dict a = dict_f1() print a dict b = lib.dict_f1() print b + + +// Variable update from function returns + +del a +bool a = false +a = bool_f1() +print a +a = lib.bool_f1() +print a + +del a +num a = 0 +a = num_f1() +print a +a = lib.num_f1() +print a + +del a +str a = '' +a = str_f1() +print a +a = lib.str_f1() +print a + +del a +any a = 0 +a = any_f1() +print a +a = lib.any_f1() +print a + +del a +list a = [] +a = list_f1() +print a +a = lib.list_f1() +print a + +del a +dict a = {} +a = dict_f1() +print a +a = lib.dict_f1() +print a + + +// Complex element update from function returns + +del a +del b +list a = [1, 2, 3, 4, 5, 6] +dict b = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6} + +a[0] = bool_f1() +print a +a[0] = lib.bool_f1() +print a +b['a'] = bool_f1() +print b +b['a'] = lib.bool_f1() +print b + +a[1] = num_f1() +print a +a[1] = lib.num_f1() +print a +b['b'] = num_f1() +print b +b['b'] = lib.num_f1() +print b + +a[2] = str_f1() +print a +a[2] = lib.str_f1() +print a +b['c'] = str_f1() +print b +b['c'] = lib.str_f1() +print b + +a[3] = any_f1() +print a +a[3] = lib.any_f1() +print a +b['d'] = any_f1() +print b +b['d'] = lib.any_f1() +print b + +a[4] = list_f1() +print a +a[4] = lib.list_f1() +print a +b['e'] = list_f1() +print b +b['e'] = lib.list_f1() +print b + +a[5] = dict_f1() +print a +a[5] = lib.dict_f1() +print a +b['f'] = dict_f1() +print b +b['f'] = lib.dict_f1() diff --git a/tests/function.out b/tests/function.out index 034f76cf..a9850109 100644 --- a/tests/function.out +++ b/tests/function.out @@ -26,14 +26,49 @@ false false [1, 2, 3] true -true -5 +false 5 +6 foo -foo +bar 7 -7 -[1, 2, 3] +8 [1, 2, 3] +[4, 5, 6] {'a': 1, 'b': 2, 'c': 3} +{'d': 4, 'e': 5, 'f': 6} +true +false +5 +6 +foo +bar +7 +8 +[1, 2, 3] +[4, 5, 6] {'a': 1, 'b': 2, 'c': 3} +{'d': 4, 'e': 5, 'f': 6} +[true, 2, 3, 4, 5, 6] +[false, 2, 3, 4, 5, 6] +{'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'a': true} +{'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'a': false} +[false, 5, 3, 4, 5, 6] +[false, 6, 3, 4, 5, 6] +{'c': 3, 'd': 4, 'e': 5, 'f': 6, 'a': false, 'b': 5} +{'c': 3, 'd': 4, 'e': 5, 'f': 6, 'a': false, 'b': 6} +[false, 6, 'foo', 4, 5, 6] +[false, 6, 'bar', 4, 5, 6] +{'d': 4, 'e': 5, 'f': 6, 'a': false, 'b': 6, 'c': 'foo'} +{'d': 4, 'e': 5, 'f': 6, 'a': false, 'b': 6, 'c': 'bar'} +[false, 6, 'bar', 7, 5, 6] +[false, 6, 'bar', 8, 5, 6] +{'e': 5, 'f': 6, 'a': false, 'b': 6, 'c': 'bar', 'd': 7} +{'e': 5, 'f': 6, 'a': false, 'b': 6, 'c': 'bar', 'd': 8} +[false, 6, 'bar', 8, [1, 2, 3], 6] +[false, 6, 'bar', 8, [4, 5, 6], 6] +{'f': 6, 'a': false, 'b': 6, 'c': 'bar', 'd': 8, 'e': [1, 2, 3]} +{'f': 6, 'a': false, 'b': 6, 'c': 'bar', 'd': 8, 'e': [4, 5, 6]} +[false, 6, 'bar', 8, [4, 5, 6], {'a': 1, 'b': 2, 'c': 3}] +[false, 6, 'bar', 8, [4, 5, 6], {'d': 4, 'e': 5, 'f': 6}] +{'a': false, 'b': 6, 'c': 'bar', 'd': 8, 'e': [4, 5, 6], 'f': {'a': 1, 'b': 2, 'c': 3}} diff --git a/tests/modules/lib.kaos b/tests/modules/lib.kaos index 83b60da4..c1535827 100644 --- a/tests/modules/lib.kaos +++ b/tests/modules/lib.kaos @@ -1,29 +1,29 @@ bool def bool_f1() - bool a = true + bool a = false return a end num def num_f1() - num a = 5 + num a = 6 return a end str def str_f1() - str a = "foo" + str a = "bar" return a end any def any_f1() - any a = 7 + any a = 8 return a end list def list_f1() - list a = [1, 2, 3] + list a = [4, 5, 6] return a end dict def dict_f1() - dict a = {'a': 1, 'b': 2, 'c': 3} + dict a = {'d': 4, 'e': 5, 'f': 6} return a end