Skip to content

Commit

Permalink
Aug23 progress
Browse files Browse the repository at this point in the history
  • Loading branch information
Seasawher committed Aug 23, 2024
1 parent fe8a3f0 commit 7df1e76
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 0 deletions.
18 changes: 18 additions & 0 deletions Monkey/Lexer/Lexer.lean
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ def readChar : StateM Lexer Unit := do
else { l with ch := l.input.get ⟨l.readPosition⟩}
set { l' with position := l.readPosition, readPosition := l.readPosition + 1 }

/-- Lexer を進めることなく、入力を覗き見(peek)する `readChar` の変種 -/
def peekChar (l : Lexer) : Char :=
if l.readPosition ≥ l.input.length then '\x00'
else l.input.get ⟨l.readPosition⟩

/-- デフォルト値を持たせたコンストラクタの変種 -/
def mkD (input : String) (position readPosition : Nat := 0)
(ch : Char := '\x00') : Lexer :=
Expand Down Expand Up @@ -84,6 +89,19 @@ def skipWhitespace : StateM Lexer Unit := do
def nextToken : StateM Lexer Token := do
skipWhitespace
let mut l ← get

/- 2文字トークンの処理 -/
if l.ch == '=' && l.peekChar == '=' then
readChar
readChar
return EQ

if l.ch == '!' && l.peekChar == '=' then
readChar
readChar
return NOT_EQ

/- 1文字トークンの処理 -/
let mut tok := match l.ch with
| '=' => ASSIGN
| '+' => PLUS
Expand Down
18 changes: 18 additions & 0 deletions Monkey/Lexer/LexerTest.lean
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ def testNextToken (input : String) (expected : Array Token) : IO Unit := do
if tok = EOF then break

if actualTokens.size ≠ expected.size then
dbg_trace actualTokens
throw <| .userError s!"tests failed: - token count wrong. expected={expected.size}, got={actualTokens.size}"

let testCases := Array.zip expected actualTokens
Expand Down Expand Up @@ -106,6 +107,7 @@ def testNextToken (input : String) (expected : Array Token) : IO Unit := do
EOF
])

-- return とか true とかのテスト
#eval testNextToken
(input := "if (5 < 10) {
return true;
Expand All @@ -132,3 +134,19 @@ def testNextToken (input : String) (expected : Array Token) : IO Unit := do
RBRACE,
EOF
])

-- `==` とか `!=` とかのテスト
#eval testNextToken
(input := "10 == 10;
10 != 9;")
(expected := #[
INT 10,
EQ,
INT 10,
SEMICOLON,
INT 10,
NOT_EQ,
INT 9,
SEMICOLON,
EOF
])
25 changes: 25 additions & 0 deletions Monkey/Repl/Repl.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import Monkey.Lexer.Lexer
import Monkey.Token.Token

open IO Token

/-- REPL を表す。
`lake env lean --run Monkey/Repl/Repl.lean` で実行できる。
標準入力に入れた Monkey のコードを読みこむ。 -/
partial def main : IO Unit := do
IO.print ">> "
let inputStream ← getStdin
let input ← inputStream.getLine
if input.trim = "" then return ()

let mut l : Lexer := Lexer.new input
let mut tokens : Array Token := #[]

while True do
let ⟨tok, l'⟩ := l.nextToken |>.run
l := l'
tokens := tokens.push tok
if tok = EOF then break

IO.println tokens
main
6 changes: 6 additions & 0 deletions Monkey/Token/Token.lean
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ inductive Token where
| LT
/-- 大なり ">" -/
| GT
/-- 等号 `==` -/
| EQ
/-- 等しくない `!=` -/
| NOT_EQ
/-- true : Bool -/
| TRUE
/-- false : Bool -/
Expand Down Expand Up @@ -81,6 +85,8 @@ def Token.toString (t : Token) : String :=
| .SLASH => "/"
| .LT => "<"
| .GT => ">"
| .EQ => "=="
| .NOT_EQ => "!="
| .TRUE => "TRUE"
| .FALSE => "FALSE"
| .IF => "IF"
Expand Down

0 comments on commit 7df1e76

Please sign in to comment.