1 /// Copyright: Copyright (c) 2021 Andrey Penechko.
2 /// License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
3 /// Authors: Andrey Penechko.
4 
5 /// Source file, source location
6 module vox.fe.ast.source_file;
7 
8 import std.format : formattedWrite;
9 import vox.all;
10 
11 /// One struct per source file
12 /// File can be virtual or located in some File System
13 /// Stored in CompilationContext.files
14 struct SourceFileInfo
15 {
16 	/// File name. Must be always set.
17 	string name;
18 	/// If set, then used as a source. Otherwise is read from file `name`
19 	const(char)[] content;
20 	/// Start of file source code in CompilationContext.sourceBuffer
21 	uint start;
22 	/// Length of source code
23 	uint length;
24 	/// Tokens of all files are stored linearly inside CompilationContext.tokenBuffer
25 	/// and CompilationContext.tokenLocationBuffer. Token file can be found with binary search
26 	TokenIndex firstTokenIndex;
27 
28 	/// Module declaration
29 	ModuleDeclNode* mod;
30 }
31 
32 /// One per token
33 /// Stored in CompilationContext.tokenLocationBuffer
34 struct SourceLocation {
35 	/// Byte offset in the CompilationContext.sourceBuffer
36 	uint start;
37 	/// Byte offset in the CompilationContext.sourceBuffer (exclusive)
38 	uint end;
39 	/// Zero based line number
40 	uint line;
41 	/// Zero based column number
42 	uint col;
43 
44 	const(char)[] getTokenString(const(char)[] input) pure const {
45 		return input[start..end];
46 	}
47 	const(char)[] getTokenString(TokenType type, const(char)[] input) pure const {
48 		switch (type) {
49 			case TokenType.EOI:
50 				return "end of input";
51 			default:
52 				return input[start..end];
53 		}
54 	}
55 	void toString(scope void delegate(const(char)[]) sink) const {
56 		sink.formattedWrite("line %s col %s start %s end %s", line+1, col+1, start, end);
57 	}
58 }
59 
60 // Helper for pretty printing
61 struct FmtSrcLoc
62 {
63 	TokenIndex tok;
64 	CompilationContext* ctx;
65 
66 	void toString(scope void delegate(const(char)[]) sink) {
67 		if (tok.index == uint.max) return;
68 		auto loc = ctx.tokenLoc(tok);
69 		if (tok.index >= ctx.initializedTokenLocBufSize) {
70 			SourceFileInfo* fileInfo = ctx.getFileFromToken(tok);
71 			sink.formattedWrite("%s:%s:%s", fileInfo.name, loc.line+1, loc.col+1);
72 		}
73 	}
74 }