Skip to content

Commit 0f5465e

Browse files
committed
wordinfo更加细致地扫描文档
1 parent 917edd4 commit 0f5465e

File tree

2 files changed

+141
-156
lines changed

2 files changed

+141
-156
lines changed

src/language/wordinfo.ts

Lines changed: 141 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
5553
export 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)冲突
6366
class 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(/(endm|ENDM)/)
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(/(endm|ENDM)/)) {
130+
type1=linetype.endm
131+
name=r[1]
132+
}
133+
//match the simplified segment definition
134+
else if(r=str.match(/^\s*\.([a-zA-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+([dD][bBwWdDfFqQtT]|=|EQU|equ)\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+|)([dD][bBwWdDfFqQtT]|=|EQU|equ)\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+
128200
export 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
}

src/test/analyse.ts

Lines changed: 0 additions & 90 deletions
This file was deleted.

0 commit comments

Comments
 (0)