0000: 2f 2a 2a 0a 20 2a 20 41 75 74 68 6f 72 73 3a 20 /**. * Authors:
0010: 6b 2e 69 6e 61 62 61 0a 20 2a 20 4c 69 63 65 6e k.inaba. * Licen
0020: 73 65 3a 20 4e 59 53 4c 20 30 2e 39 39 38 32 20 se: NYSL 0.9982
0030: 68 74 74 70 3a 2f 2f 77 77 77 2e 6b 6d 6f 6e 6f http://www.kmono
0040: 73 2e 6e 65 74 2f 6e 79 73 6c 2f 0a 20 2a 0a 20 s.net/nysl/. *.
0050: 2a 20 4c 65 78 65 72 20 66 6f 72 20 50 6f 6c 65 * Lexer for Pole
0060: 6d 79 20 70 72 6f 67 72 61 6d 6d 69 6e 67 20 6c my programming l
0070: 61 6e 67 75 61 67 65 2e 0a 20 2a 2f 0a 6d 6f 64 anguage.. */.mod
0080: 75 6c 65 20 70 6f 6c 65 6d 79 2e 6c 65 78 3b 0a ule polemy.lex;.
0090: 69 6d 70 6f 72 74 20 70 6f 6c 65 6d 79 2e 5f 63 import polemy._c
00a0: 6f 6d 6d 6f 6e 3b 0a 69 6d 70 6f 72 74 20 73 74 ommon;.import st
00b0: 64 2e 66 69 6c 65 20 20 3a 20 72 65 61 64 54 65 d.file : readTe
00c0: 78 74 3b 0a 69 6d 70 6f 72 74 20 73 74 64 2e 63 xt;.import std.c
00d0: 74 79 70 65 20 3a 20 69 73 73 70 61 63 65 2c 20 type : isspace,
00e0: 69 73 61 6c 6e 75 6d 3b 0d 0a 0d 0a 2f 2f 2f 20 isalnum;....///
00f0: 45 78 63 65 70 74 69 6f 6e 20 66 72 6f 6d 20 74 Exception from t
0100: 68 69 73 20 6d 6f 64 75 6c 65 0d 0a 0d 0a 63 6c his module....cl
0110: 61 73 73 20 4c 65 78 45 78 63 65 70 74 69 6f 6e ass LexException
0120: 20 3a 20 45 78 63 65 70 74 69 6f 6e 0d 0a 7b 0d : Exception..{.
0130: 0a 09 74 68 69 73 28 20 63 6f 6e 73 74 20 4c 65 ..this( const Le
0140: 78 50 6f 73 69 74 69 6f 6e 20 70 6f 73 2c 20 73 xPosition pos, s
0150: 74 72 69 6e 67 20 6d 73 67 20 29 0d 0a 09 09 7b tring msg )....{
0160: 20 73 75 70 65 72 28 73 70 72 69 6e 74 66 21 22 super(sprintf!"
0170: 25 73 20 5b 25 73 5d 22 28 6d 73 67 2c 20 70 6f %s [%s]"(msg, po
0180: 73 29 29 3b 20 74 68 69 73 2e 70 6f 73 20 3d 20 s)); this.pos =
0190: 70 6f 73 3b 20 7d 0d 0a 09 63 6f 6e 73 74 20 4c pos; }...const L
01a0: 65 78 50 6f 73 69 74 69 6f 6e 20 70 6f 73 3b 0d exPosition pos;.
01b0: 0a 7d 3b 0a 0a 2f 2f 2f 20 52 65 70 72 65 73 65 .};../// Represe
01c0: 6e 74 73 20 61 20 70 6f 73 69 74 69 6f 6e 20 69 nts a position i
01d0: 6e 20 61 20 73 6f 75 72 63 65 20 63 6f 64 65 0a n a source code.
01e0: 0a 63 6c 61 73 73 20 4c 65 78 50 6f 73 69 74 69 .class LexPositi
01f0: 6f 6e 0a 7b 0a 09 69 6d 6d 75 74 61 62 6c 65 20 on.{..immutable
0200: 73 74 72 69 6e 67 20 66 69 6c 65 6e 61 6d 65 3b string filename;
0210: 20 2f 2f 2f 20 6e 61 6d 65 20 6f 66 20 74 68 65 /// name of the
0220: 20 73 6f 75 72 63 65 20 66 69 6c 65 0a 09 69 6d source file..im
0230: 6d 75 74 61 62 6c 65 20 69 6e 74 20 20 20 20 6c mutable int l
0240: 69 6e 65 6e 6f 3b 20 20 20 2f 2f 2f 20 6c 69 6e ineno; /// lin
0250: 65 20 6e 75 6d 62 65 72 2c 20 31 2c 20 32 2c 20 e number, 1, 2,
0260: 2e 2e 2e 0a 09 69 6d 6d 75 74 61 62 6c 65 20 69 .....immutable i
0270: 6e 74 20 20 20 20 63 6f 6c 75 6d 6e 3b 20 20 20 nt column;
0280: 2f 2f 2f 20 63 6f 6c 75 6d 6e 2c 20 31 2c 20 32 /// column, 1, 2
0290: 2c 20 2e 2e 2e 0a 0a 09 6f 76 65 72 72 69 64 65 , ......override
02a0: 20 73 74 72 69 6e 67 20 74 6f 53 74 72 69 6e 67 string toString
02b0: 28 29 20 63 6f 6e 73 74 0a 09 09 7b 20 72 65 74 () const...{ ret
02c0: 75 72 6e 20 73 70 72 69 6e 74 66 21 22 25 73 3a urn sprintf!"%s:
02d0: 25 64 3a 25 64 22 28 66 69 6c 65 6e 61 6d 65 2c %d:%d"(filename,
02e0: 20 6c 69 6e 65 6e 6f 2c 20 63 6f 6c 75 6d 6e 29 lineno, column)
02f0: 3b 20 7d 0a 0a 09 6d 69 78 69 6e 20 53 69 6d 70 ; }...mixin Simp
0300: 6c 65 43 6f 6e 73 74 72 75 63 74 6f 72 3b 0a 09 leConstructor;..
0310: 6d 69 78 69 6e 20 53 69 6d 70 6c 65 43 6f 6d 70 mixin SimpleComp
0320: 61 72 65 3b 0d 0a 0d 0a 09 73 74 61 74 69 63 20 are;.....static
0330: 69 6d 6d 75 74 61 62 6c 65 20 4c 65 78 50 6f 73 immutable LexPos
0340: 69 74 69 6f 6e 20 64 75 6d 6d 79 3b 0d 0a 09 73 ition dummy;...s
0350: 74 61 74 69 63 20 74 68 69 73 28 29 7b 20 64 75 tatic this(){ du
0360: 6d 6d 79 20 3d 20 6e 65 77 20 69 6d 6d 75 74 61 mmy = new immuta
0370: 62 6c 65 28 4c 65 78 50 6f 73 69 74 69 6f 6e 29 ble(LexPosition)
0380: 28 22 3c 75 6e 6e 61 6d 65 64 3e 22 2c 30 2c 30 ("<unnamed>",0,0
0390: 29 3b 20 7d 0d 0a 7d 0a 0a 75 6e 69 74 74 65 73 ); }..}..unittes
03a0: 74 0a 7b 0a 09 61 75 74 6f 20 70 20 3d 20 6e 65 t.{..auto p = ne
03b0: 77 20 4c 65 78 50 6f 73 69 74 69 6f 6e 28 22 68 w LexPosition("h
03c0: 65 6c 6c 6f 2e 63 70 70 22 2c 20 31 32 33 2c 20 ello.cpp", 123,
03d0: 34 35 29 3b 0a 09 61 75 74 6f 20 71 20 3d 20 6e 45);..auto q = n
03e0: 65 77 20 4c 65 78 50 6f 73 69 74 69 6f 6e 28 22 ew LexPosition("
03f0: 68 65 6c 6c 6f 2e 63 70 70 22 2c 20 31 32 33 2c hello.cpp", 123,
0400: 20 34 36 29 3b 0a 0a 09 61 73 73 65 72 74 5f 65 46);...assert_e
0410: 71 28 20 70 2e 66 69 6c 65 6e 61 6d 65 2c 20 22 q( p.filename, "
0420: 68 65 6c 6c 6f 2e 63 70 70 22 20 29 3b 0a 09 61 hello.cpp" );..a
0430: 73 73 65 72 74 5f 65 71 28 20 70 2e 6c 69 6e 65 ssert_eq( p.line
0440: 6e 6f 2c 20 31 32 33 20 29 3b 0a 09 61 73 73 65 no, 123 );..asse
0450: 72 74 5f 65 71 28 20 70 2e 63 6f 6c 75 6d 6e 2c rt_eq( p.column,
0460: 20 34 35 20 29 3b 0a 09 61 73 73 65 72 74 5f 65 45 );..assert_e
0470: 71 28 20 74 6f 21 73 74 72 69 6e 67 28 70 29 2c q( to!string(p),
0480: 20 22 68 65 6c 6c 6f 2e 63 70 70 3a 31 32 33 3a "hello.cpp:123:
0490: 34 35 22 20 29 3b 0a 09 61 73 73 65 72 74 5f 6c 45" );..assert_l
04a0: 74 28 20 70 2c 20 71 20 29 3b 0a 09 61 73 73 65 t( p, q );..asse
04b0: 72 74 5f 6e 65 28 20 70 2c 20 71 20 29 3b 0a 0a rt_ne( p, q );..
04c0: 09 61 73 73 65 72 74 28 20 21 5f 5f 74 72 61 69 .assert( !__trai
04d0: 74 73 28 63 6f 6d 70 69 6c 65 73 2c 20 6e 65 77 ts(compiles, new
04e0: 20 4c 65 78 50 6f 73 69 74 69 6f 6e 29 20 29 3b LexPosition) );
04f0: 0a 09 61 73 73 65 72 74 28 20 21 5f 5f 74 72 61 ..assert( !__tra
0500: 69 74 73 28 63 6f 6d 70 69 6c 65 73 2c 20 70 2e its(compiles, p.
0510: 66 69 6c 65 6e 61 6d 65 3d 22 66 6f 6f 22 29 20 filename="foo")
0520: 29 3b 0a 09 61 73 73 65 72 74 28 20 21 5f 5f 74 );..assert( !__t
0530: 72 61 69 74 73 28 63 6f 6d 70 69 6c 65 73 2c 20 raits(compiles,
0540: 70 2e 6c 69 6e 65 6e 6f 20 20 3d 37 38 39 29 20 p.lineno =789)
0550: 29 3b 0a 09 61 73 73 65 72 74 28 20 21 5f 5f 74 );..assert( !__t
0560: 72 61 69 74 73 28 63 6f 6d 70 69 6c 65 73 2c 20 raits(compiles,
0570: 70 2e 63 6f 6c 75 6d 6e 20 20 3d 32 32 32 29 20 p.column =222)
0580: 29 3b 0a 7d 0a 0a 2f 2f 2f 20 52 65 70 72 65 73 );.}../// Repres
0590: 65 6e 74 73 20 61 20 6c 65 78 65 72 20 74 6f 6b ents a lexer tok
05a0: 65 6e 0a 0a 63 6c 61 73 73 20 54 6f 6b 65 6e 0a en..class Token.
05b0: 7b 0a 09 69 6d 6d 75 74 61 62 6c 65 20 4c 65 78 {..immutable Lex
05c0: 50 6f 73 69 74 69 6f 6e 20 70 6f 73 3b 20 20 20 Position pos;
05d0: 20 2f 2f 2f 20 50 6f 73 69 74 69 6f 6e 20 77 68 /// Position wh
05e0: 65 72 65 20 74 68 65 20 74 6f 6b 65 6e 20 6f 63 ere the token oc
05f0: 63 75 72 72 65 64 20 69 6e 20 74 68 65 20 73 6f curred in the so
0600: 75 72 63 65 0a 09 69 6d 6d 75 74 61 62 6c 65 20 urce..immutable
0610: 73 74 72 69 6e 67 20 20 20 20 20 20 73 74 72 3b string str;
0620: 20 20 20 20 2f 2f 2f 20 54 68 65 20 74 6f 6b 65 /// The toke
0630: 6e 20 73 74 72 69 6e 67 20 69 74 73 65 6c 66 0a n string itself.
0640: 09 69 6d 6d 75 74 61 62 6c 65 20 62 6f 6f 6c 20 .immutable bool
0650: 20 20 20 20 20 20 20 71 75 6f 74 65 64 3b 20 2f quoted; /
0660: 2f 2f 20 57 61 73 20 69 74 20 61 20 22 71 75 6f // Was it a "quo
0670: 74 65 64 22 20 74 6f 6b 65 6e 20 6f 72 20 75 6e ted" token or un
0680: 71 75 6f 74 65 64 3f 0a 0a 09 6d 69 78 69 6e 20 quoted?...mixin
0690: 53 69 6d 70 6c 65 43 6f 6e 73 74 72 75 63 74 6f SimpleConstructo
06a0: 72 3b 0a 09 6d 69 78 69 6e 20 53 69 6d 70 6c 65 r;..mixin Simple
06b0: 43 6f 6d 70 61 72 65 3b 0a 09 6d 69 78 69 6e 20 Compare;..mixin
06c0: 53 69 6d 70 6c 65 54 6f 53 74 72 69 6e 67 3b 0d SimpleToString;.
06d0: 0a 7d 0a 0a 75 6e 69 74 74 65 73 74 0a 7b 0a 09 .}..unittest.{..
06e0: 61 75 74 6f 20 70 20 3d 20 6e 65 77 20 69 6d 6d auto p = new imm
06f0: 75 74 61 62 6c 65 28 4c 65 78 50 6f 73 69 74 69 utable(LexPositi
0700: 6f 6e 29 28 22 68 65 6c 6c 6f 2e 63 70 70 22 2c on)("hello.cpp",
0710: 20 31 32 33 2c 20 34 35 29 3b 0a 09 61 75 74 6f 123, 45);..auto
0720: 20 74 20 3d 20 6e 65 77 20 54 6f 6b 65 6e 28 70 t = new Token(p
0730: 2c 20 22 63 6c 61 73 73 22 2c 20 66 61 6c 73 65 , "class", false
0740: 29 3b 0a 09 61 75 74 6f 20 75 20 3d 20 6e 65 77 );..auto u = new
0750: 20 54 6f 6b 65 6e 28 70 2c 20 22 63 6c 61 73 73 Token(p, "class
0760: 22 2c 20 74 72 75 65 29 3b 0a 0a 09 61 73 73 65 ", true);...asse
0770: 72 74 5f 65 71 28 20 74 2e 70 6f 73 2c 20 70 20 rt_eq( t.pos, p
0780: 29 3b 0a 09 61 73 73 65 72 74 5f 65 71 28 20 74 );..assert_eq( t
0790: 2e 73 74 72 2c 20 22 63 6c 61 73 73 22 20 29 3b .str, "class" );
07a0: 0a 09 61 73 73 65 72 74 28 20 21 74 2e 71 75 6f ..assert( !t.quo
07b0: 74 65 64 20 29 3b 0a 09 61 73 73 65 72 74 5f 65 ted );..assert_e
07c0: 71 28 20 74 2c 20 6e 65 77 20 54 6f 6b 65 6e 28 q( t, new Token(
07d0: 70 2c 20 22 63 6c 61 73 73 22 2c 20 66 61 6c 73 p, "class", fals
07e0: 65 29 20 29 3b 0a 09 61 73 73 65 72 74 5f 6c 74 e) );..assert_lt
07f0: 28 20 74 2c 20 6e 65 77 20 54 6f 6b 65 6e 28 70 ( t, new Token(p
0800: 2c 20 22 73 74 72 75 63 74 22 2c 20 66 61 6c 73 , "struct", fals
0810: 65 29 20 29 3b 0a 09 61 73 73 65 72 74 5f 6e 65 e) );..assert_ne
0820: 28 20 74 2c 20 75 20 29 3b 0a 09 61 73 73 65 72 ( t, u );..asser
0830: 74 28 20 75 2e 71 75 6f 74 65 64 20 29 3b 0a 0a t( u.quoted );..
0840: 09 61 73 73 65 72 74 28 20 21 5f 5f 74 72 61 69 .assert( !__trai
0850: 74 73 28 63 6f 6d 70 69 6c 65 73 2c 20 6e 65 77 ts(compiles, new
0860: 20 54 6f 6b 65 6e 29 20 29 3b 0a 09 61 73 73 65 Token) );..asse
0870: 72 74 28 20 21 5f 5f 74 72 61 69 74 73 28 63 6f rt( !__traits(co
0880: 6d 70 69 6c 65 73 2c 20 74 2e 70 6f 73 3d 70 29 mpiles, t.pos=p)
0890: 20 29 3b 0a 09 61 73 73 65 72 74 28 20 21 5f 5f );..assert( !__
08a0: 74 72 61 69 74 73 28 63 6f 6d 70 69 6c 65 73 2c traits(compiles,
08b0: 20 74 2e 73 74 72 3d 37 38 39 29 20 29 3b 0a 09 t.str=789) );..
08c0: 61 73 73 65 72 74 28 20 21 5f 5f 74 72 61 69 74 assert( !__trait
08d0: 73 28 63 6f 6d 70 69 6c 65 73 2c 20 74 2e 71 75 s(compiles, t.qu
08e0: 6f 74 65 64 3d 74 72 75 65 29 20 29 3b 0a 7d 0a oted=true) );.}.
08f0: 0a 2f 2f 2f 20 4e 61 6d 65 64 20 43 6f 6e 73 74 ./// Named Const
0900: 72 75 74 6f 72 20 66 6f 72 20 4c 65 78 65 72 0a rutor for Lexer.
0910: 0a 61 75 74 6f 20 6c 65 78 65 72 46 72 6f 6d 46 .auto lexerFromF
0920: 69 6c 65 28 54 2e 2e 2e 29 28 20 73 74 72 69 6e ile(T...)( strin
0930: 67 20 66 69 6c 65 6e 61 6d 65 2c 20 54 20 72 65 g filename, T re
0940: 73 74 20 29 0a 7b 0a 09 72 65 74 75 72 6e 20 6c st ).{..return l
0950: 65 78 65 72 46 72 6f 6d 53 74 72 69 6e 67 28 20 exerFromString(
0960: 73 74 64 2e 66 69 6c 65 2e 72 65 61 64 54 65 78 std.file.readTex
0970: 74 28 66 69 6c 65 6e 61 6d 65 29 2c 20 66 69 6c t(filename), fil
0980: 65 6e 61 6d 65 2c 20 72 65 73 74 20 29 3b 0a 7d ename, rest );.}
0990: 0a 09 0a 2f 2f 2f 20 4e 61 6d 65 64 20 43 6f 6e .../// Named Con
09a0: 73 74 72 75 74 6f 72 20 66 6f 72 20 4c 65 78 65 strutor for Lexe
09b0: 72 0a 0a 61 75 74 6f 20 6c 65 78 65 72 46 72 6f r..auto lexerFro
09c0: 6d 53 74 72 69 6e 67 28 43 68 61 72 53 65 71 29 mString(CharSeq)
09d0: 28 20 43 68 61 72 53 65 71 20 73 74 72 2c 20 73 ( CharSeq str, s
09e0: 74 72 69 6e 67 20 66 69 6c 65 6e 61 6d 65 3d 22 tring filename="
09f0: 3c 75 6e 6e 61 6d 65 64 3e 22 2c 20 69 6e 74 20 <unnamed>", int
0a00: 6c 69 6e 65 6e 6f 3d 31 2c 20 69 6e 74 20 63 6f lineno=1, int co
0a10: 6c 75 6d 6e 3d 31 20 29 0a 7b 0a 20 09 72 65 74 lumn=1 ).{. .ret
0a20: 75 72 6e 20 6e 65 77 20 4c 65 78 65 72 54 21 28 urn new LexerT!(
0a30: 50 6f 73 69 74 69 6f 6e 65 64 52 65 61 64 65 72 PositionedReader
0a40: 21 43 68 61 72 53 65 71 29 28 0d 0a 09 09 50 6f !CharSeq)(....Po
0a50: 73 69 74 69 6f 6e 65 64 52 65 61 64 65 72 21 43 sitionedReader!C
0a60: 68 61 72 53 65 71 28 73 74 72 2c 20 66 69 6c 65 harSeq(str, file
0a70: 6e 61 6d 65 2c 20 6c 69 6e 65 6e 6f 2c 20 63 6f name, lineno, co
0a80: 6c 75 6d 6e 29 0d 0a 09 29 3b 0a 7d 0a 0a 2f 2f lumn)...);.}..//
0a90: 2f 20 53 74 61 6e 64 61 72 64 20 4c 65 78 65 72 / Standard Lexer
0aa0: 20 54 79 70 65 20 28 61 6c 6c 20 75 73 65 72 73 Type (all users
0ab0: 20 68 61 76 65 20 74 6f 20 6b 6e 6f 77 20 69 73 have to know is
0ac0: 20 74 68 61 74 20 74 68 69 73 20 69 73 20 61 20 that this is a
0ad0: 66 6f 72 77 61 72 64 20 72 61 6e 67 65 20 6f 66 forward range of
0ae0: 20 54 6f 6b 65 6e 73 29 0d 0a 0d 0a 61 6c 69 61 Tokens)....alia
0af0: 73 20 4c 65 78 65 72 54 21 28 50 6f 73 69 74 69 s LexerT!(Positi
0b00: 6f 6e 65 64 52 65 61 64 65 72 21 73 74 72 69 6e onedReader!strin
0b10: 67 29 20 4c 65 78 65 72 3b 0a 0a 2f 2f 2f 20 4c g) Lexer;../// L
0b20: 65 78 65 72 20 49 6d 70 6c 65 6d 65 6e 74 61 74 exer Implementat
0b30: 69 6f 6e 0d 0a 0d 0a 63 6c 61 73 73 20 4c 65 78 ion....class Lex
0b40: 65 72 54 28 52 65 61 64 65 72 29 0d 0a 09 69 66 erT(Reader)...if
0b50: 28 20 69 73 46 6f 72 77 61 72 64 52 61 6e 67 65 ( isForwardRange
0b60: 21 28 52 65 61 64 65 72 29 20 26 26 20 69 73 28 !(Reader) && is(
0b70: 45 6c 65 6d 65 6e 74 54 79 70 65 21 28 52 65 61 ElementType!(Rea
0b80: 64 65 72 29 20 3d 3d 20 64 63 68 61 72 29 20 29 der) == dchar) )
0b90: 0a 7b 0a 09 2f 2f 2f 20 52 61 6e 67 65 20 70 72 .{../// Range pr
0ba0: 69 6d 69 74 69 76 65 0a 09 62 6f 6f 6c 20 65 6d imitive..bool em
0bb0: 70 74 79 28 29 20 2f 2a 40 70 72 6f 70 65 72 74 pty() /*@propert
0bc0: 79 2a 2f 0a 09 7b 0a 09 09 72 65 74 75 72 6e 20 y*/..{...return
0bd0: 63 75 72 72 65 6e 74 20 69 73 20 6e 75 6c 6c 3b current is null;
0be0: 0a 09 7d 0a 0a 09 2f 2f 2f 20 52 61 6e 67 65 20 ..}.../// Range
0bf0: 70 72 69 6d 69 74 69 76 65 0a 09 54 6f 6b 65 6e primitive..Token
0c00: 20 66 72 6f 6e 74 28 29 20 2f 2a 40 70 72 6f 70 front() /*@prop
0c10: 65 72 74 79 2a 2f 0a 09 7b 0a 09 09 72 65 74 75 erty*/..{...retu
0c20: 72 6e 20 73 74 64 2e 65 78 63 65 70 74 69 6f 6e rn std.exception
0c30: 2e 65 6e 66 6f 72 63 65 28 63 75 72 72 65 6e 74 .enforce(current
0c40: 2c 20 22 4c 65 78 65 72 20 68 61 73 20 61 6c 72 , "Lexer has alr
0c50: 65 61 64 79 20 72 65 61 63 68 65 64 20 74 68 65 eady reached the
0c60: 20 65 6e 64 22 29 3b 0a 09 7d 0a 0a 09 2f 2f 2f end");..}...///
0c70: 20 52 61 6e 67 65 20 70 72 69 6d 69 74 69 76 65 Range primitive
0c80: 0a 09 76 6f 69 64 20 70 6f 70 46 72 6f 6e 74 28 ..void popFront(
0c90: 29 20 2f 2a 40 70 72 6f 70 65 72 74 79 2a 2f 0a ) /*@property*/.
0ca0: 09 7b 0a 09 09 73 74 64 2e 65 78 63 65 70 74 69 .{...std.excepti
0cb0: 6f 6e 2e 65 6e 66 6f 72 63 65 28 63 75 72 72 65 on.enforce(curre
0cc0: 6e 74 2c 20 22 4c 65 78 65 72 20 68 61 73 20 61 nt, "Lexer has a
0cd0: 6c 72 65 61 64 79 20 72 65 61 63 68 65 64 20 74 lready reached t
0ce0: 68 65 20 65 6e 64 22 29 3b 0a 09 09 63 75 72 72 he end");...curr
0cf0: 65 6e 74 20 3d 20 72 65 61 64 4e 65 78 74 28 29 ent = readNext()
0d00: 3b 0a 09 7d 0a 0a 09 2f 2f 2f 20 52 61 6e 67 65 ;..}.../// Range
0d10: 20 70 72 69 6d 69 74 69 76 65 0a 09 74 79 70 65 primitive..type
0d20: 6f 66 28 74 68 69 73 29 20 73 61 76 65 28 29 20 of(this) save()
0d30: 2f 2a 40 70 72 6f 70 65 72 74 79 2a 2f 0a 09 7b /*@property*/..{
0d40: 0a 09 09 72 65 74 75 72 6e 20 6e 65 77 20 74 79 ...return new ty
0d50: 70 65 6f 66 28 74 68 69 73 29 28 72 65 61 64 65 peof(this)(reade
0d60: 72 2e 73 61 76 65 2c 20 63 75 72 72 65 6e 74 29 r.save, current)
0d70: 3b 0a 09 7d 0a 0a 70 72 69 76 61 74 65 3a 20 2f ;..}..private: /
0d80: 2f 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e / implementation
0d90: 0a 0a 09 52 65 61 64 65 72 20 72 65 61 64 65 72 ...Reader reader
0da0: 3b 0a 09 54 6f 6b 65 6e 20 20 63 75 72 72 65 6e ;..Token curren
0db0: 74 3b 0a 0a 09 69 6e 76 61 72 69 61 6e 74 28 29 t;...invariant()
0dc0: 0a 09 7b 0a 09 09 61 73 73 65 72 74 28 20 72 65 ..{...assert( re
0dd0: 61 64 65 72 2e 65 6d 70 74 79 20 7c 7c 20 21 73 ader.empty || !s
0de0: 74 64 2e 63 74 79 70 65 2e 69 73 73 70 61 63 65 td.ctype.isspace
0df0: 28 72 65 61 64 65 72 2e 66 72 6f 6e 74 29 20 29 (reader.front) )
0e00: 3b 0a 09 7d 0d 0a 0d 0a 09 74 68 69 73 28 20 52 ;..}.....this( R
0e10: 65 61 64 65 72 20 72 65 61 64 65 72 2c 20 54 6f eader reader, To
0e20: 6b 65 6e 20 63 75 72 72 65 6e 74 20 3d 20 6e 75 ken current = nu
0e30: 6c 6c 20 29 0d 0a 09 7b 0d 0a 09 09 74 68 69 73 ll )...{....this
0e40: 2e 72 65 61 64 65 72 20 3d 20 72 65 61 64 65 72 .reader = reader
0e50: 3b 0d 0a 09 09 72 65 61 64 57 68 69 6c 65 21 69 ;....readWhile!i
0e60: 73 53 70 61 63 65 28 29 3b 0d 0a 09 09 74 68 69 sSpace();....thi
0e70: 73 2e 63 75 72 72 65 6e 74 20 3d 20 28 63 75 72 s.current = (cur
0e80: 72 65 6e 74 20 69 73 20 6e 75 6c 6c 20 3f 20 72 rent is null ? r
0e90: 65 61 64 4e 65 78 74 28 29 20 3a 20 63 75 72 72 eadNext() : curr
0ea0: 65 6e 74 29 3b 0d 0a 09 7d 0d 0a 0d 0a 09 70 75 ent);...}.....pu
0eb0: 62 6c 69 63 20 73 74 61 74 69 63 20 7b 0a 09 09 blic static {...
0ec0: 62 6f 6f 6c 20 69 73 53 70 61 63 65 20 20 20 28 bool isSpace (
0ed0: 64 63 68 61 72 20 63 29 20 7b 20 72 65 74 75 72 dchar c) { retur
0ee0: 6e 20 73 74 64 2e 63 74 79 70 65 2e 69 73 73 70 n std.ctype.issp
0ef0: 61 63 65 28 63 29 21 3d 30 3b 20 7d 0a 09 09 62 ace(c)!=0; }...b
0f00: 6f 6f 6c 20 69 73 53 79 6d 62 6f 6c 20 20 28 64 ool isSymbol (d
0f10: 63 68 61 72 20 63 29 20 7b 20 72 65 74 75 72 6e char c) { return
0f20: 20 30 78 32 31 3c 3d 63 20 26 26 20 63 3c 3d 30 0x21<=c && c<=0
0f30: 78 37 66 20 26 26 20 21 73 74 64 2e 63 74 79 70 x7f && !std.ctyp
0f40: 65 2e 69 73 61 6c 6e 75 6d 28 63 29 20 26 26 20 e.isalnum(c) &&
0f50: 63 21 3d 27 5f 27 20 26 26 20 63 21 3d 27 5c 27 c!='_' && c!='\'
0f60: 27 3b 20 7d 0d 0a 09 09 62 6f 6f 6c 20 69 73 53 '; }....bool isS
0f70: 53 79 6d 62 6f 6c 20 28 64 63 68 61 72 20 63 29 Symbol (dchar c)
0f80: 20 7b 20 72 65 74 75 72 6e 20 21 66 69 6e 64 28 { return !find(
0f90: 22 28 29 5b 5d 7b 7d 3b 22 2c 20 63 29 2e 65 6d "()[]{};", c).em
0fa0: 70 74 79 3b 20 7d 0d 0a 09 09 62 6f 6f 6c 20 69 pty; }....bool i
0fb0: 73 4d 53 79 6d 62 6f 6c 20 28 64 63 68 61 72 20 sMSymbol (dchar
0fc0: 63 29 20 7b 20 72 65 74 75 72 6e 20 69 73 53 79 c) { return isSy
0fd0: 6d 62 6f 6c 28 63 29 20 26 26 20 21 69 73 53 53 mbol(c) && !isSS
0fe0: 79 6d 62 6f 6c 28 63 29 3b 20 7d 0d 0a 09 09 62 ymbol(c); }....b
0ff0: 6f 6f 6c 20 69 73 4c 65 74 74 65 72 20 20 28 64 ool isLetter (d
1000: 63 68 61 72 20 63 29 20 7b 20 72 65 74 75 72 6e char c) { return
1010: 20 21 69 73 53 70 61 63 65 28 63 29 20 26 26 20 !isSpace(c) &&
1020: 21 69 73 53 79 6d 62 6f 6c 28 63 29 3b 20 7d 0d !isSymbol(c); }.
1030: 0a 09 7d 0d 0a 0d 0a 09 73 74 72 69 6e 67 20 72 ..}.....string r
1040: 65 61 64 51 75 6f 74 65 64 28 63 6f 6e 73 74 20 eadQuoted(const
1050: 4c 65 78 50 6f 73 69 74 69 6f 6e 20 70 6f 73 29 LexPosition pos)
1060: 7b 63 68 61 72 5b 5d 20 62 75 66 3b 20 72 65 74 {char[] buf; ret
1070: 75 72 6e 20 72 65 61 64 51 75 6f 74 65 64 28 70 urn readQuoted(p
1080: 6f 73 2c 62 75 66 29 3b 7d 0d 0a 09 73 74 72 69 os,buf);}...stri
1090: 6e 67 20 72 65 61 64 51 75 6f 74 65 64 28 63 6f ng readQuoted(co
10a0: 6e 73 74 20 4c 65 78 50 6f 73 69 74 69 6f 6e 20 nst LexPosition
10b0: 70 6f 73 2c 20 72 65 66 20 63 68 61 72 5b 5d 20 pos, ref char[]
10c0: 62 75 66 29 0d 0a 09 7b 0d 0a 09 09 69 66 28 20 buf)...{....if(
10d0: 72 65 61 64 65 72 2e 65 6d 70 74 79 20 29 0d 0a reader.empty )..
10e0: 09 09 09 74 68 72 6f 77 20 6e 65 77 20 4c 65 78 ...throw new Lex
10f0: 45 78 63 65 70 74 69 6f 6e 28 70 6f 73 2c 20 22 Exception(pos, "
1100: 45 4f 46 20 66 6f 75 6e 64 20 77 68 69 6c 65 20 EOF found while
1110: 6c 65 78 69 6e 67 20 61 20 71 75 6f 74 65 64 2d lexing a quoted-
1120: 73 74 72 69 6e 67 22 29 3b 0d 0a 09 09 64 63 68 string");....dch
1130: 61 72 20 63 20 3d 20 72 65 61 64 65 72 2e 66 72 ar c = reader.fr
1140: 6f 6e 74 3b 0d 0a 09 09 72 65 61 64 65 72 2e 70 ont;....reader.p
1150: 6f 70 46 72 6f 6e 74 3b 0d 0a 09 09 69 66 28 20 opFront;....if(
1160: 63 20 3d 3d 20 27 22 27 20 29 0d 0a 09 09 09 72 c == '"' ).....r
1170: 65 74 75 72 6e 20 61 73 73 75 6d 65 55 6e 69 71 eturn assumeUniq
1180: 75 65 28 62 75 66 29 3b 0d 0a 09 09 69 66 28 20 ue(buf);....if(
1190: 63 20 3d 3d 20 27 5c 5c 27 20 26 26 20 21 72 65 c == '\\' && !re
11a0: 61 64 65 72 2e 65 6d 70 74 79 20 29 20 7b 0d 0a ader.empty ) {..
11b0: 09 09 09 69 66 28 20 72 65 61 64 65 72 2e 66 72 ...if( reader.fr
11c0: 6f 6e 74 3d 3d 27 22 27 20 29 20 7b 0d 0a 09 09 ont=='"' ) {....
11d0: 09 09 72 65 61 64 65 72 2e 70 6f 70 46 72 6f 6e ..reader.popFron
11e0: 74 3b 0d 0a 09 09 09 09 72 65 74 75 72 6e 20 72 t;......return r
11f0: 65 61 64 51 75 6f 74 65 64 28 70 6f 73 2c 62 75 eadQuoted(pos,bu
1200: 66 20 7e 3d 20 27 5c 22 27 29 3b 0d 0a 09 09 09 f ~= '\"');.....
1210: 7d 0d 0a 09 09 09 69 66 28 20 72 65 61 64 65 72 }.....if( reader
1220: 2e 66 72 6f 6e 74 3d 3d 27 5c 5c 27 20 29 20 7b .front=='\\' ) {
1230: 0d 0a 09 09 09 09 72 65 61 64 65 72 2e 70 6f 70 ......reader.pop
1240: 46 72 6f 6e 74 3b 0d 0a 09 09 09 09 72 65 74 75 Front;......retu
1250: 72 6e 20 72 65 61 64 51 75 6f 74 65 64 28 70 6f rn readQuoted(po
1260: 73 2c 62 75 66 20 7e 3d 20 27 5c 5c 27 29 3b 0d s,buf ~= '\\');.
1270: 0a 09 09 09 7d 0d 0a 09 09 7d 0d 0a 09 09 72 65 ....}....}....re
1280: 74 75 72 6e 20 72 65 61 64 51 75 6f 74 65 64 28 turn readQuoted(
1290: 70 6f 73 2c 62 75 66 20 7e 3d 20 63 29 3b 0d 0a pos,buf ~= c);..
12a0: 09 7d 0d 0a 0d 0a 09 73 74 72 69 6e 67 20 72 65 .}.....string re
12b0: 61 64 57 68 69 6c 65 28 61 6c 69 61 73 20 66 6e adWhile(alias fn
12c0: 29 28 29 0d 0a 09 7b 0d 0a 09 09 63 68 61 72 5b )()...{....char[
12d0: 5d 20 62 75 66 3b 0d 0a 09 09 66 6f 72 28 3b 20 ] buf;....for(;
12e0: 21 72 65 61 64 65 72 2e 65 6d 70 74 79 20 26 26 !reader.empty &&
12f0: 20 66 6e 28 72 65 61 64 65 72 2e 66 72 6f 6e 74 fn(reader.front
1300: 29 3b 20 72 65 61 64 65 72 2e 70 6f 70 46 72 6f ); reader.popFro
1310: 6e 74 29 0d 0a 09 09 09 62 75 66 20 7e 3d 20 72 nt).....buf ~= r
1320: 65 61 64 65 72 2e 66 72 6f 6e 74 3b 0d 0a 09 09 eader.front;....
1330: 72 65 74 75 72 6e 20 61 73 73 75 6d 65 55 6e 69 return assumeUni
1340: 71 75 65 28 62 75 66 29 3b 0d 0a 09 7d 0a 0a 09 que(buf);...}...
1350: 54 6f 6b 65 6e 20 72 65 61 64 4e 65 78 74 28 29 Token readNext()
1360: 0a 09 7b 0a 09 09 69 66 28 20 72 65 61 64 65 72 ..{...if( reader
1370: 2e 65 6d 70 74 79 20 29 0a 09 09 09 72 65 74 75 .empty )....retu
1380: 72 6e 20 6e 75 6c 6c 3b 0d 0a 09 09 73 63 6f 70 rn null;....scop
1390: 65 28 73 75 63 63 65 73 73 29 0d 0a 09 09 09 72 e(success).....r
13a0: 65 61 64 57 68 69 6c 65 21 69 73 53 70 61 63 65 eadWhile!isSpace
13b0: 28 29 3b 0d 0a 09 09 69 66 28 20 72 65 61 64 65 ();....if( reade
13c0: 72 2e 66 72 6f 6e 74 20 3d 3d 20 27 23 27 20 29 r.front == '#' )
13d0: 20 2f 2f 20 63 6f 6d 6d 65 6e 74 0d 0a 09 09 7b // comment....{
13e0: 0d 0a 09 09 09 72 65 61 64 65 72 20 3d 20 66 69 .....reader = fi
13f0: 6e 64 28 72 65 61 64 65 72 2c 20 27 5c 6e 27 29 nd(reader, '\n')
1400: 3b 0d 0a 09 09 09 72 65 61 64 57 68 69 6c 65 21 ;.....readWhile!
1410: 69 73 53 70 61 63 65 28 29 3b 0d 0a 09 09 09 72 isSpace();.....r
1420: 65 74 75 72 6e 20 72 65 61 64 4e 65 78 74 28 29 eturn readNext()
1430: 3b 0d 0a 09 09 7d 0a 09 09 65 6c 73 65 20 69 66 ;....}...else if
1440: 28 20 72 65 61 64 65 72 2e 66 72 6f 6e 74 20 3d ( reader.front =
1450: 3d 20 27 22 27 20 29 20 2f 2f 20 71 75 6f 74 65 = '"' ) // quote
1460: 64 0d 0a 09 09 7b 0d 0a 09 09 09 61 75 74 6f 20 d....{.....auto
1470: 70 6f 73 20 3d 20 72 65 61 64 65 72 2e 63 75 72 pos = reader.cur
1480: 72 65 6e 74 50 6f 73 69 74 69 6f 6e 28 29 3b 0d rentPosition();.
1490: 0a 09 09 09 72 65 61 64 65 72 2e 70 6f 70 46 72 ....reader.popFr
14a0: 6f 6e 74 3b 0d 0a 09 09 09 72 65 74 75 72 6e 20 ont;.....return
14b0: 6e 65 77 20 54 6f 6b 65 6e 28 70 6f 73 2c 20 72 new Token(pos, r
14c0: 65 61 64 51 75 6f 74 65 64 28 70 6f 73 29 2c 20 eadQuoted(pos),
14d0: 74 72 75 65 29 3b 0d 0a 09 09 7d 0d 0a 09 09 65 true);....}....e
14e0: 6c 73 65 20 69 66 28 20 69 73 53 53 79 6d 62 6f lse if( isSSymbo
14f0: 6c 28 72 65 61 64 65 72 2e 66 72 6f 6e 74 29 20 l(reader.front)
1500: 29 20 2f 2f 20 70 61 72 65 6e 0d 0a 09 09 7b 0d ) // paren....{.
1510: 0a 09 09 09 61 75 74 6f 20 70 6f 73 20 3d 20 72 ....auto pos = r
1520: 65 61 64 65 72 2e 63 75 72 72 65 6e 74 50 6f 73 eader.currentPos
1530: 69 74 69 6f 6e 28 29 3b 0d 0a 09 09 09 73 74 72 ition();.....str
1540: 69 6e 67 20 73 3b 20 73 7e 3d 72 65 61 64 65 72 ing s; s~=reader
1550: 2e 66 72 6f 6e 74 3b 20 72 65 61 64 65 72 2e 70 .front; reader.p
1560: 6f 70 46 72 6f 6e 74 3b 0d 0a 09 09 09 72 65 74 opFront;.....ret
1570: 75 72 6e 20 6e 65 77 20 54 6f 6b 65 6e 28 70 6f urn new Token(po
1580: 73 2c 20 73 2c 20 66 61 6c 73 65 29 3b 0d 0a 09 s, s, false);...
1590: 09 7d 0d 0a 09 09 65 6c 73 65 20 69 66 28 20 69 .}....else if( i
15a0: 73 4d 53 79 6d 62 6f 6c 28 72 65 61 64 65 72 2e sMSymbol(reader.
15b0: 66 72 6f 6e 74 29 20 29 20 2f 2f 20 73 79 6d 62 front) ) // symb
15c0: 6f 6c 0d 0a 09 09 7b 0a 09 09 09 61 75 74 6f 20 ol....{....auto
15d0: 70 6f 73 20 3d 20 72 65 61 64 65 72 2e 63 75 72 pos = reader.cur
15e0: 72 65 6e 74 50 6f 73 69 74 69 6f 6e 28 29 3b 0a rentPosition();.
15f0: 09 09 09 72 65 74 75 72 6e 20 6e 65 77 20 54 6f ...return new To
1600: 6b 65 6e 28 70 6f 73 2c 20 72 65 61 64 57 68 69 ken(pos, readWhi
1610: 6c 65 21 69 73 4d 53 79 6d 62 6f 6c 28 29 2c 20 le!isMSymbol(),
1620: 66 61 6c 73 65 29 3b 0a 09 09 7d 0a 09 09 65 6c false);...}...el
1630: 73 65 0a 09 09 7b 0a 09 09 09 61 75 74 6f 20 70 se...{....auto p
1640: 6f 73 20 3d 20 72 65 61 64 65 72 2e 63 75 72 72 os = reader.curr
1650: 65 6e 74 50 6f 73 69 74 69 6f 6e 28 29 3b 0d 0a entPosition();..
1660: 09 09 09 72 65 74 75 72 6e 20 6e 65 77 20 54 6f ...return new To
1670: 6b 65 6e 28 70 6f 73 2c 20 72 65 61 64 57 68 69 ken(pos, readWhi
1680: 6c 65 21 69 73 4c 65 74 74 65 72 28 29 2c 20 66 le!isLetter(), f
1690: 61 6c 73 65 29 3b 0d 0a 09 09 7d 0a 09 7d 0a 7d alse);....}..}.}
16a0: 0a 0a 75 6e 69 74 74 65 73 74 0a 7b 0a 09 61 73 ..unittest.{..as
16b0: 73 65 72 74 28 20 73 74 64 2e 72 61 6e 67 65 2e sert( std.range.
16c0: 69 73 46 6f 72 77 61 72 64 52 61 6e 67 65 21 28 isForwardRange!(
16d0: 4c 65 78 65 72 29 20 29 3b 0a 7d 0a 0a 75 6e 69 Lexer) );.}..uni
16e0: 74 74 65 73 74 0a 7b 0a 09 61 75 74 6f 20 6c 65 ttest.{..auto le
16f0: 78 20 3d 20 6c 65 78 65 72 46 72 6f 6d 53 74 72 x = lexerFromStr
1700: 69 6e 67 28 22 74 68 69 73 09 69 73 20 61 20 5c ing("this.is a \
1710: 74 5c 72 5c 6e 20 70 65 6e 20 3a 2d 28 20 40 40 t\r\n pen :-( @@
1720: 3b 20 20 22 29 3b 0a 09 54 6f 6b 65 6e 5b 5d 20 ; ");..Token[]
1730: 74 73 20 3d 20 73 74 64 2e 61 72 72 61 79 2e 61 ts = std.array.a
1740: 72 72 61 79 28 6c 65 78 29 3b 0a 0a 09 61 73 73 rray(lex);...ass
1750: 65 72 74 5f 65 71 28 20 74 73 5b 30 5d 2e 70 6f ert_eq( ts[0].po
1760: 73 2e 6c 69 6e 65 6e 6f 2c 20 31 20 29 3b 0a 09 s.lineno, 1 );..
1770: 61 73 73 65 72 74 5f 65 71 28 20 74 73 5b 30 5d assert_eq( ts[0]
1780: 2e 70 6f 73 2e 63 6f 6c 75 6d 6e 2c 20 31 20 29 .pos.column, 1 )
1790: 3b 0a 09 61 73 73 65 72 74 28 20 20 20 21 74 73 ;..assert( !ts
17a0: 5b 30 5d 2e 71 75 6f 74 65 64 20 29 3b 0a 09 61 [0].quoted );..a
17b0: 73 73 65 72 74 5f 65 71 28 20 74 73 5b 30 5d 2e ssert_eq( ts[0].
17c0: 73 74 72 2c 20 22 74 68 69 73 22 20 29 3b 0a 0a str, "this" );..
17d0: 09 61 73 73 65 72 74 5f 65 71 28 20 74 73 5b 31 .assert_eq( ts[1
17e0: 5d 2e 70 6f 73 2e 6c 69 6e 65 6e 6f 2c 20 31 20 ].pos.lineno, 1
17f0: 29 3b 0a 09 61 73 73 65 72 74 5f 65 71 28 20 74 );..assert_eq( t
1800: 73 5b 31 5d 2e 70 6f 73 2e 63 6f 6c 75 6d 6e 2c s[1].pos.column,
1810: 20 36 20 29 3b 0a 09 61 73 73 65 72 74 28 20 20 6 );..assert(
1820: 20 21 74 73 5b 31 5d 2e 71 75 6f 74 65 64 20 29 !ts[1].quoted )
1830: 3b 0a 09 61 73 73 65 72 74 5f 65 71 28 20 74 73 ;..assert_eq( ts
1840: 5b 31 5d 2e 73 74 72 2c 20 22 69 73 22 20 29 3b [1].str, "is" );
1850: 0a 0a 09 61 73 73 65 72 74 5f 65 71 28 20 74 73 ...assert_eq( ts
1860: 5b 32 5d 2e 70 6f 73 2e 6c 69 6e 65 6e 6f 2c 20 [2].pos.lineno,
1870: 31 20 29 3b 0a 09 61 73 73 65 72 74 5f 65 71 28 1 );..assert_eq(
1880: 20 74 73 5b 32 5d 2e 70 6f 73 2e 63 6f 6c 75 6d ts[2].pos.colum
1890: 6e 2c 20 39 20 29 3b 0a 09 61 73 73 65 72 74 28 n, 9 );..assert(
18a0: 20 20 20 21 74 73 5b 32 5d 2e 71 75 6f 74 65 64 !ts[2].quoted
18b0: 20 29 3b 0a 09 61 73 73 65 72 74 5f 65 71 28 20 );..assert_eq(
18c0: 74 73 5b 32 5d 2e 73 74 72 2c 20 22 61 22 20 29 ts[2].str, "a" )
18d0: 3b 0a 0a 09 61 73 73 65 72 74 5f 65 71 28 20 74 ;...assert_eq( t
18e0: 73 5b 33 5d 2e 70 6f 73 2e 6c 69 6e 65 6e 6f 2c s[3].pos.lineno,
18f0: 20 32 20 29 3b 0a 09 61 73 73 65 72 74 5f 65 71 2 );..assert_eq
1900: 28 20 74 73 5b 33 5d 2e 70 6f 73 2e 63 6f 6c 75 ( ts[3].pos.colu
1910: 6d 6e 2c 20 32 20 29 3b 0a 09 61 73 73 65 72 74 mn, 2 );..assert
1920: 28 20 20 20 21 74 73 5b 33 5d 2e 71 75 6f 74 65 ( !ts[3].quote
1930: 64 20 29 3b 0a 09 61 73 73 65 72 74 5f 65 71 28 d );..assert_eq(
1940: 20 74 73 5b 33 5d 2e 73 74 72 2c 20 22 70 65 6e ts[3].str, "pen
1950: 22 20 29 3b 0a 0a 09 61 73 73 65 72 74 5f 65 71 " );...assert_eq
1960: 28 20 74 73 5b 34 5d 2e 70 6f 73 2e 6c 69 6e 65 ( ts[4].pos.line
1970: 6e 6f 2c 20 32 20 29 3b 0a 09 61 73 73 65 72 74 no, 2 );..assert
1980: 5f 65 71 28 20 74 73 5b 34 5d 2e 70 6f 73 2e 63 _eq( ts[4].pos.c
1990: 6f 6c 75 6d 6e 2c 20 36 20 29 3b 0a 09 61 73 73 olumn, 6 );..ass
19a0: 65 72 74 5f 65 71 28 20 74 73 5b 34 5d 2e 73 74 ert_eq( ts[4].st
19b0: 72 2c 20 22 3a 2d 22 20 29 3b 0a 0a 09 61 73 73 r, ":-" );...ass
19c0: 65 72 74 5f 65 71 28 20 74 73 5b 35 5d 2e 70 6f ert_eq( ts[5].po
19d0: 73 2e 6c 69 6e 65 6e 6f 2c 20 32 20 29 3b 0d 0a s.lineno, 2 );..
19e0: 09 61 73 73 65 72 74 5f 65 71 28 20 74 73 5b 35 .assert_eq( ts[5
19f0: 5d 2e 70 6f 73 2e 63 6f 6c 75 6d 6e 2c 20 38 20 ].pos.column, 8
1a00: 29 3b 0d 0a 09 61 73 73 65 72 74 5f 65 71 28 20 );...assert_eq(
1a10: 74 73 5b 35 5d 2e 73 74 72 2c 20 22 28 22 20 29 ts[5].str, "(" )
1a20: 3b 0d 0a 09 61 73 73 65 72 74 5f 65 71 28 20 74 ;...assert_eq( t
1a30: 73 5b 36 5d 2e 73 74 72 2c 20 22 40 40 22 20 29 s[6].str, "@@" )
1a40: 3b 0d 0a 09 61 73 73 65 72 74 5f 65 71 28 20 74 ;...assert_eq( t
1a50: 73 5b 37 5d 2e 73 74 72 2c 20 22 3b 22 20 29 3b s[7].str, ";" );
1a60: 20 2f 2f 20 70 61 72 65 6e 20 61 6e 64 20 73 69 // paren and si
1a70: 6d 69 63 6f 6c 6f 6e 73 20 61 72 65 20 73 70 6c micolons are spl
1a80: 69 74 0d 0a 0d 0a 09 61 73 73 65 72 74 5f 65 71 it.....assert_eq
1a90: 28 20 74 73 2e 6c 65 6e 67 74 68 2c 20 38 20 29 ( ts.length, 8 )
1aa0: 3b 0a 7d 0a 0a 75 6e 69 74 74 65 73 74 0a 7b 0a ;.}..unittest.{.
1ab0: 09 2f 2f 20 21 21 20 62 65 20 73 75 72 65 20 74 .// !! be sure t
1ac0: 6f 20 72 75 6e 20 74 68 65 20 75 6e 69 74 74 65 o run the unitte
1ad0: 73 74 20 6f 6e 20 74 68 65 20 72 6f 6f 74 20 6f st on the root o
1ae0: 66 20 74 68 65 20 73 6f 75 72 63 65 20 64 69 72 f the source dir
1af0: 65 63 74 6f 72 79 0a 09 61 75 74 6f 20 6c 65 78 ectory..auto lex
1b00: 66 20 3d 20 6c 65 78 65 72 46 72 6f 6d 46 69 6c f = lexerFromFil
1b10: 65 28 22 70 6f 6c 65 6d 79 2f 6c 65 78 2e 64 22 e("polemy/lex.d"
1b20: 29 3b 09 0a 09 6c 65 78 66 20 3d 20 66 69 6e 64 );...lexf = find
1b30: 21 60 61 2e 73 74 72 20 3d 3d 20 22 6d 6f 64 75 !`a.str == "modu
1b40: 6c 65 22 60 28 6c 65 78 66 29 3b 0a 09 61 73 73 le"`(lexf);..ass
1b50: 65 72 74 5f 65 71 28 20 6c 65 78 66 2e 66 72 6f ert_eq( lexf.fro
1b60: 6e 74 2e 73 74 72 2c 20 22 6d 6f 64 75 6c 65 22 nt.str, "module"
1b70: 20 29 3b 0a 09 61 73 73 65 72 74 5f 65 71 28 20 );..assert_eq(
1b80: 6c 65 78 66 2e 66 72 6f 6e 74 2e 70 6f 73 2e 66 lexf.front.pos.f
1b90: 69 6c 65 6e 61 6d 65 2c 20 22 70 6f 6c 65 6d 79 ilename, "polemy
1ba0: 2f 6c 65 78 2e 64 22 20 29 3b 0a 09 61 73 73 65 /lex.d" );..asse
1bb0: 72 74 5f 65 71 28 20 6c 65 78 66 2e 66 72 6f 6e rt_eq( lexf.fron
1bc0: 74 2e 70 6f 73 2e 6c 69 6e 65 6e 6f 2c 20 37 20 t.pos.lineno, 7
1bd0: 29 3b 0a 09 61 73 73 65 72 74 5f 65 71 28 20 6c );..assert_eq( l
1be0: 65 78 66 2e 66 72 6f 6e 74 2e 70 6f 73 2e 63 6f exf.front.pos.co
1bf0: 6c 75 6d 6e 2c 20 31 20 29 3b 0a 09 6c 65 78 66 lumn, 1 );..lexf
1c00: 2e 70 6f 70 46 72 6f 6e 74 3b 0a 09 61 73 73 65 .popFront;..asse
1c10: 72 74 5f 65 71 28 20 6c 65 78 66 2e 66 72 6f 6e rt_eq( lexf.fron
1c20: 74 2e 73 74 72 2c 20 22 70 6f 6c 65 6d 79 22 20 t.str, "polemy"
1c30: 29 3b 0a 09 61 73 73 65 72 74 5f 65 71 28 20 6c );..assert_eq( l
1c40: 65 78 66 2e 66 72 6f 6e 74 2e 70 6f 73 2e 6c 69 exf.front.pos.li
1c50: 6e 65 6e 6f 2c 20 37 20 29 3b 0a 09 61 73 73 65 neno, 7 );..asse
1c60: 72 74 5f 65 71 28 20 6c 65 78 66 2e 66 72 6f 6e rt_eq( lexf.fron
1c70: 74 2e 70 6f 73 2e 63 6f 6c 75 6d 6e 2c 20 38 20 t.pos.column, 8
1c80: 29 3b 0a 09 6c 65 78 66 2e 70 6f 70 46 72 6f 6e );..lexf.popFron
1c90: 74 3b 0a 09 6c 65 78 66 2e 70 6f 70 46 72 6f 6e t;..lexf.popFron
1ca0: 74 3b 0a 09 6c 65 78 66 2e 70 6f 70 46 72 6f 6e t;..lexf.popFron
1cb0: 74 3b 0a 09 6c 65 78 66 2e 70 6f 70 46 72 6f 6e t;..lexf.popFron
1cc0: 74 3b 0a 09 61 73 73 65 72 74 5f 65 71 28 20 6c t;..assert_eq( l
1cd0: 65 78 66 2e 66 72 6f 6e 74 2e 73 74 72 2c 20 22 exf.front.str, "
1ce0: 69 6d 70 6f 72 74 22 20 29 3b 0a 09 61 73 73 65 import" );..asse
1cf0: 72 74 5f 65 71 28 20 6c 65 78 66 2e 66 72 6f 6e rt_eq( lexf.fron
1d00: 74 2e 70 6f 73 2e 6c 69 6e 65 6e 6f 2c 20 38 20 t.pos.lineno, 8
1d10: 29 3b 0a 09 61 73 73 65 72 74 5f 65 71 28 20 6c );..assert_eq( l
1d20: 65 78 66 2e 66 72 6f 6e 74 2e 70 6f 73 2e 63 6f exf.front.pos.co
1d30: 6c 75 6d 6e 2c 20 31 20 29 3b 0a 7d 0a 0d 0a 75 lumn, 1 );.}...u
1d40: 6e 69 74 74 65 73 74 0d 0a 7b 0d 0a 09 61 73 73 nittest..{...ass
1d50: 65 72 74 5f 74 68 72 6f 77 21 4c 65 78 45 78 63 ert_throw!LexExc
1d60: 65 70 74 69 6f 6e 28 20 6c 65 78 65 72 46 72 6f eption( lexerFro
1d70: 6d 53 74 72 69 6e 67 28 60 22 60 29 20 29 3b 0d mString(`"`) );.
1d80: 0a 7d 0d 0a 0a 75 6e 69 74 74 65 73 74 0a 7b 0a .}...unittest.{.
1d90: 09 61 75 74 6f 20 6c 65 78 20 3d 20 6c 65 78 65 .auto lex = lexe
1da0: 72 46 72 6f 6d 53 74 72 69 6e 67 28 60 6d 79 20 rFromString(`my
1db0: 23 20 63 6f 6d 6d 65 6e 74 20 73 68 6f 75 6c 64 # comment should
1dc0: 60 7e 22 5c 72 5c 6e 22 7e 60 23 20 68 65 79 21 `~"\r\n"~`# hey!
1dd0: 21 0a 62 65 20 69 67 6e 6f 72 65 64 2e 0a 68 61 !.be ignored..ha
1de0: 68 61 68 61 22 68 69 68 69 68 69 22 22 68 75 5c haha"hihihi""hu\
1df0: 5c 5c 22 68 75 68 75 22 23 31 32 33 20 61 61 0a \\"huhu"#123 aa.
1e00: 31 32 33 20 61 61 20 22 61 61 61 60 7e 22 5c 6e 123 aa "aaa`~"\n
1e10: 22 7e 60 62 62 62 20 23 20 31 32 33 60 7e 22 5c "~`bbb # 123`~"\
1e20: 72 5c 6e 22 7e 60 65 65 65 22 0a 7a 7a 7a 0a 60 r\n"~`eee".zzz.`
1e30: 29 3b 0a 09 54 6f 6b 65 6e 5b 5d 20 74 73 20 3d );..Token[] ts =
1e40: 20 73 74 64 2e 61 72 72 61 79 2e 61 72 72 61 79 std.array.array
1e50: 28 6c 65 78 29 3b 0a 09 61 73 73 65 72 74 5f 65 (lex);..assert_e
1e60: 71 28 20 74 73 5b 30 5d 2e 73 74 72 2c 20 22 6d q( ts[0].str, "m
1e70: 79 22 20 29 3b 0a 09 61 73 73 65 72 74 5f 65 71 y" );..assert_eq
1e80: 28 20 74 73 5b 30 5d 2e 70 6f 73 2e 6c 69 6e 65 ( ts[0].pos.line
1e90: 6e 6f 2c 20 31 20 29 3b 0a 09 61 73 73 65 72 74 no, 1 );..assert
1ea0: 28 20 20 20 21 74 73 5b 30 5d 2e 71 75 6f 74 65 ( !ts[0].quote
1eb0: 64 20 29 3b 0a 09 61 73 73 65 72 74 5f 65 71 28 d );..assert_eq(
1ec0: 20 74 73 5b 31 5d 2e 73 74 72 2c 20 22 62 65 22 ts[1].str, "be"
1ed0: 20 29 3b 0a 09 61 73 73 65 72 74 5f 65 71 28 20 );..assert_eq(
1ee0: 74 73 5b 31 5d 2e 70 6f 73 2e 6c 69 6e 65 6e 6f ts[1].pos.lineno
1ef0: 2c 20 33 20 29 3b 0a 09 61 73 73 65 72 74 28 20 , 3 );..assert(
1f00: 20 20 21 74 73 5b 31 5d 2e 71 75 6f 74 65 64 20 !ts[1].quoted
1f10: 29 3b 0a 09 61 73 73 65 72 74 5f 65 71 28 20 74 );..assert_eq( t
1f20: 73 5b 32 5d 2e 73 74 72 2c 20 22 69 67 6e 6f 72 s[2].str, "ignor
1f30: 65 64 22 20 29 3b 0a 09 61 73 73 65 72 74 28 20 ed" );..assert(
1f40: 20 20 21 74 73 5b 32 5d 2e 71 75 6f 74 65 64 20 !ts[2].quoted
1f50: 29 3b 0a 09 61 73 73 65 72 74 5f 65 71 28 20 74 );..assert_eq( t
1f60: 73 5b 33 5d 2e 73 74 72 2c 20 22 2e 22 20 29 3b s[3].str, "." );
1f70: 0a 09 61 73 73 65 72 74 28 20 20 20 21 74 73 5b ..assert( !ts[
1f80: 33 5d 2e 71 75 6f 74 65 64 20 29 3b 0a 09 61 73 3].quoted );..as
1f90: 73 65 72 74 5f 65 71 28 20 74 73 5b 34 5d 2e 73 sert_eq( ts[4].s
1fa0: 74 72 2c 20 22 68 61 68 61 68 61 22 20 29 3b 0a tr, "hahaha" );.
1fb0: 09 61 73 73 65 72 74 5f 65 71 28 20 74 73 5b 34 .assert_eq( ts[4
1fc0: 5d 2e 70 6f 73 2e 6c 69 6e 65 6e 6f 2c 20 34 20 ].pos.lineno, 4
1fd0: 29 3b 0a 09 61 73 73 65 72 74 28 20 20 20 21 74 );..assert( !t
1fe0: 73 5b 34 5d 2e 71 75 6f 74 65 64 20 29 3b 0a 09 s[4].quoted );..
1ff0: 61 73 73 65 72 74 5f 65 71 28 20 74 73 5b 35 5d assert_eq( ts[5]
2000: 2e 73 74 72 2c 20 22 68 69 68 69 68 69 22 20 29 .str, "hihihi" )
2010: 3b 0a 09 61 73 73 65 72 74 5f 65 71 28 20 74 73 ;..assert_eq( ts
2020: 5b 35 5d 2e 70 6f 73 2e 6c 69 6e 65 6e 6f 2c 20 [5].pos.lineno,
2030: 34 20 29 3b 0a 09 61 73 73 65 72 74 28 20 20 20 4 );..assert(
2040: 20 74 73 5b 35 5d 2e 71 75 6f 74 65 64 20 29 3b ts[5].quoted );
2050: 0a 09 61 73 73 65 72 74 5f 65 71 28 20 74 73 5b ..assert_eq( ts[
2060: 36 5d 2e 73 74 72 2c 20 60 68 75 5c 22 68 75 68 6].str, `hu\"huh
2070: 75 60 20 29 3b 0a 09 61 73 73 65 72 74 5f 65 71 u` );..assert_eq
2080: 28 20 74 73 5b 36 5d 2e 70 6f 73 2e 6c 69 6e 65 ( ts[6].pos.line
2090: 6e 6f 2c 20 34 20 29 3b 0a 09 61 73 73 65 72 74 no, 4 );..assert
20a0: 28 20 20 20 20 74 73 5b 36 5d 2e 71 75 6f 74 65 ( ts[6].quote
20b0: 64 20 29 3b 0a 09 61 73 73 65 72 74 5f 65 71 28 d );..assert_eq(
20c0: 20 74 73 5b 37 5d 2e 73 74 72 2c 20 22 31 32 33 ts[7].str, "123
20d0: 22 20 29 3b 0a 09 61 73 73 65 72 74 5f 65 71 28 " );..assert_eq(
20e0: 20 74 73 5b 37 5d 2e 70 6f 73 2e 6c 69 6e 65 6e ts[7].pos.linen
20f0: 6f 2c 20 35 20 29 3b 0a 09 61 73 73 65 72 74 5f o, 5 );..assert_
2100: 65 71 28 20 74 73 5b 38 5d 2e 73 74 72 2c 20 22 eq( ts[8].str, "
2110: 61 61 22 20 29 3b 0a 09 61 73 73 65 72 74 5f 65 aa" );..assert_e
2120: 71 28 20 74 73 5b 39 5d 2e 70 6f 73 2e 6c 69 6e q( ts[9].pos.lin
2130: 65 6e 6f 2c 20 35 20 29 3b 0a 09 61 73 73 65 72 eno, 5 );..asser
2140: 74 5f 65 71 28 20 74 73 5b 39 5d 2e 73 74 72 2c t_eq( ts[9].str,
2150: 20 22 61 61 61 5c 6e 62 62 62 20 23 20 31 32 33 "aaa\nbbb # 123
2160: 5c 6e 65 65 65 22 20 29 3b 0a 09 61 73 73 65 72 \neee" );..asser
2170: 74 28 20 20 20 20 74 73 5b 39 5d 2e 71 75 6f 74 t( ts[9].quot
2180: 65 64 20 29 3b 0a 09 61 73 73 65 72 74 5f 65 71 ed );..assert_eq
2190: 28 20 74 73 5b 31 30 5d 2e 70 6f 73 2e 6c 69 6e ( ts[10].pos.lin
21a0: 65 6e 6f 2c 20 38 20 29 3b 0a 09 61 73 73 65 72 eno, 8 );..asser
21b0: 74 28 20 20 20 21 74 73 5b 31 30 5d 2e 71 75 6f t( !ts[10].quo
21c0: 74 65 64 20 29 3b 0a 09 61 73 73 65 72 74 5f 65 ted );..assert_e
21d0: 71 28 20 74 73 2e 6c 65 6e 67 74 68 2c 20 31 31 q( ts.length, 11
21e0: 20 29 3b 0a 7d 0a 0d 0a 75 6e 69 74 74 65 73 74 );.}...unittest
21f0: 0d 0a 7b 0d 0a 09 61 75 74 6f 20 6c 65 78 32 20 ..{...auto lex2
2200: 3d 20 6c 65 78 65 72 46 72 6f 6d 53 74 72 69 6e = lexerFromStrin
2210: 67 28 22 20 61 31 32 5c 6e 33 61 20 35 20 22 29 g(" a12\n3a 5 ")
2220: 3b 0d 0a 09 61 73 73 65 72 74 5f 65 71 28 20 6c ;...assert_eq( l
2230: 65 78 32 2e 66 72 6f 6e 74 2e 73 74 72 2c 20 22 ex2.front.str, "
2240: 61 31 32 22 20 29 3b 0d 0a 09 6c 65 78 32 2e 70 a12" );...lex2.p
2250: 6f 70 46 72 6f 6e 74 3b 0d 0a 09 61 75 74 6f 20 opFront;...auto
2260: 6c 65 78 33 20 3d 20 6c 65 78 32 2e 73 61 76 65 lex3 = lex2.save
2270: 3b 0d 0a 09 61 73 73 65 72 74 5f 65 71 28 20 6c ;...assert_eq( l
2280: 65 78 32 2e 66 72 6f 6e 74 2e 73 74 72 2c 20 22 ex2.front.str, "
2290: 33 61 22 20 29 3b 0d 0a 09 6c 65 78 32 2e 70 6f 3a" );...lex2.po
22a0: 70 46 72 6f 6e 74 3b 0d 0a 09 61 73 73 65 72 74 pFront;...assert
22b0: 5f 65 71 28 20 6c 65 78 33 2e 66 72 6f 6e 74 2e _eq( lex3.front.
22c0: 73 74 72 2c 20 22 33 61 22 20 29 3b 0d 0a 09 61 str, "3a" );...a
22d0: 73 73 65 72 74 5f 65 71 28 20 6c 65 78 32 2e 66 ssert_eq( lex2.f
22e0: 72 6f 6e 74 2e 73 74 72 2c 20 22 35 22 20 29 3b ront.str, "5" );
22f0: 0d 0a 09 6c 65 78 32 2e 70 6f 70 46 72 6f 6e 74 ...lex2.popFront
2300: 3b 0d 0a 09 6c 65 78 33 2e 70 6f 70 46 72 6f 6e ;...lex3.popFron
2310: 74 3b 0d 0a 09 61 73 73 65 72 74 28 20 6c 65 78 t;...assert( lex
2320: 32 2e 65 6d 70 74 79 20 29 3b 0d 0a 09 61 73 73 2.empty );...ass
2330: 65 72 74 28 20 21 6c 65 78 33 2e 65 6d 70 74 79 ert( !lex3.empty
2340: 20 29 3b 0d 0a 09 61 73 73 65 72 74 5f 65 71 28 );...assert_eq(
2350: 20 6c 65 78 33 2e 66 72 6f 6e 74 2e 73 74 72 2c lex3.front.str,
2360: 20 22 35 22 20 29 3b 0d 0a 7d 0d 0a 0d 0a 2f 2f "5" );..}....//
2370: 2f 20 46 6f 72 77 61 72 64 20 72 61 6e 67 65 20 / Forward range
2380: 66 6f 72 20 72 65 61 64 65 72 20 63 68 61 72 61 for reader chara
2390: 63 74 65 72 20 62 79 20 63 68 61 72 61 63 74 65 cter by characte
23a0: 72 2c 0d 0a 2f 2f 2f 20 6b 65 65 70 69 6e 67 20 r,../// keeping
23b0: 74 72 61 63 6b 20 6f 66 20 70 6f 73 69 74 69 6f track of positio
23c0: 6e 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 6e n information an
23d0: 64 20 63 61 72 69 6e 67 20 5c 72 5c 6e 20 2d 3e d caring \r\n ->
23e0: 20 5c 6e 20 63 6f 6e 76 65 72 73 69 6f 6e 2e 0d \n conversion..
23f0: 0a 0d 0a 70 72 69 76 61 74 65 0d 0a 73 74 72 75 ...private..stru
2400: 63 74 20 50 6f 73 69 74 69 6f 6e 65 64 52 65 61 ct PositionedRea
2410: 64 65 72 28 43 68 61 72 53 65 71 29 0d 0a 09 69 der(CharSeq)...i
2420: 66 28 20 69 73 46 6f 72 77 61 72 64 52 61 6e 67 f( isForwardRang
2430: 65 21 28 43 68 61 72 53 65 71 29 20 26 26 20 69 e!(CharSeq) && i
2440: 73 28 45 6c 65 6d 65 6e 74 54 79 70 65 21 28 43 s(ElementType!(C
2450: 68 61 72 53 65 71 29 20 3d 3d 20 64 63 68 61 72 harSeq) == dchar
2460: 29 20 29 0d 0a 7b 0d 0a 09 43 68 61 72 53 65 71 ) )..{...CharSeq
2470: 20 62 75 66 66 65 72 3b 0d 0a 09 73 74 72 69 6e buffer;...strin
2480: 67 20 20 66 69 6c 65 6e 61 6d 65 3b 0d 0a 09 69 g filename;...i
2490: 6e 74 20 20 20 20 20 6c 69 6e 65 6e 6f 3b 0d 0a nt lineno;..
24a0: 09 69 6e 74 20 20 20 20 20 63 6f 6c 75 6d 6e 3b .int column;
24b0: 0d 0a 0d 0a 09 2f 2f 2f 20 52 61 6e 67 65 20 70 ...../// Range p
24c0: 72 69 6d 69 74 69 76 65 0d 0a 09 62 6f 6f 6c 20 rimitive...bool
24d0: 65 6d 70 74 79 28 29 20 2f 2a 40 70 72 6f 70 65 empty() /*@prope
24e0: 72 74 79 2a 2f 0d 0a 09 7b 0d 0a 09 09 72 65 74 rty*/...{....ret
24f0: 75 72 6e 20 62 75 66 66 65 72 2e 65 6d 70 74 79 urn buffer.empty
2500: 3b 0d 0a 09 7d 0d 0a 0d 0a 09 2f 2f 2f 20 52 61 ;...}...../// Ra
2510: 6e 67 65 20 70 72 69 6d 69 74 69 76 65 0d 0a 09 nge primitive...
2520: 64 63 68 61 72 20 66 72 6f 6e 74 28 29 20 2f 2a dchar front() /*
2530: 40 70 72 6f 70 65 72 74 79 2a 2f 0d 0a 09 7b 0d @property*/...{.
2540: 0a 09 09 64 63 68 61 72 20 63 20 3d 20 62 75 66 ...dchar c = buf
2550: 66 65 72 2e 66 72 6f 6e 74 3b 0d 0a 09 09 72 65 fer.front;....re
2560: 74 75 72 6e 20 28 63 3d 3d 27 5c 72 27 20 3f 20 turn (c=='\r' ?
2570: 27 5c 6e 27 20 3a 20 63 29 3b 0d 0a 09 7d 0d 0a '\n' : c);...}..
2580: 0d 0a 09 2f 2f 2f 20 52 61 6e 67 65 20 70 72 69 .../// Range pri
2590: 6d 69 74 69 76 65 0d 0a 09 76 6f 69 64 20 70 6f mitive...void po
25a0: 70 46 72 6f 6e 74 28 29 20 2f 2a 40 70 72 6f 70 pFront() /*@prop
25b0: 65 72 74 79 2a 2f 0d 0a 09 7b 0d 0a 09 09 64 63 erty*/...{....dc
25c0: 68 61 72 20 63 20 3d 20 62 75 66 66 65 72 2e 66 har c = buffer.f
25d0: 72 6f 6e 74 3b 0d 0a 09 09 62 75 66 66 65 72 2e ront;....buffer.
25e0: 70 6f 70 46 72 6f 6e 74 3b 0d 0a 09 09 69 66 28 popFront;....if(
25f0: 20 63 3d 3d 27 5c 72 27 20 29 0d 0a 09 09 7b 0d c=='\r' )....{.
2600: 0a 09 09 09 69 66 28 20 21 62 75 66 66 65 72 2e ....if( !buffer.
2610: 65 6d 70 74 79 20 26 26 20 62 75 66 66 65 72 2e empty && buffer.
2620: 66 72 6f 6e 74 3d 3d 27 5c 6e 27 20 29 0d 0a 09 front=='\n' )...
2630: 09 09 09 62 75 66 66 65 72 2e 70 6f 70 46 72 6f ...buffer.popFro
2640: 6e 74 3b 0d 0a 09 09 09 63 20 3d 20 27 5c 6e 27 nt;.....c = '\n'
2650: 3b 0d 0a 09 09 7d 0d 0a 09 09 69 66 28 20 63 3d ;....}....if( c=
2660: 3d 27 5c 6e 27 20 29 0d 0a 09 09 7b 0d 0a 09 09 ='\n' )....{....
2670: 09 6c 69 6e 65 6e 6f 20 2b 2b 3b 0d 0a 09 09 09 .lineno ++;.....
2680: 63 6f 6c 75 6d 6e 20 3d 20 31 3b 0d 0a 09 09 7d column = 1;....}
2690: 0d 0a 09 09 65 6c 73 65 0d 0a 09 09 09 63 6f 6c ....else.....col
26a0: 75 6d 6e 20 2b 2b 3b 0d 0a 09 7d 0d 0a 0d 0a 09 umn ++;...}.....
26b0: 2f 2f 2f 20 52 61 6e 67 65 20 70 72 69 6d 69 74 /// Range primit
26c0: 69 76 65 0d 0a 09 74 79 70 65 6f 66 28 74 68 69 ive...typeof(thi
26d0: 73 29 20 73 61 76 65 28 29 20 2f 2a 40 70 72 6f s) save() /*@pro
26e0: 70 65 72 74 79 2a 2f 0d 0a 09 7b 0d 0a 09 09 72 perty*/...{....r
26f0: 65 74 75 72 6e 20 74 68 69 73 3b 0d 0a 09 7d 0d eturn this;...}.
2700: 0a 0d 0a 09 2f 2f 2f 20 47 65 74 20 74 68 65 20 ..../// Get the
2710: 63 75 72 72 65 6e 74 20 70 6f 73 69 74 69 6f 6e current position
2720: 0d 0a 09 69 6d 6d 75 74 61 62 6c 65 28 4c 65 78 ...immutable(Lex
2730: 50 6f 73 69 74 69 6f 6e 29 20 63 75 72 72 65 6e Position) curren
2740: 74 50 6f 73 69 74 69 6f 6e 28 29 20 63 6f 6e 73 tPosition() cons
2750: 74 0d 0a 09 7b 0d 0a 09 09 72 65 74 75 72 6e 20 t...{....return
2760: 6e 65 77 20 69 6d 6d 75 74 61 62 6c 65 28 4c 65 new immutable(Le
2770: 78 50 6f 73 69 74 69 6f 6e 29 28 66 69 6c 65 6e xPosition)(filen
2780: 61 6d 65 2c 20 6c 69 6e 65 6e 6f 2c 20 63 6f 6c ame, lineno, col
2790: 75 6d 6e 29 3b 0d 0a 09 7d 0d 0a 7d 0d 0a 0d 0a umn);...}..}....
27a0: 75 6e 69 74 74 65 73 74 0d 0a 7b 0d 0a 09 61 73 unittest..{...as
27b0: 73 65 72 74 28 20 69 73 46 6f 72 77 61 72 64 52 sert( isForwardR
27c0: 61 6e 67 65 21 28 50 6f 73 69 74 69 6f 6e 65 64 ange!(Positioned
27d0: 52 65 61 64 65 72 21 73 74 72 69 6e 67 29 20 29 Reader!string) )
27e0: 3b 0d 0a 09 61 73 73 65 72 74 28 20 69 73 28 45 ;...assert( is(E
27f0: 6c 65 6d 65 6e 74 54 79 70 65 21 28 50 6f 73 69 lementType!(Posi
2800: 74 69 6f 6e 65 64 52 65 61 64 65 72 21 73 74 72 tionedReader!str
2810: 69 6e 67 29 20 3d 3d 20 64 63 68 61 72 29 20 29 ing) == dchar) )
2820: 3b 0d 0a 7d 0d 0a ;..}..