Hex Artifact Content
Not logged in

Artifact bee9af8d0f8f73488395b86b4cf2a9554859cec3:


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                                ;..}..