packages feed

husk-scheme 1.0 → 1.1

raw patch · 6 files changed

+46/−54 lines, 6 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

README.markdown view
@@ -22,35 +22,6 @@ - Hash tables, as specified by [SRFI 69](http://srfi.schemers.org/srfi-69/srfi-69.html) - Hygenic Macros: High-level macros via define-syntax - *Note this is still a heavy work in progress* and while it works well enough that many derived forms are implemented in our standard library, you may still run into problems when defining your own macros. -Roadmap----------Features planned for development:--- A scheme "library" that may be used to embed scheme scripting within a Haskell program. This will necessitate extracting the repl code from Core.hs and relocating it to its own file.--  See: http://book.realworldhaskell.org/read/writing-a-library-working-with-json-data.html--- Documentation, including a description of Scheme / Haskell, API docs (?), etc-- Release as a cabal package - see: http://www.haskell.org/haskellwiki/How_to_write_a_Haskell_program-- Continuations-- Implementation of approved SRFI's--TODO Items:--- Better error reporting. For example:-  * huski crashes when macro transformation not enclosed in ()-  * What's up with this error message:-    huski> (define vec)-    Getting an unbound variable: define-- huski crashes if the first line of a scheme file is blank-- Correct parsing of comments, including allowing them in the middle of a form (eg: (cond))-- Test cases, including those for: backtick, primitives (see spec section 4.1), others-- More example programs, perhaps derive some from SICP and http://www.scheme.dk/planet/-- General refactoring of haskell code including addressing of TODO items, etc...-- Compare our features to R5RS spec: <http://practical-scheme.net/wiliki/schemexref.cgi?R5RS> and <http://en.wikipedia.org/wiki/Scheme_(programming_language)>-- At some point, need to enter bugs for this sort of thing...- husk scheme is available under the [MIT license](http://www.opensource.org/licenses/mit-license.php).  Usage
hs-src/Scheme/Core.hs view
@@ -88,27 +88,51 @@ eval env val@(HashTable _) = return val eval env (Atom id) = getVar env id eval env (List [Atom "quote", val]) = return val-eval env (List [Atom "quasiquote", val]) = do-  case val of-    List [Atom "unquote", val] -> eval env val -- Handle cases like `,(+ 1 2) -    List [Atom "unquote-splicing", val] -> eval env val -- TODO: not quite right behavior -    List (x : xs) -> mapM (doUnQuote env) (x:xs) >>= return . List -- TODO: understand *why* this works -    otherwise -> doUnQuote env val +eval env (List [Atom "quasiquote", val]) = doUnQuote env val    where doUnQuote :: Env -> LispVal -> IOThrowsError LispVal         doUnQuote env val = do           case val of             List [Atom "unquote", val] -> eval env val-            List [Atom "unquote-splicing", val] -> eval env val -- TODO: not quite right behavior-            otherwise -> eval env (List [Atom "quote", val]) -- TODO: could this be simplified?+            List (x : xs) -> unquoteListM env (x:xs) >>= return . List+            DottedList xs x -> do+              rxs <- unquoteListM env xs >>= return +              rx <- doUnQuote env x+              case rx of+                List [] -> return $ List rxs+                List rxlst -> return $ List $ rxs ++ rxlst +                DottedList rxlst rxlast -> return $ DottedList (rxs ++ rxlst) rxlast+                otherwise -> return $ DottedList rxs rx+            Vector vec -> do+              let len = length (elems vec)+              vList <- unquoteListM env $ elems vec >>= return+              return $ Vector $ listArray (0, len) vList+            otherwise -> eval env (List [Atom "quote", val]) -- Behave like quote if there is nothing to "unquote"... +        unquoteListM env lst = foldlM (unquoteListFld env) ([]) lst+        unquoteListFld env (acc) val = do+            case val of+                List [Atom "unquote-splicing", val] -> do+                    value <- eval env val+                    case value of+                        List v -> return $ (acc ++ v)+                        -- Question: In which cases should I generate a type error if value is not a list?+                        --+                        -- csi reports an error for this: `(1 ,@(+ 1 2) 4)+                        -- but allows cases such as: `,@2+                        -- For now we just throw an error - perhaps more strict than we need to be, but at+                        -- least we will not allow anything invalid to be returned.+                        --+                        -- Old code that we might build on if this changes down the road: otherwise -> return $ (acc ++ [v])+                        otherwise -> throwError $ TypeMismatch "proper list" value +                otherwise -> do result <- doUnQuote env val+                                return $ (acc ++ [result])+ eval env (List [Atom "if", pred, conseq, alt]) =     do result <- eval env pred        case result of          Bool False -> eval env alt          otherwise -> eval env conseq-         {- ex #1: only allow boolean conditions: otherwise -> throwError $ TypeMismatch "bool" otherwise-} --- TODO: implement this 'if' form, such that it returns nothing if the pred evaluates to false eval env (List [Atom "if", pred, conseq]) =      do result <- eval env pred        case result of@@ -166,16 +190,6 @@ eval env (List (Atom "lambda" : varargs@(Atom _) : body)) =    makeVarargs varargs env [] body -{- TODO: for proper tail calls (above):- -- - consider comments from http://www.sidhe.org/~dan/blog/archives/000211.html- - in particular:- -  - how a compiler can deal with tail recursion- -  - And if you have a continuation passing style of calling functions, it turns out to be essentially free, which is really cool, though the topic of another WTHI entry- -   perhaps: http://www.sidhe.org/~dan/blog/archives/000213.html- -   - - -}- eval env (List [Atom "string-fill!", Atom var, character]) = do    str <- eval env =<< getVar env var   chr <- eval env character@@ -237,8 +251,6 @@     otherwise -> throwError $ TypeMismatch "hash-table" otherwise  -- TODO:---  hash-table-update!---  hash-table-update!/default --  hash-table-merge!  eval env (List (function : args)) = do
hs-src/Scheme/Macro.hs view
@@ -90,7 +90,7 @@ -- Determine if the next element in a list matches 0-to-n times due to an ellipsis macroElementMatchesMany :: LispVal -> Bool macroElementMatchesMany (List (p:ps)) = do-  if length ps > 0+  if not (null ps)      then case (head ps) of                 Atom "..." -> True                 otherwise -> False
hs-src/shell.hs view
@@ -47,7 +47,7 @@ showBanner = do   putStrLn " __  __     __  __     ______     __  __                             "   putStrLn "/\\ \\_\\ \\   /\\ \\/\\ \\   /\\  ___\\   /\\ \\/ /     Scheme Interpreter " -  putStrLn "\\ \\  __ \\  \\ \\ \\_\\ \\  \\ \\___  \\  \\ \\  _\\\"-.  Version 1.0"+  putStrLn "\\ \\  __ \\  \\ \\ \\_\\ \\  \\ \\___  \\  \\ \\  _\\\"-.  Version 1.1"   putStrLn " \\ \\_\\ \\_\\  \\ \\_____\\  \\/\\_____\\  \\ \\_\\ \\_\\  (c) 2010 Justin Ethier "   putStrLn "  \\/_/\\/_/   \\/_____/   \\/_____/   \\/_/\\/_/  github.com/justinethier/husk-scheme "   putStrLn ""
husk-scheme.cabal view
@@ -1,5 +1,5 @@ Name:                husk-scheme-Version:             1.0+Version:             1.1 Synopsis:            R5RS Scheme interpreter program and library. Description:         Husk is a dialect of Scheme written in Haskell that implements                       a subset of the R5RS standard. Husk is not intended to be a 
stdlib.scm view
@@ -222,11 +222,20 @@                          (set! result-ready? #t)                          result)))))))) ++; Hash table derived forms (define hash-table-walk   (lambda (ht proc)     (map        (lambda (kv) (proc (car kv) (cdr kv)))       (hash-table->alist ht)))) ++(define (hash-table-update! hash-table key function)+  (hash-table-set! hash-table key+                  (function (hash-table-ref hash-table key thunk))))++;(define (hash-table-update!/default hash-table key function default)+;  (hash-table-update! hash-table key function (lambda () default)))  ; TODO: hash-table-fold