66pub extern crate mech_core as core;
77pub extern crate mech_syntax as syntax;
88//pub extern crate mech_program as program;
9- pub extern crate mech_utilities as utilities;
9+ // pub extern crate mech_utilities as utilities;
1010
1111//mod repl;
1212
1313pub use mech_core:: * ;
14+ use mech_core:: nodes:: Program ;
1415//pub use mech_syntax::compiler::*;
1516//pub use mech_program::*;
16- pub use mech_utilities:: * ;
17+ // pub use mech_utilities::*;
1718//pub use self::repl::*;
1819
1920extern crate colored;
@@ -40,6 +41,164 @@ lazy_static! {
4041 static ref CORE_MAP : Mutex <HashMap <SocketAddr , ( String , SystemTime ) >> = Mutex :: new( HashMap :: new( ) ) ;
4142}
4243
44+ pub fn format_parse_tree ( program : & Program ) -> String {
45+ let json_string = serde_json:: to_string_pretty ( & program) . unwrap ( ) ;
46+
47+ let depth = |line : & str |->usize { line. chars ( ) . take_while ( |& c| c == ' ' ) . count ( ) } ;
48+ let mut result = String :: new ( ) ;
49+ let lines: Vec < & str > = json_string. lines ( ) . collect ( ) ;
50+ result. push_str ( "Program\n " ) ;
51+ for ( index, line) in lines. iter ( ) . enumerate ( ) {
52+ let trm = line. trim ( ) ;
53+ if trm == "}" ||
54+ trm == "}," ||
55+ trm == "{" ||
56+ trm == "[" ||
57+ trm == "]," ||
58+ trm == "]" {
59+ continue ;
60+ }
61+
62+ // Count leading spaces to determine depth
63+ let d = depth ( line) ;
64+ // Construct the tree-like prefix
65+ let mut prefix = String :: new ( ) ;
66+ for _ in 0 ..d {
67+ prefix. push_str ( " " ) ;
68+ }
69+ if index == lines. len ( ) {
70+ prefix. push_str ( "└ " ) ;
71+ } else {
72+ if depth ( lines[ index + 1 ] ) != d {
73+ prefix. push_str ( "└ " ) ;
74+ } else {
75+ prefix. push_str ( "├ " ) ;
76+ }
77+ }
78+ let trm = line. trim ( ) ;
79+ let trm = trm. trim_end_matches ( '{' )
80+ . trim_start_matches ( '"' )
81+ . trim_end_matches ( ':' )
82+ . trim_end_matches ( '"' )
83+ . trim_end_matches ( '[' ) ;
84+ prefix. push_str ( trm) ;
85+
86+ // Append formatted line to result
87+ result. push_str ( & prefix) ;
88+ result. push ( '\n' ) ;
89+ result = result. replace ( "\" :" , "" ) ;
90+ }
91+ let mut indexed_str = IndexedString :: new ( & result) ;
92+ ' rows: for i in 0 ..indexed_str. rows {
93+ let rowz = & indexed_str. index_map [ i] ;
94+ for j in 0 ..rowz. len ( ) {
95+ let c = match indexed_str. get ( i, j) {
96+ Some ( c) => c,
97+ None => continue ,
98+ } ;
99+ if c == '└' {
100+ for k in i+1 ..indexed_str. rows {
101+ match indexed_str. get ( k, j) {
102+ Some ( c2) => {
103+ if c2 == '└' {
104+ indexed_str. set ( i, j, '├' ) ;
105+ for l in i+1 ..k {
106+ match indexed_str. get ( l, j) {
107+ Some ( ' ' ) => { indexed_str. set ( l, j, '│' ) ; } ,
108+ Some ( '└' ) => { indexed_str. set ( l, j, '├' ) ; } ,
109+ _ => ( ) ,
110+ }
111+ }
112+ } else if c2 == ' ' {
113+ continue ;
114+ } else {
115+ continue ' rows;
116+ }
117+ } ,
118+ None => continue ,
119+ }
120+
121+ }
122+ } else if c == ' ' || c == '│' {
123+ continue ;
124+ } else {
125+ continue ' rows;
126+ }
127+ }
128+ }
129+ indexed_str. to_string ( )
130+ }
131+
132+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
133+ struct IndexedString {
134+ pub data : Vec < char > ,
135+ pub index_map : Vec < Vec < usize > > ,
136+ pub rows : usize ,
137+ pub cols : usize ,
138+ }
139+
140+ impl IndexedString {
141+ fn new ( input : & str ) -> Self {
142+ let mut data = Vec :: new ( ) ;
143+ let mut index_map = Vec :: new ( ) ;
144+ let mut current_row = 0 ;
145+ let mut current_col = 0 ;
146+ index_map. push ( Vec :: new ( ) ) ;
147+ for c in input. chars ( ) {
148+ data. push ( c) ;
149+ if c == '\n' {
150+ index_map. push ( Vec :: new ( ) ) ;
151+ current_row += 1 ;
152+ current_col = 0 ;
153+ } else {
154+ index_map[ current_row] . push ( data. len ( ) - 1 ) ;
155+ current_col += 1 ;
156+ }
157+ }
158+ let rows = index_map. len ( ) ;
159+ let cols = if rows > 0 { index_map[ 0 ] . len ( ) } else { 0 } ;
160+ IndexedString {
161+ data,
162+ index_map,
163+ rows,
164+ cols,
165+ }
166+ }
167+ fn to_string ( & self ) -> String {
168+ self . data . iter ( ) . collect ( )
169+ }
170+ fn get ( & self , row : usize , col : usize ) -> Option < char > {
171+ if row < self . rows {
172+ let rowz = & self . index_map [ row] ;
173+ if col < rowz. len ( ) {
174+ let index = self . index_map [ row] [ col] ;
175+ Some ( self . data [ index] )
176+ } else {
177+ None
178+ }
179+ } else {
180+ None
181+ }
182+ }
183+
184+ fn set ( & mut self , row : usize , col : usize , new_char : char ) -> Result < ( ) , String > {
185+ if row < self . rows {
186+ let row_indices = & mut self . index_map [ row] ;
187+ if col < row_indices. len ( ) {
188+ let index = row_indices[ col] ;
189+ self . data [ index] = new_char;
190+ Ok ( ( ) )
191+ } else {
192+ Err ( "Column index out of bounds" . to_string ( ) )
193+ }
194+ } else {
195+ Err ( "Row index out of bounds" . to_string ( ) )
196+ }
197+ }
198+
199+
200+ }
201+
43202//extern crate nom;
44203
45204/*
0 commit comments