@@ -130,6 +130,8 @@ Validator::Validator(SourceModel* source)
130130
131131 m_lineindex = -1 ;
132132 m_line = nullptr ;
133+
134+ m_forcount = 0 ;
133135}
134136
135137bool Validator::ProcessLine ()
@@ -144,24 +146,30 @@ bool Validator::ProcessLine()
144146
145147 if (m_lineindex >= (int )m_source->lines .size ())
146148 {
147- // ProcessEnd();
149+ ProcessEnd ();
148150 m_lineindex = INT_MAX ;
149151 return false ;
150152 }
151153
152154 m_line = &(m_source->lines [m_lineindex]);
153155
154- // Spectial case: line with FOR statement should have line number
155- if (m_line->linenum == 0 && m_line->statement .token .keyword == KeywordFOR)
156- {
157- Error (" Line with FOR statement should have line number." );
158- }
159-
160156 ValidateStatement (m_line->statement );
161157
162158 return true ;
163159}
164160
161+ void Validator::ProcessEnd ()
162+ {
163+ if (!m_fornextstack.empty ())
164+ {
165+ const ValidatorForSpec& forspec = m_fornextstack.back ();
166+
167+ std::cerr << " ERROR at " << forspec.srclinenum << " - FOR statement has no corresponding NEXT." << std::endl;
168+ m_line->error = true ;
169+ RegisterError ();
170+ }
171+ }
172+
165173void Validator::ValidateStatement (StatementModel& statement)
166174{
167175 // Find validator implementation
@@ -527,11 +535,14 @@ void Validator::ValidateFor(StatementModel& statement)
527535 // TODO: check variable type
528536
529537 // Add FOR variable to FOR/NEXT stack
538+ m_forcount++;
530539 ValidatorForSpec forspec;
531540 forspec.varname = var.name ;
532- forspec.linenum = m_line->linenum ;
541+ forspec.srclinenum = m_line->srclinenum ;
533542 m_fornextstack.push_back (forspec);
534543
544+ statement.forindex = m_forcount;
545+
535546 if (statement.args .size () < 2 )
536547 MODEL_ERROR (" Two parameters expected." );
537548
@@ -554,6 +565,63 @@ void Validator::ValidateFor(StatementModel& statement)
554565 }
555566}
556567
568+ // NEXT [<ПАРАМЕТР>[,< ПАРАМЕТР >...]]
569+ void Validator::ValidateNext (StatementModel& statement)
570+ {
571+ // NOTE: Filling statement.variables with list of NEXT variables plus link to FOR statement for each
572+
573+ if (statement.params .empty ()) // NEXT without parameters
574+ {
575+ if (m_fornextstack.empty ())
576+ MODEL_ERROR (" NEXT without FOR." );
577+
578+ ValidatorForSpec forspec = m_fornextstack.back ();
579+ m_fornextstack.pop_back ();
580+
581+ Token tokenvar;
582+ tokenvar.type = TokenTypeIdentifier;
583+ tokenvar.text = forspec.varname ;
584+ statement.params .push_back (tokenvar);
585+
586+ // link FOR to the NEXT line number
587+ SourceLineModel& linefor = m_source->GetSourceLine (forspec.srclinenum );
588+ assert (linefor.statement .forindex != 0 );
589+
590+ VariableModel variable;
591+ variable.name = forspec.varname ;
592+ variable.psourceline = &linefor;
593+ statement.variables .push_back (variable);
594+
595+ return ;
596+ }
597+
598+ for (auto it = std::begin (statement.params ); it != std::end (statement.params ); ++it)
599+ {
600+ if (m_fornextstack.empty ())
601+ MODEL_ERROR (" NEXT without FOR." );
602+
603+ ValidatorForSpec forspec = m_fornextstack.back ();
604+
605+ string varname = GetCanonicVariableName (it->text );
606+ if (forspec.varname != varname)
607+ MODEL_ERROR (" NEXT variable expected: " + forspec.varname + " , found: " + varname + " ." );
608+ assert (m_source->IsVariableRegistered (varname));
609+
610+ // TODO: Check for numeric variable type?
611+
612+ m_fornextstack.pop_back ();
613+
614+ // link FOR to the NEXT line number
615+ SourceLineModel& linefor = m_source->GetSourceLine (forspec.srclinenum );
616+ assert (linefor.statement .forindex != 0 );
617+
618+ VariableModel variable;
619+ variable.name = varname;
620+ variable.psourceline = &linefor;
621+ statement.variables .push_back (variable);
622+ }
623+ }
624+
557625void Validator::ValidateGotoGosub (StatementModel& statement)
558626{
559627 if (!m_source->IsLineNumberExists (statement.paramline ))
@@ -884,63 +952,6 @@ void Validator::ValidatePsetPreset(StatementModel& statement)
884952 MODEL_ERROR (" Too many parameters." );
885953}
886954
887- // NEXT [<ПАРАМЕТР>[,< ПАРАМЕТР >...]]
888- void Validator::ValidateNext (StatementModel& statement)
889- {
890- // NOTE: Filling statement.variables with list of NEXT variables plus link to FOR statement for each
891-
892- if (statement.params .empty ()) // NEXT without parameters
893- {
894- if (m_fornextstack.empty ())
895- MODEL_ERROR (" NEXT without FOR." );
896-
897- ValidatorForSpec forspec = m_fornextstack.back ();
898- m_fornextstack.pop_back ();
899-
900- Token tokenvar;
901- tokenvar.type = TokenTypeIdentifier;
902- tokenvar.text = forspec.varname ;
903- statement.params .push_back (tokenvar);
904-
905- // link FOR to the NEXT line number
906- SourceLineModel& linefor = m_source->GetSourceLine (forspec.linenum );
907- linefor.statement .paramline = m_line->linenum ;
908-
909- VariableModel variable;
910- variable.name = forspec.varname ;
911- variable.psourceline = &linefor;
912- statement.variables .push_back (variable);
913-
914- return ;
915- }
916-
917- for (auto it = std::begin (statement.params ); it != std::end (statement.params ); ++it)
918- {
919- if (m_fornextstack.empty ())
920- MODEL_ERROR (" NEXT without FOR." );
921-
922- ValidatorForSpec forspec = m_fornextstack.back ();
923-
924- string varname = GetCanonicVariableName (it->text );
925- if (forspec.varname != varname)
926- MODEL_ERROR (" NEXT variable expected: " + forspec.varname + " , found: " + varname + " ." );
927- assert (m_source->IsVariableRegistered (varname));
928-
929- // TODO: Check for numeric variable type?
930-
931- m_fornextstack.pop_back ();
932-
933- // link FOR to the NEXT line number
934- SourceLineModel& linefor = m_source->GetSourceLine (forspec.linenum );
935- linefor.statement .paramline = m_line->linenum ;
936-
937- VariableModel variable;
938- variable.name = varname;
939- variable.psourceline = &linefor;
940- statement.variables .push_back (variable);
941- }
942- }
943-
944955// ON <ВЫРАЖЕНИЕ> GOTO <СПИСОК>
945956// ON <ВЫРАЖЕНИЕ> GOSUB <СПИСОК>
946957void Validator::ValidateOn (StatementModel& statement)
0 commit comments