It appears that something is destroyed when operator_resolution returns, hilarity...
[fridhskrift.git] / parser / statement.cpp
blobd2c01385b8d33c4eb36c8054a95c12f24656edf0
1 #include <ail/file.hpp>
2 #include <ail/string.hpp>
3 #include <fridh/parser.hpp>
4 #include <fridh/lexer.hpp>
6 namespace fridh
8 void set_last_group(lexeme_group::type new_last_group, lexeme_group::type & last_group, bool & got_last_group)
10 last_group = new_last_group;
11 got_last_group = true;
14 void add_unary_node(lexeme & current_lexeme, parse_tree_nodes & arguments)
16 parse_tree_node unary_operator_node;
17 lexeme_to_unary_operator_node(current_lexeme, unary_operator_node);
18 arguments.push_back(unary_operator_node);
21 void add_negation_lexeme(parse_tree_nodes & arguments)
23 add_unary_node(lexeme(lexeme_type::negation), arguments);
26 void visualise_nodes(parse_tree_nodes & nodes)
28 std::cout << "Parse tree nodes:" << std::endl;
29 uword counter = 1;
30 for(parse_tree_nodes::iterator i = nodes.begin(), end = nodes.end(); i != end; i++, counter++)
31 std::cout << counter << ". " << i->to_string() << std::endl;
34 void parser::process_node_group(parse_tree_nodes & arguments, parse_tree_nodes & output)
36 std::cout << "process_node_group" << std::endl;
37 visualise_nodes(arguments);
38 parse_tree_node new_node;
39 std::cout << "new_node:" << std::endl;
40 std::cout << new_node.to_string() << std::endl;
41 operator_resolution(arguments, new_node);
42 std::cout << "operator_resolution returned:" << std::endl;
43 std::cout << new_node.to_string() << std::endl;
44 output.push_back(new_node);
45 std::cout << "/process_node_group" << std::endl;
48 void parser::process_atomic_statement(lexeme_container & lexemes, std::size_t & offset, parse_tree_nodes & output, bool allow_multi_statements, lexeme_type::type terminator)
50 bool got_last_group = false;
51 lexeme_group::type last_group;
53 parse_tree_nodes arguments;
55 symbol_prefix::type prefix = symbol_prefix::none;
57 for(std::size_t & i = offset, end = lexemes.size(); i < end; i++)
59 lexeme & current_lexeme = lexemes[i];
61 if(current_lexeme.type == terminator)
63 i++;
64 break;
66 else if(prefix != symbol_prefix::none && current_lexeme.type != lexeme_type::name)
67 double_lexeme_error("Invalid use of a symbol prefix", i);
69 switch(current_lexeme.type)
71 case lexeme_type::scope_operator:
72 prefix = symbol_prefix::scope_operator;
73 continue;
75 case lexeme_type::class_operator:
76 prefix = symbol_prefix::class_operator;
77 continue;
79 case lexeme_type::bracket_start:
81 parse_tree_nodes content;
82 if(got_last_group && last_group == lexeme_group::argument)
84 process_atomic_statement(lexemes, offset, content, true, lexeme_type::bracket_end);
85 parse_tree_node call;
86 call.is_call();
87 call.call_pointer->arguments = content;
88 arguments.push_back(call);
90 else
92 process_atomic_statement(lexemes, offset, content, false, lexeme_type::bracket_end);
93 arguments.push_back(content[0]);
95 set_last_group(lexeme_group::argument, last_group, got_last_group);
96 break;
99 case lexeme_type::bracket_end:
100 error("Unmatched closing bracket");
102 case lexeme_type::array_start:
104 parse_tree_nodes elements;
105 process_atomic_statement(lexemes, offset, elements, true, lexeme_type::array_end);
106 arguments.push_back(parse_tree_node(elements));
107 set_last_group(lexeme_group::argument, last_group, got_last_group);
108 break;
111 case lexeme_type::array_end:
112 error("Unmatched curled brace");
114 case lexeme_type::call_operator:
115 arguments.push_back(parse_tree_node(parse_tree_node_type::call_operator));
116 set_last_group(lexeme_group::call_operator, last_group, got_last_group);
117 continue;
119 case lexeme_type::spaced_call_operator:
120 arguments.push_back(parse_tree_node(parse_tree_node_type::spaced_call_operator));
121 set_last_group(lexeme_group::call_operator, last_group, got_last_group);
122 continue;
124 case lexeme_type::iterator:
125 arguments.push_back(parse_tree_node(parse_tree_node_type::iterator));
126 set_last_group(lexeme_group::argument, last_group, got_last_group);
127 continue;
130 lexeme_group::type group;
131 if(!get_lexeme_group(current_lexeme.type, group))
132 single_lexeme_error("Invalid lexeme type in statement", i);
134 switch(group)
136 case lexeme_group::argument:
138 if(got_last_group && last_group == lexeme_group::argument)
140 if(allow_multi_statements)
142 process_node_group(arguments, output);
143 arguments.clear();
144 got_last_group = false;
146 else
147 double_lexeme_error("Encountered two arguments without an operator between them", i);
150 parse_tree_node argument_node;
151 lexeme_to_argument_node(current_lexeme, argument_node);
152 if(current_lexeme.type == lexeme_type::name)
154 argument_node.symbol_pointer->type = prefix;
155 if(prefix != symbol_prefix::none)
159 argument_node.type == parse_tree_node_type::binary_operator_node &&
160 argument_node.binary_operator_pointer->type == binary_operator_type::selection
162 double_lexeme_error("Encountered a symbol prefix after a selection operator", i);
163 prefix = symbol_prefix::none;
166 //std::cout << "Pushing " << argument_node.to_string() << std::endl;
167 arguments.push_back(argument_node);
168 //visualise_nodes(arguments);
169 break;
172 case lexeme_group::unary_operator:
173 if(got_last_group && last_group == lexeme_group::argument)
174 double_lexeme_error("Encountered an argument followed by a unary operator without a binary operator between them", i);
175 add_unary_node(current_lexeme, arguments);
176 break;
178 case lexeme_group::binary_operator:
180 if(got_last_group)
182 switch(last_group)
184 case lexeme_group::unary_operator:
185 double_lexeme_error("Encountered a unary operator followed by a binary operator", i);
187 case lexeme_group::binary_operator:
188 if(current_lexeme.type == lexeme_type::subtraction)
189 add_negation_lexeme(arguments);
190 else
191 double_lexeme_error("Encountered two sequential binary operators", i);
192 break;
195 else
197 if(current_lexeme.type == lexeme_type::subtraction)
198 add_negation_lexeme(arguments);
199 else
200 single_lexeme_error("Encountered a binary operator in the beginning of a statement", i);
201 break;
204 parse_tree_node binary_operator_node;
205 lexeme_to_binary_operator_node(current_lexeme, binary_operator_node);
206 arguments.push_back(binary_operator_node);
207 break;
210 case lexeme_group::post_fix_operator:
211 if(got_last_group)
213 if(last_group != lexeme_group::argument)
214 single_lexeme_error("Encountered a post fix operator after a non-argument", i);
216 else
217 single_lexeme_error("A post fix operator requires a previous argument", i);
219 add_unary_node(current_lexeme, arguments);
220 set_last_group(lexeme_group::argument, last_group, got_last_group);
221 continue;
224 set_last_group(group, last_group, got_last_group);
227 if(!got_last_group)
228 error("Empty statement");
230 if(last_group != lexeme_group::argument)
231 error("An operator is missing an argument");
233 std::cout << "Bottom" << std::endl;
234 visualise_nodes(arguments);
236 process_node_group(arguments, output);