Skip to content

Commit 8fa129d

Browse files
committed
Implement functions that return typed lists or dictionaries
1 parent ba2baf7 commit 8fa129d

File tree

8 files changed

+100
-19
lines changed

8 files changed

+100
-19
lines changed

Chaos.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#include "function.h"
77
#include "Chaos.h"
88

9-
int defineFunction(char *name, enum Type type, char *params_name[], unsigned params_type[], unsigned short params_length) {
9+
int defineFunction(char *name, enum Type type, enum Type secondary_type, char *params_name[], unsigned params_type[], unsigned short params_length) {
1010
char *function_name = malloc(strlen(name) + 1);
1111
strcpy(function_name, name);
1212
startFunctionParameters();
@@ -17,7 +17,7 @@ int defineFunction(char *name, enum Type type, char *params_name[], unsigned par
1717
addFunctionParameter(param_name, params_type[i]);
1818
}
1919

20-
startFunction(function_name, type);
20+
startFunction(function_name, type, secondary_type);
2121
endFunction();
2222
return 0;
2323
}

Chaos.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include "chaos/language.h"
1212
#endif
1313

14-
int defineFunction(char *name, enum Type type, char *params_name[], unsigned params_type[], unsigned short params_length);
14+
int defineFunction(char *name, enum Type type, enum Type secondary_type, char *params_name[], unsigned params_type[], unsigned short params_length);
1515
bool getVariableBool(char *name);
1616
long long getVariableInt(char *name);
1717
long double getVariableFloat(char *name);
@@ -70,7 +70,7 @@ void raiseError(char *msg);
7070
void parseJson(char *json);
7171

7272
struct Kaos {
73-
int (*defineFunction)(char *name, enum Type type, char *params_name[], unsigned params_type[], unsigned short params_length);
73+
int (*defineFunction)(char *name, enum Type type, enum Type secondary_type, char *params_name[], unsigned params_type[], unsigned short params_length);
7474
bool (*getVariableBool)(char *name);
7575
long long (*getVariableInt)(char *name);
7676
long double (*getVariableFloat)(char *name);

chaos.y

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -114,13 +114,19 @@ preparser_line: T_NEWLINE
114114
;
115115

116116
function:
117-
| T_VAR_BOOL T_FUNCTION T_VAR function_parameters_start { startFunction($3, K_BOOL); }
118-
| T_VAR_NUMBER T_FUNCTION T_VAR function_parameters_start { startFunction($3, K_NUMBER); }
119-
| T_VAR_STRING T_FUNCTION T_VAR function_parameters_start { startFunction($3, K_STRING); }
120-
| T_VAR_ANY T_FUNCTION T_VAR function_parameters_start { startFunction($3, K_ANY); }
121-
| T_VAR_LIST T_FUNCTION T_VAR function_parameters_start { startFunction($3, K_LIST); }
122-
| T_VAR_DICT T_FUNCTION T_VAR function_parameters_start { startFunction($3, K_DICT); }
123-
| T_VOID T_FUNCTION T_VAR function_parameters_start { startFunction($3, K_VOID); }
117+
| T_VAR_BOOL T_FUNCTION T_VAR function_parameters_start { startFunction($3, K_BOOL, K_ANY); }
118+
| T_VAR_NUMBER T_FUNCTION T_VAR function_parameters_start { startFunction($3, K_NUMBER, K_ANY); }
119+
| T_VAR_STRING T_FUNCTION T_VAR function_parameters_start { startFunction($3, K_STRING, K_ANY); }
120+
| T_VAR_ANY T_FUNCTION T_VAR function_parameters_start { startFunction($3, K_ANY, K_ANY); }
121+
| T_VAR_LIST T_FUNCTION T_VAR function_parameters_start { startFunction($3, K_LIST, K_ANY); }
122+
| T_VAR_DICT T_FUNCTION T_VAR function_parameters_start { startFunction($3, K_DICT, K_ANY); }
123+
| T_VAR_BOOL T_VAR_LIST T_FUNCTION T_VAR function_parameters_start { startFunction($4, K_LIST, K_BOOL); }
124+
| T_VAR_BOOL T_VAR_DICT T_FUNCTION T_VAR function_parameters_start { startFunction($4, K_DICT, K_BOOL); }
125+
| T_VAR_NUMBER T_VAR_LIST T_FUNCTION T_VAR function_parameters_start { startFunction($4, K_LIST, K_NUMBER); }
126+
| T_VAR_NUMBER T_VAR_DICT T_FUNCTION T_VAR function_parameters_start { startFunction($4, K_DICT, K_NUMBER); }
127+
| T_VAR_STRING T_VAR_LIST T_FUNCTION T_VAR function_parameters_start { startFunction($4, K_LIST, K_STRING); }
128+
| T_VAR_STRING T_VAR_DICT T_FUNCTION T_VAR function_parameters_start { startFunction($4, K_DICT, K_STRING); }
129+
| T_VOID T_FUNCTION T_VAR function_parameters_start { startFunction($3, K_VOID, K_ANY); }
124130
| T_PRINT T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($2, NULL); printFunctionReturn($2, NULL, "\n", false, true); } free($2); }
125131
| T_ECHO T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($2, NULL); printFunctionReturn($2, NULL, "", false, true); } free($2); }
126132
| T_PRETTY T_PRINT T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($3, NULL); printFunctionReturn($3, NULL, "\n", true, true); } free($3); }
@@ -537,6 +543,10 @@ variable: { }
537543
| T_VAR_BOOL T_VAR_DICT T_VAR T_EQUAL dictionarystart { finishComplexMode($3, K_BOOL); $$ = ""; free($3); }
538544
| T_VAR_BOOL T_VAR T_EQUAL T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($4, NULL); createCloneFromFunctionReturn($2, K_BOOL, $4, NULL, K_ANY); } else { free($2); free($4); } $$ = ""; }
539545
| T_VAR_BOOL T_VAR T_EQUAL T_VAR T_DOT T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($6, $4); createCloneFromFunctionReturn($2, K_BOOL, $6, $4, K_ANY); } else { free($2); free($4); free($6); } $$ = ""; }
546+
| T_VAR_BOOL T_VAR_LIST T_VAR T_EQUAL T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($5, NULL); createCloneFromFunctionReturn($3, K_LIST, $5, NULL, K_BOOL); } else { free($3); free($5); } $$ = ""; }
547+
| T_VAR_BOOL T_VAR_LIST T_VAR T_EQUAL T_VAR T_DOT T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($7, $5); createCloneFromFunctionReturn($3, K_LIST, $7, $5, K_BOOL); } else { free($3); free($5); free($7); } $$ = ""; }
548+
| T_VAR_BOOL T_VAR_DICT T_VAR T_EQUAL T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($5, NULL); createCloneFromFunctionReturn($3, K_DICT, $5, NULL, K_BOOL); } else { free($3); free($5); } $$ = ""; }
549+
| T_VAR_BOOL T_VAR_DICT T_VAR T_EQUAL T_VAR T_DOT T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($7, $5); createCloneFromFunctionReturn($3, K_DICT, $7, $5, K_BOOL); } else { free($3); free($5); free($7); } $$ = ""; }
540550
;
541551

