1 #include <ail/file.hpp>
2 #include <ail/string.hpp>
3 #include <fridh/parser.hpp>
4 #include <fridh/lexer.hpp>
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
;
23 bool got_an_operator
= false;
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
];
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
50 if(get_parse_tree_node_precedence(current_node
, precedence
))
55 precedence
> extremum
||
56 (is_right_to_left_operator(current_node
) && precedence
== extremum
)
59 got_an_operator
= true;
60 extremum
= precedence
;
65 catch(ail::exception
& exception
)
67 error(exception
.get_message());
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;
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
);
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");
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
;
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());
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())
131 operator_node
.call_pointer
->arguments
.push_back(input
[next_offset
]);
132 input
.erase(input
.end() - 1);
137 error("Invalid operator node type encountered during operator resolution");
140 operator_resolution(input
, output
);