Skip to content

Commit

Permalink
Add Lox.lox support
Browse files Browse the repository at this point in the history
  • Loading branch information
0rphee committed Jan 23, 2025
1 parent 8d3fe66 commit 316dcf8
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 9 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "craftinginterpreters"]
path = craftinginterpreters
url = https://github.com/munificent/craftinginterpreters.git
[submodule "loxlox"]
path = loxlox
url = https://github.com/mrjameshamilton/loxlox.git
14 changes: 7 additions & 7 deletions baseline.csv
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Name,Mean (ps),2*Stdev (ps)
All.interpretStr.lightTests.Str concat and num mult in for loop,36445605,3438826
All.interpretStr.lightTests.inherited_method,43448022,3666036
All.interpretStr.lightTests.assign_to_closure,45684985,4001120
All.interpretStr.lightTests.rec fib(5),39641979,2240544
All.interpretStr.lightTests.nested_closure,42180859,3581092
All.interpretStr.lightTests.inheritance_lambdas,34427716,1301214
All.interpretStr.heavyTests.rec fib(27),329285400000,19244942654
All.interpretStr.lightTests.Str concat and num mult in for loop,58463549,5549662
All.interpretStr.lightTests.inherited_method,72326098,4288052
All.interpretStr.lightTests.assign_to_closure,74239257,6959324
All.interpretStr.lightTests.rec fib(5),66069750,3786356
All.interpretStr.lightTests.nested_closure,68085253,3721392
All.interpretStr.lightTests.inheritance_lambdas,62312573,4899696
All.interpretStr.heavyTests.rec fib(27),543526600000,42208913570
1 change: 1 addition & 0 deletions loxlox
Submodule loxlox added at 7e3185
73 changes: 71 additions & 2 deletions src/Interpreter.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Control.Monad.State.Strict
)
import Control.Monad.State.Strict qualified as State
import Control.Monad.Trans.Except (finallyE)
import Data.ByteString qualified as B
import Data.ByteString.Char8 (ByteString)
import Data.ByteString.Char8 qualified as BS
import Data.Foldable (traverse_)
Expand All @@ -25,12 +26,16 @@ import Data.Maybe (fromMaybe, isJust)
import Data.Time.Clock.POSIX qualified as Time
import Data.Vector (Vector)
import Data.Vector qualified as V
import Data.Word (Word8)
import Environment
import Error qualified
import Expr qualified
import Foreign (Ptr, free, mallocBytes, peek)
import Numeric qualified
import Scanner (whileM)
import Stmt qualified
import System.Exit qualified
import System.IO (Handle, hGetBuf, stderr, stdin)
import TokenType qualified

evaluate :: Expr.Expr2 -> InterpreterM Expr.LiteralValue
Expand Down Expand Up @@ -438,12 +443,76 @@ interpret statements = do
, Expr.fun_closure = GlobalEnvironment globalsRef
, Expr.fun_isInitializer = False
, Expr.fun_call = \_evaluator _args ->
-- realToFrac & fromIntegral treat NominalDiffTime as seconds
Expr.LNumber . realToFrac <$> liftIO Time.getPOSIXTime
liftIO $ readByte stdin
}
)
,
( "utf"
, -- see https://docs.oracle.com/javase/specs/jls/se20/html/jls-5.html#jls-5.1.3 and original java loxlox
Expr.LCallable $
Expr.CFunction $
Expr.LRFunction
{ Expr.fun_toString = "<native fn>"
, Expr.fun_arity = 4
, Expr.fun_closure = GlobalEnvironment globalsRef
, Expr.fun_isInitializer = False
, Expr.fun_call = \_evaluator _args -> do
let bytes =
V.foldr'
(\n acc -> case n of Expr.LNumber d -> round d : acc; _else -> acc)
[]
_args
pure $ Expr.LString $ B.pack bytes
}
)
,
( "exit"
, Expr.LCallable $
Expr.CFunction $
Expr.LRFunction
{ Expr.fun_toString = "<native fn>"
, Expr.fun_arity = 1
, Expr.fun_closure = GlobalEnvironment globalsRef
, Expr.fun_isInitializer = False
, Expr.fun_call = \_evaluator _args ->
let exitCode = case _args `V.unsafeIndex` 0 of
Expr.LNumber n -> floor n
_ -> 70
in liftIO $ System.Exit.exitWith $ System.Exit.ExitFailure exitCode
}
)
,
( "printerr"
, Expr.LCallable $
Expr.CFunction $
Expr.LRFunction
{ Expr.fun_toString = "<native fn>"
, Expr.fun_arity = 1
, Expr.fun_closure = GlobalEnvironment globalsRef
, Expr.fun_isInitializer = False
, Expr.fun_call = \_evaluator _args -> do
errstr <- stringify $ _args `V.unsafeIndex` 0
liftIO $ BS.hPutStrLn stderr errstr
pure Expr.LNil
}
)
]

-- for loxlox: https://github.com/mrjameshamilton/loxlox/tree/main/bin
-- see https://docs.oracle.com/en/java/javase/20/docs/api/java.base/java/io/InputStream.html#read()
readByte :: Handle -> IO Expr.LiteralValue
readByte handle = do
buffer :: Ptr Word8 <- mallocBytes 1
actReadBytes <- hGetBuf handle buffer 1
res <-
if actReadBytes == 0
then pure Expr.LNil
else do
byte <- peek buffer
pure $ Expr.LNumber $ fromIntegral byte
free buffer
pure res

executeStmts :: Vector Stmt.Stmt2 -> InterpreterM ()
executeStmts = traverse_ execute

Expand Down

0 comments on commit 316dcf8

Please sign in to comment.