@@ -16,8 +16,15 @@ class Emitter {
1616 std::vector<unsigned int > fixups;
1717 unsigned int target;
1818 };
19+ class LoopLabels {
20+ public:
21+ LoopLabels (): exit(nullptr ), next(nullptr ) {}
22+ LoopLabels (Label *exit, Label *next): exit(exit), next(next) {}
23+ Label *exit;
24+ Label *next;
25+ };
1926public:
20- Emitter (DebugInfo *debug): code(), strings(), globals(), functions(), exit_label (), debug_info(debug) {}
27+ Emitter (DebugInfo *debug): code(), strings(), globals(), functions(), loop_labels (), debug_info(debug) {}
2128 void emit (unsigned char b);
2229 void emit_uint32 (uint32_t value);
2330 void emit (unsigned char b, uint32_t value);
@@ -31,16 +38,17 @@ class Emitter {
3138 Label create_label ();
3239 void emit_jump (unsigned char b, Label &label);
3340 void jump_target (Label &label);
34- void add_exit_label (unsigned int loop_id, Label &label );
35- void remove_exit_label (unsigned int loop_id);
41+ void add_loop_labels (unsigned int loop_id, Label &exit, Label &next );
42+ void remove_loop_labels (unsigned int loop_id);
3643 Label &get_exit_label (unsigned int loop_id);
44+ Label &get_next_label (unsigned int loop_id);
3745 void debug_line (int line);
3846private:
3947 std::vector<unsigned char > code;
4048 std::vector<std::string> strings;
4149 std::vector<std::string> globals;
4250 std::vector<Label> functions;
43- std::map<size_t , Label *> exit_label ;
51+ std::map<size_t , LoopLabels> loop_labels ;
4452 DebugInfo *debug_info;
4553private:
4654 Emitter (const Emitter &);
@@ -156,22 +164,30 @@ void Emitter::jump_target(Label &label)
156164 }
157165}
158166
159- void Emitter::add_exit_label (unsigned int loop_id, Label &label )
167+ void Emitter::add_loop_labels (unsigned int loop_id, Label &exit, Label &next )
160168{
161- exit_label [loop_id] = &label ;
169+ loop_labels [loop_id] = LoopLabels (&exit, &next) ;
162170}
163171
164- void Emitter::remove_exit_label (unsigned int loop_id)
172+ void Emitter::remove_loop_labels (unsigned int loop_id)
165173{
166- exit_label .erase (loop_id);
174+ loop_labels .erase (loop_id);
167175}
168176
169177Emitter::Label &Emitter::get_exit_label (unsigned int loop_id)
170178{
171- if (exit_label.find (loop_id) == exit_label.end ()) {
179+ if (loop_labels.find (loop_id) == loop_labels.end ()) {
180+ internal_error (" loop_id not found" );
181+ }
182+ return *loop_labels[loop_id].exit ;
183+ }
184+
185+ Emitter::Label &Emitter::get_next_label (unsigned int loop_id)
186+ {
187+ if (loop_labels.find (loop_id) == loop_labels.end ()) {
172188 internal_error (" loop_id not found" );
173189 }
174- return *exit_label [loop_id];
190+ return *loop_labels [loop_id]. next ;
175191}
176192
177193void Emitter::debug_line (int line)
@@ -740,14 +756,14 @@ void WhileStatement::generate_code(Emitter &emitter) const
740756 emitter.jump_target (top);
741757 condition->generate (emitter);
742758 auto skip = emitter.create_label ();
743- emitter.add_exit_label (loop_id, skip);
744759 emitter.emit_jump (JF, skip);
760+ emitter.add_loop_labels (loop_id, skip, top);
745761 for (auto stmt: statements) {
746762 stmt->generate (emitter);
747763 }
748764 emitter.emit_jump (JUMP, top);
749765 emitter.jump_target (skip);
750- emitter.remove_exit_label (loop_id);
766+ emitter.remove_loop_labels (loop_id);
751767}
752768
753769void CaseStatement::generate_code (Emitter &emitter) const
@@ -824,8 +840,8 @@ void CaseStatement::RangeWhenCondition::generate(Emitter &emitter) const
824840void ForStatement::generate_code (Emitter &emitter) const
825841{
826842 auto skip = emitter.create_label ();
827- emitter.add_exit_label (loop_id, skip);
828843 auto loop = emitter.create_label ();
844+ auto next = emitter.create_label ();
829845
830846 start->generate (emitter);
831847 var->generate_store (emitter);
@@ -836,25 +852,33 @@ void ForStatement::generate_code(Emitter &emitter) const
836852 emitter.emit (GEN);
837853 emitter.emit_jump (JF, skip);
838854
855+ emitter.add_loop_labels (loop_id, skip, next);
856+
839857 for (auto stmt: statements) {
840858 stmt->generate (emitter);
841859 }
842860
861+ emitter.jump_target (next);
843862 emitter.emit (PUSHN, number_from_uint32 (1 ));
844863 var->generate_load (emitter);
845864 emitter.emit (ADDN);
846865 var->generate_store (emitter);
847866 emitter.emit_jump (JUMP, loop);
848867
849868 emitter.jump_target (skip);
850- emitter.remove_exit_label (loop_id);
869+ emitter.remove_loop_labels (loop_id);
851870}
852871
853872void ExitStatement::generate_code (Emitter &emitter) const
854873{
855874 emitter.emit_jump (JUMP, emitter.get_exit_label (loop_id));
856875}
857876
877+ void NextStatement::generate_code (Emitter &emitter) const
878+ {
879+ emitter.emit_jump (JUMP, emitter.get_next_label (loop_id));
880+ }
881+
858882void Scope::predeclare (Emitter &emitter) const
859883{
860884 for (auto n: names) {
0 commit comments