A scope is now only left after a function or a class - I erroneously went up when...
[fridhskrift.git] / parser / operator.cpp
blobce4e555ef727eb048bdf93530081309811c32e38
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 parse_tree_node & current_node = input[i];
29 word precedence;
33 current_node.type == parse_tree_node_type::unary_operator_node &&
34 current_node.unary_operator_pointer->argument.type != parse_tree_node_type::uninitialised
36 continue;
38 try
40 if(get_parse_tree_node_precedence(current_node, precedence))
44 !got_an_operator ||
45 precedence > extremum ||
46 (is_right_to_left_operator(current_node) && precedence == extremum)
49 got_an_operator = true;
50 extremum = precedence;
51 extremum_offset = i;
55 catch(ail::exception & exception)
57 error(exception.get_message());
61 if(!got_an_operator)
62 error("Failed to perform operator resolution");
64 parse_tree_node & operator_node = input[extremum_offset];
65 std::size_t next_offset = extremum_offset + 1;
66 switch(operator_node.type)
68 case parse_tree_node_type::unary_operator_node:
70 std::size_t argument_offset;
71 if(operator_node.is_post_fix())
72 argument_offset = extremum_offset - 1;
73 else
74 argument_offset = next_offset;
76 parse_tree_unary_operator_node & unary_operator_node = *operator_node.unary_operator_pointer;
77 unary_operator_node.argument = input.at(argument_offset);
78 input.erase(input.begin() + argument_offset);
79 break;
82 case parse_tree_node_type::binary_operator_node:
84 parse_tree_binary_operator_node & binary_operator_node = *operator_node.binary_operator_pointer;
86 parse_tree_nodes
87 left_side(input.begin(), input.begin() + extremum_offset),
88 right_side(input.begin() + next_offset, input.end());
90 operator_resolution(left_side, binary_operator_node.left_argument);
91 operator_resolution(right_side, binary_operator_node.right_argument);
93 output = operator_node;
95 return;
98 case parse_tree_node_type::call:
99 //this is questionable
100 call_check(extremum_offset);
101 operator_node.call_pointer->function = input[0];
102 input.erase(input.begin());
103 break;
105 case parse_tree_node_type::call_operator:
106 case parse_tree_node_type::spaced_call_operator:
107 call_check(extremum_offset);
108 operator_node.is_call();
109 operator_node.call_pointer->function = input[0];
110 input.erase(input.begin());
111 if(operator_node.type != parse_tree_node_type::spaced_call_operator && next_offset != input.size())
113 //it's an unary call
114 operator_node.call_pointer->arguments.push_back(input[next_offset]);
115 input.erase(input.end() - 1);
117 break;
119 default:
120 error("Invalid operator node type encountered during operator resolution");
123 operator_resolution(input, output);