A scope is now only left after a function or a class - I erroneously went up when...
[fridhskrift.git] / parser / control_flow.cpp
blob761011281a15a04c299669b26e25a12936171554
1 #include <ail/file.hpp>
2 #include <ail/string.hpp>
3 #include <fridh/parser.hpp>
4 #include <fridh/lexer.hpp>
6 namespace fridh
8 bool parser::is_if_statement()
10 return lines[line_offset].lexemes[0].type == lexeme_type::division;
13 bool parser::process_if(executable_unit & output)
15 lexeme_container & lexemes = get_lexemes();
16 if(!is_if_statement())
17 return false;
19 parse_tree_node conditional;
20 process_composite_term(conditional);
22 executable_units if_body;
23 process_body(&if_body);
25 bool is_if_else = false;
27 if(line_offset < line_end)
29 lexeme_container & lexemes = get_lexemes();
30 if(is_if_statement() && lexemes.size() == 1)
32 is_if_else = true;
34 executable_units else_body;
35 process_body(&else_body);
37 output.type = executable_unit_type::if_else_statement;
38 if_else_statement * & if_else_pointer = output.if_else_pointer;
39 if_else_pointer = new if_else_statement;
40 if_else_pointer->conditional_term = conditional;
41 if_else_pointer->if_body = if_body;
42 if_else_pointer->else_body = else_body;
46 if(!is_if_else)
48 output.type = executable_unit_type::if_statement;
49 if_statement * & if_pointer = output.if_pointer;
50 if_pointer = new if_statement;
51 if_pointer->conditional_term = conditional;
52 if_pointer->body = if_body;
55 return true;
58 bool parser::process_while(executable_unit & output)
60 lexeme_container & lexemes = get_lexemes();
61 if(lexemes[0].type != lexeme_type::while_operator)
62 return false;
64 parse_tree_node conditional;
65 process_composite_term(conditional);
67 output.type = executable_unit_type::while_statement;
68 while_statement * & while_pointer = output.while_pointer;
69 while_pointer = new while_statement;
70 while_pointer->conditional_term = conditional;
72 process_body(&while_pointer->body);
74 return true;
77 bool parser::process_for(executable_unit & output)
79 lexeme_container & lexemes = get_lexemes();
80 if(lexemes[0].type != lexeme_type::iteration)
81 return false;
83 if(lexemes.size() == 1)
85 //three part for
87 if(lines.size() - line_offset < 4)
88 throw ail::exception("Incomplete for statement");
90 line_offset++;
92 for(std::size_t i = line_offset, end = i + 3; i < end; i++)
94 if(lines[i].indentation_level != indentation_level)
95 throw ail::exception("Invalid indentation level in a for statement");
98 output.type = executable_unit_type::for_statement;
99 for_statement * & for_pointer = output.for_pointer;
100 for_pointer = new for_statement;
101 process_offset_atomic_statement(for_pointer->initialisation);
102 process_offset_atomic_statement(for_pointer->conditional);
103 process_offset_atomic_statement(for_pointer->iteration);
105 else
107 //for each statement
109 output.type = executable_unit_type::for_each_statement;
110 for_each_statement * & for_each_pointer = output.for_each_pointer;
111 for_each_pointer = new for_each_statement;
112 process_composite_term(for_each_pointer->container);
114 process_body(&for_each_pointer->body);
117 return true;
120 bool parser::process_return(executable_unit & output)
122 lexeme_container & lexemes = get_lexemes();
123 if(lexemes[0].type != lexeme_type::selection_operator)
124 return false;
126 output.type = executable_unit_type::return_statement;
127 parse_tree_node * & statement_pointer = output.statement_pointer;
128 statement_pointer = new parse_tree_node;
129 process_composite_term(*statement_pointer);
131 return true;
134 void parser::process_statement(executable_unit & output)
140 process_if(output) ||
141 process_while(output) ||
142 process_for(output) ||
143 process_return(output)
147 output.type = executable_unit_type::statement;
148 parse_tree_node * & node = output.statement_pointer;
149 node = new parse_tree_node;
150 process_offset_atomic_statement(*node);
153 line_offset++;
154 std::cout << "process_statement" << std::endl;