This repository has been archived by the owner on Nov 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
function_call_parser.c
126 lines (104 loc) · 2.49 KB
/
function_call_parser.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <assert.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "ast.h"
#include "buffer.h"
#include "expression_parser.h"
#include "function_call_parser.h"
#include "lexer.h"
#include "symbol.h"
#include "utils.h"
ast_t* function_call_parser(buffer_t* buffer, symbol_t** global_table, symbol_t** local_table)
{
char* function_name = lexer_getalphanum(buffer);
symbol_t* symbol = sym_search(*global_table, function_name);
free(function_name);
if (symbol == NULL)
{
parse_error("Cannot find function with this name.", buffer, 1);
}
if (buf_getchar(buffer) != '(')
{
parse_error("Invalid token, exepected '('.", buffer, 1);
}
assert(symbol != NULL && symbol->attributes != NULL);
ast_list_t* exepcted_params = symbol->attributes->function.params;
ast_list_t* params = NULL;
buf_lock(buffer);
if (buf_getchar_after_blank(buffer) == ')')
{
buf_unlock(buffer);
goto last_check;
}
buf_rollback_and_unlock(buffer, 1);
while (true)
{
if (exepcted_params == NULL)
{
parse_error("Too many arguments.", buffer, 1);
}
// TODO: Replace by expression_parser...
ast_t* ast = NULL;
char c = buf_getchar_rollback(buffer);
if (isdigit(c) || c == '-')
{
ast = ast_new_integer(lexer_getnumber(buffer));
}
else if (isalpha(c))
{
char* lexem = lexer_getalphanum(buffer);
if (strcmp(lexem, "vrai") == 0)
{
ast = ast_new_boolean(true);
}
else if (strcmp(lexem, "faux") == 0)
{
ast = ast_new_boolean(false);
}
else
{
symbol_t* symbol = sym_search(*local_table, lexem);
if (symbol == NULL)
{
parse_error("Invalid argument.", buffer, 1);
}
ast = symbol->attributes;
}
free(lexem);
}
else
{
parse_error("Invalid argument", buffer, 1);
}
// ----------
assert(ast != NULL);
assert(exepcted_params != NULL && exepcted_params->value != NULL && exepcted_params->value->type == AST_VARIABLE);
// TODO: Compare AST types and TYPE type...
//if (exepcted_params->value->var.type != ast->type)
//{
// parse_error("Invalid error type.", buffer, 1);
//}
params = ast_list_add(params, ast);
exepcted_params = exepcted_params->next;
c = buf_getchar(buffer);
if (c == ',')
{
continue;
}
if (c == ')')
{
break;
}
else
{
parse_error("Invalid token, expected ',' or ')' token.", buffer, 1);
}
}
last_check:
if (exepcted_params != NULL)
{
parse_error("Expected more arguments.", buffer, 1);
}
return ast_new_fncall(symbol->attributes->function.name, params);
}