Skip to content

Commit 02f9f92

Browse files
JD-HowardJoshSen-real
authored
Maintenance (#170)
* Temporary fix for erroneous vla-set prefix * Restructuring Co-authored-by: Josh <[email protected]> Co-authored-by: linse-adsk <[email protected]>
1 parent 2a36df6 commit 02f9f92

30 files changed

+489
-459
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { Position, Range } from 'vscode';
2+
import { LispContainer } from './lispContainer';
3+
4+
// This interface is intended to let us work in more generic ways without direct context of LispAtom|LispContainer
5+
export interface ILispFragment {
6+
symbol: string;
7+
line: number;
8+
column: number;
9+
flatIndex: number;
10+
commentLinks?: Array<number>;
11+
hasGlobalFlag?: boolean;
12+
13+
14+
readonly body?: LispContainer | undefined;
15+
16+
isLispFragment(): boolean;
17+
18+
equal(atom: ILispFragment): boolean;
19+
20+
symbLine(last?: boolean): number;
21+
22+
length(): number;
23+
24+
isLineComment(): boolean;
25+
26+
isComment(): boolean;
27+
28+
isRightParen(): boolean;
29+
30+
isLeftParen(): boolean;
31+
32+
isPrimitive(): boolean;
33+
34+
contains(pos: Position): boolean;
35+
36+
getRange(): Range;
37+
}

extension/src/astObjects/lispAtom.ts

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import { ILispFragment } from './ILispFragment';
2+
import { Position, Range } from 'vscode';
3+
import { Sexpression } from './sexpression';
4+
5+
6+
// General purpose test for basic known primitive values; Including: T, NIL, Number, (single or multi-line) Strings & Comments
7+
export const primitiveRegex = /^([\(\)\'\.]|"[\s\S]*"|;[\s\S]*|'?[tT]|'?[nN][iI][lL]|'?-?\d+[eE][+-]?\d+|-?\d+|-?\d+\.\d+)$/;
8+
const primitiveGlyphs = ['\'', '(', ')', '.', ';']; //, '']; //, null, undefined];
9+
10+
11+
// Represents the most fundamental building blocks of a lisp document
12+
export class LispAtom implements ILispFragment {
13+
public symbol: string;
14+
protected _line: number;
15+
protected _column: number;
16+
17+
get line(): number {
18+
return this._line;
19+
}
20+
21+
set line(value) {
22+
this._line = value;
23+
}
24+
25+
get column(): number {
26+
return this._column;
27+
}
28+
29+
set column(value) {
30+
this._column = value;
31+
}
32+
33+
// These 3 fields exist to support comment driven intelligence. Creation of Symbol mappings is an expensive operation
34+
// and these 2 fields prevent ~80% of the required overhead when working in concert with the highly efficient parser
35+
public flatIndex: number;
36+
public commentLinks?: Array<number>;
37+
public hasGlobalFlag?: boolean;
38+
39+
constructor(line: number, column: number, sym: string, flatIdx = -1) {
40+
this._line = line;
41+
this._column = column;
42+
this.symbol = sym;
43+
this.flatIndex = flatIdx;
44+
}
45+
46+
47+
// Does a simple comparison between 2 ILispFragments without the reference problem
48+
equal(atom: ILispFragment): boolean {
49+
return JSON.stringify(this) === JSON.stringify(atom);
50+
}
51+
52+
53+
// Determines if this LispAtom or its derived type can be used as an ILispFragment
54+
isLispFragment(): boolean {
55+
if (this instanceof Sexpression) {
56+
return false;
57+
} else {
58+
return true;
59+
}
60+
}
61+
62+
63+
// returns the start or ending line of the LispAtom depending on the boolean flag
64+
symbLine(last: boolean = true): number {
65+
if (last) {
66+
let internalLines = 0;
67+
if (this.symbol.startsWith(';|')) {
68+
for (let i = 0; i < this.symbol.length; i++) {
69+
if (this.symbol.charAt(i) === '\n') { // it can handle the \r\n and \n
70+
internalLines++;
71+
}
72+
}
73+
}
74+
return this.line + internalLines;
75+
} else {
76+
return this.line;
77+
}
78+
}
79+
80+
81+
// Returns the length of the LispAtom's text value
82+
length(): number {
83+
return this.symbol.length;
84+
}
85+
86+
87+
// Tests if the LispAtom is representing a single-line comment
88+
isLineComment(): boolean {
89+
return this.symbol.startsWith(';') && !this.symbol.startsWith(';|');
90+
}
91+
92+
93+
// Tests if the LispAtom is representing any type of comment
94+
isComment(): boolean {
95+
return this.symbol.startsWith(';');
96+
}
97+
98+
99+
// Tests if the LispAtom is representing a structural closing parenthesis
100+
isRightParen(): boolean {
101+
return this.symbol === ')';
102+
}
103+
104+
105+
// Tests if the LispAtom is representing a structural opening parenthesis
106+
isLeftParen(): boolean {
107+
return this.symbol === '(';
108+
}
109+
110+
isPrimitive(): boolean {
111+
// if (!this['atoms']) {
112+
// return primitiveRegex.test(this.symbol);
113+
// }
114+
// return false;
115+
return primitiveGlyphs.indexOf(this.symbol[0]) > -1
116+
|| primitiveRegex.test(this.symbol);
117+
}
118+
119+
// Returns true if this LispAtom encapsulates the provided Position
120+
contains(position: Position): boolean {
121+
return this.getRange().contains(position);
122+
}
123+
124+
125+
// Gets the full range of the LispAtom and is capable of handling multi line strings or comments
126+
getRange(): Range {
127+
let cLine = this.line;
128+
let cColm = this.column;
129+
const begin: Position = new Position(cLine, cColm);
130+
for (let i = 0; i < this.symbol.length; i++) {
131+
const ch = this.symbol[i];
132+
if (ch === '\n') {
133+
cLine += 1;
134+
cColm = 0;
135+
} else {
136+
cColm += 1;
137+
}
138+
}
139+
const close: Position = new Position(cLine, cColm);
140+
return new Range(begin.line, begin.character, close.line, close.character);
141+
}
142+
143+
}

0 commit comments

Comments
 (0)