542552
variable: { }
@@ -550,6 +560,10 @@ variable: { }
550560
| T_VAR_NUMBER T_VAR T_EQUAL expression { addSymbolFloat($2, $4); $$ = ""; }
551561
| T_VAR_NUMBER T_VAR T_EQUAL T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($4, NULL); createCloneFromFunctionReturn($2, K_NUMBER, $4, NULL, K_ANY); } else { free($2); free($4); } $$ = ""; }
552562
| T_VAR_NUMBER T_VAR T_EQUAL T_VAR T_DOT T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($6, $4); createCloneFromFunctionReturn($2, K_NUMBER, $6, $4, K_ANY); } else { free($2); free($4); free($6); } $$ = ""; }
563+
| T_VAR_NUMBER T_VAR_LIST T_VAR T_EQUAL T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($5, NULL); createCloneFromFunctionReturn($3, K_LIST, $5, NULL, K_NUMBER); } else { free($3); free($5); } $$ = ""; }
564+
| T_VAR_NUMBER T_VAR_LIST T_VAR T_EQUAL T_VAR T_DOT T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($7, $5); createCloneFromFunctionReturn($3, K_LIST, $7, $5, K_NUMBER); } else { free($3); free($5); free($7); } $$ = ""; }
565+
| T_VAR_NUMBER T_VAR_DICT T_VAR T_EQUAL T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($5, NULL); createCloneFromFunctionReturn($3, K_DICT, $5, NULL, K_NUMBER); } else { free($3); free($5); } $$ = ""; }
566+
| T_VAR_NUMBER T_VAR_DICT T_VAR T_EQUAL T_VAR T_DOT T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($7, $5); createCloneFromFunctionReturn($3, K_DICT, $7, $5, K_NUMBER); } else { free($3); free($5); free($7); } $$ = ""; }
553567
;
554568

