1 module dlangui.core.textsource; 2 3 private import std.utf; 4 private import std.array; 5 6 /** 7 * Source file information. 8 * Even if contains only file name, it's better to use it instead of string - object reference size is twice less than array ref. 9 */ 10 class SourceFile { 11 protected string _filename; 12 @property string filename() { return _filename; } 13 public this(string filename) { 14 _filename = filename; 15 } 16 override @property string toString() const { 17 return _filename; 18 } 19 } 20 21 /// source lines for tokenizer 22 interface SourceLines { 23 /// source file 24 @property SourceFile file(); 25 /// last read line 26 @property uint line(); 27 /// source encoding 28 //@property EncodingType encoding() { return _encoding; } 29 /// error code 30 @property int errorCode(); 31 /// error message 32 @property string errorMessage(); 33 /// error line 34 @property int errorLine(); 35 /// error position 36 @property int errorPos(); 37 /// end of file reached 38 @property bool eof(); 39 40 /// read line, return null if EOF reached or error occured 41 dchar[] readLine(); 42 } 43 44 const TEXT_SOURCE_ERROR_EOF = 1; 45 46 /// Simple text source based on array 47 class ArraySourceLines : SourceLines { 48 protected SourceFile _file; 49 protected uint _line; 50 protected uint _firstLine; 51 protected dstring[] _lines; 52 static __gshared protected dchar[] _emptyLine = ""d.dup; 53 54 this() { 55 } 56 57 this(dstring[] lines, SourceFile file, uint firstLine = 0) { 58 initialize(lines, file, firstLine); 59 } 60 61 this(string code, string filename) { 62 _lines = (toUTF32(code)).split("\n"); 63 _file = new SourceFile(filename); 64 } 65 66 void close() { 67 _lines = null; 68 _line = 0; 69 _firstLine = 0; 70 _file = null; 71 } 72 73 void initialize(dstring[] lines, SourceFile file, uint firstLine = 0) { 74 _lines = lines; 75 _firstLine = firstLine; 76 _line = 0; 77 _file = file; 78 } 79 80 bool reset(int line) { 81 _line = line; 82 return true; 83 } 84 85 /// end of file reached 86 override @property bool eof() { 87 return _line >= _lines.length; 88 } 89 /// source file 90 override @property SourceFile file() { return _file; } 91 /// last read line 92 override @property uint line() { return _line + _firstLine; } 93 /// source encoding 94 //@property EncodingType encoding() { return _encoding; } 95 /// error code 96 override @property int errorCode() { return 0; } 97 /// error message 98 override @property string errorMessage() { return ""; } 99 /// error line 100 override @property int errorLine() { return 0; } 101 /// error position 102 override @property int errorPos() { return 0; } 103 104 /// read line, return null if EOF reached or error occured 105 override dchar[] readLine() { 106 if (_line < _lines.length) { 107 if (_lines[_line]) 108 return cast(dchar[])_lines[_line++]; 109 _line++; 110 return _emptyLine; 111 } 112 return null; // EOF 113 } 114 } 115