package Ġcom . ro bin v db . k lox Ċ Ċ val Ġkeywords Ġ= Ġmap Of ( ĊĠĠĠ Ġ" and " Ġto ĠTokenType . AND , ĊĠĠĠ Ġ" class " Ġto ĠTokenType . CLASS , ĊĠĠĠ Ġ" else " Ġto ĠTokenType . ELSE , ĊĠĠĠ Ġ" false " Ġto ĠTokenType . FALSE , ĊĠĠĠ Ġ" for " Ġto ĠTokenType . FOR , ĊĠĠĠ Ġ" fun " Ġto ĠTokenType . FUN , ĊĠĠĠ Ġ" if " Ġto ĠTokenType . IF , ĊĠĠĠ Ġ" nil " Ġto ĠTokenType . NIL , ĊĠĠĠ Ġ" or " Ġto ĠTokenType . OR , ĊĠĠĠ Ġ" print " Ġto ĠTokenType . PRINT , ĊĠĠĠ Ġ" return " Ġto ĠTokenType . RETURN , ĊĠĠĠ Ġ" super " Ġto ĠTokenType . SUPER , ĊĠĠĠ Ġ" this " Ġto ĠTokenType . THIS , ĊĠĠĠ Ġ" true " Ġto ĠTokenType . TRUE , ĊĠĠĠ Ġ" var " Ġto ĠTokenType . VAR , ĊĠĠĠ Ġ" while " Ġto ĠTokenType . WH ILE Ċ ) Ċ Ċ class ĠScanner ( private Ġval Ġctx : ĠContext , Ġprivate Ġval Ġsource Code : ĠString ) Ġ{ ĊĠĠĠ Ġprivate Ġval Ġtokens Ġ= Ġmutable ListOf < Token >() ĊĠĠĠ Ġprivate Ġvar Ġcurrent Ġ= Ġ 0 ĊĠĠĠ Ġprivate Ġvar Ġstart Ġ= Ġ 0 ĊĠĠĠ Ġprivate Ġvar Ġline Ġ= Ġ 1 ĊĊĠĠĠ Ġprivate Ġval Ġis At End : ĠBoolean ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġsource Code . length Ġ<= Ġcurrent ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġcurrent Substring : ĠString ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġsource Code . substring ( start , Ġcurrent ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĊĠĠĠ Ġfun Ġscan Tokens (): ĠList < Token > Ġ{ ĊĠĠĠĠĠĠĠ Ġwhile Ġ(! is At End ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstart Ġ= Ġcurrent ĊĠĠĠĠĠĠĠĠĠĠĠ Ġscan Token () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġtoken Ġ= ĠToken ( TokenType . EOF , Ġ"", Ġnull , Ġline ) ĊĠĠĠĠĠĠĠ Ġtokens . add ( token ) ĊĠĠĠĠĠĠĠ Ġreturn Ġtokens ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠLooks Ġfor Ġthe Ġnext Ġtoken , Ġand Ġif Ġone Ġexists , Ġadds Ġthem . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġscan Token () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġc Ġ= Ġadvance () ĊĠĠĠĠĠĠĠ Ġif Ġ( c Ġ== Ġ'(' ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Token ( TokenType . LEFT _ PAREN ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( c Ġ== Ġ') ') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Token ( TokenType . RIGHT _ PAREN ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( c Ġ== Ġ'{ ') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Token ( TokenType . LEFT _ BRACE ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( c Ġ== Ġ' }') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Token ( TokenType . RIGHT _ BRACE ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( c Ġ== Ġ', ') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Token ( TokenType . COMMA ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( c Ġ== Ġ'.') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Token ( TokenType . DOT ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( c Ġ== Ġ'-') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Token ( TokenType . MINUS ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( c Ġ== Ġ'+ ') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Token ( TokenType . PLUS ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( c Ġ== Ġ'; ') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Token ( TokenType . SE MIC OL ON ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( c Ġ== Ġ'* ') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Token ( TokenType . STAR ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( c Ġ== Ġ' !') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtoken : ĠTokenType Ġ= Ġif Ġ( match (' =' )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . B ANG _ EQUAL ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . B ANG ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Token ( token ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( c Ġ== Ġ'= ') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtoken Ġ= Ġif Ġ( match (' =' )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . EQUAL _ EQUAL ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . EQUAL ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Token ( token ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( c Ġ== Ġ'< ') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtoken Ġ= Ġif Ġ( match (' =' )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . LESS _ EQUAL ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . LESS ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Token ( token ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( c Ġ== Ġ' >') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtoken Ġ= Ġif Ġ( match (' =' )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . GRE ATER _ EQUAL ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . GRE ATER ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Token ( token ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( c Ġ== Ġ'/') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif (! match ('/ ')) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Token ( TokenType . SL ASH ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile ( this . peek () Ġ!= Ġ'\ n ' Ġ&& Ġ! this . is At End ) Ġthis . advance () Ġ// Ġskip Ġthe Ġcomment ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( c Ġ== Ġ' Ġ' Ġ|| Ġc Ġ== Ġ'\ r ' Ġ|| Ġc Ġ== Ġ'\ t ') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( c Ġ== Ġ'\ n ') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġline Ġ+= Ġ 1 ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( c Ġ== Ġ'" ') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstring () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( c . is Digit ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnumber () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( c . is Letter ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġidentifier () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġctx . error ( line , Ġ" Unexpected Ġcharacter Ġ'$ c '") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprivate Ġfun Ġadvance (): ĠChar Ġ{ ĊĠĠĠĠĠĠĠ Ġcurrent Ġ+= Ġ 1 ĊĠĠĠĠĠĠĠ Ġreturn Ġsource Code [ current Ġ- Ġ 1 ] ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprivate Ġfun Ġadd Token ( token Type : ĠTokenType , Ġliteral : ĠAny ? Ġ= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġle xe me Ġ= Ġcurrent Substring ĊĠĠĠĠĠĠĠ Ġval Ġtoken Ġ= ĠToken ( token Type , Ġle xe me , Ġliteral , Ġline ) ĊĠĠĠĠĠĠĠ Ġtokens . add ( token ) ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCheck Ġif Ġthe Ġcurrent Ġchar Ġmatches Ġthe Ġexpected Ġone . ĊĠĠĠĠ Ġ* ĠIf Ġit Ġdoes , Ġalso Ġadv ances Ġthe Ġcurrent ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġmatch ( expected : ĠChar ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( this . is At End Ġ|| Ġsource Code [ current ] Ġ!= Ġexpected ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcurrent Ġ+= Ġ 1 ĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprivate Ġfun Ġstring () Ġ{ ĊĠĠĠĠĠĠĠ Ġwhile Ġ( peek () Ġ!= Ġ'"' Ġ&& Ġ! is At End ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( peek () Ġ== Ġ'\ n ') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġline Ġ+= Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadvance () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠString Ġis Ġnot Ġclosed ĊĠĠĠĠĠĠĠ Ġif Ġ( is At End ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġctx . error ( line , Ġ" Un terminated Ġstring ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġcloses Ġthe Ġstring ĊĠĠĠĠĠĠĠ Ġadvance () ĊĊĠĠĠĠĠĠĠ Ġval Ġvalue Ġ= Ġsource Code . substring ( start Ġ+ Ġ 1 , Ġcurrent Ġ- Ġ 1 ) ĊĠĠĠĠĠĠĠ Ġadd Token ( TokenType . STRING , Ġvalue ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġnumber () Ġ{ ĊĠĠĠĠĠĠĠ Ġwhile Ġ( peek (). is Digit ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadvance () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( peek () Ġ== Ġ'.' Ġ&& Ġpeek ( 1 ). is Digit ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadvance () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( peek (). is Digit ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadvance () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġnumber Ġ= Ġcurrent Substring . toDouble () ĊĠĠĠĠĠĠĠ Ġadd Token ( TokenType . NUMBER , Ġnumber ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġidentifier () Ġ{ ĊĠĠĠĠĠĠĠ Ġwhile Ġ( peek (). is Letter Or Digit ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadvance () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġtext Ġ= Ġcurrent Substring ĊĠĠĠĠĠĠĠ Ġif Ġ( text Ġin Ġkeywords . keys ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtype Ġ= Ġkeywords . getValue ( text ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Token ( type ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Token ( TokenType . IDENTIFIER ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturn Ġthe Ġcurrent Ġchar . ĠIf Ġnone Ġis Ġfound , Ġreturn Ġa Ġnull Ġchar ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġpeek ( offset : ĠInt Ġ= Ġ 0 ): ĠChar Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( sourceCode . length Ġ<= Ġcurrent ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ'\ u 0 0 0 0 ' ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġsource Code [ current Ġ+ Ġoffset ] ĊĠĠĠ Ġ} Ċ } Ċ