-
Notifications
You must be signed in to change notification settings - Fork 0
/
datatypes.ts
111 lines (94 loc) · 4.02 KB
/
datatypes.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/**
* Data class storing positions in a program consisting of line and column number.
* Contains some static helper methods for comparing Position objects.
*/
class Position {
constructor(public readonly line: string | number, public readonly column: string | number) {
this.line = Number(line);
this.column = Number(column);
}
public static posEq(pos1: Position, pos2: Position): boolean {
return pos1.line === pos2.line && pos1.column == pos2.column;
}
public static posIsSmallerEq(pos1: Position, pos2: Position): boolean {
return pos1.line < pos2.line || (pos1.line == pos2.line && pos1.column <= pos2.column);
}
public static toString(position: Position): string {
return `${position.line}:${position.column}`;
}
public static in_between(left: Position, inner: Position, right: Position): boolean {
return Position.posIsSmallerEq(left, inner) && Position.posIsSmallerEq(inner, right);
}
}
/**
* Data class storing locations in a program consisting of a start and an end Position.
* Contains some static helper methods for construction and comparison of SourceLocation objects.
*/
class SourceLocation {
constructor(public readonly start: Position, public readonly end: Position, public readonly p?: string) {}
static fromParts(
startLine: string | number,
startCol: string | number,
endLine: string | number,
endCol: string | number,
p?: string
): SourceLocation {
return new SourceLocation(new Position(startLine, startCol), new Position(endLine, endCol), p);
}
static fromJSON(d: { start: Position; end: Position }): SourceLocation {
return new SourceLocation(d.start, d.end);
}
public static within_line(location: SourceLocation, line: number): boolean {
return location.start.line == location.end.line && location.end.line == line;
}
public static boundingLocation(locations: SourceLocation[]): SourceLocation {
const start = locations.map((l) => l.start).reduce((a, b) => (Position.posIsSmallerEq(a, b) ? a : b));
const end = locations.map((l) => l.end).reduce((a, b) => (Position.posIsSmallerEq(a, b) ? b : a));
return new SourceLocation(start, end);
}
public static fromJalangiLocation(jalangiLocation: string): SourceLocation {
const r = /\((.+):(\d+):(\d+):(\d+):(\d+)\)/;
const m = jalangiLocation.match(r);
if (m && m.length == 6) {
return SourceLocation.fromParts(m[2], parseInt(m[3]) - 1, m[4], parseInt(m[5]) - 1, m[1]);
} else {
console.log("error in location conversion");
return SourceLocation.fromParts(-1, -1, -1, -1);
}
}
public static locEq(loc1: SourceLocation, loc2: SourceLocation): boolean {
return Position.posEq(loc1.start, loc2.start) && Position.posEq(loc1.end, loc2.end);
}
public static overlap(loc1: SourceLocation, loc2: SourceLocation): boolean {
return (
Position.in_between(loc1.start, loc2.start, loc1.end) ||
Position.in_between(loc2.start, loc1.start, loc2.end)
);
}
public static in_between_inclusive(outer: SourceLocation, inner: SourceLocation): boolean {
const includesStart = Position.posIsSmallerEq(outer.start, inner.start);
const includesEnd = Position.posIsSmallerEq(inner.end, outer.end);
return includesStart && includesEnd;
}
public toString(): string {
return `${Position.toString(this.start)};${Position.toString(this.end)}`;
}
}
/**
* Helper interface to mark objects which are tracked by id in dynamic analysis.
*/
interface Identifiable {
__id__: number;
}
/**
* If exists, remove last occurence of element from arr in place.
* @param arr an array potentially containing element
* @param element
*/
function removeLast<T>(arr: T[], element: T): void {
const i = arr.lastIndexOf(element);
if(i !== -1) {
arr.splice(i, 1);
}
}
export { Position, SourceLocation, Identifiable, removeLast };