Skip to content

Commit ac67ba2

Browse files
committed
匹配segment
1 parent 278a2bb commit ac67ba2

File tree

3 files changed

+180
-73
lines changed

3 files changed

+180
-73
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,18 @@ All notable changes to the "masm-tasm" extension will be documented in this file
1010
- [ ] LSP和DAP支持(目前对我来说太难了)
1111
- [ ] 根据具体的AH值显示跳转到不同的信息
1212

13+
### 0.1.5
14+
15+
汇编语言支持的symbol大概有以下几种,但是vscode的[SymbolKind](https://code.visualstudio.com/api/references/vscode-api#SymbolKind)却与它们不对应,我决定做以下对应
16+
17+
|assembly symbol|vscode symbol|
18+
|---|---|
19+
|macro 宏|class|
20+
|segment段|module|
21+
|variable变量|variable|
22+
|label 标号|key|
23+
|procedure子程序|function|
24+
1325
### 0.1.4
1426

1527
- 使用[Roncho](https://marketplace.visualstudio.com/publishers/Roncho)'s extension [Assembly (TASM)](https://marketplace.visualstudio.com/items?itemName=Roncho.assembly-8086)来实现对汇编语法的支持

src/language/provider.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,18 @@ class TasmDefProvider implements vscode.DefinitionProvider{
4343
return output;
4444
}
4545
}
46+
class Tasmsymbolprovider implements vscode.DocumentSymbolProvider{
47+
provideDocumentSymbols(document: vscode.TextDocument, token: vscode.CancellationToken){
48+
let docsymbol:vscode.DocumentSymbol[]=[]
49+
console.log(document,document.getText())
50+
docsymbol=info.sacnDoc(document)
51+
return docsymbol
52+
}
4653

54+
}
4755
export function provider(context: vscode.ExtensionContext) {
48-
info.scanDoc()
4956
if(vscode.workspace.getConfiguration('masmtasm.language').get('hover'))context.subscriptions.push(vscode.languages.registerHoverProvider('assembly',new TasmHoverProvider()));
5057
context.subscriptions.push(vscode.languages.registerDefinitionProvider("assembly",new TasmDefProvider()));
58+
context.subscriptions.push(vscode.languages.registerDocumentSymbolProvider("assembly",new Tasmsymbolprovider()))
5159
}
5260

src/language/wordinfo.ts

Lines changed: 159 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,39 @@
11
import * as vscode from 'vscode';
2-
import * as fstream from 'fs';
32
import * as nls from 'vscode-nls'
43
const localize = nls.loadMessageBundle()
5-
4+
const symbols:TasmSymbol[]=[]
5+
let _document:vscode.TextDocument
6+
let docsymbol:vscode.DocumentSymbol[]=[]
67
enum symboltype{
7-
macro,procedure,struct,label,asmvar
8+
other,
9+
macro,
10+
procedure,
11+
struct,
12+
label,
13+
asmvar,
14+
segment
15+
}
16+
function SymbolVSCfy(a:symboltype){
17+
let output=vscode.SymbolKind.Null
18+
switch(a){
19+
case symboltype.macro:output=vscode.SymbolKind.Module;break;
20+
case symboltype.segment:output=vscode.SymbolKind.Class;break;
21+
case symboltype.procedure:output=vscode.SymbolKind.Function;break;
22+
case symboltype.struct:output=vscode.SymbolKind.Struct;break;
23+
case symboltype.label:output=vscode.SymbolKind.Key;break;
24+
case symboltype.asmvar:output=vscode.SymbolKind.Variable;break;
25+
}
26+
return output
827
}
928
class TasmSymbol{
1029
type:number
1130
name:string
1231
location:vscode.Location|undefined
13-
constructor(type:number,name:string,RangeorPosition:vscode.Range|vscode.Position){
14-
let uri=vscode.window.activeTextEditor?.document.uri
32+
belong:string|undefined
33+
constructor(type:number,name:string,RangeorPosition:vscode.Range|vscode.Position,belong?:string){
1534
this.type=type
1635
this.name=name
17-
if(uri) this.location=new vscode.Location(uri,RangeorPosition)
36+
if(_document) this.location=new vscode.Location(_document.uri,RangeorPosition)
1837
}
1938
public markdown():vscode.MarkdownString{
2039
let md=new vscode.MarkdownString()
@@ -25,12 +44,13 @@ class TasmSymbol{
2544
case symboltype.procedure:typestr=localize("keykind.Procedure","procedure"); break;
2645
case symboltype.struct:typestr=localize("keykind.Structure","Structure"); break;
2746
case symboltype.macro:typestr=localize("keykind.Macro","macro"); break;
47+
case symboltype.macro:typestr=localize("keykind.Segment","segment"); break;
2848
}
2949
md.appendMarkdown('**'+typestr+"** "+this.name)
3050
return md
3151
}
3252
}
33-
enum linetype{other,macro,endm,segment,ends,proc,endp}
53+
enum linetype{other,macro,endm,segment,ends,struct,proc,endp}//暂时先不支持struct因为可能会与ends(segment)冲突
3454

3555
export function findSymbol (word:string):TasmSymbol|undefined{
3656
for(let sym of symbols){
@@ -40,76 +60,141 @@ export function findSymbol (word:string):TasmSymbol|undefined{
4060
}
4161
return
4262
}
43-
const symbols:TasmSymbol[]=[]
44-
function scanline(line:string){
45-
let str=line.toLowerCase()
46-
if (str.includes("macro")) return linetype.macro
47-
if (str.includes("endm")) return linetype.endm
48-
if (str.includes("segment")) return linetype.segment
49-
if (str.includes("ends")) return linetype.ends
50-
if (str.includes("proc")) return linetype.proc
51-
if (str.includes("endp")) return linetype.endp
63+
class Asmline{
64+
type:linetype
65+
name:string|undefined
66+
line:number
67+
index:number
68+
constructor(type:linetype,line:number,index:number,name?:string)
69+
{
70+
this.type=type
71+
this.line=line
72+
this.index=index
73+
this.name=name
74+
}
75+
public selectrange(){
76+
if(this.name) return new vscode.Range(this.line,this.index,this.line,this.index+this.name?.length)
77+
}
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(/(\w+)\s+(\w+)\s/)
83+
if(r) {
84+
let type1:linetype|undefined
85+
switch (r[2].toUpperCase()){
86+
case 'MACRO':type1=linetype.macro;break;
87+
case 'SEGMENT':type1=linetype.segment;break;
88+
case 'PROC':type1=linetype.proc;break;
89+
case 'ENDS':type1=linetype.ends;break;
90+
case 'ENDP':type1=linetype.endp;break
91+
}
92+
if(type1) asmline= new Asmline(type1,line,item.indexOf(r[1]),r[1])
93+
}
94+
r=item.match(/(endm|ENDM)/)
95+
if(r) asmline= new Asmline(linetype.endm,line,item.indexOf(r[1]))
96+
return asmline
5297
}
53-
async function sacnDoc(document:string[],alsoVars : boolean = true) : Promise<number> {
98+
function getvarlabel(item:string,index:number,belong?:string):vscode.DocumentSymbol|undefined{
99+
let r=item.match(/\s*(\w+)\s*:/)
100+
let vscsymbol:vscode.DocumentSymbol
101+
let name:string
102+
let range:vscode.Range
103+
let srange:vscode.Range
104+
if(r){
105+
name=r[1]
106+
let start=item.indexOf(name)
107+
let one:TasmSymbol=new TasmSymbol(symboltype.label,r[1],new vscode.Position(index,start),belong)
108+
symbols.push(one)
109+
range=new vscode.Range(index,0,start,item.length)
110+
srange=new vscode.Range(index,start,index,index+r[1].length)
111+
let kind=SymbolVSCfy(symboltype.label)
112+
vscsymbol= new vscode.DocumentSymbol(name,item,kind,range,srange)
113+
console.log(vscsymbol)
114+
}
115+
r=item.match (/\s*(\w+)\s*[dD][bBwWdDfFqQtT]/)
116+
if(r){
117+
name=r[1]
118+
let start=item.indexOf(r[1])
119+
let one:TasmSymbol=new TasmSymbol(symboltype.asmvar,r[1],new vscode.Position(index,start),belong)
120+
symbols.push(one)
121+
range=new vscode.Range(index,0,start,item.length)
122+
srange=new vscode.Range(index,start,index,index+r[1].length)
123+
return new vscode.DocumentSymbol(r[1],item,SymbolVSCfy(symboltype.label),range,srange)
124+
}
125+
return
126+
}
127+
export function sacnDoc(document:vscode.TextDocument) : vscode.DocumentSymbol[] {
128+
_document=document
129+
let doc=document.getText().split('\n')
54130
// scan the document for necessary information
55-
let labelreg=/^\s*(\w+)\s*:/
56-
document.forEach(
57-
(item,index,array)=>{
58-
let a=labelreg.exec(item)
59-
if(a){
60-
let name:string=a[1]
61-
let idx:number=item.indexOf(a[1])
62-
let one:TasmSymbol=new TasmSymbol(symboltype.label,name,new vscode.Position(index,idx))
63-
symbols.push(one)
131+
let docsymbol:vscode.DocumentSymbol[]=[]
132+
let asmline:Asmline[]=[]
133+
doc.forEach(
134+
(item,index)=>{
135+
let line=scanline(item,index)
136+
if(line!==null) asmline.push(line)
137+
}
138+
)
139+
let skip:boolean,i:number
140+
asmline.forEach(
141+
(line,index,array)=>{
142+
//是否为宏指令
143+
if(line.type===linetype.macro){
144+
let line_endm:Asmline|undefined
145+
//寻赵宏指令结束的位置
146+
for (i=index;i<asmline.length;i++){
147+
if(array[i].type===linetype.endm){
148+
line_endm=array[i]
149+
break
150+
}
151+
}
152+
//找到宏指令结束标志
153+
if(line.name && line_endm?.line){
154+
let macrorange=new vscode.Range(line.line,line.index,line_endm?.line,line_endm?.index)
155+
symbols.push(new TasmSymbol(symboltype.macro,line.name,macrorange))
156+
let varlabel:vscode.DocumentSymbol[]=[]
157+
let symbol1=new vscode.DocumentSymbol(line.name+": "+getType(KeywordType.Macro)," ",SymbolVSCfy(symboltype.macro),macrorange,new vscode.Range(line.line,line.index,line.line,line.index+line.name.length))
158+
symbol1.children=varlabel
159+
docsymbol.push(symbol1)
160+
}
64161
}
65-
let b=item.match (/\s*(\w+)\s*[db|DB|dw|DW|dd|DD|df|DF|dq|DQ|dt|DT]/)
66-
if(b){
67-
let name:string=b[1]
68-
let idx:number=item.indexOf(b[1])
69-
let one:TasmSymbol=new TasmSymbol(symboltype.asmvar,name,new vscode.Position(index,idx))
70-
symbols.push(one)
162+
if(line.type===linetype.segment){
163+
let line_ends:Asmline|undefined
164+
//寻赵段结束的位置
165+
for (i=index;i<asmline.length;i++){
166+
if(array[i].type===linetype.ends && array[i].name===line.name){
167+
line_ends=array[i]
168+
break
169+
}
170+
}
171+
//找到逻辑段结束标志
172+
if(line.name && line_ends?.line){
173+
let range=new vscode.Range(line.line,line.index,line_ends?.line,line_ends?.index)
174+
symbols.push(new TasmSymbol(symboltype.segment,line.name,range))
175+
let varlabel:vscode.DocumentSymbol[]=[]
176+
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))
177+
symbol1.children=varlabel
178+
docsymbol.push(symbol1)
179+
}
71180
}
72-
},
181+
}
73182
)
74-
return new Promise(resolve => {
75-
setTimeout(() => {
76-
resolve(2);
77-
},10);
78-
});
79-
}
80-
const autoScanDoc = async (change : vscode.TextDocumentChangeEvent) => {
81-
if(vscode.window.activeTextEditor === undefined){
82-
return;
83-
}
84-
let doc : string = await fstream.readFileSync(vscode.window.activeTextEditor.document.uri.fsPath,'utf8');
85-
let fin : string[] = doc.split('\n');
86-
sacnDoc(fin);
87-
};
88-
const autoScanDoc2 = async (change : vscode.TextDocument) => {
89-
let fin = doucmentToStringArray(change);
90-
sacnDoc(fin);
91-
};
92-
const autoScanDoc3 = async (change : vscode.TextEditor | undefined) => {
93-
if(change === undefined){
94-
return;
95-
}
96-
let fin = doucmentToStringArray(change.document);
97-
sacnDoc(fin);
98-
};
99-
function doucmentToStringArray(str:vscode.TextDocument) : string[] {
100-
let array : string[] = [];
101-
for (let i = 0; i < str.lineCount; i++) {
102-
const line = str.lineAt(i);
103-
array.push(line.text);
183+
docsymbol.forEach(
184+
(item)=>{
185+
// if(item.kind==SymbolVSCfy(symboltype.macro)){
186+
// let symbol3:vscode.DocumentSymbol|undefined
187+
// for (i=item.range.start.line;i<=item.range.end.line;i++){
188+
// symbol3=getvarlabel(doc[i],i)
189+
// if(symbol3)item.children.push(symbol3)
190+
// }
191+
// }
192+
item.children.push(new vscode.DocumentSymbol("fk","fake",1,new vscode.Range(1,1,1,1),new vscode.Range(1,1,1,1)))
193+
}
194+
)
195+
return docsymbol
104196
}
105-
return array;
106-
}
107-
export function scanDoc(){
108-
vscode.workspace.onDidChangeTextDocument(e => autoScanDoc(e));
109-
vscode.workspace.onDidOpenTextDocument(e => autoScanDoc2(e));
110-
vscode.workspace.onDidSaveTextDocument(e => autoScanDoc2(e));
111-
vscode.window.onDidChangeActiveTextEditor(e => autoScanDoc3(e));
112-
}
197+
113198
const possibleNumbers : string[] = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'];
114199

115200
export function isNumberStr(str:string) : boolean{
@@ -235,7 +320,7 @@ class KeywordDef {
235320
}
236321
}
237322
enum KeywordType {
238-
MacroLabel,File,Instruction, Register, PreCompileCommand,MemoryAllocation,SavedWord,Size,Variable,Method,Structure,Macro,Label
323+
MacroLabel,File,Instruction, Register, PreCompileCommand,MemoryAllocation,SavedWord,Size,Variable,Method,Structure,Macro,Label,Segment
239324
}
240325
const KEYWORD_DICONTARY : Array<KeywordDef>= [
241326
//Sizes
@@ -544,6 +629,8 @@ export function getType(type : KeywordType) : string {
544629
return localize("keykind.Structure","(Structure)");
545630
case KeywordType.Variable:
546631
return localize("keykind.Variable","(Variable)");
632+
case KeywordType.Segment:
633+
return localize("keykind.Segment","(Segment)");
547634
}
548635
return "(Unknown)";
549636
}

0 commit comments

Comments
 (0)