Mercurial > projects > dang
comparison src/basic/SourceLocation.d @ 206:d3c148ca429b
Major moving of files. all src now goes into src, all docs in docs.
author | Anders Johnsen <skabet@gmail.com> |
---|---|
date | Tue, 12 Aug 2008 18:14:56 +0200 |
parents | |
children | e0551773a005 |
comparison
equal
deleted
inserted
replaced
205:8387cbaa85ab | 206:d3c148ca429b |
---|---|
1 module basic.SourceLocation; | |
2 | |
3 /// Shorter alias for SourceLocation | |
4 public alias SourceLocation SLoc; | |
5 | |
6 /// SourceLocation points to a place in some buffer | |
7 struct SourceLocation | |
8 { | |
9 /// Returns true, if the location is from a real file | |
10 bool isReal() { return (val & 0x80_00_00_00) == 0; } | |
11 /// Returns true, if the location is not from a real file | |
12 bool isVirtual() { return (val & 0x80_00_00_00) != 0; } | |
13 | |
14 /// Check if this location is invalid or not | |
15 bool isValid() { return val != uint.max; } | |
16 /// ditto | |
17 bool isInvalid() { return val == uint.max; } | |
18 | |
19 /** | |
20 Extracts the file id. | |
21 | |
22 Warning: In release mode this may return junk, if the loc is not from a | |
23 file | |
24 **/ | |
25 uint fileID() { | |
26 assert(isValid, "Location is invalid"); | |
27 assert(isReal, "You can only extract fileID from a real location"); | |
28 // Here we can rely on two facts, first that the high bit is zero | |
29 // since its a real position, second that FileOffset is saved in the | |
30 // high end, so all we need is some shifting | |
31 return val >> Bits.FileOffset; | |
32 } | |
33 | |
34 /** | |
35 Extracts the offset into the "file". (actually in to the referenced | |
36 chunk) | |
37 | |
38 Warning: In release mode this may return junk, if the loc is not from a | |
39 file | |
40 **/ | |
41 uint fileOffset() { | |
42 assert(isValid, "Location is invalid"); | |
43 assert(isReal, "You can only extract fileOffset from real locations"); | |
44 // FileOffset is stored in the lower bits, so all that is needed is a | |
45 // binary and with all ones in the lower bits. | |
46 return val & (1 << Bits.FileOffset) - 1; | |
47 } | |
48 | |
49 /// Get a new location, placed n bytes after the given location | |
50 SourceLocation opAdd(int n) | |
51 { | |
52 SourceLocation res = *this; | |
53 res.val += n; | |
54 return res; | |
55 } | |
56 | |
57 /// Get a new location, placed n bytes before the given location | |
58 SourceLocation opSub(int n) | |
59 { | |
60 SourceLocation res = *this; | |
61 res.val -= n; | |
62 return res; | |
63 } | |
64 | |
65 /// Creates a SourceLocation from a File ID | |
66 static SourceLocation fromFileID(uint fileID) | |
67 { | |
68 assert(fileID < Bits.MaxFileID, "To large fileID"); | |
69 SourceLocation res; | |
70 res.val = fileID << Bits.FileOffset; | |
71 return res; | |
72 } | |
73 | |
74 /** | |
75 Used for invalid/unknown locations. (also the default value, but this is | |
76 more explicit) | |
77 **/ | |
78 static const SourceLocation Invalid = {val: uint.max}; | |
79 | |
80 private: | |
81 /** | |
82 A SourceLocation consists of 1 bit, indicating real or virtual, meaning | |
83 if the location points to a file(real), a string mixin or has been | |
84 affected by #line(virtual). That information is saved in the most | |
85 significant bit. | |
86 The rest depends on which type we are dealing with. | |
87 Real: | |
88 13 bits for a file identifier | |
89 18 bits for offset into that "file" (one file may be split) | |
90 Virtual: | |
91 Unknown for now. Likely skewed toward more ids and some meta data | |
92 An invalid location is uint.max, this might happen by accident but its | |
93 unlikely. | |
94 **/ | |
95 uint val = uint.max; | |
96 | |
97 /** | |
98 This enum contains some constants that are useful for manipulating | |
99 SourceLocation's, like the size of various “members” of val. | |
100 **/ | |
101 static enum Bits { | |
102 /// Number of bits used for the offset into file buffers | |
103 FileOffset = 18, | |
104 /// Number of bits used to identify which file buffer this is from | |
105 FileID = 31 - FileOffset, | |
106 | |
107 /// Indicates how much can be indexed within one block(2^FileOffset) | |
108 MaxFileOffset = 1 << FileOffset, | |
109 MaxFileID = 1 << FileID, | |
110 } | |
111 } | |
112 | |
113 /// A simple pair used to describe a range in a buffer and not just a point. | |
114 struct SourceRange | |
115 { | |
116 SourceLocation begin, end; | |
117 | |
118 static SourceRange opCall(SourceLocation loc) | |
119 { | |
120 return SourceRange(loc, loc + 1); | |
121 } | |
122 | |
123 static SourceRange opCall(SourceLocation begin, SourceLocation end) | |
124 { | |
125 SourceRange res; | |
126 res.begin = begin; | |
127 res.end = end; | |
128 return res; | |
129 } | |
130 | |
131 bool isValid() { return begin.isValid && end.isValid; } | |
132 bool isInvalid() { return begin.isInvalid || end.isInvalid; } | |
133 | |
134 bool isReal() { return begin.isReal && end.isReal; } | |
135 | |
136 /// Get a new range spanning both ranges | |
137 SourceRange opAdd(SourceRange that) | |
138 { | |
139 assert(this.isValid && that.isValid, "Invalid range"); | |
140 return SourceRange( | |
141 this.begin.val < that.begin.val? this.begin : that.begin, | |
142 this.end.val > that.end.val? this.end : that.end); | |
143 } | |
144 } | |
145 |