Ganymede (empty) → 0.0.0.1
raw patch · 4 files changed
+294/−0 lines, 4 filesdep +basedep +containersdep +directorysetup-changed
Dependencies added: base, containers, directory, filepath, mtl, parsec, transformers
Files
- Ganymede.cabal +64/−0
- Ganymede.hs +198/−0
- LICENSE +30/−0
- Setup.hs +2/−0
+ Ganymede.cabal view
@@ -0,0 +1,64 @@+-- Ganymede.cabal auto-generated by cabal init. For additional +-- options, see +-- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr. +-- The name of the package. +Name: Ganymede + +-- The package version. See the Haskell package versioning policy +-- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for +-- standards guiding when and how versions should be incremented. +Version: 0.0.0.1 + +-- A short (one-line) description of the package. +Synopsis: An Io interpreter in Haskell. + +-- A longer description of the package. +Description: Ganymede is an Io interpreter, originally based on Martin "\"vague\"" Sandin's + Amalthea, which is an Io interpreter written in OCaml. There are some + differences since Amalthea is based on the description of Io found in Raphael + Finkel's 1996 book "Advanced Programming Language Design" (APLD), whereas + Ganymede is more faithful to Raph Levien's original 1989 paper. + +-- The license under which the package is released. +License: BSD3 + +-- The file containing the license text. +License-file: LICENSE + +-- The package author(s). +Author: Walt Rorie-Baety + +-- An email address to which users can send suggestions, bug reports, +-- and patches. +Maintainer: black.meph@gmail.com + +-- A copyright notice. +-- Copyright: + +Category: Language + +Build-type: Simple + +-- Extra files to be distributed with the package, such as examples or +-- a README. +-- Extra-source-files: AmalObs.txt + +-- Constraint on the version of Cabal needed to build this package. +Cabal-version: >=1.6 + + +Executable ganymede + -- .hs or .lhs file containing the Main module. + Main-is: Ganymede.hs + + -- Packages needed in order to build this package. + Build-depends: base >= 3 && < 5, containers, directory, filepath, mtl, + parsec ==3.*, transformers ==0.2.* + + -- Modules not exported by this package. + -- Other-modules: + + -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source. + -- Build-tools: + ghc-options: -Wall -optl-Wl + ghc-prof-options: -prof -auto-all
+ Ganymede.hs view
@@ -0,0 +1,198 @@+{------------------------------------------------------------ +(************************************************************ + Ganymede: the main Io interpreter module + Based on: + Amalthea, amalthea.ml + Martin Sandin (d97masa@dtek.chalmers.se) + Translated to Haskell in 2011 by Walt "BMeph" Rorie-Baety + (black.meph@gmail.com) + ************************************************************) +-------------------------------------------------------------} + +module Main where + + +import Io.Modules as Module (catch_module_errors, loadAST, load_world_of_ast) +import Io.Interpreter as Interp (catch_interpreter_errors, interpret_expr_in_env) +import Io.Pretty as Pretty (prettyPrint) +import Io.Types +import Io.Util (freshPos, ref) + +import Prelude hiding (catch) +import Control.Exception (Handler(..), catch, catches, throw) +import Control.Monad (when) +import Data.List (foldl') +import Data.Maybe (fromMaybe, fromJust, listToMaybe) +import System.Console.GetOpt +import System.Environment (getArgs) +import System.Exit (ExitCode(ExitSuccess), exitSuccess) +import System.FilePath (FilePath) +import System.IO (hFlush, stdout) +import System.IO.Error as Error (annotateIOError) + +-- Informative program values: +version = "0.0.0.1" + +usage_msg = + "Usage: ganymede [options] <sourcefile>\n\ + \Runs the Io source file.\n\ + \Options are:" + +data Options = Options + { inputOpt :: Maybe FilePath + , ppOpt :: Bool + , showOpts :: Bool + , versionOpt :: Bool + , traceOpt :: Bool + , pLoadOpt :: IoImports + , varSuptOpt :: Bool + } deriving (Show) + +ganyOpts = Options + { inputOpt = Nothing + , ppOpt = False + , showOpts = False + , versionOpt = False + , traceOpt = False + , pLoadOpt = [("prelude", Nothing)] + , varSuptOpt = False + } + +-- (* Argument handling *) +speclist :: [OptDescr (Options -> IO Options)] +speclist = + [ Option ['h','?'] ["help"] + (NoArg (\_ -> putStrLn (usageInfo usage_msg speclist) + >> exitSuccess)) + " Show this help text" + , Option ['d','t'] ["debug","trace"] + (NoArg (\ opts -> return$ opts { traceOpt = True })) + " print execution trace" + , Option ['V'] ["version"] + (NoArg (\_ -> putStrLn ("Ganymede, version "++ version) + >> exitSuccess)) + " print the Ganymede version number" + , Option ['c'] ["clean","noprelude"] + (NoArg (\opts -> return$ opts { pLoadOpt = [] })) + " prevent the prelude from being loaded" + , Option ['P'] ["Prelude"] + (OptArg ((\f opts -> return$ opts { pLoadOpt = [(f, Nothing)] }) . fromMaybe "prelude") "FILE") + " load FILE as prelude" + , Option ['p'] ["pretty"] + (NoArg (\opts -> return$ opts { ppOpt = True })) + " pretty-print the source file" + , Option ['m'] ["mutable","vars"] + (NoArg (\ opts -> return$ opts { varSuptOpt = True })) + " enable mutable module variables (unpure)" + ] +{- [Option ['c'] ["noprelude"], Arg.Unit (fun _ -> Io_module.default_imports := []), " prevent the prelude from being loaded", + Option ['r'] ["prelude"], Arg.String (fun n -> Io_module.default_imports := [(n,None)]), " load module <name> as prelude", + Option ['p'] ["pretty"], Arg.Set pretty_flag, " pretty print the source file", + Option ['d'] ["trace"], Arg.Set Io_interpreter.trace_flag", + Option ['m'] ["vars"], Arg.Set Io_env.variable_flag, " enable mutable module variables (unpure)", + Option ['V','?'] ["version"], Arg.Set version_flag, " print the Ganymede version number"] + -} + +ganyRunErr :: String -> IO a +ganyRunErr errs = ioError (userError (errs ++ usageInfo usage_msg speclist)) + +getOpts :: [String] -> IO (Options, [String]) +getOpts args = + case getOpt Permute speclist args of + (o,n, [] ) -> do { + opts <- foldl' (>>=) (return ganyOpts) $ + (\opts -> return$ opts { inputOpt = listToMaybe n }) : o; + if null n + then ganyRunErr "missing argument <sourcefile>\n" + else return (opts, drop 1 n) } + (_,_,errs) -> ganyRunErr (concat errs) + +{- --Loads dependent modules and interprets the program -} +build_n_run :: (String, IoAST) -> (Bool, Bool) -> IO () +build_n_run p@(_, (_, _, _, ex)) (varStatus, traceStatus) = do { + (_,env,_) <- Module.catch_module_errors -- Modules + (Module.load_world_of_ast traceStatus) p ; + Interp.catch_interpreter_errors -- Interp + Interp.interpret_expr_in_env (env, ex, (varStatus, traceStatus)) } +{--} + +main = do + (opts,_) <- getOpts =<< getArgs + let filename = fromJust (inputOpt opts) + ast <- Module.catch_module_errors Module.loadAST filename + if ppOpt opts + then putStrLn $ Pretty.prettyPrint ast "\n" + else (do + build_n_run (filename, ast) (varSuptOpt opts, traceOpt opts) + hFlush stdout + `catches` [ Handler (\(IoError error) -> ioError (userError error)) + -- if all else fails... + , Handler + (\e -> ioError (Error.annotateIOError e "Ganymede: " Nothing Nothing))]) +{- +(************************************************************ + Amalthea main + Amalthea, amalthea.ml + Martin Sandin (d97masa@dtek.chalmers.se) + ************************************************************) +-- +open Io_types + +(* The version of Amalthea *) +let amalthea_version = 0.875 + + +(* Flags *) +let filename = ref "" +let pretty_flag = ref false +let version_flag = ref false + +(* Argument handling *) +let usage_msg = + "Usage: amalthea [options] <sourcefile>\n\ + Runs the Io source file.\n\ + Options are:" +let speclist = + [("-noprelude", Arg.Unit (fun _ -> Io_module.default_imports := []), " prevent the prelude from being loaded"); + ("-prelude <name>", Arg.String (fun n -> Io_module.default_imports := [(n,None)]), " load a different module as prelude"); + ("-pretty", Arg.Set pretty_flag, " pretty print the source file"); + ("-trace", Arg.Set Io_interpreter.trace_flag, " print execution trace"); + ("-vars", Arg.Set Io_env.variable_flag, " enable mutable module variables (unpure)"); + ("-version", Arg.Set version_flag, " print the Amalthea version number")] + + +(* Loads dependant modules and interprets the program *) +let build_n_run : string * io_ast -> unit += function (_, (_, _, _, ex)) as p -> + let world = Io_module.catch_module_errors + Io_module.load_world_of_ast p in + Io_interpreter.catch_interpreter_errors + Io_interpreter.interpret_expr_in_world (world, ex) + + +(* And the program starts here *) +let _ = + Arg.parse speclist (fun f -> filename := f) usage_msg; + if !version_flag then + print_string ("Amalthea version " ^ string_of_float amalthea_version + ^ "") + else + if !filename = "" then + (print_endline "Amalthea: missing argument sourcefile"; + Arg.usage speclist usage_msg) + else + try + let ast = Io_module.catch_module_errors Io_module.load_ast !filename in + if !pretty_flag then + print_string (Io_pretty.pretty_print ast) + else + build_n_run (!filename, ast); + flush stdout + with + | Sys_error error -> print_endline ("Amalthea: " ^ error) + | Io_error error -> print_endline error + -} + + + +
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c)2011, Walt Rorie-Baety + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of Walt Rorie-Baety nor the names of other + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple +main = defaultMain