diff --git a/README.md b/README.md index 928141b..f83a52c 100644 --- a/README.md +++ b/README.md @@ -1 +1,5 @@ # crafting-interpreters-hs + +Usage: `lox [file]` + +Implemented up to control flow statements (chapter 9). diff --git a/app/Main.hs b/app/Main.hs index 007e933..c35aa2a 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -15,8 +15,20 @@ run source = do Left (SyntaxError s) -> putStrLn s Right statements -> runStatements statements +runEval :: String -> IO () +runEval source = do + let tokensMaybe = scanTokensFromSource source + object <- case tokensMaybe of + Left UnexpectedCharacterError -> putStrLn "Unexpected character" >> return NullObject + Right tokens -> do + let exprMaybe = parseExpression tokens + case exprMaybe of + Left (SyntaxError s) -> putStrLn s >> return NullObject + Right statements -> eval statements + print object + repl :: IO () -repl = putStr ">> " >> hFlush stdout >> getLine >>= run +repl = putStr ">> " >> hFlush stdout >> getLine >>= runEval main :: IO () main = getArgs >>= fs diff --git a/examples/fibonacci.lox b/examples/fibonacci.lox new file mode 100644 index 0000000..aa85ecf --- /dev/null +++ b/examples/fibonacci.lox @@ -0,0 +1,9 @@ +var a = 0; +var temp; + +for (var b = 1; a < 10000; b = temp + b) { + print a; + temp = a; + a = b; +} + diff --git a/examples/scope.lox b/examples/scope.lox new file mode 100644 index 0000000..d563807 --- /dev/null +++ b/examples/scope.lox @@ -0,0 +1,19 @@ +var a = "global a"; +var b = "global b"; +var c = "global c"; +{ + var a = "outer a"; + var b = "outer b"; + { + var a = "inner a"; + print a; + print b; + print c; + } + print a; + print b; + print c; +} +print a; +print b; +print c; diff --git a/src/Lox/Parser.hs b/src/Lox/Parser.hs index ff04174..cc44a96 100644 --- a/src/Lox/Parser.hs +++ b/src/Lox/Parser.hs @@ -1,6 +1,7 @@ module Lox.Parser ( SyntaxError (..), - parse + parse, + parseExpression ) where import Control.Monad @@ -55,6 +56,9 @@ data SyntaxError = SyntaxError String deriving Show parse :: [Token] -> Either SyntaxError [Stmt] parse tokens = evalState program (ParserState {tokens=tokens}) +parseExpression :: [Token] -> Either SyntaxError Expr +parseExpression tokens = evalState expression (ParserState {tokens=tokens}) + program :: State ParserState (Either SyntaxError [Stmt]) program = do atEnd <- isAtEnd