@@ -50,8 +50,6 @@ class TasmSymbol{
5050 return md
5151 }
5252}
53- enum linetype { other , macro , endm , segment , ends , struct , proc , endp } //暂时先不支持struct因为可能会与ends(segment)冲突
54-
5553export function findSymbol ( word :string ) :TasmSymbol | undefined {
5654 for ( let sym of symbols ) {
5755 if ( sym . name === word ) {
@@ -60,84 +58,157 @@ export function findSymbol (word:string):TasmSymbol|undefined{
6058 }
6159 return
6260}
61+ enum linetype {
62+ other , macro , endm , segment , ends , struct , proc , endp , label , variable ,
63+ end , onlycomment , labelB , variableB
64+ }
65+ //暂时先不支持struct因为可能会与ends(segment)冲突
6366class Asmline {
64- type :linetype
65- name :string | undefined
67+ type :linetype = linetype . other
6668 line :number
67- index :number
68- constructor ( type :linetype , line :number , index :number , name ?:string )
69+ str :string
70+ name :string | undefined
71+ index :number = 1
72+ comment :string | undefined
73+ commentIndex :number | undefined
74+ operator :string | undefined
75+ operand :string | undefined
76+ constructor ( str :string , line :number )
6977 {
70- this . type = type
7178 this . line = line
72- this . index = index
73- this . name = name
79+ this . str = str
80+ let main = this . getcomment ( str . split ( "" ) ) //split mainbody and comment
81+ if ( main === null ) {
82+ if ( this . comment ) this . type = linetype . onlycomment
83+ }
84+ else {
85+ if ( this . getsymbol1 ( main ) === false ) //get symbols of macros,segments,procedures
86+ { this . getvarlabel ( main ) } //get symbols of labels,variables
87+ }
7488 }
75- public selectrange ( ) {
76- if ( this . name ) return new vscode . Range ( this . line , this . index , this . line , this . index + this . name ?. length )
89+ private getcomment ( arr :string [ ] ) :string | null {
90+ let i :number , quoted :boolean = false , index :number | undefined
91+ let main :string | null = null
92+ for ( i = 0 ; i < arr . length ; i ++ ) {
93+ if ( arr [ i ] === "'" ) {
94+ if ( quoted ) quoted = false
95+ else quoted = true
96+ }
97+ if ( arr [ i ] == ";" && quoted === false ) {
98+ index = i
99+ break }
100+ }
101+ if ( index ) {
102+ this . comment = arr . slice ( index ) . join ( "" )
103+ this . commentIndex = index
104+ }
105+ main = arr . slice ( 0 , index ) . join ( "" ) . trim ( )
106+ if ( main . length === 0 ) main = null
107+ return main
77108 }
78- }
79- function scanline ( item : string , line : number ) : Asmline | null {
80- let r : RegExpMatchArray | null = null
81- let asmline : Asmline | null = null
82- r = item . match ( / ^ \s * ( \w + ) \s + ( \w + ) \s * / )
109+ private getsymbol1 ( str : string ) : boolean {
110+ let r : RegExpMatchArray | null = null , name : string | undefined
111+ let flag : boolean = false
112+ r = str . match ( / ^ \s * ( \w + ) \s + ( \w + ) \s * / )
113+ let type1 : linetype | undefined
83114 if ( r ) {
84- let type1 :linetype | undefined
85115 switch ( r [ 2 ] . toUpperCase ( ) ) {
86116 case 'MACRO' :type1 = linetype . macro ; break ;
87117 case 'SEGMENT' :type1 = linetype . segment ; break ;
88118 case 'PROC' :type1 = linetype . proc ; break ;
89119 case 'ENDS' :type1 = linetype . ends ; break ;
90120 case 'ENDP' :type1 = linetype . endp ; break
91121 }
92- if ( type1 ) asmline = new Asmline ( type1 , line , item . indexOf ( r [ 1 ] ) , r [ 1 ] )
122+ if ( type1 ) name = r [ 1 ]
123+ if ( r [ 1 ] . toLowerCase ( ) === 'end' ) {
124+ type1 = linetype . end
125+ name = r [ 2 ]
126+ }
93127 }
94- r = item . match ( / ( e n d m | E N D M ) / )
95- if ( r ) asmline = new Asmline ( linetype . endm , line , item . indexOf ( r [ 1 ] ) )
96- return asmline
97- }
98- function getvarlabel ( item :string , index :number , belong ?:string ) :vscode . DocumentSymbol | undefined {
99- let vscsymbol :vscode . DocumentSymbol | undefined
100- let name :string
101- let kind :vscode . SymbolKind
102- let range :vscode . Range
103- let srange :vscode . Range
104- let r = item . match ( / ^ \s * ( \w + ) \s * : ( [ ^ ; : ] * ) / )
105- if ( r ) {
106- name = r [ 1 ]
107- let start = item . indexOf ( name )
108- let one :TasmSymbol = new TasmSymbol ( symboltype . label , r [ 1 ] , new vscode . Position ( index , start ) , belong )
109- symbols . push ( one )
110- range = new vscode . Range ( index , 0 , index , item . length )
111- srange = new vscode . Range ( index , start , index , start + name . length )
112- kind = SymbolVSCfy ( symboltype . label )
113- vscsymbol = new vscode . DocumentSymbol ( name , r [ 2 ] , kind , range , srange )
128+ //match the end of macro
129+ else if ( r = str . match ( / ( e n d m | E N D M ) / ) ) {
130+ type1 = linetype . endm
131+ name = r [ 1 ]
132+ }
133+ //match the simplified segment definition
134+ else if ( r = str . match ( / ^ \s * \. ( [ a - z A - Z _ @ ? $ ] \w + ) \s * $ / ) ) {
135+ type1 = linetype . segment
136+ name = r [ 1 ]
137+ }
138+ if ( type1 && name ) {
139+ this . type = type1
140+ this . index = str . indexOf ( name )
141+ this . name = name
142+ flag = true
143+ }
144+ return flag
114145 }
115- r = item . match ( / ^ \s * ( \w + ) \s + ( [ d D ] [ b B w W d D f F q Q t T ] | = | E Q U | e q u ) \s + / )
116- if ( r ) {
117- name = r [ 1 ]
118- let start = item . indexOf ( r [ 1 ] )
119- let one :TasmSymbol = new TasmSymbol ( symboltype . variable , r [ 1 ] , new vscode . Position ( index , start ) , belong )
120- symbols . push ( one )
121- kind = SymbolVSCfy ( symboltype . variable )
122- range = new vscode . Range ( index , 0 , index , item . length )
123- srange = new vscode . Range ( index , start , index , start + r [ 1 ] . length )
124- vscsymbol = new vscode . DocumentSymbol ( name , item , kind , range , srange )
146+ private getvarlabel ( item :string ) {
147+ let r = item . match ( / ^ \s * ( \w + \s * : | ) \s * ( \w + ) \s + ( .* ) $ / )
148+ let name :string | undefined
149+ if ( r ) {
150+ name = r [ 1 ]
151+ if ( name . length === 0 ) this . type = linetype . labelB
152+ else {
153+ this . name = name . slice ( 0 , name . length - 1 ) . trim ( )
154+ this . type = linetype . label
155+ }
156+ let start = item . indexOf ( r [ 1 ] )
157+ let one :TasmSymbol = new TasmSymbol ( symboltype . label , r [ 1 ] , new vscode . Position ( this . line , start ) )
158+ symbols . push ( one )
159+ }
160+ r = item . match ( / ^ \s * ( \w + \s + | ) ( [ d D ] [ b B w W d D f F q Q t T ] | = | E Q U | e q u ) \s + ( .* ) $ / )
161+ if ( r ) {
162+ name = r [ 1 ] . trim ( )
163+ if ( name . length === 0 ) this . type = linetype . variableB
164+ else {
165+ this . type = linetype . variable
166+ this . name = name
167+ }
168+ this . operator = r [ 2 ]
169+ this . operand = r [ 3 ]
170+ let start = item . indexOf ( r [ 1 ] )
171+ let one :TasmSymbol = new TasmSymbol ( symboltype . variable , r [ 1 ] , new vscode . Position ( this . line , start ) )
172+ symbols . push ( one )
173+ }
174+ }
175+ public varlabelsymbol ( ) :vscode . DocumentSymbol | undefined {
176+ let vscsymbol :vscode . DocumentSymbol | undefined
177+ let name = this . name
178+ if ( name && ( this . type === linetype . variable || this . type === linetype . label ) ) {
179+ let kind :vscode . SymbolKind , range :vscode . Range , srange :vscode . Range
180+ range = new vscode . Range ( this . line , 0 , this . line , this . str . length )
181+ let start = this . str . indexOf ( name )
182+ srange = new vscode . Range ( this . line , start , this . line , start + name . length )
183+ if ( this . type === linetype . label ) {
184+ kind = SymbolVSCfy ( symboltype . label )
185+ vscsymbol = new vscode . DocumentSymbol ( name , " " , kind , range , srange )
186+ }
187+ else if ( this . type === linetype . variable ) {
188+ kind = SymbolVSCfy ( symboltype . variable )
189+ vscsymbol = new vscode . DocumentSymbol ( name , " " , kind , range , srange )
190+ }
191+ }
192+
193+ return vscsymbol
194+ }
195+ public selectrange ( ) {
196+ if ( this . name && this . index ) return new vscode . Range ( this . line , this . index , this . line , this . index + this . name ?. length )
125197 }
126- return vscsymbol
127198}
199+
128200export function sacnDoc ( document :vscode . TextDocument ) : vscode . DocumentSymbol [ ] {
129201 _document = document ; symbols = [ ] ; let doc = document . getText ( ) . split ( "\n" )
130- console . log ( doc , document . getText ( ) )
131202 // scan the document for necessary information
132203 let docsymbol :vscode . DocumentSymbol [ ] = [ ]
133204 let asmline :Asmline [ ] = [ ]
134205 doc . forEach (
135206 ( item , index ) => {
136- let line = scanline ( item , index )
137- if ( line !== null ) asmline . push ( line )
207+ asmline . push ( new Asmline ( item , index ) )
138208 }
139209 )
140- let skip :boolean , i :number
210+ console . log ( asmline )
211+ let i :number
141212 asmline . forEach (
142213 ( line , index , array ) => {
143214 //是否为宏指令
@@ -159,17 +230,17 @@ export function sacnDoc(document:vscode.TextDocument) : vscode.DocumentSymbol[]
159230 }
160231 }
161232 else if ( line . type === linetype . segment ) {
162- let line_ends :Asmline | undefined
163- let proc :Asmline | undefined //正在寻找的子程序信息
233+ let line_ends :Asmline | undefined //the line information of the endline of the segment
234+ let proc :Asmline | undefined //the procedure finding
164235 let procschild :vscode . DocumentSymbol [ ] = [ ]
165- //寻找段结束的位置,并收集子程序的信息
236+ //finding the end of segment line.name and collecting information of procedure
166237 for ( i = index ; i < asmline . length ; i ++ ) {
167- //寻找子程序
238+ //find proc
168239 if ( array [ i ] . type === linetype . proc ) {
169240 proc = array [ i ]
170241 }
171- //找到子程序结束标志
172- if ( array [ i ] . type === linetype . endp && proc ?. name === array [ i ] . name ) {
242+ //finding the end of proc
243+ if ( array [ i ] . type === linetype . endp && proc ?. name === array [ i ] . name ) {
173244 let _name = array [ i ] . name
174245 if ( proc ?. name && _name ) {
175246 let range :vscode . Range = new vscode . Range ( proc ?. line , proc ?. index , array [ i ] . line , array [ i ] . index + _name . length )
@@ -178,17 +249,22 @@ export function sacnDoc(document:vscode.TextDocument) : vscode.DocumentSymbol[]
178249 symbols . push ( new TasmSymbol ( symboltype . procedure , _name , range ) )
179250 }
180251 }
181- //寻找段结束语句
252+ //finding the end of segment
182253 if ( array [ i ] . type === linetype . ends && array [ i ] . name === line . name ) {
183254 line_ends = array [ i ]
184255 break
185256 }
257+ //if finding another start of segment, also view as end of the finding segment
258+ if ( array [ i + 1 ] . type === linetype . segment || array [ i + 1 ] . type === linetype . end ) {
259+ line_ends = array [ i ]
260+ break
261+ }
186262 }
187- //找到逻辑段结束标志
263+ //finded the end of segment
188264 if ( line . name && line_ends ?. line ) {
189265 let range = new vscode . Range ( line . line , line . index , line_ends ?. line , line_ends ?. index )
190266 symbols . push ( new TasmSymbol ( symboltype . segment , line . name , range ) )
191- let symbol1 = new vscode . DocumentSymbol ( line . name + ": " + getType ( KeywordType . Segment ) , " " , SymbolVSCfy ( symboltype . segment ) , range , new vscode . Range ( line . line , line . index , line . line , line . index + line . name . length ) )
267+ let symbol1 = new vscode . DocumentSymbol ( line . name + ": " + getType ( KeywordType . Segment ) , " " , SymbolVSCfy ( symboltype . segment ) , range , new vscode . Range ( line . line , line . line , line . line , line . line + line . name . length ) )
192268 symbol1 . children = procschild
193269 docsymbol . push ( symbol1 )
194270 }
@@ -202,7 +278,7 @@ export function sacnDoc(document:vscode.TextDocument) : vscode.DocumentSymbol[]
202278 if ( item . kind == SymbolVSCfy ( symboltype . macro ) ) {
203279 let symbol3 :vscode . DocumentSymbol | undefined
204280 for ( i = item . range . start . line ; i <= item . range . end . line ; i ++ ) {
205- symbol3 = getvarlabel ( doc [ i ] , i )
281+ symbol3 = asmline [ i ] . varlabelsymbol ( )
206282 if ( symbol3 ) item . children . push ( symbol3 )
207283 }
208284 }
@@ -212,14 +288,13 @@ export function sacnDoc(document:vscode.TextDocument) : vscode.DocumentSymbol[]
212288 item . children . forEach (
213289 ( item2 , index , array ) => {
214290 for ( i = item2 . range . start . line ; i <= item2 . range . end . line ; i ++ ) {
215- let symbol3 = getvarlabel ( doc [ i ] , i )
216- doc [ i ] = " "
291+ let symbol3 = asmline [ i ] . varlabelsymbol ( )
217292 if ( symbol3 ) item2 . children . push ( symbol3 )
218293 }
219294 } ,
220295 )
221296 for ( i = item . range . start . line + 1 ; i < item . range . end . line ; i ++ ) {
222- symbol2 = getvarlabel ( doc [ i ] , i )
297+ symbol2 = asmline [ i ] . varlabelsymbol ( )
223298 if ( symbol2 ) item . children . push ( symbol2 )
224299 }
225300 }
0 commit comments