@@ -11,12 +11,23 @@ use std::{
1111 str:: FromStr ,
1212 num:: ParseIntError ,
1313 fmt:: Display ,
14+ panic:: catch_unwind,
15+ process:: exit,
1416} ;
1517
1618pub type Tag = usize ;
1719pub type TagsTable = Vec < usize > ;
1820pub const UNINIT_TAG_TARGET : usize = usize:: MAX ;
1921
22+ /// 带有Error前缀, 并且文本为红色的eprintln
23+ #[ macro_export]
24+ macro_rules! err {
25+ ( $fmtter: expr $( , $args: expr) * $( , ) ? ) => {
26+ eprintln!( concat!( "\x1b [1;31m" , "Error: " , $fmtter, "\x1b [0m" ) , $( $args) ,* ) ;
27+ } ;
28+ }
29+
30+
2031/// 传入`TagsTable`, 生成逻辑代码
2132pub trait Compile {
2233 fn compile ( & self , tags_table : & TagsTable ) -> String ;
@@ -92,6 +103,30 @@ impl From<(Tag, String)> for Jump {
92103}
93104impl Compile for Jump {
94105 fn compile ( & self , tags_table : & TagsTable ) -> String {
106+ if self . 0 >= tags_table. len ( ) || tags_table[ self . 0 ] == UNINIT_TAG_TARGET {
107+ err ! (
108+ concat!(
109+ "进行了越界的跳转标签构建, " ,
110+ "你可以查看是否在尾部编写了空的被跳转标签\n " ,
111+ "标签id: {}, 目标行表:\n " ,
112+ "id \t -> target\n " ,
113+ "{}" ,
114+ ) ,
115+ self . 0 ,
116+ tags_table. iter( )
117+ . enumerate( )
118+ . map( |( id, & target) | {
119+ format!( "\t {} \t -> {}," , id, if target == UNINIT_TAG_TARGET {
120+ "{unknown}" . to_string( )
121+ } else {
122+ target. to_string( )
123+ } )
124+ } )
125+ . collect:: <Vec <_>>( )
126+ . join( "\n " )
127+ ) ;
128+ panic ! ( "显式恐慌" ) ;
129+ }
95130 assert ! ( self . 0 < tags_table. len( ) ) ; // 越界检查
96131 assert_ne ! ( tags_table[ self . 0 ] , UNINIT_TAG_TARGET ) ; // 确保要跳转的目标有效
97132 format ! ( "jump {} {}" , tags_table[ self . 0 ] , self . 1 )
@@ -301,7 +336,6 @@ impl TagLine {
301336 }
302337 }
303338}
304-
305339impl From < TagBox < String > > for TagLine {
306340 fn from ( value : TagBox < String > ) -> Self {
307341 Self :: Line ( value)
@@ -581,7 +615,29 @@ impl TagCodes {
581615
582616 let mut logic_lines = Vec :: with_capacity ( self . lines . len ( ) ) ;
583617 for line in & self . lines {
584- logic_lines. push ( line. compile ( & tags_table) )
618+ match catch_unwind ( || line. compile ( & tags_table) ) {
619+ Ok ( line) => logic_lines. push ( line) ,
620+ Err ( _e) => {
621+ err ! (
622+ concat!(
623+ "构建行时出现了恐慌, 全部须构建的行:\n {}\n " ,
624+ "已经构建完毕的行:\n {}\n " ,
625+ "恐慌的行:\n \t {}\n " ,
626+ ) ,
627+ self . lines( )
628+ . iter( )
629+ . map( |x| format!( "\t {}" , x) )
630+ . collect:: <Vec <_>>( )
631+ . join( "\n " ) ,
632+ logic_lines. iter( )
633+ . map( |x| format!( "\t {}" , x) )
634+ . collect:: <Vec <_>>( )
635+ . join( "\n " ) ,
636+ line,
637+ ) ;
638+ exit ( 8 ) ;
639+ } ,
640+ } ;
585641 }
586642 Ok ( logic_lines)
587643 }
0 commit comments