The call operator parsing looks alright to me
[fridhskrift.git] / parser / operator.cpp
blob6d73ca0314b693f58dd2671d274b88471d2445f4
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 call_check(std::size_t extremum_offset)
10 if(extremum_offset != 1)
11 throw ail::exception("Invalid call offset encountered during operator resolution");
14 void parser::operator_resolution(parse_tree_nodes & input, parse_tree_node & output)
16 std::cout << "Performing operator resolution on " << input.size() << " node(s)" << std::endl;
17 if(input.size() == 1)
19 output = input[0];
20 return;
23 bool got_an_operator = false;
24 word extremum;
25 std::size_t extremum_offset;
27 for(std::size_t i = 0, end = input.size(); i < end; i++)
29 parse_tree_node & current_node = input[i];
30 word precedence;
32 bool is_initialised_unary_node =
33 current_node.type == parse_tree_node_type::unary_operator_node &&
34 current_node.unary_operator_pointer->argument.type != parse_tree_node_type::uninitialised
37 bool is_initialised_call_node =
38 current_node.type == parse_tree_node_type::call &&
39 current_node.call_pointer->initialised;
43 is_initialised_unary_node ||
44 is_initialised_call_node
46 continue;
48 try
50 if(get_parse_tree_node_precedence(current_node, precedence))
54 !got_an_operator ||
55 precedence > extremum ||
56 (is_right_to_left_operator(current_node) && precedence == extremum)
59 got_an_operator = true;
60 extremum = precedence;
61 extremum_offset = i;
65 catch(ail::exception & exception)
67 error(exception.get_message());
71 if(!got_an_operator)
72 error("Failed to perform operator resolution");
74 parse_tree_node & operator_node = input[extremum_offset];
75 std::size_t next_offset = extremum_offset + 1;
76 switch(operator_node.type)
78 case parse_tree_node_type::unary_operator_node:
80 std::size_t argument_offset;
81 if(operator_node.is_post_fix())
82 argument_offset = extremum_offset - 1;
83 else
84 argument_offset = next_offset;
86 if(argument_offset >= input.size())
87 error("Missing operator for unary argument");
89 parse_tree_unary_operator_node & unary_operator_node = *operator_node.unary_operator_pointer;
90 unary_operator_node.argument = input[argument_offset];
91 input.erase(input.begin() + argument_offset);
92 break;
95 case parse_tree_node_type::binary_operator_node:
97 parse_tree_binary_operator_node & binary_operator_node = *operator_node.binary_operator_pointer;
99 if(extremum_offset == 0)
100 error("Encountered a binary operator which lacks a left hand argument");
101 else if(next_offset >= input.size())
102 error("Encountered a binary operator which lacks a right hand argument");
104 parse_tree_nodes
105 left_side(input.begin(), input.begin() + extremum_offset),
106 right_side(input.begin() + next_offset, input.end());
108 operator_resolution(left_side, binary_operator_node.left_argument);
109 operator_resolution(right_side, binary_operator_node.right_argument);
111 output = operator_node;
113 return;
116 case parse_tree_node_type::call:
117 call_check(extremum_offset);
118 operator_node.call_pointer->function = input[0];
119 input.erase(input.begin());
120 break;
122 case parse_tree_node_type::call_operator:
123 case parse_tree_node_type::spaced_call_operator:
124 call_check(extremum_offset);
125 operator_node.is_call();
126 operator_node.call_pointer->function = input[0];
127 input.erase(input.begin());
128 if(operator_node.type != parse_tree_node_type::spaced_call_operator && next_offset != input.size())
130 //it's a unary call
131 operator_node.call_pointer->arguments.push_back(input[next_offset]);
132 input.erase(input.end() - 1);
134 break;
136 default:
137 error("Invalid operator node type encountered during operator resolution");
140 operator_resolution(input, output);