Operator resolution is now part of the parser class
[fridhskrift.git] / parser / operator.cpp
blobd25a6d1574844d068b55a6d3ca1c41f0fbbeec6d
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 if(input.size() != 1)
18 output = input[0];
19 return;
22 bool got_an_operator = false;
23 word extremum;
24 std::size_t extremum_offset;
26 for(std::size_t i = 0, end = input.size(); i < end; i++)
28 word precedence;
29 parse_tree_node & current_node = input[i];
30 if(get_parse_tree_node_precedence(current_node, precedence))
34 !got_an_operator ||
35 precedence > extremum ||
36 (is_right_to_left_operator(current_node) && precedence == extremum)
39 got_an_operator = true;
40 extremum = precedence;
41 extremum_offset = i;
46 if(!got_an_operator)
47 error("Failed to perform operator resolution");
49 parse_tree_node & operator_node = input[extremum_offset];
50 std::size_t next_offset = extremum_offset + 1;
51 switch(operator_node.type)
53 case parse_tree_node_type::unary_operator_node:
55 std::size_t argument_offset = next_offset;
56 parse_tree_unary_operator_node & unary_operator_node = *operator_node.unary_operator_pointer;
57 unary_operator_node.argument = input.at(argument_offset);
58 input.erase(input.begin() + argument_offset);
59 break;
62 case parse_tree_node_type::binary_operator_node:
64 parse_tree_binary_operator_node & binary_operator_node = *operator_node.binary_operator_pointer;
66 parse_tree_nodes
67 left_side,
68 right_side;
70 std::copy(input.begin(), input.begin() + extremum_offset, left_side.begin());
71 std::copy(input.begin() + next_offset, input.end(), right_side.begin());
73 operator_resolution(left_side, binary_operator_node.left_argument);
74 operator_resolution(right_side, binary_operator_node.right_argument);
76 output = operator_node;
77 break;
80 case parse_tree_node_type::call:
81 //this is questionable
82 call_check(extremum_offset);
83 operator_node.call_pointer->function = input[0];
84 input.erase(input.begin());
85 break;
87 case parse_tree_node_type::call_operator:
88 case parse_tree_node_type::spaced_call_operator:
89 call_check(extremum_offset);
90 operator_node.is_call();
91 operator_node.call_pointer->function = input[0];
92 input.erase(input.begin());
93 if(operator_node.type != parse_tree_node_type::spaced_call_operator && next_offset != input.size())
95 //it's an unary call
96 operator_node.call_pointer->arguments.push_back(input[next_offset]);
97 input.erase(input.end() - 1);
99 break;
101 default:
102 throw ail::exception("Invalid operator node type encountered during operator resolution");