555569
variable: { }
@@ -562,6 +576,10 @@ variable: { }
562576
| T_VAR_STRING T_VAR_DICT T_VAR T_EQUAL dictionarystart { finishComplexMode($3, K_STRING); $$ = ""; free($3); }
563577
| T_VAR_STRING T_VAR T_EQUAL T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($4, NULL); createCloneFromFunctionReturn($2, K_STRING, $4, NULL, K_ANY); } else { free($2); free($4); } $$ = ""; }
564578
| T_VAR_STRING T_VAR T_EQUAL T_VAR T_DOT T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($6, $4); createCloneFromFunctionReturn($2, K_STRING, $6, $4, K_ANY); } else { free($2); free($4); free($6); } $$ = ""; }
579+
| T_VAR_STRING T_VAR_LIST T_VAR T_EQUAL T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($5, NULL); createCloneFromFunctionReturn($3, K_LIST, $5, NULL, K_STRING); } else { free($3); free($5); } $$ = ""; }
580+
| T_VAR_STRING T_VAR_LIST T_VAR T_EQUAL T_VAR T_DOT T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($7, $5); createCloneFromFunctionReturn($3, K_LIST, $7, $5, K_STRING); } else { free($3); free($5); free($7); } $$ = ""; }
581+
| T_VAR_STRING T_VAR_DICT T_VAR T_EQUAL T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($5, NULL); createCloneFromFunctionReturn($3, K_DICT, $5, NULL, K_STRING); } else { free($3); free($5); } $$ = ""; }
582+
| T_VAR_STRING T_VAR_DICT T_VAR T_EQUAL T_VAR T_DOT T_VAR T_LEFT function_call_parameters_start { if (phase == PROGRAM) { callFunction($7, $5); createCloneFromFunctionReturn($3, K_DICT, $7, $5, K_STRING); } else { free($3); free($5); free($7); } $$ = ""; }
565583
;
566584

567585
variable: { }

functions/function.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ extern int yyparse();
77
int reset_line_no_to = 0;
88
bool decision_execution_mode = false;
99

