Changed the FNV include path
[fridhskrift.git] / parser / operator.cpp
blob94efc0f8fd245b21634d70fd4b2bab923a13ded1
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 visualise_parse_tree_nodes(parse_tree_nodes & input)
16 for(std::size_t i = 0; i < input.size(); i++)
17 std::cout << (i + 1) << ". " << input[i].to_string() << std::endl;
20 void parser::operator_resolution(parse_tree_nodes & input, parse_tree_node & output)
22 if(input.size() == 1)
24 output = input[0];
25 return;
28 bool got_an_operator = false;
29 word extremum;
30 std::size_t extremum_offset;
32 for(std::size_t i = 0, end = input.size(); i < end; i++)
34 parse_tree_node & current_node = input[i];
35 word precedence;
37 bool is_initialised_unary_node =
38 current_node.type == parse_tree_node_type::unary_operator_node &&
39 current_node.unary_operator_pointer->argument.type != parse_tree_node_type::uninitialised
42 bool is_initialised_call_node =
43 current_node.type == parse_tree_node_type::call &&
44 i == 0;
48 is_initialised_unary_node ||
49 is_initialised_call_node
51 continue;
53 try
55 if(get_parse_tree_node_precedence(current_node, precedence))
59 !got_an_operator ||
60 precedence > extremum ||
61 (is_right_to_left_operator(current_node) && precedence == extremum)
64 got_an_operator = true;
65 extremum = precedence;
66 extremum_offset = i;
70 catch(ail::exception & exception)
72 error(exception.get_message());
76 if(!got_an_operator)
77 error("Failed to perform operator resolution");
79 parse_tree_node & operator_node = input[extremum_offset];
80 std::size_t next_offset = extremum_offset + 1;
81 switch(operator_node.type)
83 case parse_tree_node_type::unary_operator_node:
85 std::size_t argument_offset;
86 if(operator_node.is_post_fix())
87 argument_offset = extremum_offset - 1;
88 else
89 argument_offset = next_offset;
91 if(argument_offset >= input.size())
92 error("Missing operator for unary argument");
94 parse_tree_unary_operator_node & unary_operator_node = *operator_node.unary_operator_pointer;
95 unary_operator_node.argument = input[argument_offset];
96 input.erase(input.begin() + argument_offset);
97 break;
100 case parse_tree_node_type::binary_operator_node:
102 parse_tree_binary_operator_node & binary_operator_node = *operator_node.binary_operator_pointer;
104 if(extremum_offset == 0)
105 error("Encountered a binary operator which lacks a left hand argument");
106 else if(next_offset >= input.size())
107 error("Encountered a binary operator which lacks a right hand argument");
109 parse_tree_nodes
110 left_side(input.begin(), input.begin() + extremum_offset),
111 right_side(input.begin() + next_offset, input.end());
113 operator_resolution(left_side, binary_operator_node.left_argument);
114 operator_resolution(right_side, binary_operator_node.right_argument);
116 output = operator_node;
118 return;
121 case parse_tree_node_type::call:
122 call_check(extremum_offset);
123 operator_node.call_pointer->function = input[0];
124 input.erase(input.begin());
125 break;
127 case parse_tree_node_type::call_operator:
128 case parse_tree_node_type::spaced_call_operator:
130 call_check(extremum_offset);
131 operator_node.is_call();
132 operator_node.call_pointer->function = input[0];
133 input.erase(input.begin());
135 parse_tree_node & new_operator_node = input[0];
137 next_offset--;
138 if(new_operator_node.type != parse_tree_node_type::spaced_call_operator && next_offset < input.size())
140 new_operator_node.call_pointer->arguments.push_back(input[next_offset]);
141 input.erase(input.begin() + next_offset);
143 break;
146 default:
147 error("Invalid operator node type encountered during operator resolution");
150 operator_resolution(input, output);