// generates an error for an undefined `goto'; choose appropriate // message when label name is a reserved word (which can only be `break') private void UndefGoto( LabelDesc gt ) { string template = Lexer.IsReservedWord( gt.Name ) ? "<{0}> at line {1} not inside a loop" : "no visible label '{0}' for <goto> at line {1}"; var msg = string.Format( template, gt.Name, gt.Line ); SemanticError( msg ); }
private LabelDesc NewLebelEntry( string name, int line, int pc ) { var desc = new LabelDesc(); desc.Name = name; desc.Pc = pc; desc.Line = line; desc.NumActVar = CurFunc.NumActVar; return desc; }
// check whether new label `label' matches any pending gotos in current // block; solves forward jumps private void FindGotos( LabelDesc label ) { int i = CurFunc.Block.FirstGoto; while( i < PendingGotos.Count ) { if( PendingGotos[i].Name == label.Name ) CloseGoto( i, label ); else ++i; } }
private void CloseGoto( int g, LabelDesc label ) { var gt = PendingGotos[g]; Utl.Assert( gt.Name == label.Name ); if( gt.NumActVar < label.NumActVar ) { var v = GetLocalVar( CurFunc, gt.NumActVar ); var msg = string.Format( "<goto {0}> at line {1} jumps into the scope of local '{2}'", gt.Name, gt.Line, v.VarName); SemanticError( msg ); } Coder.PatchList( CurFunc, gt.Pc, label.Pc ); PendingGotos.RemoveAt(g); }