10-
void startFunction(char *name, enum Type type) {
10+
void startFunction(char *name, enum Type type, enum Type secondary_type) {
1111
if (is_interactive) {
1212
phase = PREPARSE;
1313
}
@@ -42,6 +42,7 @@ void startFunction(char *name, enum Type type) {
4242
function_mode->line_no = yylineno;
4343
strcpy(function_mode->name, name);
4444
function_mode->type = type;
45+
function_mode->secondary_type = secondary_type;
4546
function_mode->parameter_count = 0;
4647

4748
function_mode->decision_expressions.capacity = 0;
@@ -341,6 +342,14 @@ void returnSymbol(char *name) {
341342
free(name);
342343
throw_error(E_ILLEGAL_VARIABLE_TYPE_FOR_FUNCTION, getTypeName(symbol->type), executed_function->name);
343344
}
345+
if (symbol->secondary_type != K_ANY &&
346+
executed_function->secondary_type != K_ANY &&
347+
symbol->secondary_type != executed_function->secondary_type
348+
) {
349+
free(name);
350+
throw_error(E_ILLEGAL_VARIABLE_TYPE_FOR_FUNCTION, getTypeName(symbol->secondary_type), executed_function->name);
351+
}
352+
344353
scope_override = executed_function->parent_scope;
345354
executed_function->symbol = createCloneFromSymbol(
346355
NULL,

functions/function.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ typedef struct _Function {
2525
struct Symbol** parameters;
2626
unsigned short parameter_count;
2727
enum Type type;
28+
enum Type secondary_type;
2829
struct Symbol* symbol;
2930
struct _Function* previous;
3031
struct _Function* next;
@@ -69,7 +70,7 @@ int reset_line_no_to;
6970
jmp_buf InteractiveShellFunctionErrorAbsorber;
7071
bool interactive_shell_function_error_absorbed;
7172

72-
void startFunction(char *name, enum Type type);
73+
void startFunction(char *name, enum Type type, enum Type secondary_type);
7374
void endFunction();
7475
void freeFunctionMode();
7576
_Function* getFunction(char *name, char *module);

tests/extensions/spells/example/example.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,12 @@ int KAOS_EXPORT Kaos_dictionary()
9494
int KAOS_EXPORT KaosRegister(struct Kaos _kaos)
9595
{
9696
kaos = _kaos;
97-
kaos.defineFunction("hello", K_VOID, hello_params_name, hello_params_type, hello_params_length);
98-
kaos.defineFunction("add", K_NUMBER, add_params_name, add_params_type, add_params_length);
99-
kaos.defineFunction("log", K_VOID, log_params_name, log_params_type, log_params_length);
100-
kaos.defineFunction("complex", K_VOID, complex_params_name, complex_params_type, complex_params_length);
101-
kaos.defineFunction("array", K_LIST, array_params_name, array_params_type, array_params_length);
102-
kaos.defineFunction("dictionary", K_DICT, dictionary_params_name, dictionary_params_type, dictionary_params_length);
97+
kaos.defineFunction("hello", K_VOID, K_ANY, hello_params_name, hello_params_type, hello_params_length);
98+
kaos.defineFunction("add", K_NUMBER, K_ANY, add_params_name, add_params_type, add_params_length);
99+
kaos.defineFunction("log", K_VOID, K_ANY, log_params_name, log_params_type, log_params_length);
100+
kaos.defineFunction("complex", K_VOID, K_ANY, complex_params_name, complex_params_type, complex_params_length);
101+
kaos.defineFunction("array", K_LIST, K_ANY, array_params_name, array_params_type, array_params_length);
102+
kaos.defineFunction("dictionary", K_DICT, K_ANY, dictionary_params_name, dictionary_params_type, dictionary_params_length);
103103

104104
return 0;
105105
}

tests/function.kaos

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,3 +281,50 @@ print a
281281
b['f'] = dict_f1()
282282
print b
283283
b['f'] = lib.dict_f1()
284+
285+
286+
// Direct assignments to typed lists
287+
288+
bool list def bool_list_test()
289+
bool list x = [true, false]
290+
return x
291+
end
292+
bool list bool_list_test_var = bool_list_test()
293+
print bool_list_test_var
294+
295+
num list def num_list_test()
296+
num list x = [1, 3.14]
297+
return x
298+
end
299+
num list num_list_test_var = num_list_test()
300+
print num_list_test_var
301+
302+
str list def str_list_test()
303+
str list x = ['a', "b"]
304+
return x
305+
end
306+
str list str_list_test_var = str_list_test()
307+
print str_list_test_var
308+
309+
// Direct assignments to typed dictionaries
310+
311+
bool dict def bool_dict_test()
312+
bool dict x = {'a': true, 'b': false}
313+
return x
314+
end
315+
bool dict bool_dict_test_var = bool_dict_test()
316+
print bool_dict_test_var
317+
318+
num dict def num_dict_test()
319+
num dict x = {'a': 1, 'b': 3.14}
320+
return x
321+
end
322+
num dict num_dict_test_var = num_dict_test()
323+
print num_dict_test_var
324+
325+
str dict def str_dict_test()
326+
str dict x = {'a': 'a', "b": "b"}
327+
return x
328+
end
329+
str dict str_dict_test_var = str_dict_test()
330+
print str_dict_test_var

tests/function.out

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,9 @@ bar
7272
[false, 6, 'bar', 8, [4, 5, 6], {'a': 1, 'b': 2, 'c': 3}]
7373
[false, 6, 'bar', 8, [4, 5, 6], {'d': 4, 'e': 5, 'f': 6}]
7474
{'a': false, 'b': 6, 'c': 'bar', 'd': 8, 'e': [4, 5, 6], 'f': {'a': 1, 'b': 2, 'c': 3}}
75+
[true, false]
76+
[1, 3.14]
77+
['a', 'b']
78+
{'a': true, 'b': false}
79+
{'a': 1, 'b': 3.14}
80+
{'a': 'a', 'b': 'b'}

0 commit comments

Comments
 (0)