on master help sign in
Merge branch 'stable' into canonicalize
e99d840Evan Czaplicki
.gitignore+1−3
@@ -13,7 +13,5 @@ data
13build
13build
14cache
14cache
15*~
15*~
16−tests/elm/build/
17−tests/elm/cache/
18−tests/elm/exe.js
16+exe.js
19node_modules/
17node_modules/
.travis.yml+31−3
@@ -1,3 +1,31 @@
1+# Based on https://github.com/hvr/multi-ghc-travis and https://github.com/ekmett/lens/blob/master/.travis.yml
2+
1−language: haskell
3+# NB: don't set `language: haskell` here
2−ghc:
4+
3− - 7.6
5+# The following enables several GHC versions to be tested; often it's enough to test only against the last release in a major GHC version. Feel free to omit lines listings versions you don't need/want testing for.
6+env:
7+ - GHCVER=7.6.3
8+ - GHCVER=7.8.2
9+
10+# Note: the distinction between `before_install` and `install` is not important.
11+before_install:
12+ - travis_retry sudo add-apt-repository -y ppa:hvr/ghc
13+ - travis_retry sudo apt-get update
14+ - travis_retry sudo apt-get install cabal-install-1.18 ghc-$GHCVER happy alex # see note about happy/alex
15+ - export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/1.18/bin:$PATH
16+ - cabal update
17+ # Update happy when building with GHC 7.8 or head
18+ - |
19+ if [ $GHCVER = "head" ] || [ $GHCVER = "7.8.2" ]; then
20+ cabal install happy alex
21+ export PATH=$HOME/.cabal/bin:$PATH
22+ fi
23+
24+install:
25+ - cabal install --only-dependencies --enable-tests --enable-benchmarks
26+
27+# Here starts the actual work to be performed for the package under test; any command which exits with a non-zero exit code causes the build to fail.
28+script:
29+ - cabal configure --enable-tests
30+ - cabal build
31+ - cabal test
Elm.cabal+17−9
@@ -1,5 +1,5 @@
1Name: Elm
1Name: Elm
2−Version: 0.12.1
2+Version: 0.12.2
3Synopsis: The Elm language module.
3Synopsis: The Elm language module.
4Description: Elm aims to make client-side web-development more pleasant.
4Description: Elm aims to make client-side web-development more pleasant.
5 It is a statically/strongly typed, functional reactive
5 It is a statically/strongly typed, functional reactive
@@ -113,10 +113,12 @@ Library
113 pandoc >= 1.10,
113 pandoc >= 1.10,
114 parsec >= 3.1.1,
114 parsec >= 3.1.1,
115 pretty,
115 pretty,
116+ scientific,
116 text,
117 text,
117 transformers >= 0.2,
118 transformers >= 0.2,
118 union-find,
119 union-find,
119− unordered-containers
120+ unordered-containers,
121+ yaml
120
122
121Executable elm
123Executable elm
122 Main-is: Compiler.hs
124 Main-is: Compiler.hs
@@ -197,11 +199,13 @@ Executable elm
197 mtl >= 2,
199 mtl >= 2,
198 pandoc >= 1.10,
200 pandoc >= 1.10,
199 parsec >= 3.1.1,
201 parsec >= 3.1.1,
202+ scientific,
200 pretty,
203 pretty,
201 text,
204 text,
202 transformers >= 0.2,
205 transformers >= 0.2,
203 union-find,
206 union-find,
204− unordered-containers
207+ unordered-containers,
208+ yaml
205
209
206Executable elm-doc
210Executable elm-doc
207 Main-is: Docs.hs
211 Main-is: Docs.hs
@@ -240,12 +244,14 @@ Executable elm-doc
240 pandoc >= 1.10,
244 pandoc >= 1.10,
241 parsec >= 3.1.1,
245 parsec >= 3.1.1,
242 pretty,
246 pretty,
247+ scientific,
243 text,
248 text,
244− union-find
249+ union-find,
250+ yaml
245
251
246Test-Suite compiler-tests
252Test-Suite compiler-tests
247 Type: exitcode-stdio-1.0
253 Type: exitcode-stdio-1.0
248− Hs-Source-Dirs: tests/hs, compiler
254+ Hs-Source-Dirs: tests/compiler, compiler
249 Main-is: CompilerTest.hs
255 Main-is: CompilerTest.hs
250 other-modules: Tests.Compiler
256 other-modules: Tests.Compiler
251 Tests.Property
257 Tests.Property
@@ -278,15 +284,17 @@ Test-Suite compiler-tests
278 pandoc >= 1.10,
284 pandoc >= 1.10,
279 parsec >= 3.1.1,
285 parsec >= 3.1.1,
280 pretty,
286 pretty,
287+ scientific,
281 text,
288 text,
282 transformers >= 0.2,
289 transformers >= 0.2,
283 union-find,
290 union-find,
284− unordered-containers
291+ unordered-containers,
292+ yaml
285
293
286−Test-Suite lib-tests
294+Test-Suite library-tests
287 Type: exitcode-stdio-1.0
295 Type: exitcode-stdio-1.0
288− Hs-Source-Dirs: tests/hs
296+ Hs-Source-Dirs: tests/libraries
289− Main-is: LibTest.hs
297+ Main-is: LibraryTest.hs
290 build-depends: base,
298 build-depends: base,
291 directory,
299 directory,
292 Elm,
300 Elm,
compiler/AST/Literal.hs+4−4
@@ -29,10 +29,10 @@ glTipeName glTipe =
29 case glTipe of
29 case glTipe of
30 Int -> "Int"
30 Int -> "Int"
31 Float -> "Float"
31 Float -> "Float"
32− V2 -> "MJS.V2"
32+ V2 -> "Math.Vector2.Vec2"
33− V3 -> "MJS.V3"
33+ V3 -> "Math.Vector3.Vec3"
34− V4 -> "MJS.V4"
34+ V4 -> "Math.Vector4.Vec4"
35− M4 -> "MJS.M4x4"
35+ M4 -> "Math.Matrix4.Mat4"
36 Texture -> "Graphics.WebGL.Texture"
36 Texture -> "Graphics.WebGL.Texture"
37
37
38data GLShaderTipe = GLShaderTipe
38data GLShaderTipe = GLShaderTipe
compiler/Build/Dependencies.hs+67−42
@@ -1,55 +1,57 @@
1{-# OPTIONS_GHC -W #-}
1{-# OPTIONS_GHC -W #-}
2−module Build.Dependencies (getSortedDependencies, readDeps) where
2+module Build.Dependencies (Recipe(..), getBuildRecipe, readDeps) where
3
3
4−import Control.Applicative
5import Control.Monad.Error
4import Control.Monad.Error
6import qualified Control.Monad.State as State
5import qualified Control.Monad.State as State
7−import qualified Data.Aeson as Json
8−import qualified Data.ByteString.Lazy.Char8 as BSC
9import qualified Data.Graph as Graph
6import qualified Data.Graph as Graph
10import qualified Data.List as List
7import qualified Data.List as List
11import qualified Data.Map as Map
8import qualified Data.Map as Map
12−import qualified Data.Maybe as Maybe
13import qualified Data.Set as Set
9import qualified Data.Set as Set
14import System.Directory
10import System.Directory
15import System.FilePath as FP
11import System.FilePath as FP
16
12
17−import Build.Print (failure)
18−
19import qualified AST.Module as Module
13import qualified AST.Module as Module
20import qualified Parse.Parse as Parse
14import qualified Parse.Parse as Parse
21import qualified Elm.Internal.Paths as Path
15import qualified Elm.Internal.Paths as Path
22import qualified Elm.Internal.Name as N
16import qualified Elm.Internal.Name as N
17+import qualified Elm.Internal.Version as V
23import qualified Elm.Internal.Dependencies as Deps
18import qualified Elm.Internal.Dependencies as Deps
24
19
20+data Recipe = Recipe
21+ { _elmFiles :: [FilePath]
22+ , _jsFiles :: [FilePath]
23+ }
24+
25−getSortedDependencies :: [FilePath] -> Module.Interfaces -> FilePath -> IO [String]
25+getBuildRecipe :: [FilePath] -> Module.Interfaces -> FilePath -> ErrorT String IO Recipe
26−getSortedDependencies srcDirs builtIns root =
26+getBuildRecipe srcDirs builtIns root =
27− do extras <- extraDependencies
27+ do directories <- getDependencies
28+ jsFiles <- nativeFiles ("." : directories)
28− let allSrcDirs = srcDirs ++ Maybe.fromMaybe [] extras
29+ let allSrcDirs = srcDirs ++ directories
29− result <- runErrorT $ readAllDeps allSrcDirs builtIns root
30+ nodes <- collectDependencies allSrcDirs builtIns root
30− case result of
31+ elmFiles <- sortElmFiles nodes
31− Right deps -> sortDeps deps
32+ return (Recipe elmFiles jsFiles)
32− Left err -> failure err
33+
33−
34+-- | Based on the projects elm_dependencies.json, find all of the paths and
34−extraDependencies :: IO (Maybe [FilePath])
35+-- dependency information we might need.
35−extraDependencies =
36+getDependencies :: ErrorT String IO [FilePath]
37+getDependencies =
36− do exists <- doesFileExist Path.dependencyFile
38+ do exists <- liftIO $ doesFileExist Path.dependencyFile
37− if not exists then return Nothing else Just <$> getPaths
39+ if not exists then return [] else getPaths
38 where
40 where
39− getPaths = do
41+ getPaths :: ErrorT String IO [FilePath]
40− raw <- BSC.readFile Path.dependencyFile
42+ getPaths =
41− case Json.eitherDecode raw of
43+ Deps.withDeps Path.dependencyFile $ \deps ->
42− Right (Deps.Mini deps) -> mapM validate deps
44+ mapM getPath (Deps.dependencies deps)
43− Left err ->
45+
44− failure $ "Error reading the " ++ Path.dependencyFile ++ " file:\n" ++ err
46+ getPath :: (N.Name, V.Version) -> ErrorT String IO FilePath
45−
46− validate (name,version) = do
47+ getPath (name,version) = do
47− let path = Path.dependencyDirectory </> toPath name version
48+ let path = Path.dependencyDirectory </> N.toFilePath name </> show version
48− exists <- doesDirectoryExist path
49+ exists <- liftIO $ doesDirectoryExist path
50+ if exists
51+ then return path
49− if exists then return path else failure (notFound name version)
52+ else throwError (notFound name version)
50−
53+
51− toPath name version = N.toFilePath name </> show version
54+ notFound :: N.Name -> V.Version -> String
52−
53 notFound name version =
55 notFound name version =
54 unlines
56 unlines
55 [ "Your " ++ Path.dependencyFile ++ " file says you depend on library"
57 [ "Your " ++ Path.dependencyFile ++ " file says you depend on library"
@@ -58,27 +60,50 @@ extraDependencies =
58 , ""
60 , ""
59 , " elm-get install " ++ show name ++ " " ++ show version ]
61 , " elm-get install " ++ show name ++ " " ++ show version ]
60
62
63+nativeFiles :: [FilePath] -> ErrorT String IO [FilePath]
64+nativeFiles directories =
65+ do exists <- liftIO $ doesFileExist Path.dependencyFile
66+ if not exists
67+ then return []
68+ else concat `fmap` mapM getNativeFiles directories
69+ where
70+ getNativeFiles dir =
71+ Deps.withDeps (dir </> Path.dependencyFile) $ \deps ->
72+ return (map (toPath dir) (Deps.native deps))
73+
74+ toPath dir moduleName =
75+ dir </> joinPath (split moduleName) <.> "js"
76+
77+split :: String -> [String]
78+split moduleName = go [] moduleName
79+ where
80+ go paths str =
81+ case break (=='.') str of
82+ (path, _:rest) -> go (paths ++ [path]) rest
83+ (path, []) -> paths ++ [path]
84+
61−type Deps = (FilePath, String, [String])
85+type DependencyNode = (FilePath, String, [String])
62
86
63−sortDeps :: [Deps] -> IO [String]
87+sortElmFiles :: [DependencyNode] -> ErrorT String IO [FilePath]
64−sortDeps depends =
88+sortElmFiles depends =
65 if null mistakes
89 if null mistakes
66 then return (concat sccs)
90 then return (concat sccs)
67− else failure $ msg ++ unlines (map show mistakes)
91+ else throwError $ msg ++ unlines (map show mistakes)
68 where
92 where
69 sccs = map Graph.flattenSCC $ Graph.stronglyConnComp depends
93 sccs = map Graph.flattenSCC $ Graph.stronglyConnComp depends
70
94
71 mistakes = filter (\scc -> length scc > 1) sccs
95 mistakes = filter (\scc -> length scc > 1) sccs
72 msg = "A cyclical module dependency or was detected in:\n"
96 msg = "A cyclical module dependency or was detected in:\n"
73
97
74−readAllDeps :: [FilePath] -> Module.Interfaces -> FilePath -> ErrorT String IO [Deps]
98+collectDependencies :: [FilePath] -> Module.Interfaces -> FilePath
99+ -> ErrorT String IO [DependencyNode]
75−readAllDeps srcDirs rawBuiltIns filePath =
100+collectDependencies srcDirs rawBuiltIns filePath =
76 State.evalStateT (go Nothing filePath) Set.empty
101 State.evalStateT (go Nothing filePath) Set.empty
77 where
102 where
78 builtIns :: Set.Set String
103 builtIns :: Set.Set String
79 builtIns = Set.fromList $ Map.keys rawBuiltIns
104 builtIns = Set.fromList $ Map.keys rawBuiltIns
80
105
81− go :: Maybe String -> FilePath -> State.StateT (Set.Set String) (ErrorT String IO) [Deps]
106+ go :: Maybe String -> FilePath -> State.StateT (Set.Set String) (ErrorT String IO) [DependencyNode]
82 go parentModuleName filePath = do
107 go parentModuleName filePath = do
83 filePath' <- lift $ findSrcFile parentModuleName srcDirs filePath
108 filePath' <- lift $ findSrcFile parentModuleName srcDirs filePath
84 (moduleName, deps) <- lift $ readDeps filePath'
109 (moduleName, deps) <- lift $ readDeps filePath'
@@ -93,9 +118,9 @@ readDeps :: FilePath -> ErrorT String IO (String, [String])
93readDeps path = do
118readDeps path = do
94 txt <- lift $ readFile path
119 txt <- lift $ readFile path
95 case Parse.dependencies txt of
120 case Parse.dependencies txt of
121+ Right o -> return o
96 Left err -> throwError $ msg ++ show err
122 Left err -> throwError $ msg ++ show err
97 where msg = "Error resolving dependencies in " ++ path ++ ":\n"
123 where msg = "Error resolving dependencies in " ++ path ++ ":\n"
98− Right o -> return o
99
124
100findSrcFile :: Maybe String -> [FilePath] -> FilePath -> ErrorT String IO FilePath
125findSrcFile :: Maybe String -> [FilePath] -> FilePath -> ErrorT String IO FilePath
101findSrcFile parentModuleName dirs path =
126findSrcFile parentModuleName dirs path =
compiler/Build/Flags.hs+7−4
@@ -7,7 +7,8 @@ import System.Console.CmdArgs
7data Flags = Flags
7data Flags = Flags
8 { make :: Bool
8 { make :: Bool
9 , files :: [FilePath]
9 , files :: [FilePath]
10− , runtime :: Maybe FilePath
10+ , set_runtime :: Maybe FilePath
11+ , get_runtime :: Bool
11 , only_js :: Bool
12 , only_js :: Bool
12 , print_types :: Bool
13 , print_types :: Bool
13 , scripts :: [FilePath]
14 , scripts :: [FilePath]
@@ -28,8 +29,10 @@ flags = Flags
28 &= help "Do not import Prelude by default, used only when compiling standard libraries."
29 &= help "Do not import Prelude by default, used only when compiling standard libraries."
29 , scripts = [] &= typFile
30 , scripts = [] &= typFile
30 &= help "Load JavaScript files in generated HTML. Files will be included in the given order."
31 &= help "Load JavaScript files in generated HTML. Files will be included in the given order."
31− , runtime = Nothing &= typFile
32+ , set_runtime = Nothing &= typFile
32− &= help "Specify a custom location for Elm's runtime system."
33+ &= help "Specify a custom location for Elm's runtime system."
34+ , get_runtime = False
35+ &= help "Print the absolute path to the default Elm runtime."
33 , cache_dir = "cache" &= typFile
36 , cache_dir = "cache" &= typFile
34 &= help "Directory for files cached to make builds faster. Defaults to cache/ directory."
37 &= help "Directory for files cached to make builds faster. Defaults to cache/ directory."
35 , build_dir = "build" &= typFile
38 , build_dir = "build" &= typFile
@@ -37,7 +40,7 @@ flags = Flags
37 , src_dir = ["."] &= typFile
40 , src_dir = ["."] &= typFile
38 &= help "Additional source directories besides project root. Searched when using --make"
41 &= help "Additional source directories besides project root. Searched when using --make"
39 , print_types = False
42 , print_types = False
40− &= help "Print out infered types of top-level definitions."
43+ &= help "Print out inferred types of top-level definitions."
41 } &= help "Compile Elm programs to HTML, CSS, and JavaScript."
44 } &= help "Compile Elm programs to HTML, CSS, and JavaScript."
42 &= helpArg [explicit, name "help", name "h"]
45 &= helpArg [explicit, name "help", name "h"]
43 &= versionArg [explicit, name "version", name "v", summary (show Version.elmVersion)]
46 &= versionArg [explicit, name "version", name "v", summary (show Version.elmVersion)]
compiler/Build/Utils.hs+9
@@ -1,10 +1,12 @@
1{-# OPTIONS_GHC -W #-}
1{-# OPTIONS_GHC -W #-}
2module Build.Utils where
2module Build.Utils where
3
3
4+import Control.Monad.Error
4import System.Directory (doesFileExist)
5import System.Directory (doesFileExist)
5import System.Environment (getEnv)
6import System.Environment (getEnv)
6import System.FilePath ((</>), replaceExtension)
7import System.FilePath ((</>), replaceExtension)
7import qualified Build.Flags as Flag
8import qualified Build.Flags as Flag
9+import qualified Build.Print as Print
8import qualified Paths_Elm as This
10import qualified Paths_Elm as This
9
11
10buildPath :: Flag.Flags -> FilePath -> String -> FilePath
12buildPath :: Flag.Flags -> FilePath -> String -> FilePath
@@ -33,3 +35,10 @@ getDataFile name = do
33 else do
35 else do
34 env <- getEnv "ELM_HOME"
36 env <- getEnv "ELM_HOME"
35 return (env </> name)
37 return (env </> name)
38+
39+run :: ErrorT String IO a -> IO a
40+run command = do
41+ either <- runErrorT command
42+ case either of
43+ Left err -> Print.failure err
44+ Right result -> return result
compiler/Compiler.hs+16−10
@@ -1,16 +1,17 @@
1{-# OPTIONS_GHC -W #-}
1{-# OPTIONS_GHC -W #-}
2module Main where
2module Main where
3
3
4−import Control.Monad (foldM)
4+import Control.Monad (foldM, when)
5import qualified Data.Maybe as Maybe
5import qualified Data.Maybe as Maybe
6import Text.Blaze.Html.Renderer.String (renderHtml)
6import Text.Blaze.Html.Renderer.String (renderHtml)
7import qualified Data.ByteString.Lazy.Char8 as BS
7import qualified Data.ByteString.Lazy.Char8 as BS
8import qualified System.Console.CmdArgs as CmdArgs
8import qualified System.Console.CmdArgs as CmdArgs
9import System.Directory
9import System.Directory
10+import System.Exit (exitSuccess)
10import System.FilePath
11import System.FilePath
11import GHC.Conc
12import GHC.Conc
12
13
13−import Build.Dependencies (getSortedDependencies)
14+import Build.Dependencies (getBuildRecipe, Recipe(..))
14import qualified Generate.Html as Html
15import qualified Generate.Html as Html
15import qualified Metadata.Prelude as Prelude
16import qualified Metadata.Prelude as Prelude
16import qualified Build.Utils as Utils
17import qualified Build.Utils as Utils
@@ -24,7 +25,10 @@ main = do setNumCapabilities =<< getNumProcessors
24
25
25compileArgs :: Flag.Flags -> IO ()
26compileArgs :: Flag.Flags -> IO ()
26compileArgs flags =
27compileArgs flags =
28+ do when (Flag.get_runtime flags) $
29+ do putStrLn Path.runtime
30+ exitSuccess
27− case Flag.files flags of
31+ case Flag.files flags of
28 [] -> putStrLn "Usage: elm [OPTIONS] [FILES]\nFor more help: elm --help"
32 [] -> putStrLn "Usage: elm [OPTIONS] [FILES]\nFor more help: elm --help"
29 fs -> mapM_ (build flags) fs
33 fs -> mapM_ (build flags) fs
30
34
@@ -33,13 +37,15 @@ build flags rootFile =
33 do let noPrelude = Flag.no_prelude flags
37 do let noPrelude = Flag.no_prelude flags
34 builtIns <- Prelude.interfaces noPrelude
38 builtIns <- Prelude.interfaces noPrelude
35
39
40+ (Recipe elmFiles jsFiles) <-
36− files <- if Flag.make flags
41+ if Flag.make flags
37− then getSortedDependencies (Flag.src_dir flags) builtIns rootFile
42+ then Utils.run (getBuildRecipe (Flag.src_dir flags) builtIns rootFile)
38− else return [rootFile]
43+ else return (Recipe [rootFile] [])
39
44
40− moduleName <- File.build flags builtIns files
45+ moduleName <- File.build flags builtIns elmFiles
41
46
47+ let elmos = map (Utils.elmo flags) elmFiles
42− js <- foldM appendToOutput BS.empty files
48+ js <- foldM appendToOutput BS.empty (elmos ++ jsFiles)
43
49
44 (extension, code) <-
50 (extension, code) <-
45 if Flag.only_js flags
51 if Flag.only_js flags
@@ -56,12 +62,12 @@ build flags rootFile =
56 where
62 where
57 appendToOutput :: BS.ByteString -> FilePath -> IO BS.ByteString
63 appendToOutput :: BS.ByteString -> FilePath -> IO BS.ByteString
58 appendToOutput js filePath = do
64 appendToOutput js filePath = do
59− src <- BS.readFile (Utils.elmo flags filePath)
65+ src <- BS.readFile filePath
60 return (BS.append src js)
66 return (BS.append src js)
61
67
62 sources js = map Html.Link (Flag.scripts flags) ++ [ Html.Source js ]
68 sources js = map Html.Link (Flag.scripts flags) ++ [ Html.Source js ]
63
69
64 makeHtml js moduleName = ("html", BS.pack $ renderHtml html)
70 makeHtml js moduleName = ("html", BS.pack $ renderHtml html)
65 where
71 where
66− rtsPath = Maybe.fromMaybe Path.runtime (Flag.runtime flags)
72+ rtsPath = Maybe.fromMaybe Path.runtime (Flag.set_runtime flags)
67 html = Html.generate rtsPath (takeBaseName rootFile) (sources js) moduleName ""
73 html = Html.generate rtsPath (takeBaseName rootFile) (sources js) moduleName ""
compiler/Elm/Internal/Dependencies.hs+39−37
@@ -2,10 +2,13 @@
2module Elm.Internal.Dependencies where
2module Elm.Internal.Dependencies where
3
3
4import Control.Applicative
4import Control.Applicative
5+import Control.Arrow (first)
5import Control.Monad.Error
6import Control.Monad.Error
6import qualified Control.Exception as E
7import qualified Control.Exception as E
7import Data.Aeson
8import Data.Aeson
9+import Data.Aeson.Types (Parser)
8import Data.Aeson.Encode.Pretty
10import Data.Aeson.Encode.Pretty
11+import Data.Maybe (fromMaybe)
9import qualified Data.List as List
12import qualified Data.List as List
10import qualified Data.ByteString.Lazy as BS
13import qualified Data.ByteString.Lazy as BS
11import qualified Data.HashMap.Strict as Map
14import qualified Data.HashMap.Strict as Map
@@ -23,33 +26,28 @@ data Deps = Deps
23 , license :: String
26 , license :: String
24 , repo :: String
27 , repo :: String
25 , exposed :: [String]
28 , exposed :: [String]
29+ , native :: [String]
26 , elmVersion :: V.Version
30 , elmVersion :: V.Version
27 , dependencies :: [(N.Name,V.Version)]
31 , dependencies :: [(N.Name,V.Version)]
28 } deriving (Show, Eq, Ord)
32 } deriving (Show, Eq, Ord)
29
33
30−data MiniDeps = Mini [(N.Name,V.Version)]
31− deriving (Show, Eq, Ord)
32−
33−instance ToJSON MiniDeps where
34− toJSON (Mini m) = toJSON m
35−
36−instance FromJSON MiniDeps where
37− parseJSON (Object obj) = Mini <$> getDependencies obj
38− parseJSON _ = mzero
39−
40instance ToJSON Deps where
34instance ToJSON Deps where
41− toJSON d = object [
35+ toJSON d =
36+ object $
42− "version" .= version d,
37+ [ "version" .= version d
43− "summary" .= summary d,
38+ , "summary" .= summary d
44− "description" .= description d,
39+ , "description" .= description d
45− "license" .= license d,
40+ , "license" .= license d
46− "repository" .= repo d,
41+ , "repository" .= repo d
47− "exposed-modules" .= exposed d,
42+ , "exposed-modules" .= exposed d
48− "elm-version" .= elmVersion d,
43+ , "elm-version" .= elmVersion d
49− "dependencies" .= (jsonDeps . dependencies $ d)
44+ , "dependencies" .= (jsonDeps . dependencies $ d)
50− ]
45+ ] ++ nativeModules
46+ where
51− where jsonDeps = Map.fromList . map (mapFst (T.pack . show))
47+ jsonDeps = Map.fromList . map (first (T.pack . show))
52− mapFst f (a,b) = (f a, b)
48+ nativeModules
49+ | null (native d) = []
50+ | otherwise = [ "native-modules" .= native d ]
53
51
54instance FromJSON Deps where
52instance FromJSON Deps where
55 parseJSON (Object obj) =
53 parseJSON (Object obj) =
@@ -69,15 +67,18 @@ instance FromJSON Deps where
69 Right nm -> return nm
67 Right nm -> return nm
70
68
71 exposed <- get obj "exposed-modules" "a list of modules exposed to users"
69 exposed <- get obj "exposed-modules" "a list of modules exposed to users"
70+
71+ native <- fromMaybe [] <$> (obj .:? "native-modules")
72
72
73 elmVersion <- get obj "elm-version" "the version of the Elm compiler you are using"
73 elmVersion <- get obj "elm-version" "the version of the Elm compiler you are using"
74
74
75 deps <- getDependencies obj
75 deps <- getDependencies obj
76
76
77− return $ Deps name version summary desc license repo exposed elmVersion deps
77+ return $ Deps name version summary desc license repo exposed native elmVersion deps
78
78
79 parseJSON _ = mzero
79 parseJSON _ = mzero
80
80
81+getDependencies :: Object -> Parser [(N.Name, V.Version)]
81getDependencies obj =
82getDependencies obj =
82 toDeps =<< get obj "dependencies" "a listing of your project's dependencies"
83 toDeps =<< get obj "dependencies" "a listing of your project's dependencies"
83 where
84 where
@@ -88,7 +89,7 @@ getDependencies obj =
88 (Nothing, _) -> fail $ N.errorMsg f
89 (Nothing, _) -> fail $ N.errorMsg f
89 (_, Nothing) -> fail $ "invalid version number " ++ v
90 (_, Nothing) -> fail $ "invalid version number " ++ v
90
91
91−
92+get :: FromJSON a => Object -> T.Text -> String -> Parser a
92get obj field desc =
93get obj field desc =
93 do maybe <- obj .:? field
94 do maybe <- obj .:? field
94 case maybe of
95 case maybe of
@@ -117,12 +118,12 @@ repoToName repo
117 \like <https://github.com/USER/PROJECT.git> where USER is your GitHub name\n\
118 \like <https://github.com/USER/PROJECT.git> where USER is your GitHub name\n\
118 \and PROJECT is the repo you want to upload."
119 \and PROJECT is the repo you want to upload."
119
120
120−withDeps :: (Deps -> a) -> FilePath -> ErrorT String IO a
121+withDeps :: FilePath -> (Deps -> ErrorT String IO a) -> ErrorT String IO a
121−withDeps handle path =
122+withDeps path handle =
122 do json <- readPath
123 do json <- readPath
123 case eitherDecode json of
124 case eitherDecode json of
124 Left err -> throwError $ "Error reading file " ++ path ++ ":\n " ++ err
125 Left err -> throwError $ "Error reading file " ++ path ++ ":\n " ++ err
125− Right ds -> return (handle ds)
126+ Right ds -> handle ds
126 where
127 where
127 readPath :: ErrorT String IO BS.ByteString
128 readPath :: ErrorT String IO BS.ByteString
128 readPath = do
129 readPath = do
@@ -136,19 +137,20 @@ withDeps handle path =
136 " <https://github.com/evancz/automaton/blob/master/elm_dependencies.json>"
137 " <https://github.com/evancz/automaton/blob/master/elm_dependencies.json>"
137
138
138depsAt :: FilePath -> ErrorT String IO Deps
139depsAt :: FilePath -> ErrorT String IO Deps
139−depsAt = withDeps id
140+depsAt filePath = withDeps filePath return
140
141
141-- | Encode dependencies in a canonical JSON format
142-- | Encode dependencies in a canonical JSON format
142prettyJSON :: Deps -> BS.ByteString
143prettyJSON :: Deps -> BS.ByteString
143prettyJSON = encodePretty' config
144prettyJSON = encodePretty' config
144 where config = defConfig { confCompare = order }
145 where config = defConfig { confCompare = order }
145− order = keyOrder [ "name",
146+ order = keyOrder [ "name"
146− "version",
147+ , "version"
147− "summary",
148+ , "summary"
148− "description",
149+ , "description"
149− "license",
150+ , "license"
150− "repo",
151+ , "repo"
151− "exposed-modules",
152+ , "exposed-modules"
153+ , "native-modules"
152− "elm-version",
154+ , "elm-version"
153− "dependencies"
155+ , "dependencies"
154 ]
156 ]
compiler/Elm/Internal/Utils.hs+8−1
@@ -1,12 +1,13 @@
1{- | This module exports functions for compiling Elm to JS.
1{- | This module exports functions for compiling Elm to JS.
2-}
2-}
3−module Elm.Internal.Utils (compile, moduleName) where
3+module Elm.Internal.Utils (compile, moduleName, nameAndImports) where
4
4
5import qualified Data.List as List
5import qualified Data.List as List
6import qualified Generate.JavaScript as JS
6import qualified Generate.JavaScript as JS
7import qualified Build.Source as Source
7import qualified Build.Source as Source
8import qualified Parse.Module as Parser
8import qualified Parse.Module as Parser
9import qualified AST.Module as M
9import qualified AST.Module as M
10+import Parse.Parse (dependencies)
10import qualified Text.PrettyPrint as P
11import qualified Text.PrettyPrint as P
11import qualified Metadata.Prelude as Prelude
12import qualified Metadata.Prelude as Prelude
12import System.IO.Unsafe
13import System.IO.Unsafe
@@ -26,3 +27,9 @@ interfaces = unsafePerformIO $ Prelude.interfaces False
26-- |This function extracts the module name of a given source program.
27-- |This function extracts the module name of a given source program.
27moduleName :: String -> Maybe String
28moduleName :: String -> Maybe String
28moduleName = Parser.getModuleName
29moduleName = Parser.getModuleName
30+
31+-- |This function extracts the module name and imported modules from a given
32+-- source program.
33+nameAndImports :: String -> Maybe (String, [String])
34+nameAndImports src =
35+ either (const Nothing) Just (dependencies src)
compiler/Generate/JavaScript.hs+2−1
@@ -36,10 +36,11 @@ include alias moduleName =
36
36
37internalImports :: String -> Statement ()
37internalImports :: String -> Statement ()
38internalImports name =
38internalImports name =
39− VarDeclStmt ()
39+ VarDeclStmt ()
40 [ varDecl "_N" (obj "Elm.Native")
40 [ varDecl "_N" (obj "Elm.Native")
41 , include "_U" "_N.Utils"
41 , include "_U" "_N.Utils"
42 , include "_L" "_N.List"
42 , include "_L" "_N.List"
43+ , include "_A" "_N.Array"
43 , include "_E" "_N.Error"
44 , include "_E" "_N.Error"
44 , varDecl "$moduleName" (string name)
45 , varDecl "$moduleName" (string name)
45 ]
46 ]
compiler/Generate/JavaScript/Ports.hs+16−8
@@ -44,7 +44,7 @@ inc tipe x =
44
44
45 Data (Var.Canonical (Var.Module "Json") "Value") [] ->
45 Data (Var.Canonical (Var.Module "Json") "Value") [] ->
46 obj "Native.Json.fromJS" <| x
46 obj "Native.Json.fromJS" <| x
47−
47+
48 Data (Var.Canonical Var.BuiltIn ctor) []
48 Data (Var.Canonical Var.BuiltIn ctor) []
49 | ctor == "Int" -> from JSNumber
49 | ctor == "Int" -> from JSNumber
50 | ctor == "Float" -> from JSNumber
50 | ctor == "Float" -> from JSNumber
@@ -58,8 +58,13 @@ inc tipe x =
58 (obj "Maybe.Nothing")
58 (obj "Maybe.Nothing")
59 (obj "Maybe.Just" <| inc t x)
59 (obj "Maybe.Just" <| inc t x)
60
60
61− Data (Var.Canonical Var.BuiltIn "_List") [t] ->
61+ Data (Var.Canonical Var.BuiltIn ctor) [t]
62+ | ctor == "_List" ->
62− check x JSArray (obj "_L.fromArray" <| array)
63+ check x JSArray (obj "_L.fromArray" <| array)
64+
65+ | ctor == "Array.Array" ->
66+ check x JSArray (obj "_A.fromJSArray" <| array)
67+
63 where
68 where
64 array = DotRef () x (var "map") <| incoming t
69 array = DotRef () x (var "map") <| incoming t
65
70
@@ -72,10 +77,10 @@ inc tipe x =
72 , inc t (BracketRef () x (IntLit () n)))
77 , inc t (BracketRef () x (IntLit () n)))
73
78
74 Data _ _ ->
79 Data _ _ ->
75− error "bad ADT got to port generation code"
80+ error "bad ADT got to incoming port generation code"
76
81
77 Record _ (Just _) ->
82 Record _ (Just _) ->
78− error "bad record got to port generation code"
83+ error "bad record got to incoming port generation code"
79
84
80 Record fields Nothing ->
85 Record fields Nothing ->
81 check x (JSObject (map fst fields)) object
86 check x (JSObject (map fst fields)) object
@@ -126,6 +131,9 @@ out tipe x =
126 (NullLit ())
131 (NullLit ())
127 (out t (DotRef () x (var "_0")))
132 (out t (DotRef () x (var "_0")))
128
133
134+ Data (Var.Canonical (Var.Module "Array") "Array") [t] ->
135+ DotRef () (obj "_A.toJSArray" <| x) (var "map") <| outgoing t
136+
129 Data (Var.Canonical Var.BuiltIn "_List") [t] ->
137 Data (Var.Canonical Var.BuiltIn "_List") [t] ->
130 DotRef () (obj "_L.toArray" <| x) (var "map") <| outgoing t
138 DotRef () (obj "_L.toArray" <| x) (var "map") <| outgoing t
131
139
@@ -133,12 +141,12 @@ out tipe x =
133 | Help.isTuple ctor ->
141 | Help.isTuple ctor ->
134 let convert n t = out t $ DotRef () x $ var ('_':show n)
142 let convert n t = out t $ DotRef () x $ var ('_':show n)
135 in ArrayLit () $ zipWith convert [0..] ts
143 in ArrayLit () $ zipWith convert [0..] ts
136−
144+
137 Data _ _ ->
145 Data _ _ ->
138− error "bad ADT got to port generation code"
146+ error "bad ADT got to outgoing port generation code"
139
147
140 Record _ (Just _) ->
148 Record _ (Just _) ->
141− error "bad record got to port generation code"
149+ error "bad record got to outgoing port generation code"
142
150
143 Record fields Nothing ->
151 Record fields Nothing ->
144 ObjectLit () keys
152 ObjectLit () keys
compiler/Type/ExtraChecks.hs+4−1
@@ -62,6 +62,9 @@ portTypes rules expr =
62 ST.Data (V.Canonical (V.Module "Maybe") "Maybe") [t] ->
62 ST.Data (V.Canonical (V.Module "Maybe") "Maybe") [t] ->
63 valid t
63 valid t
64
64
65+ ST.Data (V.Canonical (V.Module "Array") "Array") [t] ->
66+ valid t
67+
65 ST.Data (V.Canonical (V.Module "Json") "Value") [] ->
68 ST.Data (V.Canonical (V.Module "Json") "Value") [] ->
66 return ()
69 return ()
67
70
@@ -109,7 +112,7 @@ portTypes rules expr =
109 , txt [ "It contains ", kind, ":\n" ]
112 , txt [ "It contains ", kind, ":\n" ]
110 , (P.nest 4 . PP.pretty $ Alias.realias rules tipe) <> P.text "\n"
113 , (P.nest 4 . PP.pretty $ Alias.realias rules tipe) <> P.text "\n"
111 , txt [ "Acceptable values for ", dir "incoming" "outgoing", " ports include:" ]
114 , txt [ "Acceptable values for ", dir "incoming" "outgoing", " ports include:" ]
112− , txt [ " Ints, Floats, Bools, Strings, Maybes, Lists, Tuples," ]
115+ , txt [ " Ints, Floats, Bools, Strings, Maybes, Lists, Arrays, Tuples," ]
113 , txt [ " Json.Values, ", dir "" "first-order functions, ", "and concrete records." ]
116 , txt [ " Json.Values, ", dir "" "first-order functions, ", "and concrete records." ]
114 ] ++ if couldBeAlias then aliasWarning else []
117 ] ++ if couldBeAlias then aliasWarning else []
115
118
compiler/Type/Type.hs+2−2
@@ -188,7 +188,7 @@ instance PrettyType a => PrettyType (Term1 a) where
188 prettyExt = prty ext
188 prettyExt = prty ext
189 extend | P.render prettyExt == "{}" = P.empty
189 extend | P.render prettyExt == "{}" = P.empty
190 | otherwise = prettyExt <+> P.text "|"
190 | otherwise = prettyExt <+> P.text "|"
191− mkPretty f t = P.text (reprime f) <+> P.text ":" <+> prty t
191+ mkPretty f t = P.text f <+> P.text ":" <+> prty t
192 prettyFields = concatMap (\(f,ts) -> map (mkPretty f) ts) (Map.toList fields)
192 prettyFields = concatMap (\(f,ts) -> map (mkPretty f) ts) (Map.toList fields)
193
193
194
194
@@ -203,7 +203,7 @@ instance PrettyType Descriptor where
203 pretty when desc =
203 pretty when desc =
204 case (structure desc, name desc) of
204 case (structure desc, name desc) of
205 (Just term, _) -> pretty when term
205 (Just term, _) -> pretty when term
206− (_, Just name) -> if not (isTuple name) then P.text (reprime name) else
206+ (_, Just name) -> if not (isTuple name) then P.text name else
207 P.parens . P.text $ replicate (read (drop 6 name) - 1) ','
207 P.parens . P.text $ replicate (read (drop 6 name) - 1) ','
208 _ -> P.text "?"
208 _ -> P.text "?"
209
209
libraries/Array.elm+22−13
@@ -14,7 +14,7 @@ reads, updates, and appends.
14@docs get, getOrElse, getOrFail, set
14@docs get, getOrElse, getOrFail, set
15
15
16# Taking Arrays Apart
16# Taking Arrays Apart
17−@docs toList, toIndexedList, slice
17+@docs slice, toList, toIndexedList
18
18
19# Mapping and Folding
19# Mapping and Folding
20@docs map, indexedMap, foldl, foldr
20@docs map, indexedMap, foldl, foldr
@@ -122,7 +122,7 @@ push = Native.Array.push
122
122
123{-| Get the element at a particular index.
123{-| Get the element at a particular index.
124
124
125− getOrFail 2 (A.fromList [3,2,1]) == 1
125+ getOrFail 0 (A.fromList [0,1,2]) == 0
126
126
127Warning: this function will result in a runtime error if the index is not found,
127Warning: this function will result in a runtime error if the index is not found,
128so it is best to use `get` or `getOrElse` unless you are sure the index will be
128so it is best to use `get` or `getOrElse` unless you are sure the index will be
@@ -133,9 +133,10 @@ getOrFail = Native.Array.get
133
133
134{-| Return Just the element at the index or Nothing if the index is out of range.
134{-| Return Just the element at the index or Nothing if the index is out of range.
135
135
136− get 2 (fromList [3,2,1]) == Just 2
136+ get 0 (fromList [0,1,2]) == Just 0
137+ get 2 (fromList [0,1,2]) == Just 2
137− get 5 (fromList [3,2,1]) == Nothing
138+ get 5 (fromList [0,1,2]) == Nothing
138− get -1 (fromList [3,2,1]) == Nothing
139+ get -1 (fromList [0,1,2]) == Nothing
139-}
140-}
140get : Int -> Array a -> Maybe a
141get : Int -> Array a -> Maybe a
141get i array =
142get i array =
@@ -146,8 +147,8 @@ get i array =
146{-| Get the element at the index. Or if the index is out of range, a default
147{-| Get the element at the index. Or if the index is out of range, a default
147value is returned.
148value is returned.
148
149
149− getOrElse 0 2 (fromList [3,2,1]) == 1
150+ getOrElse 0 2 (fromList [0,1,2]) == 2
150− getOrElse 0 5 (fromList [3,2,1]) == 0
151+ getOrElse 0 5 (fromList [0,1,2]) == 0
151-}
152-}
152getOrElse : a -> Int -> Array a -> a
153getOrElse : a -> Int -> Array a -> a
153getOrElse default i array =
154getOrElse default i array =
@@ -163,13 +164,21 @@ If the index is out of range, the array is unaltered.
163set : Int -> a -> Array a -> Array a
164set : Int -> a -> Array a -> Array a
164set = Native.Array.set
165set = Native.Array.set
165
166
166−{-| Slice an array given a range. The selection is inclusive, so the last
167+{-| Get a sub-section of an array: `(slice start end array)`. The `start` is a
167−element in the selection will also be in the new array. This may change in the
168+zero-based index where we will start our slice. The `end` is a zero-based index
168−future. You can select from the end by giving a negative Int.
169+that indicates the end of the slice. The slice extracts up to but not including
170+`end`.
169
171
170− slice 1 2 (fromList [0,1,2,3,4]) == fromList [1,2]
172+ slice 0 3 (fromList [0,1,2,3,4]) == fromList [0,1,2]
171− slice 1 -2 (fromList [0,1,2,3,4]) == fromList [1,2,3]
173+ slice 1 4 (fromList [0,1,2,3,4]) == fromList [1,2,3]
174+
175+Both the `start` and `end` indexes can be negative, indicating an offset from
176+the end of the array.
177+
178+ slice 1 -1 (fromList [0,1,2,3,4]) == fromList [1,2,3]
172− slice -3 -2 (fromList [0,1,2,3,4]) == fromList [2,3]
179+ slice -2 5 (fromList [0,1,2,3,4]) == fromList [3,4]
180+
181+This makes it pretty easy to `pop` the last element off of an array: `slice 0 -1 array`
173-}
182-}
174slice : Int -> Int -> Array a -> Array a
183slice : Int -> Int -> Array a -> Array a
175slice = Native.Array.slice
184slice = Native.Array.slice
libraries/Color.elm+186−88
@@ -2,18 +2,18 @@ module Color where
2
2
3{-| Library for working with colors. Includes
3{-| Library for working with colors. Includes
4[RGB](https://en.wikipedia.org/wiki/RGB_color_model) and
4[RGB](https://en.wikipedia.org/wiki/RGB_color_model) and
5−[HSV](http://en.wikipedia.org/wiki/HSL_and_HSV) creation, gradients, and
5+[HSL](http://en.wikipedia.org/wiki/HSL_and_HSV) creation, gradients, and
6built-in names.
6built-in names.
7
7
8# Creation
8# Creation
9−@docs rgb, rgba, hsv, hsva, greyscale, grayscale
9+@docs rgb, rgba, hsl, hsla, greyscale, grayscale, complement
10−
11−# From Other Colors
12−@docs complement
13
10
14# Gradients
11# Gradients
15@docs linear, radial
12@docs linear, radial
16
13
14+# Extracting Colors
15+@docs toRgb, toHsl
16+
17# Built-in Colors
17# Built-in Colors
18These colors come from the [Tango
18These colors come from the [Tango
19palette](http://tango.freedesktop.org/Tango_Icon_Theme_Guidelines)
19palette](http://tango.freedesktop.org/Tango_Icon_Theme_Guidelines)
@@ -24,12 +24,10 @@ comes with a light and dark version.
24@docs red, orange, yellow, green, blue, purple, brown
24@docs red, orange, yellow, green, blue, purple, brown
25
25
26### Light
26### Light
27−@docs lightRed, lightOrange, lightYellow, lightGreen, lightBlue, lightPurple,
27+@docs lightRed, lightOrange, lightYellow, lightGreen, lightBlue, lightPurple, lightBrown
28− lightBrown
29
28
30### Dark
29### Dark
31−@docs darkRed, darkOrange, darkYellow, darkGreen, darkBlue, darkPurple,
30+@docs darkRed, darkOrange, darkYellow, darkGreen, darkBlue, darkPurple, darkBrown
32− darkBrown
33
31
34### Eight Shades of Grey
32### Eight Shades of Grey
35These colors are a compatible series of shades of grey, fitting nicely
33These colors are a compatible series of shades of grey, fitting nicely
@@ -42,133 +40,233 @@ that has never helped me remember which one I should be writing.
42
40
43-}
41-}
44
42
45−import Native.Color
46−import Basics ((-))
43+import Basics (..)
47
44
45+data Color
48−data Color = Color Int Int Int Float
46+ = RGBA Int Int Int Float
47+ | HSLA Float Float Float Float
49
48
50{-| Create RGB colors with an alpha component for transparency.
49{-| Create RGB colors with an alpha component for transparency.
51The alpha component is specified with numbers between 0 and 1. -}
50The alpha component is specified with numbers between 0 and 1. -}
52rgba : Int -> Int -> Int -> Float -> Color
51rgba : Int -> Int -> Int -> Float -> Color
53−rgba = Color
52+rgba = RGBA
54
53
55{-| Create RGB colors from numbers between 0 and 255 inclusive. -}
54{-| Create RGB colors from numbers between 0 and 255 inclusive. -}
56rgb : Int -> Int -> Int -> Color
55rgb : Int -> Int -> Int -> Color
57−rgb r g b = Color r g b 1
56+rgb r g b = RGBA r g b 1
57+
58+{-| Create [HSL colors](http://en.wikipedia.org/wiki/HSL_and_HSV)
59+with an alpha component for transparency.
60+-}
61+hsla : Float -> Float -> Float -> Float -> Color
62+hsla hue saturation lightness alpha =
63+ HSLA (hue - toFloat (floor (hue / (2*pi)))) saturation lightness alpha
64+
65+{-| Create [HSL colors](http://en.wikipedia.org/wiki/HSL_and_HSV). This gives
66+you access to colors more like a color wheel, where all hues are aranged in a
67+circle that you specify with standard Elm angles (radians).
68+
69+ red = hsl (degrees 0) 1 0.5
70+ green = hsl (degrees 120) 1 0.5
71+ blue = hsl (degrees 240) 1 0.5
72+
73+ pastelRed = hsl (degrees 0) 0.7 0.7
74+
75+To cycle through all colors, just cycle through degrees. The saturation level
76+is how vibrant the color is, like a dial between grey and bright colors. The
77+lightness level is a dial between white and black.
78+-}
79+hsl : Float -> Float -> Float -> Color
80+hsl hue saturation lightness =
81+ hsla hue saturation lightness 1
82+
83+{-| Produce a gray based on the input. 0 is white, 1 is black. -}
84+grayscale : Float -> Color
85+grayscale p = HSLA 0 0 (1-p) 1
86+
87+greyscale : Float -> Color
88+greyscale p = HSLA 0 0 (1-p) 1
89+
90+{-| Produce a &ldquo;complementary color&rdquo;. The two colors will
91+accent each other. This is the same as rotating the hue by 180&deg;.
92+-}
93+complement : Color -> Color
94+complement color =
95+ case color of
96+ HSLA h s l a -> hsla (h + degrees 180) s l a
97+ RGBA r g b a -> let (h,s,l) = rgbToHsl r g b
98+ in hsla (h + degrees 180) s l a
99+
100+{-| Extract the the components of a color in the HSL format.
101+-}
102+toHsl : Color -> { hue:Float, saturation:Float, lightness:Float, alpha:Float }
103+toHsl color =
104+ case color of
105+ HSLA h s l a -> { hue=h, saturation=s, lightness=l, alpha=a }
106+ RGBA r g b a ->
107+ let (h,s,l) = rgbToHsl r g b
108+ in { hue=h, saturation=s, lightness=l, alpha=a }
109+
110+{-| Extract the the components of a color in the RGB format.
111+-}
112+toRgb : Color -> { red:Int, green:Int, blue:Int, alpha:Float }
113+toRgb color =
114+ case color of
115+ RGBA r g b a -> { red=r, green=g, blue=b, alpha=a }
116+ HSLA h s l a ->
117+ let (r,g,b) = hslToRgb h s l
118+ in { red = round (255 * r)
119+ , green = round (255 * g)
120+ , blue = round (255 * b)
121+ , alpha = a
122+ }
123+
124+fmod : Float -> Int -> Float
125+fmod f n =
126+ let integer = floor f
127+ in toFloat (integer `mod` n) + f - toFloat integer
128+
129+rgbToHsl : Int -> Int -> Int -> (Float,Float,Float)
130+rgbToHsl red green blue =
131+ let r = toFloat red / 255
132+ g = toFloat green / 255
133+ b = toFloat blue / 255
134+
135+ cMax = max (max r g) b
136+ cMin = min (min r g) b
137+
138+ c = cMax - cMin
139+
140+ hue = degrees 60 * if | cMax == r -> ((g - b) / c) `fmod` 6
141+ | cMax == g -> ((b - r) / c) + 2
142+ | cMax == b -> ((r - g) / c) + 4
143+
144+ lightness = (cMax + cMin) / 2
145+
146+ saturation =
147+ if lightness == 0
148+ then 0
149+ else c / (1 - abs (2 * lightness - 1))
150+ in
151+ (hue, saturation, lightness)
152+
153+hslToRgb : Float -> Float -> Float -> (Float,Float,Float)
154+hslToRgb hue saturation lightness =
155+ let chroma = (1 - abs (2 * lightness - 1)) * saturation
156+ hue' = hue / degrees 60
157+
158+ x = chroma * (1 - abs (fmod hue' 2 - 1))
159+
160+ (r,g,b) = if | hue' < 0 -> (0, 0, 0)
161+ | hue' < 1 -> (chroma, x, 0)
162+ | hue' < 2 -> (x, chroma, 0)
163+ | hue' < 3 -> (0, chroma, x)
164+ | hue' < 4 -> (0, x, chroma)
165+ | hue' < 5 -> (x, 0, chroma)
166+ | hue' < 6 -> (chroma, 0, x)
167+ | otherwise -> (0, 0, 0)
168+
169+ m = lightness - chroma / 2
170+ in
171+ (r + m, g + m, b + m)
172+
173+--toV3 : Color -> V3
174+
175+--toV4 : Color -> V4
176+
177+data Gradient
178+ = Linear (Float,Float) (Float,Float) [(Float,Color)]
179+ | Radial (Float,Float) Float (Float,Float) Float [(Float,Color)]
180+
181+{-| Create a linear gradient. Takes a start and end point and then a series of
182+&ldquo;color stops&rdquo; that indicate how to interpolate between the start and
183+end points. See [this example](/edit/examples/Elements/LinearGradient.elm) for a
184+more visual explanation. -}
185+linear : (number, number) -> (number, number) -> [(Float,Color)] -> Gradient
186+linear = Linear
187+
188+{-| Create a radial gradient. First takes a start point and inner radius. Then
189+takes an end point and outer radius. It then takes a series of &ldquo;color
190+stops&rdquo; that indicate how to interpolate between the inner and outer
191+circles. See [this example](/edit/examples/Elements/RadialGradient.elm) for a
192+more visual explanation. -}
193+radial : (number,number) -> number -> (number,number) -> number -> [(Float,Color)] -> Gradient
194+radial = Radial
195+
196+
197+-- BUILT-IN COLORS
58
198
59lightRed : Color
199lightRed : Color
60−lightRed = Color 239 41 41 1
200+lightRed = RGBA 239 41 41 1
61red : Color
201red : Color
62−red = Color 204 0 0 1
202+red = RGBA 204 0 0 1
63darkRed : Color
203darkRed : Color
64−darkRed = Color 164 0 0 1
204+darkRed = RGBA 164 0 0 1
65
205
66lightOrange : Color
206lightOrange : Color
67−lightOrange = Color 252 175 62 1
207+lightOrange = RGBA 252 175 62 1
68orange : Color
208orange : Color
69−orange = Color 245 121 0 1
209+orange = RGBA 245 121 0 1
70darkOrange : Color
210darkOrange : Color
71−darkOrange = Color 206 92 0 1
211+darkOrange = RGBA 206 92 0 1
72
212
73lightYellow : Color
213lightYellow : Color
74−lightYellow = Color 255 233 79 1
214+lightYellow = RGBA 255 233 79 1
75yellow : Color
215yellow : Color
76−yellow = Color 237 212 0 1
216+yellow = RGBA 237 212 0 1
77darkYellow : Color
217darkYellow : Color
78−darkYellow = Color 196 160 0 1
218+darkYellow = RGBA 196 160 0 1
79
219
80lightGreen : Color
220lightGreen : Color
81−lightGreen = Color 138 226 52 1
221+lightGreen = RGBA 138 226 52 1
82green : Color
222green : Color
83−green = Color 115 210 22 1
223+green = RGBA 115 210 22 1
84darkGreen : Color
224darkGreen : Color
85−darkGreen = Color 78 154 6 1
225+darkGreen = RGBA 78 154 6 1
86
226
87lightBlue : Color
227lightBlue : Color
88−lightBlue = Color 114 159 207 1
228+lightBlue = RGBA 114 159 207 1
89blue : Color
229blue : Color
90−blue = Color 52 101 164 1
230+blue = RGBA 52 101 164 1
91darkBlue : Color
231darkBlue : Color
92−darkBlue = Color 32 74 135 1
232+darkBlue = RGBA 32 74 135 1
93
233
94lightPurple : Color
234lightPurple : Color
95−lightPurple = Color 173 127 168 1
235+lightPurple = RGBA 173 127 168 1
96purple : Color
236purple : Color
97−purple = Color 117 80 123 1
237+purple = RGBA 117 80 123 1
98darkPurple : Color
238darkPurple : Color
99−darkPurple = Color 92 53 102 1
239+darkPurple = RGBA 92 53 102 1
100
240
101lightBrown : Color
241lightBrown : Color
102−lightBrown = Color 233 185 110 1
242+lightBrown = RGBA 233 185 110 1
103brown : Color
243brown : Color
104−brown = Color 193 125 17 1
244+brown = RGBA 193 125 17 1
105darkBrown : Color
245darkBrown : Color
106−darkBrown = Color 143 89 2 1
246+darkBrown = RGBA 143 89 2 1
107
247
108black : Color
248black : Color
109−black = Color 0 0 0 1
249+black = RGBA 0 0 0 1
110white : Color
250white : Color
111−white = Color 255 255 255 1
251+white = RGBA 255 255 255 1
112
252
113lightGrey : Color
253lightGrey : Color
114−lightGrey = Color 238 238 236 1
254+lightGrey = RGBA 238 238 236 1
115grey : Color
255grey : Color
116−grey = Color 211 215 207 1
256+grey = RGBA 211 215 207 1
117darkGrey : Color
257darkGrey : Color
118−darkGrey = Color 186 189 182 1
258+darkGrey = RGBA 186 189 182 1
119
259
120lightGray : Color
260lightGray : Color
121−lightGray = Color 238 238 236 1
261+lightGray = RGBA 238 238 236 1
122gray : Color
262gray : Color
123−gray = Color 211 215 207 1
263+gray = RGBA 211 215 207 1
124darkGray : Color
264darkGray : Color
125−darkGray = Color 186 189 182 1
265+darkGray = RGBA 186 189 182 1
126
266
127lightCharcoal : Color
267lightCharcoal : Color
128−lightCharcoal = Color 136 138 133 1
268+lightCharcoal = RGBA 136 138 133 1
129charcoal : Color
269charcoal : Color
130−charcoal = Color 85 87 83 1
270+charcoal = RGBA 85 87 83 1
131darkCharcoal : Color
271darkCharcoal : Color
132−darkCharcoal = Color 46 52 54 1
272+darkCharcoal = RGBA 46 52 54 1
133−
134−{-| Produce a gray based on the input. 0 is white, 1 is black. -}
135−grayscale : Float -> Color
136−grayscale p = hsv 0 0 (1-p)
137−
138−greyscale : Float -> Color
139−greyscale p = hsv 0 0 (1-p)
140−
141−{-| Produce a &ldquo;complementary color&rdquo;.
142−The two colors will accent each other. -}
143−complement : Color -> Color
144−complement = Native.Color.complement
145−
146−{-| Create [HSV colors](http://en.wikipedia.org/wiki/HSL_and_HSV)
147−with an alpha component for transparency. -}
148−hsva : Float -> Float -> Float -> Float -> Color
149−hsva = Native.Color.hsva
150−
151−{-| Create [HSV colors](http://en.wikipedia.org/wiki/HSL_and_HSV). This is very
152−convenient for creating colors that cycle and shift. Hue is an angle and should
153−be given in standard Elm angles (radians). -}
154−hsv : Float -> Float -> Float -> Color
155−hsv = Native.Color.hsv
156−
157−data Gradient
158− = Linear (Float,Float) (Float,Float) [(Float,Color)]
159− | Radial (Float,Float) Float (Float,Float) Float [(Float,Color)]
160−
161−{-| Create a linear gradient. Takes a start and end point and then a series of
162−&ldquo;color stops&rdquo; that indicate how to interpolate between the start and
163−end points. See [this example](/edit/examples/Elements/LinearGradient.elm) for a
164−more visual explanation. -}
165−linear : (number, number) -> (number, number) -> [(Float,Color)] -> Gradient
166−linear = Linear
167−
168−{-| Create a radial gradient. First takes a start point and inner radius. Then
169−takes an end point and outer radius. It then takes a series of &ldquo;color
170−stops&rdquo; that indicate how to interpolate between the inner and outer
171−circles. See [this example](/edit/examples/Elements/RadialGradient.elm) for a
172−more visual explanation. -}
173−radial : (number,number) -> number -> (number,number) -> number -> [(Float,Color)] -> Gradient
174−radial = Radial
libraries/Graphics/WebGL.elmdeleted−56
@@ -1,56 +0,0 @@
1−module Graphics.WebGL (mapTriangle, zipTriangle, loadTex, model, webgl) where
2−
3−{-| The WebGL API is for high performance drawing.
4−
5−# Triangle Convenience Functions
6−@docs Triangle, mapTriangle, zipTriangle
7−
8−# Shaders
9−Shaders are created using glsl blocks.
10−
11−vertex : Shader { a | pos : V3 } {} {}
12−vertex = [glsl|
13−
14−attribute vec3 pos;
15−
16−void main () {
17− gl_Position = vec4(pos,1.0);
18−}
19−
20−|]
21−
22−# WebGL Element
23−@docs webgl
24−
25−-}
26−
27−import Graphics.Element (Element)
28−import Http (Response)
29−import Native.Graphics.WebGL
30−import Signal (Signal)
31−
32−unsafeCoerceGLSL : String -> Shader attr unif vary
33−unsafeCoerceGLSL = Native.Graphics.WebGL.unsafeCoerceGLSL
34−
35−type Triangle a = (a,a,a)
36−
37−mapTriangle : (a -> b) -> Triangle a -> Triangle b
38−mapTriangle f (x,y,z) = (f x, f y, f z)
39−
40−zipTriangle : (a -> b -> c) -> Triangle a -> Triangle b -> Triangle c
41−zipTriangle f (x,y,z) (x',y',z') = (f x x', f y y', f z z')
42−
43−data Shader attr unif vary = Shader
44−
45−data Texture = Texture
46−
47−loadTex : String -> Signal (Response Texture)
48−loadTex = Native.Graphics.WebGL.loadTex
49−
50−data Model = Model
51−
52−model : Shader attr unif vary -> Shader {} unif vary -> [Triangle attr] -> unif -> Model
53−model = Native.Graphics.WebGL.model
54−
55−webgl : (Int,Int) -> [Model] -> Element
56−webgl = Native.Graphics.WebGL.webgl
libraries/MJS.elmdeleted−129
@@ -1,129 +0,0 @@
1−module MJS where
2−
3−{-| MJS
4−
5−A high performance linear algebra library using
6−native JS arrays. Geared towards 3D graphics
7−and use with Graphics.WebGL.
8−
9−Both vectors and matrices are immutable.
10−
11−-}
12−
13−import Native.MJS
14−
15−data V2 = V2
16−data V3 = V3
17−data V4 = V4
18−data M4x4 = M4x4
19−
20−v3 : Float -> Float -> Float -> V3
21−v3 = Native.MJS.v3
22−
23−toTuple3 : V3 -> (Float,Float,Float)
24−toTuple3 = Native.MJS.toTuple3
25−
26−add : V3 -> V3 -> V3
27−add = Native.MJS.v3add
28−
29−sub : V3 -> V3 -> V3
30−sub = Native.MJS.v3sub
31−
32−neg : V3 -> V3
33−neg = Native.MJS.v3neg
34−
35−{- The normalized direction from v1 to v2 -}
36−direction : V3 -> V3 -> V3
37−direction = Native.MJS.v3direction
38−
39−length : V3 -> Float
40−length = Native.MJS.v3length
41−
42−lengthSquared : V3 -> Float
43−lengthSquared = Native.MJS.v3lengthSquared
44−
45−normalize : V3 -> V3
46−normalize = Native.MJS.v3normalize
47−
48−scale : V3 -> Float -> V3
49−scale = Native.MJS.v3scale
50−
51−dot : V3 -> V3 -> Float
52−dot = Native.MJS.v3dot
53−
54−cross : V3 -> V3 -> V3
55−cross = Native.MJS.v3cross
56−
57−mul4x4 : M4x4 -> V3 -> V3
58−mul4x4 = Native.MJS.v3mul4x4
59−
60−--m4x4 : V3[16] -> M4x4 ?
61−
62−identity : M4x4
63−identity = Native.MJS.m4x4identity
64−
65−--topLeft3x3 : M4x4 -> M3x3 ?
66−
67−{- Assumes that m is orthonormal -}
68−inverseOrthonormal : M4x4 -> M4x4
69−inverseOrthonormal = Native.MJS.m4x4inverseOrthonormal
70−
71−--inverseTo3x3 : M4x4 -> M3x3 ?
72−
73−makeFrustrum : Float -> Float -> Float -> Float -> Float -> Float -> Float -> M4x4
74−makeFrustrum = Native.MJS.m4x4makeFrustrum
75−
76−makePerspective : Float -> Float -> Float -> Float -> M4x4
77−makePerspective = Native.MJS.m4x4makePerspective
78−
79−makeOrtho : Float -> Float -> Float -> Float -> Float -> Float -> Float -> M4x4
80−makeOrtho = Native.MJS.m4x4makeOrtho
81−
82−makeOrtho2D : Float -> Float -> Float -> Float -> M4x4
83−makeOrtho2D = Native.MJS.m4x4makeOrtho2D
84−
85−mul : M4x4 -> M4x4 -> M4x4
86−mul = Native.MJS.m4x4mul
87−
88−mulAffine : M4x4 -> M4x4 -> M4x4
89−mulAffine = Native.MJS.m4x4mulAffine
90−
91−makeRotate : Float -> V3 -> M4x4
92−makeRotate = Native.MJS.m4x4makeRotate
93−
94−rotate : Float -> V3 -> M4x4 -> M4x4
95−rotate = Native.MJS.m4x4rotate
96−
97−makeScale3 : Float -> Float -> Float -> M4x4
98−makeScale3 = Native.MJS.m4x4makeScale3
99−
100−makeScale : V3 -> M4x4
101−makeScale = Native.MJS.m4x4makeScale
102−
103−scaleM3 : Float -> Float -> Float -> M4x4 -> M4x4
104−scaleM3 = Native.MJS.m4x4scale3
105−
106−scaleM : V3 -> M4x4 -> M4x4
107−scaleM = Native.MJS.m4x4scale
108−
109−makeTranslate3 : Float -> Float -> Float -> M4x4
110−makeTranslate3 = Native.MJS.m4x4makeTranslate3
111−
112−makeTranslate : V3 -> M4x4
113−makeTranslate = Native.MJS.m4x4makeTranslate
114−
115−translate3 : Float -> Float -> Float -> M4x4 -> M4x4
116−translate3 = Native.MJS.m4x4translate3
117−
118−translate : V3 -> M4x4 -> M4x4
119−translate = Native.MJS.m4x4translate
120−
121−makeLookAt : V3 -> V3 -> V3 -> M4x4
122−makeLookAt = Native.MJS.m4x4makeLookAt
123−
124−transpose : M4x4 -> M4x4
125−transpose = Native.MJS.m4x4transpose
126−
127−{- Custom constructor for supplying arbitrary x,y,z axis -}
128−makeBasis : V3 -> V3 -> V3 -> M4x4
129−makeBasis = Native.MJS.m4x4makeBasis
libraries/Native/Array.js+53−7
@@ -1,4 +1,4 @@
1−Elm.Native.Array = {};
1+Elm.Native.Array = {};
2Elm.Native.Array.make = function(elm) {
2Elm.Native.Array.make = function(elm) {
3 elm.Native = elm.Native || {};
3 elm.Native = elm.Native || {};
4 elm.Native.Array = elm.Native.Array || {};
4 elm.Native.Array = elm.Native.Array || {};
@@ -240,10 +240,16 @@ Elm.Native.Array.make = function(elm) {
240
240
241 // Maps a function over the elements with their index as first argument.
241 // Maps a function over the elements with their index as first argument.
242 function indexedMap(f, a) {
242 function indexedMap(f, a) {
243+ return indexedMap_(f, a, 0);
244+ }
245+
246+ function indexedMap_(f, a, from) {
243 var newA = { ctor:"_Array", height:a.height, table:new Array(a.table) };
247 var newA = { ctor:"_Array", height:a.height, table:new Array(a.table) };
244 if (a.height > 0) { newA.lengths = a.lengths; }
248 if (a.height > 0) { newA.lengths = a.lengths; }
245 for (var i = 0; i < a.table.length; i++) {
249 for (var i = 0; i < a.table.length; i++) {
246− newA.table[i] = a.height == 0 ? A2(f, i, a.table[i]) : indexedMap(f, a.table[i]);
250+ newA.table[i] = a.height == 0 ? A2(f, from + i, a.table[i])
251+ : indexedMap_( f, a.table[i]
252+ , i == 0 ? 0 : a.lengths[i - 1]);
247 }
253 }
248 return newA;
254 return newA;
249 }
255 }
@@ -262,9 +268,6 @@ Elm.Native.Array.make = function(elm) {
262 return b;
268 return b;
263 }
269 }
264
270
265− // Returns a sliced tree. "to" is inclusive, but this may change,
266− // when I understand, why e.g. JS does not handle it this way. :-)
267− // If "from" or "to" is negative, they will select from the end on.
268 // TODO: currently, it slices the right, then the left. This can be
271 // TODO: currently, it slices the right, then the left. This can be
269 // optimized.
272 // optimized.
270 function slice(from, to, a) {
273 function slice(from, to, a) {
@@ -281,7 +284,7 @@ Elm.Native.Array.make = function(elm) {
281 // Handle leaf level.
284 // Handle leaf level.
282 if (a.height == 0) {
285 if (a.height == 0) {
283 var newA = { ctor:"_Array", height:0 };
286 var newA = { ctor:"_Array", height:0 };
284− newA.table = a.table.slice(0, to + 1);
287+ newA.table = a.table.slice(0, to);
285 return newA;
288 return newA;
286 }
289 }
287
290
@@ -576,6 +579,46 @@ Elm.Native.Array.make = function(elm) {
576 , lengths:[length(a), length(a) + length(b)] };
579 , lengths:[length(a), length(a) + length(b)] };
577 }
580 }
578
581
582+ function toJSArray(a) {
583+ var jsArray = new Array(length(a));
584+ toJSArray_(jsArray, 0, a);
585+ return jsArray;
586+ }
587+
588+ function toJSArray_(jsArray, i, a) {
589+ for (var t = 0; t < a.table.length; t++) {
590+ if (a.height == 0) {
591+ jsArray[i + t] = a.table[t];
592+ } else {
593+ var inc = t == 0 ? 0 : a.lengths[t - 1];
594+ toJSArray_(jsArray, i + inc, a.table[t]);
595+ }
596+ }
597+ }
598+
599+ function fromJSArray(jsArray) {
600+ if (jsArray.length == 0) { return empty; }
601+ var h = Math.floor(Math.log(jsArray.length) / Math.log(M));
602+ return fromJSArray_(jsArray, h, 0, jsArray.length);
603+ }
604+
605+ function fromJSArray_(jsArray, h, from, to) {
606+ if (h == 0) {
607+ return { ctor:"_Array", height:0
608+ , table:jsArray.slice(from, to) };
609+ }
610+
611+ var step = Math.pow(M, h);
612+ var table = new Array(Math.ceil((to - from) / step));
613+ var lengths = new Array(table.length);
614+ for (var i = 0; i < table.length; i++) {
615+ table[i] = fromJSArray_( jsArray, h - 1, from + (i * step)
616+ , Math.min(from + ((i + 1) * step), to));
617+ lengths[i] = length(table[i]) + (i > 0 ? lengths[i-1] : 0);
618+ }
619+ return { ctor:"_Array", height:h, table:table, lengths:lengths };
620+ }
621+
579 Elm.Native.Array.values = {
622 Elm.Native.Array.values = {
580 empty:empty,
623 empty:empty,
581 fromList:fromList,
624 fromList:fromList,
@@ -590,7 +633,10 @@ Elm.Native.Array.make = function(elm) {
590 indexedMap:F2(indexedMap),
633 indexedMap:F2(indexedMap),
591 foldl:F3(foldl),
634 foldl:F3(foldl),
592 foldr:F3(foldr),
635 foldr:F3(foldr),
593− length:length
636+ length:length,
637+
638+ toJSArray:toJSArray,
639+ fromJSArray:fromJSArray
594 };
640 };
595
641
596 return elm.Native.Array.values = Elm.Native.Array.values;
642 return elm.Native.Array.values = Elm.Native.Array.values;
libraries/Native/Bitwise.js+1−1
@@ -19,7 +19,7 @@ Elm.Native.Bitwise.make = function(elm) {
19 complement: not,
19 complement: not,
20 shiftLeft : F2(sll),
20 shiftLeft : F2(sll),
21 shiftRightArithmatic: F2(sra),
21 shiftRightArithmatic: F2(sra),
22− shiftRightLogical : F2(srl),
22+ shiftRightLogical : F2(srl)
23 };
23 };
24
24
25};
25};
libraries/Native/Color.js+16−60
@@ -7,69 +7,25 @@ Elm.Native.Color.make = function(elm) {
7 var Utils = Elm.Native.Utils.make(elm);
7 var Utils = Elm.Native.Utils.make(elm);
8
8
9 function toCss(c) {
9 function toCss(c) {
10− return (c._3 === 1)
10+ var format = '';
11− ? ('rgb(' + c._0 + ', ' + c._1 + ', ' + c._2 + ')')
11+ var colors = '';
12− : ('rgba(' + c._0 + ', ' + c._1 + ', ' + c._2 + ', ' + c._3 + ')');
12+ if (c.ctor === 'RGBA') {
13− }
13+ format = 'rgb';
14−
14+ colors = c._0 + ', ' + c._1 + ', ' + c._2;
15− function complement(rgb) {
15+ } else {
16− var hsv = toHSV(rgb);
16+ format = 'hsl';
17− hsv.hue = (hsv.hue + 180) % 360;
17+ colors = (c._0 * 180 / Math.PI) + ', ' +
18− return toRGB(hsv);
18+ (c._1 * 100) + '%, ' +
19− }
19+ (c._2 * 100) + '%';
20−
20+ }
21− function hsva(h,s,v,a) {
21+ if (c._3 === 1) {
22− var degree = A2(Utils.mod, h * 180 / Math.PI, 360);
22+ return format + '(' + colors + ')';
23− var clr = toRGB({hue:degree, saturation:s, value:v});
23+ } else {
24− clr._3 = a;
24+ return format + 'a(' + colors + ', ' + c._3 + ')';
25− return clr;
25+ }
26− }
27−
28− function hsv(h,s,v) {
29− var degree = A2(Utils.mod, h * 180 / Math.PI, 360);
30− return toRGB({hue:degree, saturation:s, value:v});
31− }
32−
33− function toHSV(rgb) {
34− var hsv = {};
35− var r = rgb._0 / 255.0, g = rgb._1 / 255.0, b = rgb._2 / 255.0;
36− var M = Math.max(r,g,b);
37− var m = Math.min(r,g,b);
38− var c = M - m;
39−
40− var h = 0;
41− if (c === 0) { h = 0; }
42− else if (M === r) { h = ((g - b) / c) % 6; }
43− else if (M === g) { h = ((b - r) / c) + 2; }
44− else if (M === b) { h = ((r - g) / c) + 4; }
45− h *= 60;
46−
47− return { value : M, hue : h, saturation : (M === 0 ? 0 : c / M) };
48− }
49−
50− function between(lo,hi,x) { return lo <= x && x < hi; }
51− function norm(n) { return Math.round(n*255); }
52−
53− function toRGB(hsv) {
54− var c = hsv.value * hsv.saturation;
55− var hue = hsv.hue / 60;
56− var x = c * (1 - Math.abs((hue % 2) - 1));
57− var r = 0, g = 0, b = 0;
58− if (between(0,1,hue)) { r = c; g = x; b = 0; }
59− else if (between(1,2,hue)) { r = x; g = c; b = 0; }
60− else if (between(2,3,hue)) { r = 0; g = c; b = x; }
61− else if (between(3,4,hue)) { r = 0; g = x; b = c; }
62− else if (between(4,5,hue)) { r = x; g = 0; b = c; }
63− else if (between(5,6,hue)) { r = c; g = 0; b = x; }
64−
65− var m = hsv.value - c;
66− return { ctor:"Color", _0:norm(r+m), _1:norm(g+m), _2:norm(b+m), _3:1 };
67 }
26 }
68
27
69 return elm.Native.Color.values = {
28 return elm.Native.Color.values = {
70− hsva:F4(hsva),
71− hsv:F3(hsv),
72− complement:complement,
73 toCss:toCss
29 toCss:toCss
74 };
30 };
75
31
libraries/Native/Error.js+2−4
@@ -4,8 +4,6 @@ Elm.Native.Error.make = function(elm) {
4 elm.Native.Error = elm.Native.Error || {};
4 elm.Native.Error = elm.Native.Error || {};
5 if (elm.Native.Error.values) return elm.Native.Error.values;
5 if (elm.Native.Error.values) return elm.Native.Error.values;
6
6
7− var fromString = Elm.Native.JavaScript.make(elm).fromString;
8−
9 function indent(lines) {
7 function indent(lines) {
10 var msg = '';
8 var msg = '';
11 for (var i = 0; i < lines.length; ++i) {
9 for (var i = 0; i < lines.length; ++i) {
@@ -26,7 +24,7 @@ Elm.Native.Error.make = function(elm) {
26 throw new Error('Runtime error in module ' + moduleName + ' (' + span + '):' + msg);
24 throw new Error('Runtime error in module ' + moduleName + ' (' + span + '):' + msg);
27 }
25 }
28
26
29− function raise(str) { throw new Error(fromString(str)); }
27+ function raise(str) { throw new Error(str); }
30
28
31 return elm.Native.Error.values = { Case: Case, If: If, raise: raise };
29 return elm.Native.Error.values = { Case: Case, If: If, raise: raise };
32−};
30+};
libraries/Native/Graphics/Input.js+1−1
@@ -286,7 +286,7 @@ Elm.Native.Graphics.Input.make = function(elm) {
286 start: start,
286 start: start,
287 end: end,
287 end: end,
288 direction: { ctor: direction }
288 direction: { ctor: direction }
289− },
289+ }
290 }));
290 }));
291 }
291 }
292
292
libraries/Native/Graphics/WebGL.jsdeleted−366
@@ -1,366 +0,0 @@
1−Elm.Native.Graphics.WebGL = {};
2−Elm.Native.Graphics.WebGL.make = function(elm) {
3−
4− // LOG LEVEL
5−
6− elm.Native = elm.Native || {};
7− elm.Native.Graphics = elm.Native.Graphics || {};
8− elm.Native.Graphics.WebGL = elm.Native.Graphics.WebGL || {};
9− if (elm.Native.Graphics.WebGL.values) return elm.Native.Graphics.WebGL.values;
10−
11− var newNode = ElmRuntime.use(ElmRuntime.Render.Utils).newElement;
12− var newElement = Elm.Graphics.Element.make(elm).newElement;
13−
14− var List = Elm.Native.List.make(elm);
15− var MJS = Elm.Native.MJS.make(elm);
16− var Utils = Elm.Native.Utils.make(elm);
17− var Signal = Elm.Signal.make(elm);
18− var Tuple2 = Utils.Tuple2;
19−
20− function unsafeCoerceGLSL(src) {
21− return { src : src };
22− }
23−
24− function loadTex(source) {
25−
26− var response = Signal.constant(elm.Http.values.Waiting);
27−
28− var img = new Image();
29−
30− img.onload = function() {
31− var success = elm.Http.values.Success({img:img});
32− elm.notify(response.id, success);
33− }
34−
35− img.onerror = function(e) {
36− var failure = A2(elm.Http.values.Failure,0,"Failed");
37− elm.notify(response.id, failure);
38− }
39−
40− img.src = source;
41−
42− return response;
43−
44− }
45−
46− function model(vert, frag, buffer, uniforms) {
47−
48− return model = {
49− vert: vert,
50− frag: frag,
51− buffer: buffer,
52− uniforms: uniforms
53− };
54−
55− }
56−
57− function do_texture (gl, img) {
58−
59− var tex = gl.createTexture();
60− console.log("Created texture");
61− gl.bindTexture(gl.TEXTURE_2D, tex);
62− gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
63− gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
64− gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
65− gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
66− gl.generateMipmap(gl.TEXTURE_2D);
67− //gl.bindTexture(gl.TEXTURE0, null);
68− return tex;
69−
70− }
71−
72− function do_compile (gl, src, tipe) {
73−
74− var shader = gl.createShader(tipe);
75− console.log("Created shader");
76−
77− gl.shaderSource(shader, src);
78− gl.compileShader(shader);
79− var compile = gl.COMPILE_STATUS;
80− if (!gl.getShaderParameter(shader,compile)) {
81− throw gl.getShaderInfoLog(shader);
82− }
83−
84− return shader;
85−
86− }
87−
88− function do_link (gl, vshader, fshader) {
89−
90− var program = gl.createProgram();
91− console.log("Created program");
92−
93− gl.attachShader(program, vshader);
94− gl.attachShader(program, fshader);
95− gl.linkProgram(program);
96− if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
97− throw gl.getProgramInfoLog(program);
98− }
99−
100− return program;
101−
102− }
103−
104− function do_bind (gl, program, bufferElems) {
105−
106− var buffers = {};
107−
108− var attributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
109− for (var i = 0; i < attributes; i += 1) {
110− var attribute = gl.getActiveAttrib(program, i);
111− switch (attribute.type) {
112− case gl.FLOAT_VEC3:
113−
114− // Might want to invert the loop
115− // to build the array buffer first
116− // and then bind each one-at-a-time
117− var data = [];
118− List.each(function(elem){
119− data.push(elem._0[attribute.name][0]);
120− data.push(elem._0[attribute.name][1]);
121− data.push(elem._0[attribute.name][2]);
122− data.push(elem._1[attribute.name][0]);
123− data.push(elem._1[attribute.name][1]);
124− data.push(elem._1[attribute.name][2]);
125− data.push(elem._2[attribute.name][0]);
126− data.push(elem._2[attribute.name][1]);
127− data.push(elem._2[attribute.name][2]);
128− }, bufferElems);
129− var array = new Float32Array(data);
130−
131− var buffer = gl.createBuffer();
132− console.log("Created attribute buffer " + attribute.name);
133− gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
134− gl.bufferData(gl.ARRAY_BUFFER, array, gl.STATIC_DRAW);
135−
136− buffers[attribute.name] = buffer;
137−
138− break;
139−
140− default:
141− console.log("Bad buffer type");
142− break;
143− }
144−
145− }
146−
147− var numIndices = 3 * List.length(bufferElems);
148− var indices = List.toArray(List.range(0, numIndices - 1));
149− console.log("Created index buffer");
150− var indexBuffer = gl.createBuffer();
151− gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
152− gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
153−
154− var bufferObject = {
155− numIndices: numIndices,
156− indexBuffer: indexBuffer,
157− buffers: buffers
158− };
159−
160− return bufferObject;
161−
162− }
163−
164− function drawGL(model) {
165−
166− var gl = model.cache.gl;
167−
168− gl.viewport(0, 0, model.w, model.h);
169− gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
170− console.log("Drawing");
171−
172− function drawModel(m) {
173−
174− var program;
175− if (m.vert.id && m.frag.id) {
176− var progid = m.vert.id + '#' + m.frag.id;
177− program = model.cache.programs[progid];
178− }
179−
180− if (!program) {
181−
182− var vshader = undefined;
183− if (m.vert.id) {
184− vshader = model.cache.shaders[m.vert.id];
185− } else {
186− m.vert.id = Utils.guid();
187− }
188−
189− if (!vshader) {
190− vshader = do_compile(gl, m.vert.src, gl.VERTEX_SHADER);
191− model.cache.shaders[m.vert.id] = vshader;
192− }
193−
194− var fshader = undefined;
195− if (m.frag.id) {
196− fshader = model.cache.shaders[m.frag.id];
197− } else {
198− m.frag.id = Utils.guid();
199− }
200−
201− if (!fshader) {
202− fshader = do_compile(gl, m.frag.src, gl.FRAGMENT_SHADER);
203− model.cache.shaders[m.frag.id] = fshader;
204− }
205−
206− program = do_link(gl, vshader, fshader);
207− var progid = m.vert.id + '#' + m.frag.id;
208− model.cache.programs[progid] = program;
209−
210− }
211−
212− gl.useProgram(program);
213−
214− var numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
215− var textureCounter = 0;
216− for (var i = 0; i < numUniforms; i += 1) {
217− var uniform = gl.getActiveUniform(program, i);
218− var uniformLocation = gl.getUniformLocation(program, uniform.name);
219− switch (uniform.type) {
220− case gl.INT:
221− gl.uniform1i(uniformLocation, m.uniforms[uniform.name]);
222− break;
223− case gl.FLOAT:
224− gl.uniform1f(uniformLocation, m.uniforms[uniform.name]);
225− break;
226− case gl.FLOAT_VEC3:
227− gl.uniform3fv(uniformLocation, m.uniforms[uniform.name]);
228− break;
229− case gl.FLOAT_MAT4:
230− gl.uniformMatrix4fv(uniformLocation, false, m.uniforms[uniform.name]);
231− break;
232− case gl.SAMPLER_2D:
233− var texture = m.uniforms[uniform.name];
234− var tex = undefined;
235− if (texture.id) {
236− tex = model.cache.textures[texture.id];
237− } else {
238− texture.id = Utils.guid();
239− }
240− if (!tex) {
241− tex = do_texture(gl, texture.img);
242− model.cache.textures[texture.id] = tex;
243− }
244− var activeName = 'TEXTURE' + textureCounter;
245− gl.activeTexture(gl[activeName]);
246− gl.bindTexture(gl.TEXTURE_2D,tex);
247− gl.uniform1i(uniformLocation, textureCounter);
248− textureCounter += 1;
249− break;
250− default:
251− console.log("Unsupported uniform type: " + uniform.type);
252− break;
253− }
254− }
255−
256− var buffer = model.cache.buffers[m.buffer.guid];
257− if (!buffer) {
258− buffer = do_bind(gl, program, m.buffer);
259− model.cache.buffers[m.buffer.guid] = buffer;
260− }
261−
262− var numIndices = buffer.numIndices;
263− var indexBuffer = buffer.indexBuffer;
264− gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
265−
266− var numAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
267− for (var i = 0; i < numAttributes; i += 1) {
268− var attribute = gl.getActiveAttrib(program, i);
269− var attribLocation = gl.getAttribLocation(program, attribute.name);
270− gl.enableVertexAttribArray(attribLocation);
271− var attributeBuffer = buffer.buffers[attribute.name];
272−
273− switch (attribute.type) {
274− case gl.FLOAT_VEC3:
275− gl.bindBuffer(gl.ARRAY_BUFFER, attributeBuffer);
276− gl.vertexAttribPointer(attribLocation, 3, gl.FLOAT, false, 0, 0);
277− break;
278− default:
279− console.log("Unsupported attribute type: " + attribute.type);
280− break;
281− }
282− }
283−
284− gl.drawElements(gl.TRIANGLES, numIndices, gl.UNSIGNED_SHORT, 0);
285−
286− }
287−
288− List.each(drawModel, model.models);
289−
290− }
291−
292− function webgl(dimensions, models) {
293−
294− if (!window.WebGLRenderingContext) {
295− throw new Error("It appears your browser does not support WebGL! http://get.webgl.org/troubleshooting");
296− return;
297− }
298−
299− var w = dimensions._0;
300− var h = dimensions._1;
301−
302− function render(model) {
303−
304− var div = newNode('div');
305− div.style.overflow = 'hidden';
306− var canvas = newNode('canvas');
307− var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
308− gl.enable(gl.DEPTH_TEST);
309−
310− model.cache.gl = gl;
311− model.cache.canvas = canvas;
312− model.cache.shaders = [];
313− model.cache.programs = {};
314− model.cache.buffers = [];
315− model.cache.textures = [];
316−
317− update(div, model, model);
318−
319− return div;
320−
321− }
322−
323− function update(div, oldModel, newModel) {
324−
325− newModel.cache = oldModel.cache;
326−
327− var canvas = newModel.cache.canvas;
328−
329− canvas.style.width = oldModel.w + 'px';
330− canvas.style.height = oldModel.h + 'px';
331− canvas.style.display = "block";
332− canvas.style.position = "absolute";
333− canvas.width = oldModel.w;
334− canvas.height = oldModel.h;
335−
336− drawGL(newModel);
337−
338− div.appendChild(canvas);
339−
340− }
341−
342− var elem = {
343− ctor: 'Custom',
344− type: 'WebGL',
345− render: render,
346− update: update,
347− model: {
348− models: models,
349− cache: {},
350− w: w,
351− h: h,
352− }
353− };
354−
355− return A3(newElement, w, h, elem);
356−
357− }
358−
359− return elm.Native.Graphics.WebGL.values = {
360− unsafeCoerceGLSL:unsafeCoerceGLSL,
361− loadTex:loadTex,
362− model:F4(model),
363− webgl:F2(webgl)
364− };
365−
366−};
libraries/Native/Json.js+1−1
@@ -79,7 +79,7 @@ Elm.Native.Json.make = function(elm) {
79 toString : F2(toString),
79 toString : F2(toString),
80 fromString : fromString,
80 fromString : fromString,
81 fromJS : fromJS,
81 fromJS : fromJS,
82− toJS : toJS,
82+ toJS : toJS
83 };
83 };
84
84
85};
85};
libraries/Native/MJS.jsdeleted−1783
@@ -1,1783 +0,0 @@
1−
2−/*
3− * Copyright (c) 2010 Mozilla Corporation
4− * Copyright (c) 2010 Vladimir Vukicevic
5− * Copyright (c) 2013 John Mayer
6− *
7− * Permission is hereby granted, free of charge, to any person
8− * obtaining a copy of this software and associated documentation
9− * files (the "Software"), to deal in the Software without
10− * restriction, including without limitation the rights to use,
11− * copy, modify, merge, publish, distribute, sublicense, and/or sell
12− * copies of the Software, and to permit persons to whom the
13− * Software is furnished to do so, subject to the following
14− * conditions:
15− *
16− * The above copyright notice and this permission notice shall be
17− * included in all copies or substantial portions of the Software.
18− *
19− * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20− * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21− * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22− * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23− * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24− * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25− * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26− * OTHER DEALINGS IN THE SOFTWARE.
27− */
28−
29−/*
30− * File: mjs
31− *
32− * Vector and Matrix math utilities for JavaScript, optimized for WebGL.
33− * Edited to work with Elm Programming Language
34− */
35−
36−Elm.Native.MJS = {};
37−Elm.Native.MJS.make = function(elm) {
38−
39− elm.Native = elm.Native || {};
40− elm.Native.MJS = elm.Native.MJS || {};
41− if (elm.Native.MJS.values) return elm.Native.MJS.values;
42−
43− /*
44− * Constant: MJS_VERSION
45− *
46− * mjs version number aa.bb.cc, encoded as an integer of the form:
47− * 0xaabbcc.
48− */
49− var MJS_VERSION = 0x000000;
50−
51− /*
52− * Constant: MJS_DO_ASSERT
53− *
54− * Enables or disables runtime assertions.
55− *
56− * For potentially more performance, the assert methods can be
57− * commented out in each place where they are called.
58− */
59− //var MJS_DO_ASSERT = true;
60−
61− /*
62− * Constant: MJS_FLOAT_ARRAY_TYPE
63− *
64− * The base float array type. By default, WebGLFloatArray.
65− *
66− * mjs can work with any array-like elements, but if an array
67− * creation is requested, it will create an array of the type
68− * MJS_FLOAT_ARRAY_TYPE. Also, the builtin constants such as (M4x4.I)
69− * will be of this type.
70− */
71− //MJS_FLOAT_ARRAY_TYPE = WebGLFloatArray;
72− var MJS_FLOAT_ARRAY_TYPE = Float32Array;
73− //MJS_FLOAT_ARRAY_TYPE = Float64Array;
74− //MJS_FLOAT_ARRAY_TYPE = Array;
75−
76− //if (MJS_DO_ASSERT) {
77− //function MathUtils_assert(cond, msg) {
78− //if (!cond)
79− //throw "Assertion failed: " + msg;
80− //}
81− //} else {
82− function MathUtils_assert() { }
83− //}
84−
85− /*
86− * Class: V3
87− *
88− * Methods for working with 3-element vectors. A vector is represented by a 3-element array.
89− * Any valid JavaScript array type may be used, but if new
90− * vectors are created they are created using the configured MJS_FLOAT_ARRAY_TYPE.
91− */
92−
93− var V3 = { };
94−
95− V3._temp1 = new MJS_FLOAT_ARRAY_TYPE(3);
96− V3._temp2 = new MJS_FLOAT_ARRAY_TYPE(3);
97− V3._temp3 = new MJS_FLOAT_ARRAY_TYPE(3);
98−
99− if (MJS_FLOAT_ARRAY_TYPE == Array) {
100− V3.x = [1.0, 0.0, 0.0];
101− V3.y = [0.0, 1.0, 0.0];
102− V3.z = [0.0, 0.0, 1.0];
103−
104− V3.$ = function V3_$(x, y, z) {
105− return [x, y, z];
106− };
107−
108− V3.clone = function V3_clone(a) {
109− //MathUtils_assert(a.length == 3, "a.length == 3");
110− return [a[0], a[1], a[2]];
111− };
112− } else {
113− V3.x = new MJS_FLOAT_ARRAY_TYPE([1.0, 0.0, 0.0]);
114− V3.y = new MJS_FLOAT_ARRAY_TYPE([0.0, 1.0, 0.0]);
115− V3.z = new MJS_FLOAT_ARRAY_TYPE([0.0, 0.0, 1.0]);
116−
117− /*
118− * Function: V3.$
119− *
120− * Creates a new 3-element vector with the given values.
121− *
122− * Parameters:
123− *
124− * x,y,z - the 3 elements of the new vector.
125− *
126− * Returns:
127− *
128− * A new vector containing with the given argument values.
129− */
130−
131− V3.$ = function V3_$(x, y, z) {
132− return new MJS_FLOAT_ARRAY_TYPE([x, y, z]);
133− };
134−
135− /*
136− * Function: V3.clone
137− *
138− * Clone the given 3-element vector.
139− *
140− * Parameters:
141− *
142− * a - the 3-element vector to clone
143− *
144− * Returns:
145− *
146− * A new vector with the same values as the passed-in one.
147− */
148−
149− V3.clone = function V3_clone(a) {
150− //MathUtils_assert(a.length == 3, "a.length == 3");
151− return new MJS_FLOAT_ARRAY_TYPE(a);
152− };
153− }
154−
155− V3.u = V3.x;
156− V3.v = V3.y;
157−
158− /* Function: V3.toTuple3
159− *
160− * Turn into an Elm Tuple
161− */
162− V3.toTuple3 = function V3_toTuple3(a) {
163− return v = {
164− ctor:"_Tuple3",
165− _0:a[0],
166− _1:a[1],
167− _2:a[2]
168− };
169− };
170−
171− /*
172− * Function: V3.add
173− *
174− * Perform r = a + b.
175− *
176− * Parameters:
177− *
178− * a - the first vector operand
179− * b - the second vector operand
180− * r - optional vector to store the result in
181− *
182− * Returns:
183− *
184− * If r is specified, returns r after performing the operation.
185− * Otherwise, returns a new 3-element vector with the result.
186− */
187− V3.add = function V3_add(a, b, r) {
188− //MathUtils_assert(a.length == 3, "a.length == 3");
189− //MathUtils_assert(b.length == 3, "b.length == 3");
190− //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
191−
192− if (r == undefined)
193− r = new MJS_FLOAT_ARRAY_TYPE(3);
194− r[0] = a[0] + b[0];
195− r[1] = a[1] + b[1];
196− r[2] = a[2] + b[2];
197− return r;
198− };
199−
200− /*
201− * Function: V3.sub
202− *
203− * Perform
204− * r = a - b.
205− *
206− * Parameters:
207− *
208− * a - the first vector operand
209− * b - the second vector operand
210− * r - optional vector to store the result in
211− *
212− * Returns:
213− *
214− * If r is specified, returns r after performing the operation.
215− * Otherwise, returns a new 3-element vector with the result.
216− */
217− V3.sub = function V3_sub(a, b, r) {
218− //MathUtils_assert(a.length == 3, "a.length == 3");
219− //MathUtils_assert(b.length == 3, "b.length == 3");
220− //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
221−
222− if (r == undefined)
223− r = new MJS_FLOAT_ARRAY_TYPE(3);
224− r[0] = a[0] - b[0];
225− r[1] = a[1] - b[1];
226− r[2] = a[2] - b[2];
227− return r;
228− };
229−
230− /*
231− * Function: V3.neg
232− *
233− * Perform
234− * r = - a.
235− *
236− * Parameters:
237− *
238− * a - the vector operand
239− * r - optional vector to store the result in
240− *
241− * Returns:
242− *
243− * If r is specified, returns r after performing the operation.
244− * Otherwise, returns a new 3-element vector with the result.
245− */
246− V3.neg = function V3_neg(a, r) {
247− //MathUtils_assert(a.length == 3, "a.length == 3");
248− //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
249−
250− if (r == undefined)
251− r = new MJS_FLOAT_ARRAY_TYPE(3);
252− r[0] = - a[0];
253− r[1] = - a[1];
254− r[2] = - a[2];
255− return r;
256− };
257−
258− /*
259− * Function: V3.direction
260− *
261− * Perform
262− * r = (a - b) / |a - b|. The result is the normalized
263− * direction from a to b.
264− *
265− * Parameters:
266− *
267− * a - the first vector operand
268− * b - the second vector operand
269− * r - optional vector to store the result in
270− *
271− * Returns:
272− *
273− * If r is specified, returns r after performing the operation.
274− * Otherwise, returns a new 3-element vector with the result.
275− */
276− V3.direction = function V3_direction(a, b, r) {
277− //MathUtils_assert(a.length == 3, "a.length == 3");
278− //MathUtils_assert(b.length == 3, "b.length == 3");
279− //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
280−
281− if (r == undefined)
282− r = new MJS_FLOAT_ARRAY_TYPE(3);
283− return V3.normalize(V3.sub(a, b, r), r);
284− };
285−
286− /*
287− * Function: V3.length
288− *
289− * Perform r = |a|.
290− *
291− * Parameters:
292− *
293− * a - the vector operand
294− *
295− * Returns:
296− *
297− * The length of the given vector.
298− */
299− V3.length = function V3_length(a) {
300− //MathUtils_assert(a.length == 3, "a.length == 3");
301−
302− return Math.sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]);
303− };
304−
305− /*
306− * Function: V3.lengthSquard
307− *
308− * Perform r = |a|*|a|.
309− *
310− * Parameters:
311− *
312− * a - the vector operand
313− *
314− * Returns:
315− *
316− * The square of the length of the given vector.
317− */
318− V3.lengthSquared = function V3_lengthSquared(a) {
319− //MathUtils_assert(a.length == 3, "a.length == 3");
320−
321− return a[0]*a[0] + a[1]*a[1] + a[2]*a[2];
322− };
323−
324− /*
325− * Function: V3.normalize
326− *
327− * Perform r = a / |a|.
328− *
329− * Parameters:
330− *
331− * a - the vector operand
332− * r - optional vector to store the result in
333− *
334− * Returns:
335− *
336− * If r is specified, returns r after performing the operation.
337− * Otherwise, returns a new 3-element vector with the result.
338− */
339− V3.normalize = function V3_normalize(a, r) {
340− //MathUtils_assert(a.length == 3, "a.length == 3");
341− //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
342−
343− if (r == undefined)
344− r = new MJS_FLOAT_ARRAY_TYPE(3);
345− var im = 1.0 / V3.length(a);
346− r[0] = a[0] * im;
347− r[1] = a[1] * im;
348− r[2] = a[2] * im;
349− return r;
350− };
351−
352− /*
353− * Function: V3.scale
354− *
355− * Perform r = a * k.
356− *
357− * Parameters:
358− *
359− * a - the vector operand
360− * k - a scalar value
361− * r - optional vector to store the result in
362− *
363− * Returns:
364− *
365− * If r is specified, returns r after performing the operation.
366− * Otherwise, returns a new 3-element vector with the result.
367− */
368− V3.scale = function V3_scale(a, k, r) {
369− //MathUtils_assert(a.length == 3, "a.length == 3");
370− //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
371−
372− if (r == undefined)
373− r = new MJS_FLOAT_ARRAY_TYPE(3);
374− r[0] = a[0] * k;
375− r[1] = a[1] * k;
376− r[2] = a[2] * k;
377− return r;
378− };
379−
380− /*
381− * Function: V3.dot
382− *
383− * Perform
384− * r = dot(a, b).
385− *
386− * Parameters:
387− *
388− * a - the first vector operand
389− * b - the second vector operand
390− *
391− * Returns:
392− *
393− * The dot product of a and b.
394− */
395− V3.dot = function V3_dot(a, b) {
396− //MathUtils_assert(a.length == 3, "a.length == 3");
397− //MathUtils_assert(b.length == 3, "b.length == 3");
398−
399− return a[0] * b[0] +
400− a[1] * b[1] +
401− a[2] * b[2];
402− };
403−
404− /*
405− * Function: V3.cross
406− *
407− * Perform r = a x b.
408− *
409− * Parameters:
410− *
411− * a - the first vector operand
412− * b - the second vector operand
413− * r - optional vector to store the result in
414− *
415− * Returns:
416− *
417− * If r is specified, returns r after performing the operation.
418− * Otherwise, returns a new 3-element vector with the result.
419− */
420− V3.cross = function V3_cross(a, b, r) {
421− //MathUtils_assert(a.length == 3, "a.length == 3");
422− //MathUtils_assert(b.length == 3, "b.length == 3");
423− //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
424−
425− if (r == undefined)
426− r = new MJS_FLOAT_ARRAY_TYPE(3);
427− r[0] = a[1]*b[2] - a[2]*b[1];
428− r[1] = a[2]*b[0] - a[0]*b[2];
429− r[2] = a[0]*b[1] - a[1]*b[0];
430− return r;
431− };
432−
433− /*
434− * Function: V3.mul4x4
435− *
436− * Perform
437− * r = m * v.
438− *
439− * Parameters:
440− *
441− * m - the 4x4 matrix operand
442− * v - the 3-element vector operand
443− * r - optional vector to store the result in
444− *
445− * Returns:
446− *
447− * If r is specified, returns r after performing the operation.
448− * Otherwise, returns a new 3-element vector with the result.
449− * The 4-element result vector is divided by the w component
450− * and returned as a 3-element vector.
451− */
452− V3.mul4x4 = function V3_mul4x4(m, v, r) {
453− //MathUtils_assert(m.length == 16, "m.length == 16");
454− //MathUtils_assert(v.length == 3, "v.length == 3");
455− //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
456−
457− var w;
458− var tmp = V3._temp1;
459− if (r == undefined)
460− r = new MJS_FLOAT_ARRAY_TYPE(3);
461− tmp[0] = m[ 3];
462− tmp[1] = m[ 7];
463− tmp[2] = m[11];
464− w = V3.dot(v, tmp) + m[15];
465− tmp[0] = m[ 0];
466− tmp[1] = m[ 4];
467− tmp[2] = m[ 8];
468− r[0] = (V3.dot(v, tmp) + m[12])/w;
469− tmp[0] = m[ 1];
470− tmp[1] = m[ 5];
471− tmp[2] = m[ 9];
472− r[1] = (V3.dot(v, tmp) + m[13])/w;
473− tmp[0] = m[ 2];
474− tmp[1] = m[ 6];
475− tmp[2] = m[10];
476− r[2] = (V3.dot(v, tmp) + m[14])/w;
477− return r;
478− };
479−
480− /*
481− * Class: M4x4
482− *
483− * Methods for working with 4x4 matrices. A matrix is represented by a 16-element array
484− * in column-major order. Any valid JavaScript array type may be used, but if new
485− * matrices are created they are created using the configured MJS_FLOAT_ARRAY_TYPE.
486− */
487−
488− var M4x4 = { };
489−
490− M4x4._temp1 = new MJS_FLOAT_ARRAY_TYPE(16);
491− M4x4._temp2 = new MJS_FLOAT_ARRAY_TYPE(16);
492−
493− if (MJS_FLOAT_ARRAY_TYPE == Array) {
494− M4x4.I = [1.0, 0.0, 0.0, 0.0,
495− 0.0, 1.0, 0.0, 0.0,
496− 0.0, 0.0, 1.0, 0.0,
497− 0.0, 0.0, 0.0, 1.0];
498−
499− M4x4.$ = function M4x4_$(m00, m01, m02, m03,
500− m04, m05, m06, m07,
501− m08, m09, m10, m11,
502− m12, m13, m14, m15)
503− {
504− return [m00, m01, m02, m03,
505− m04, m05, m06, m07,
506− m08, m09, m10, m11,
507− m12, m13, m14, m15];
508− };
509−
510− M4x4.clone = function M4x4_clone(m) {
511− //MathUtils_assert(m.length == 16, "m.length == 16");
512− return new [m[0], m[1], m[2], m[3],
513− m[4], m[5], m[6], m[7],
514− m[8], m[9], m[10], m[11],
515− m[12], m[13], m[14], m[15]];
516− };
517− } else {
518− M4x4.I = new MJS_FLOAT_ARRAY_TYPE([1.0, 0.0, 0.0, 0.0,
519− 0.0, 1.0, 0.0, 0.0,
520− 0.0, 0.0, 1.0, 0.0,
521− 0.0, 0.0, 0.0, 1.0]);
522−
523− /*
524− * Function: M4x4.$
525− *
526− * Creates a new 4x4 matrix with the given values.
527− *
528− * Parameters:
529− *
530− * m00..m15 - the 16 elements of the new matrix.
531− *
532− * Returns:
533− *
534− * A new matrix filled with the given argument values.
535− */
536− M4x4.$ = function M4x4_$(m00, m01, m02, m03,
537− m04, m05, m06, m07,
538− m08, m09, m10, m11,
539− m12, m13, m14, m15)
540− {
541− return new MJS_FLOAT_ARRAY_TYPE([m00, m01, m02, m03,
542− m04, m05, m06, m07,
543− m08, m09, m10, m11,
544− m12, m13, m14, m15]);
545− };
546−
547− /*
548− * Function: M4x4.clone
549− *
550− * Clone the given 4x4 matrix.
551− *
552− * Parameters:
553− *
554− * m - the 4x4 matrix to clone
555− *
556− * Returns:
557− *
558− * A new matrix with the same values as the passed-in one.
559− */
560− M4x4.clone = function M4x4_clone(m) {
561− //MathUtils_assert(m.length == 16, "m.length == 16");
562− return new MJS_FLOAT_ARRAY_TYPE(m);
563− };
564− }
565−
566− M4x4.identity = M4x4.I;
567−
568− /*
569− * Function: M4x4.topLeft3x3
570− *
571− * Return the top left 3x3 matrix from the given 4x4 matrix m.
572− *
573− * Parameters:
574− *
575− * m - the matrix
576− * r - optional 3x3 matrix to store the result in
577− *
578− * Returns:
579− *
580− * If r is specified, returns r after performing the operation.
581− * Otherwise, returns a new 3x3 matrix with the result.
582− */
583− M4x4.topLeft3x3 = function M4x4_topLeft3x3(m, r) {
584− //MathUtils_assert(m.length == 16, "m.length == 16");
585− //MathUtils_assert(r == undefined || r.length == 9, "r == undefined || r.length == 9");
586−
587− if (r == undefined)
588− r = new MJS_FLOAT_ARRAY_TYPE(9);
589− r[0] = m[0]; r[1] = m[1]; r[2] = m[2];
590− r[3] = m[4]; r[4] = m[5]; r[5] = m[6];
591− r[6] = m[8]; r[7] = m[9]; r[8] = m[10];
592− return r;
593− };
594−
595− /*
596− * Function: M4x4.inverseOrthonormal
597− *
598− * Computes the inverse of the given matrix m, assuming that
599− * the matrix is orthonormal.
600− *
601− * Parameters:
602− *
603− * m - the matrix
604− * r - optional 4x4 matrix to store the result in
605− *
606− * Returns:
607− *
608− * If r is specified, returns r after performing the operation.
609− * Otherwise, returns a new 4x4 matrix with the result.
610− */
611− M4x4.inverseOrthonormal = function M4x4_inverseOrthonormal(m, r) {
612− //MathUtils_assert(m.length == 16, "m.length == 16");
613− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
614− //MathUtils_assert(m != r, "m != r");
615−
616− if (r == undefined)
617− r = new MJS_FLOAT_ARRAY_TYPE(16);
618− M4x4.transpose(m, r);
619− var t = [m[12], m[13], m[14]];
620− r[3] = r[7] = r[11] = 0;
621− r[12] = -V3.dot([r[0], r[4], r[8]], t);
622− r[13] = -V3.dot([r[1], r[5], r[9]], t);
623− r[14] = -V3.dot([r[2], r[6], r[10]], t);
624− return r;
625− };
626−
627− /*
628− * Function: M4x4.inverseTo3x3
629− *
630− * Computes the inverse of the given matrix m, but calculates
631− * only the top left 3x3 values of the result.
632− *
633− * Parameters:
634− *
635− * m - the matrix
636− * r - optional 3x3 matrix to store the result in
637− *
638− * Returns:
639− *
640− * If r is specified, returns r after performing the operation.
641− * Otherwise, returns a new 3x3 matrix with the result.
642− */
643− M4x4.inverseTo3x3 = function M4x4_inverseTo3x3(m, r) {
644− //MathUtils_assert(m.length == 16, "m.length == 16");
645− //MathUtils_assert(r == undefined || r.length == 9, "r == undefined || r.length == 9");
646−
647− if (r == undefined)
648− r = new MJS_FLOAT_ARRAY_TYPE(9);
649−
650− var a11 = m[10]*m[5]-m[6]*m[9],
651− a21 = -m[10]*m[1]+m[2]*m[9],
652− a31 = m[6]*m[1]-m[2]*m[5],
653− a12 = -m[10]*m[4]+m[6]*m[8],
654− a22 = m[10]*m[0]-m[2]*m[8],
655− a32 = -m[6]*m[0]+m[2]*m[4],
656− a13 = m[9]*m[4]-m[5]*m[8],
657− a23 = -m[9]*m[0]+m[1]*m[8],
658− a33 = m[5]*m[0]-m[1]*m[4];
659− var det = m[0]*(a11) + m[1]*(a12) + m[2]*(a13);
660− if (det == 0) // no inverse
661− throw "matrix not invertible";
662− var idet = 1.0 / det;
663−
664− r[0] = idet*a11;
665− r[1] = idet*a21;
666− r[2] = idet*a31;
667− r[3] = idet*a12;
668− r[4] = idet*a22;
669− r[5] = idet*a32;
670− r[6] = idet*a13;
671− r[7] = idet*a23;
672− r[8] = idet*a33;
673−
674− return r;
675− };
676−
677− /*
678− * Function: M4x4.makeFrustum
679− *
680− * Creates a matrix for a projection frustum with the given parameters.
681− *
682− * Parameters:
683− *
684− * left - the left coordinate of the frustum
685− * right- the right coordinate of the frustum
686− * bottom - the bottom coordinate of the frustum
687− * top - the top coordinate of the frustum
688− * znear - the near z distance of the frustum
689− * zfar - the far z distance of the frustum
690− * r - optional 4x4 matrix to store the result in
691− *
692− * Returns:
693− *
694− * If r is specified, returns r after creating the projection matrix.
695− * Otherwise, returns a new 4x4 matrix.
696− */
697− M4x4.makeFrustum = function M4x4_makeFrustum(left, right, bottom, top, znear, zfar, r) {
698− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
699−
700− if (r == undefined)
701− r = new MJS_FLOAT_ARRAY_TYPE(16);
702−
703− var X = 2*znear/(right-left);
704− var Y = 2*znear/(top-bottom);
705− var A = (right+left)/(right-left);
706− var B = (top+bottom)/(top-bottom);
707− var C = -(zfar+znear)/(zfar-znear);
708− var D = -2*zfar*znear/(zfar-znear);
709−
710− r[0] = 2*znear/(right-left);
711− r[1] = 0;
712− r[2] = 0;
713− r[3] = 0;
714− r[4] = 0;
715− r[5] = 2*znear/(top-bottom);
716− r[6] = 0;
717− r[7] = 0;
718− r[8] = (right+left)/(right-left);
719− r[9] = (top+bottom)/(top-bottom);
720− r[10] = -(zfar+znear)/(zfar-znear);
721− r[11] = -1;
722− r[12] = 0;
723− r[13] = 0;
724− r[14] = -2*zfar*znear/(zfar-znear);
725− r[15] = 0;
726−
727− return r;
728− };
729−
730− /*
731− * Function: M4x4.makePerspective
732− *
733− * Creates a matrix for a perspective projection with the given parameters.
734− *
735− * Parameters:
736− *
737− * fovy - field of view in the y axis, in degrees
738− * aspect - aspect ratio
739− * znear - the near z distance of the projection
740− * zfar - the far z distance of the projection
741− * r - optional 4x4 matrix to store the result in
742− *
743− * Returns:
744− *
745− * If r is specified, returns r after creating the projection matrix.
746− * Otherwise, returns a new 4x4 matrix.
747− */
748− M4x4.makePerspective = function M4x4_makePerspective (fovy, aspect, znear, zfar, r) {
749− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
750−
751− var ymax = znear * Math.tan(fovy * Math.PI / 360.0);
752− var ymin = -ymax;
753− var xmin = ymin * aspect;
754− var xmax = ymax * aspect;
755−
756− return M4x4.makeFrustum(xmin, xmax, ymin, ymax, znear, zfar, r);
757− };
758−
759− /*
760− * Function: M4x4.makeOrtho
761− *
762− * Creates a matrix for an orthogonal frustum projection with the given parameters.
763− *
764− * Parameters:
765− *
766− * left - the left coordinate of the frustum
767− * right- the right coordinate of the frustum
768− * bottom - the bottom coordinate of the frustum
769− * top - the top coordinate of the frustum
770− * znear - the near z distance of the frustum
771− * zfar - the far z distance of the frustum
772− * r - optional 4x4 matrix to store the result in
773− *
774− * Returns:
775− *
776− * If r is specified, returns r after creating the projection matrix.
777− * Otherwise, returns a new 4x4 matrix.
778− */
779− M4x4.makeOrtho = function M4x4_makeOrtho (left, right, bottom, top, znear, zfar, r) {
780− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
781−
782− if (r == undefined)
783− r = new MJS_FLOAT_ARRAY_TYPE(16);
784−
785− var tX = -(right+left)/(right-left);
786− var tY = -(top+bottom)/(top-bottom);
787− var tZ = -(zfar+znear)/(zfar-znear);
788− var X = 2 / (right-left);
789− var Y = 2 / (top-bottom);
790− var Z = -2 / (zfar-znear);
791−
792− r[0] = 2 / (right-left);
793− r[1] = 0;
794− r[2] = 0;
795− r[3] = 0;
796− r[4] = 0;
797− r[5] = 2 / (top-bottom);
798− r[6] = 0;
799− r[7] = 0;
800− r[8] = 0;
801− r[9] = 0;
802− r[10] = -2 / (zfar-znear);
803− r[11] = 0;
804− r[12] = -(right+left)/(right-left);
805− r[13] = -(top+bottom)/(top-bottom);
806− r[14] = -(zfar+znear)/(zfar-znear);
807− r[15] = 1;
808−
809− return r;
810− };
811−
812− /*
813− * Function: M4x4.makeOrtho2D
814− *
815− * Creates a matrix for a 2D orthogonal frustum projection with the given parameters.
816− * znear and zfar are assumed to be -1 and 1, respectively.
817− *
818− * Parameters:
819− *
820− * left - the left coordinate of the frustum
821− * right- the right coordinate of the frustum
822− * bottom - the bottom coordinate of the frustum
823− * top - the top coordinate of the frustum
824− * r - optional 4x4 matrix to store the result in
825− *
826− * Returns:
827− *
828− * If r is specified, returns r after creating the projection matrix.
829− * Otherwise, returns a new 4x4 matrix.
830− */
831− M4x4.makeOrtho2D = function M4x4_makeOrtho2D (left, right, bottom, top, r) {
832− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
833−
834− return M4x4.makeOrtho(left, right, bottom, top, -1, 1, r);
835− };
836−
837− /*
838− * Function: M4x4.mul
839− *
840− * Performs r = a * b.
841− *
842− * Parameters:
843− *
844− * a - the first matrix operand
845− * b - the second matrix operand
846− * r - optional 4x4 matrix to store the result in
847− *
848− * Returns:
849− *
850− * If r is specified, returns r after performing the operation.
851− * Otherwise, returns a new 4x4 matrix with the result.
852− */
853− M4x4.mul = function M4x4_mul(a, b, r) {
854− //MathUtils_assert(a.length == 16, "a.length == 16");
855− //MathUtils_assert(b.length == 16, "b.length == 16");
856− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
857− //MathUtils_assert(a != r && b != r, "a != r && b != r");
858−
859− if (r == undefined)
860− r = new MJS_FLOAT_ARRAY_TYPE(16);
861−
862− var a11 = a[0];
863− var a21 = a[1];
864− var a31 = a[2];
865− var a41 = a[3];
866− var a12 = a[4];
867− var a22 = a[5];
868− var a32 = a[6];
869− var a42 = a[7];
870− var a13 = a[8];
871− var a23 = a[9];
872− var a33 = a[10];
873− var a43 = a[11];
874− var a14 = a[12];
875− var a24 = a[13];
876− var a34 = a[14];
877− var a44 = a[15];
878−
879− var b11 = b[0];
880− var b21 = b[1];
881− var b31 = b[2];
882− var b41 = b[3];
883− var b12 = b[4];
884− var b22 = b[5];
885− var b32 = b[6];
886− var b42 = b[7];
887− var b13 = b[8];
888− var b23 = b[9];
889− var b33 = b[10];
890− var b43 = b[11];
891− var b14 = b[12];
892− var b24 = b[13];
893− var b34 = b[14];
894− var b44 = b[15];
895−
896− r[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
897− r[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
898− r[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
899− r[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
900− r[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
901− r[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
902− r[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
903− r[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
904− r[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
905− r[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
906− r[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
907− r[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
908− r[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
909− r[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
910− r[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
911− r[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
912−
913− return r;
914− };
915−
916− /*
917− * Function: M4x4.mulAffine
918− *
919− * Performs r = a * b, assuming a and b are affine (elements 3,7,11,15 = 0,0,0,1)
920− *
921− * Parameters:
922− *
923− * a - the first matrix operand
924− * b - the second matrix operand
925− * r - optional 4x4 matrix to store the result in
926− *
927− * Returns:
928− *
929− * If r is specified, returns r after performing the operation.
930− * Otherwise, returns a new 4x4 matrix with the result.
931− */
932− M4x4.mulAffine = function M4x4_mulAffine(a, b, r) {
933− //MathUtils_assert(a.length == 16, "a.length == 16");
934− //MathUtils_assert(b.length == 16, "b.length == 16");
935− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
936− //MathUtils_assert(a != r && b != r, "a != r && b != r");
937−
938− if (r == undefined)
939− r = new MJS_FLOAT_ARRAY_TYPE(16);
940− var a11 = a[0];
941− var a21 = a[1];
942− var a31 = a[2];
943− var a12 = a[4];
944− var a22 = a[5];
945− var a32 = a[6];
946− var a13 = a[8];
947− var a23 = a[9];
948− var a33 = a[10];
949− var a14 = a[12];
950− var a24 = a[13];
951− var a34 = a[14];
952−
953− var b11 = b[0];
954− var b21 = b[1];
955− var b31 = b[2];
956− var b12 = b[4];
957− var b22 = b[5];
958− var b32 = b[6];
959− var b13 = b[8];
960− var b23 = b[9];
961− var b33 = b[10];
962− var b14 = b[12];
963− var b24 = b[13];
964− var b34 = b[14];
965−
966− r[0] = a11 * b11 + a12 * b21 + a13 * b31;
967− r[1] = a21 * b11 + a22 * b21 + a23 * b31;
968− r[2] = a31 * b11 + a32 * b21 + a33 * b31;
969− r[3] = 0;
970− r[4] = a11 * b12 + a12 * b22 + a13 * b32;
971− r[5] = a21 * b12 + a22 * b22 + a23 * b32;
972− r[6] = a31 * b12 + a32 * b22 + a33 * b32;
973− r[7] = 0;
974− r[8] = a11 * b13 + a12 * b23 + a13 * b33;
975− r[9] = a21 * b13 + a22 * b23 + a23 * b33;
976− r[10] = a31 * b13 + a32 * b23 + a33 * b33;
977− r[11] = 0;
978− r[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14;
979− r[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24;
980− r[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34;
981− r[15] = 1;
982−
983− return r;
984− };
985−
986− /*
987− * Function: M4x4.makeRotate
988− *
989− * Creates a transformation matrix for rotation by angle radians about the 3-element vector axis.
990− *
991− * Parameters:
992− *
993− * angle - the angle of rotation, in radians
994− * axis - the axis around which the rotation is performed, a 3-element vector
995− * r - optional 4x4 matrix to store the result in
996− *
997− * Returns:
998− *
999− * If r is specified, returns r after creating the matrix.
1000− * Otherwise, returns a new 4x4 matrix with the result.
1001− */
1002− M4x4.makeRotate = function M4x4_makeRotate(angle, axis, r) {
1003− //MathUtils_assert(angle.length == 3, "angle.length == 3");
1004− //MathUtils_assert(axis.length == 3, "axis.length == 3");
1005− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1006−
1007− if (r == undefined)
1008− r = new MJS_FLOAT_ARRAY_TYPE(16);
1009−
1010− axis = V3.normalize(axis, V3._temp1);
1011− var x = axis[0], y = axis[1], z = axis[2];
1012− var c = Math.cos(angle);
1013− var c1 = 1-c;
1014− var s = Math.sin(angle);
1015−
1016− r[0] = x*x*c1+c;
1017− r[1] = y*x*c1+z*s;
1018− r[2] = z*x*c1-y*s;
1019− r[3] = 0;
1020− r[4] = x*y*c1-z*s;
1021− r[5] = y*y*c1+c;
1022− r[6] = y*z*c1+x*s;
1023− r[7] = 0;
1024− r[8] = x*z*c1+y*s;
1025− r[9] = y*z*c1-x*s;
1026− r[10] = z*z*c1+c;
1027− r[11] = 0;
1028− r[12] = 0;
1029− r[13] = 0;
1030− r[14] = 0;
1031− r[15] = 1;
1032−
1033− return r;
1034− };
1035−
1036− /*
1037− * Function: M4x4.rotate
1038− *
1039− * Concatenates a rotation of angle radians about the axis to the give matrix m.
1040− *
1041− * Parameters:
1042− *
1043− * angle - the angle of rotation, in radians
1044− * axis - the axis around which the rotation is performed, a 3-element vector
1045− * m - the matrix to concatenate the rotation to
1046− * r - optional 4x4 matrix to store the result in
1047− *
1048− * Returns:
1049− *
1050− * If r is specified, returns r after performing the operation.
1051− * Otherwise, returns a new 4x4 matrix with the result.
1052− */
1053− M4x4.rotate = function M4x4_rotate(angle, axis, m, r) {
1054− //MathUtils_assert(angle.length == 3, "angle.length == 3");
1055− //MathUtils_assert(axis.length == 3, "axis.length == 3");
1056− //MathUtils_assert(m.length == 16, "m.length == 16");
1057− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1058−
1059− if (r == undefined)
1060− r = new MJS_FLOAT_ARRAY_TYPE(16);
1061− var a0=axis [0], a1=axis [1], a2=axis [2];
1062− var l = Math.sqrt(a0*a0 + a1*a1 + a2*a2);
1063− var x = a0, y = a1, z = a2;
1064− if (l != 1.0) {
1065− var im = 1.0 / l;
1066− x *= im;
1067− y *= im;
1068− z *= im;
1069− }
1070− var c = Math.cos(angle);
1071− var c1 = 1-c;
1072− var s = Math.sin(angle);
1073− var xs = x*s;
1074− var ys = y*s;
1075− var zs = z*s;
1076− var xyc1 = x * y * c1;
1077− var xzc1 = x * z * c1;
1078− var yzc1 = y * z * c1;
1079−
1080− var m11 = m[0];
1081− var m21 = m[1];
1082− var m31 = m[2];
1083− var m41 = m[3];
1084− var m12 = m[4];
1085− var m22 = m[5];
1086− var m32 = m[6];
1087− var m42 = m[7];
1088− var m13 = m[8];
1089− var m23 = m[9];
1090− var m33 = m[10];
1091− var m43 = m[11];
1092−
1093− var t11 = x * x * c1 + c;
1094− var t21 = xyc1 + zs;
1095− var t31 = xzc1 - ys;
1096− var t12 = xyc1 - zs;
1097− var t22 = y * y * c1 + c;
1098− var t32 = yzc1 + xs;
1099− var t13 = xzc1 + ys;
1100− var t23 = yzc1 - xs;
1101− var t33 = z * z * c1 + c;
1102−
1103− r[0] = m11 * t11 + m12 * t21 + m13 * t31;
1104− r[1] = m21 * t11 + m22 * t21 + m23 * t31;
1105− r[2] = m31 * t11 + m32 * t21 + m33 * t31;
1106− r[3] = m41 * t11 + m42 * t21 + m43 * t31;
1107− r[4] = m11 * t12 + m12 * t22 + m13 * t32;
1108− r[5] = m21 * t12 + m22 * t22 + m23 * t32;
1109− r[6] = m31 * t12 + m32 * t22 + m33 * t32;
1110− r[7] = m41 * t12 + m42 * t22 + m43 * t32;
1111− r[8] = m11 * t13 + m12 * t23 + m13 * t33;
1112− r[9] = m21 * t13 + m22 * t23 + m23 * t33;
1113− r[10] = m31 * t13 + m32 * t23 + m33 * t33;
1114− r[11] = m41 * t13 + m42 * t23 + m43 * t33;
1115− if (r != m) {
1116− r[12] = m[12];
1117− r[13] = m[13];
1118− r[14] = m[14];
1119− r[15] = m[15];
1120− }
1121− return r;
1122− };
1123−
1124− /*
1125− * Function: M4x4.makeScale3
1126− *
1127− * Creates a transformation matrix for scaling by 3 scalar values, one for
1128− * each of the x, y, and z directions.
1129− *
1130− * Parameters:
1131− *
1132− * x - the scale for the x axis
1133− * y - the scale for the y axis
1134− * z - the scale for the z axis
1135− * r - optional 4x4 matrix to store the result in
1136− *
1137− * Returns:
1138− *
1139− * If r is specified, returns r after creating the matrix.
1140− * Otherwise, returns a new 4x4 matrix with the result.
1141− */
1142− M4x4.makeScale3 = function M4x4_makeScale3(x, y, z, r) {
1143− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1144−
1145− if (r == undefined)
1146− r = new MJS_FLOAT_ARRAY_TYPE(16);
1147−
1148− r[0] = x;
1149− r[1] = 0;
1150− r[2] = 0;
1151− r[3] = 0;
1152− r[4] = 0;
1153− r[5] = y;
1154− r[6] = 0;
1155− r[7] = 0;
1156− r[8] = 0;
1157− r[9] = 0;
1158− r[10] = z;
1159− r[11] = 0;
1160− r[12] = 0;
1161− r[13] = 0;
1162− r[14] = 0;
1163− r[15] = 1;
1164−
1165− return r;
1166− };
1167−
1168− /*
1169− * Function: M4x4.makeScale1
1170− *
1171− * Creates a transformation matrix for a uniform scale by a single scalar value.
1172− *
1173− * Parameters:
1174− *
1175− * k - the scale factor
1176− * r - optional 4x4 matrix to store the result in
1177− *
1178− * Returns:
1179− *
1180− * If r is specified, returns r after creating the matrix.
1181− * Otherwise, returns a new 4x4 matrix with the result.
1182− */
1183− M4x4.makeScale1 = function M4x4_makeScale1(k, r) {
1184− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1185−
1186− return M4x4.makeScale3(k, k, k, r);
1187− };
1188−
1189− /*
1190− * Function: M4x4.makeScale
1191− *
1192− * Creates a transformation matrix for scaling each of the x, y, and z axes by the amount
1193− * given in the corresponding element of the 3-element vector.
1194− *
1195− * Parameters:
1196− *
1197− * v - the 3-element vector containing the scale factors
1198− * r - optional 4x4 matrix to store the result in
1199− *
1200− * Returns:
1201− *
1202− * If r is specified, returns r after creating the matrix.
1203− * Otherwise, returns a new 4x4 matrix with the result.
1204− */
1205− M4x4.makeScale = function M4x4_makeScale(v, r) {
1206− //MathUtils_assert(v.length == 3, "v.length == 3");
1207− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1208−
1209− return M4x4.makeScale3(v[0], v[1], v[2], r);
1210− };
1211−
1212− /*
1213− * Function: M4x4.scale3
1214− */
1215− M4x4.scale3 = function M4x4_scale3(x, y, z, m, r) {
1216− //MathUtils_assert(m.length == 16, "m.length == 16");
1217− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1218−
1219− if (r == m) {
1220− m[0] *= x;
1221− m[1] *= x;
1222− m[2] *= x;
1223− m[3] *= x;
1224− m[4] *= y;
1225− m[5] *= y;
1226− m[6] *= y;
1227− m[7] *= y;
1228− m[8] *= z;
1229− m[9] *= z;
1230− m[10] *= z;
1231− m[11] *= z;
1232− return m;
1233− }
1234−
1235− if (r == undefined)
1236− r = new MJS_FLOAT_ARRAY_TYPE(16);
1237−
1238− r[0] = m[0] * x;
1239− r[1] = m[1] * x;
1240− r[2] = m[2] * x;
1241− r[3] = m[3] * x;
1242− r[4] = m[4] * y;
1243− r[5] = m[5] * y;
1244− r[6] = m[6] * y;
1245− r[7] = m[7] * y;
1246− r[8] = m[8] * z;
1247− r[9] = m[9] * z;
1248− r[10] = m[10] * z;
1249− r[11] = m[11] * z;
1250− r[12] = m[12];
1251− r[13] = m[13];
1252− r[14] = m[14];
1253− r[15] = m[15];
1254−
1255− return r;
1256− };
1257−
1258− /*
1259− * Function: M4x4.scale1
1260− */
1261− M4x4.scale1 = function M4x4_scale1(k, m, r) {
1262− //MathUtils_assert(m.length == 16, "m.length == 16");
1263− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1264− if (r == m) {
1265− m[0] *= k;
1266− m[1] *= k;
1267− m[2] *= k;
1268− m[3] *= k;
1269− m[4] *= k;
1270− m[5] *= k;
1271− m[6] *= k;
1272− m[7] *= k;
1273− m[8] *= k;
1274− m[9] *= k;
1275− m[10] *= k;
1276− m[11] *= k;
1277− return m;
1278− }
1279−
1280−
1281− if (r == undefined)
1282− r = new MJS_FLOAT_ARRAY_TYPE(16);
1283−
1284− r[0] = m[0] * k;
1285− r[1] = m[1] * k;
1286− r[2] = m[2] * k;
1287− r[3] = m[3] * k;
1288− r[4] = m[4] * k;
1289− r[5] = m[5] * k;
1290− r[6] = m[6] * k;
1291− r[7] = m[7] * k;
1292− r[8] = m[8] * k;
1293− r[9] = m[9] * k;
1294− r[10] = m[10] * k;
1295− r[11] = m[11] * k;
1296− r[12] = m[12];
1297− r[13] = m[13];
1298− r[14] = m[14];
1299− r[15] = m[15];
1300−
1301− return r;
1302− };
1303−
1304− /*
1305− * Function: M4x4.scale1
1306− */
1307− M4x4.scale = function M4x4_scale(v, m, r) {
1308− //MathUtils_assert(v.length == 3, "v.length == 3");
1309− //MathUtils_assert(m.length == 16, "m.length == 16");
1310− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1311− var x = v[0], y = v[1], z = v[2];
1312−
1313− if (r == m) {
1314− m[0] *= x;
1315− m[1] *= x;
1316− m[2] *= x;
1317− m[3] *= x;
1318− m[4] *= y;
1319− m[5] *= y;
1320− m[6] *= y;
1321− m[7] *= y;
1322− m[8] *= z;
1323− m[9] *= z;
1324− m[10] *= z;
1325− m[11] *= z;
1326− return m;
1327− }
1328−
1329− if (r == undefined)
1330− r = new MJS_FLOAT_ARRAY_TYPE(16);
1331−
1332−
1333− r[0] = m[0] * x;
1334− r[1] = m[1] * x;
1335− r[2] = m[2] * x;
1336− r[3] = m[3] * x;
1337− r[4] = m[4] * y;
1338− r[5] = m[5] * y;
1339− r[6] = m[6] * y;
1340− r[7] = m[7] * y;
1341− r[8] = m[8] * z;
1342− r[9] = m[9] * z;
1343− r[10] = m[10] * z;
1344− r[11] = m[11] * z;
1345− r[12] = m[12];
1346− r[13] = m[13];
1347− r[14] = m[14];
1348− r[15] = m[15];
1349−
1350− return r;
1351− };
1352−
1353− /*
1354− * Function: M4x4.makeTranslate3
1355− */
1356− M4x4.makeTranslate3 = function M4x4_makeTranslate3(x, y, z, r) {
1357− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1358−
1359− if (r == undefined)
1360− r = new MJS_FLOAT_ARRAY_TYPE(16);
1361−
1362− r[0] = 1;
1363− r[1] = 0;
1364− r[2] = 0;
1365− r[3] = 0;
1366− r[4] = 0;
1367− r[5] = 1;
1368− r[6] = 0;
1369− r[7] = 0;
1370− r[8] = 0;
1371− r[9] = 0;
1372− r[10] = 1;
1373− r[11] = 0;
1374− r[12] = x;
1375− r[13] = y;
1376− r[14] = z;
1377− r[15] = 1;
1378−
1379− return r;
1380− };
1381−
1382− /*
1383− * Function: M4x4.makeTranslate1
1384− */
1385− M4x4.makeTranslate1 = function M4x4_makeTranslate1 (k, r) {
1386− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1387−
1388− return M4x4.makeTranslate3(k, k, k, r);
1389− };
1390−
1391− /*
1392− * Function: M4x4.makeTranslate
1393− */
1394− M4x4.makeTranslate = function M4x4_makeTranslate (v, r) {
1395− //MathUtils_assert(v.length == 3, "v.length == 3");
1396− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1397−
1398− return M4x4.makeTranslate3(v[0], v[1], v[2], r);
1399− };
1400−
1401− /*
1402− * Function: M4x4.translate3Self
1403− */
1404− M4x4.translate3Self = function M4x4_translate3Self (x, y, z, m) {
1405− //MathUtils_assert(m.length == 16, "m.length == 16");
1406− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1407− m[12] += m[0] * x + m[4] * y + m[8] * z;
1408− m[13] += m[1] * x + m[5] * y + m[9] * z;
1409− m[14] += m[2] * x + m[6] * y + m[10] * z;
1410− m[15] += m[3] * x + m[7] * y + m[11] * z;
1411− return m;
1412− };
1413−
1414− /*
1415− * Function: M4x4.translate3
1416− */
1417− M4x4.translate3 = function M4x4_translate3 (x, y, z, m, r) {
1418− //MathUtils_assert(m.length == 16, "m.length == 16");
1419− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1420−
1421− if (r == m) {
1422− m[12] += m[0] * x + m[4] * y + m[8] * z;
1423− m[13] += m[1] * x + m[5] * y + m[9] * z;
1424− m[14] += m[2] * x + m[6] * y + m[10] * z;
1425− m[15] += m[3] * x + m[7] * y + m[11] * z;
1426− return m;
1427− }
1428−
1429− if (r == undefined)
1430− r = new MJS_FLOAT_ARRAY_TYPE(16);
1431−
1432− var m11 = m[0];
1433− var m21 = m[1];
1434− var m31 = m[2];
1435− var m41 = m[3];
1436− var m12 = m[4];
1437− var m22 = m[5];
1438− var m32 = m[6];
1439− var m42 = m[7];
1440− var m13 = m[8];
1441− var m23 = m[9];
1442− var m33 = m[10];
1443− var m43 = m[11];
1444−
1445−
1446− r[0] = m11;
1447− r[1] = m21;
1448− r[2] = m31;
1449− r[3] = m41;
1450− r[4] = m12;
1451− r[5] = m22;
1452− r[6] = m32;
1453− r[7] = m42;
1454− r[8] = m13;
1455− r[9] = m23;
1456− r[10] = m33;
1457− r[11] = m43;
1458− r[12] = m11 * x + m12 * y + m13 * z + m[12];
1459− r[13] = m21 * x + m22 * y + m23 * z + m[13];
1460− r[14] = m31 * x + m32 * y + m33 * z + m[14];
1461− r[15] = m41 * x + m42 * y + m43 * z + m[15];
1462−
1463− return r;
1464− };
1465−
1466− /*
1467− * Function: M4x4.translate1
1468− */
1469− M4x4.translate1 = function M4x4_translate1 (k, m, r) {
1470− //MathUtils_assert(m.length == 16, "m.length == 16");
1471− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1472−
1473− return M4x4.translate3(k, k, k, m, r);
1474− };
1475− /*
1476− * Function: M4x4.translateSelf
1477− */
1478− M4x4.translateSelf = function M4x4_translateSelf (v, m) {
1479− //MathUtils_assert(v.length == 3, "v.length == 3");
1480− //MathUtils_assert(m.length == 16, "m.length == 16");
1481− var x=v[0], y=v[1], z=v[2];
1482− m[12] += m[0] * x + m[4] * y + m[8] * z;
1483− m[13] += m[1] * x + m[5] * y + m[9] * z;
1484− m[14] += m[2] * x + m[6] * y + m[10] * z;
1485− m[15] += m[3] * x + m[7] * y + m[11] * z;
1486− return m;
1487− };
1488− /*
1489− * Function: M4x4.translate
1490− */
1491− M4x4.translate = function M4x4_translate (v, m, r) {
1492− //MathUtils_assert(v.length == 3, "v.length == 3");
1493− //MathUtils_assert(m.length == 16, "m.length == 16");
1494− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1495− var x=v[0], y=v[1], z=v[2];
1496− if (r == m) {
1497− m[12] += m[0] * x + m[4] * y + m[8] * z;
1498− m[13] += m[1] * x + m[5] * y + m[9] * z;
1499− m[14] += m[2] * x + m[6] * y + m[10] * z;
1500− m[15] += m[3] * x + m[7] * y + m[11] * z;
1501− return m;
1502− }
1503−
1504− if (r == undefined)
1505− r = new MJS_FLOAT_ARRAY_TYPE(16);
1506−
1507− var m11 = m[0];
1508− var m21 = m[1];
1509− var m31 = m[2];
1510− var m41 = m[3];
1511− var m12 = m[4];
1512− var m22 = m[5];
1513− var m32 = m[6];
1514− var m42 = m[7];
1515− var m13 = m[8];
1516− var m23 = m[9];
1517− var m33 = m[10];
1518− var m43 = m[11];
1519−
1520− r[0] = m11;
1521− r[1] = m21;
1522− r[2] = m31;
1523− r[3] = m41;
1524− r[4] = m12;
1525− r[5] = m22;
1526− r[6] = m32;
1527− r[7] = m42;
1528− r[8] = m13;
1529− r[9] = m23;
1530− r[10] = m33;
1531− r[11] = m43;
1532− r[12] = m11 * x + m12 * y + m13 * z + m[12];
1533− r[13] = m21 * x + m22 * y + m23 * z + m[13];
1534− r[14] = m31 * x + m32 * y + m33 * z + m[14];
1535− r[15] = m41 * x + m42 * y + m43 * z + m[15];
1536−
1537− return r;
1538− };
1539−
1540− /*
1541− * Function: M4x4.makeLookAt
1542− */
1543− M4x4.makeLookAt = function M4x4_makeLookAt (eye, center, up, r) {
1544− //MathUtils_assert(eye.length == 3, "eye.length == 3");
1545− //MathUtils_assert(center.length == 3, "center.length == 3");
1546− //MathUtils_assert(up.length == 3, "up.length == 3");
1547− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1548−
1549− var z = V3.direction(eye, center, V3._temp1);
1550− var x = V3.normalize(V3.cross(up, z, V3._temp2), V3._temp2);
1551− var y = V3.normalize(V3.cross(z, x, V3._temp3), V3._temp3);
1552−
1553− var tm1 = M4x4._temp1;
1554− var tm2 = M4x4._temp2;
1555−
1556− tm1[0] = x[0];
1557− tm1[1] = y[0];
1558− tm1[2] = z[0];
1559− tm1[3] = 0;
1560− tm1[4] = x[1];
1561− tm1[5] = y[1];
1562− tm1[6] = z[1];
1563− tm1[7] = 0;
1564− tm1[8] = x[2];
1565− tm1[9] = y[2];
1566− tm1[10] = z[2];
1567− tm1[11] = 0;
1568− tm1[12] = 0;
1569− tm1[13] = 0;
1570− tm1[14] = 0;
1571− tm1[15] = 1;
1572−
1573− tm2[0] = 1; tm2[1] = 0; tm2[2] = 0; tm2[3] = 0;
1574− tm2[4] = 0; tm2[5] = 1; tm2[6] = 0; tm2[7] = 0;
1575− tm2[8] = 0; tm2[9] = 0; tm2[10] = 1; tm2[11] = 0;
1576− tm2[12] = -eye[0]; tm2[13] = -eye[1]; tm2[14] = -eye[2]; tm2[15] = 1;
1577−
1578− if (r == undefined)
1579− r = new MJS_FLOAT_ARRAY_TYPE(16);
1580− return M4x4.mul(tm1, tm2, r);
1581− };
1582−
1583− /*
1584− * Function: M4x4.transposeSelf
1585− */
1586− M4x4.transposeSelf = function M4x4_transposeSelf (m) {
1587− //MathUtils_assert(m.length == 16, "m.length == 16");
1588− var tmp = m[1]; m[1] = m[4]; m[4] = tmp;
1589− tmp = m[2]; m[2] = m[8]; m[8] = tmp;
1590− tmp = m[3]; m[3] = m[12]; m[12] = tmp;
1591− tmp = m[6]; m[6] = m[9]; m[9] = tmp;
1592− tmp = m[7]; m[7] = m[13]; m[13] = tmp;
1593− tmp = m[11]; m[11] = m[14]; m[14] = tmp;
1594− return m;
1595− };
1596− /*
1597− * Function: M4x4.transpose
1598− */
1599− M4x4.transpose = function M4x4_transpose (m, r) {
1600− //MathUtils_assert(m.length == 16, "m.length == 16");
1601− //MathUtils_assert(r == undefined || r.length == 16, "r == undefined || r.length == 16");
1602−
1603− if (m == r) {
1604− var tmp = 0.0;
1605− tmp = m[1]; m[1] = m[4]; m[4] = tmp;
1606− tmp = m[2]; m[2] = m[8]; m[8] = tmp;
1607− tmp = m[3]; m[3] = m[12]; m[12] = tmp;
1608− tmp = m[6]; m[6] = m[9]; m[9] = tmp;
1609− tmp = m[7]; m[7] = m[13]; m[13] = tmp;
1610− tmp = m[11]; m[11] = m[14]; m[14] = tmp;
1611− return m;
1612− }
1613−
1614− if (r == undefined)
1615− r = new MJS_FLOAT_ARRAY_TYPE(16);
1616−
1617− r[0] = m[0]; r[1] = m[4]; r[2] = m[8]; r[3] = m[12];
1618− r[4] = m[1]; r[5] = m[5]; r[6] = m[9]; r[7] = m[13];
1619− r[8] = m[2]; r[9] = m[6]; r[10] = m[10]; r[11] = m[14];
1620− r[12] = m[3]; r[13] = m[7]; r[14] = m[11]; r[15] = m[15];
1621−
1622− return r;
1623− };
1624−
1625−
1626− /*
1627− * Function: M4x4.transformPoint
1628− */
1629− M4x4.transformPoint = function M4x4_transformPoint (m, v, r) {
1630− //MathUtils_assert(m.length == 16, "m.length == 16");
1631− //MathUtils_assert(v.length == 3, "v.length == 3");
1632− //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
1633− if (r == undefined)
1634− r = new MJS_FLOAT_ARRAY_TYPE(3);
1635−
1636− var v0 = v[0], v1 = v[1], v2 = v[2];
1637−
1638− r[0] = m[0] * v0 + m[4] * v1 + m[8] * v2 + m[12];
1639− r[1] = m[1] * v0 + m[5] * v1 + m[9] * v2 + m[13];
1640− r[2] = m[2] * v0 + m[6] * v1 + m[10] * v2 + m[14];
1641− var w = m[3] * v0 + m[7] * v1 + m[11] * v2 + m[15];
1642−
1643− if (w != 1.0) {
1644− r[0] /= w;
1645− r[1] /= w;
1646− r[2] /= w;
1647− }
1648−
1649− return r;
1650− };
1651−
1652− /*
1653− * Function: M4x4.transformLine
1654− */
1655− M4x4.transformLine = function M4x4_transformLine(m, v, r) {
1656− //MathUtils_assert(m.length == 16, "m.length == 16");
1657− //MathUtils_assert(v.length == 3, "v.length == 3");
1658− //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
1659− if (r == undefined)
1660− r = new MJS_FLOAT_ARRAY_TYPE(3);
1661−
1662− var v0 = v[0], v1 = v[1], v2 = v[2];
1663− r[0] = m[0] * v0 + m[4] * v1 + m[8] * v2;
1664− r[1] = m[1] * v0 + m[5] * v1 + m[9] * v2;
1665− r[2] = m[2] * v0 + m[6] * v1 + m[10] * v2;
1666− var w = m[3] * v0 + m[7] * v1 + m[11] * v2;
1667−
1668− if (w != 1.0) {
1669− r[0] /= w;
1670− r[1] /= w;
1671− r[2] /= w;
1672− }
1673−
1674− return r;
1675− };
1676−
1677−
1678− /*
1679− * Function: M4x4.transformPointAffine
1680− */
1681− M4x4.transformPointAffine = function M4x4_transformPointAffine (m, v, r) {
1682− //MathUtils_assert(m.length == 16, "m.length == 16");
1683− //MathUtils_assert(v.length == 3, "v.length == 3");
1684− //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
1685− if (r == undefined)
1686− r = new MJS_FLOAT_ARRAY_TYPE(3);
1687−
1688− var v0 = v[0], v1 = v[1], v2 = v[2];
1689−
1690− r[0] = m[0] * v0 + m[4] * v1 + m[8] * v2 + m[12];
1691− r[1] = m[1] * v0 + m[5] * v1 + m[9] * v2 + m[13];
1692− r[2] = m[2] * v0 + m[6] * v1 + m[10] * v2 + m[14];
1693−
1694− return r;
1695− };
1696−
1697− /*
1698− * Function: M4x4.transformLineAffine
1699− */
1700− M4x4.transformLineAffine = function M4x4_transformLineAffine(m, v, r) {
1701− //MathUtils_assert(m.length == 16, "m.length == 16");
1702− //MathUtils_assert(v.length == 3, "v.length == 3");
1703− //MathUtils_assert(r == undefined || r.length == 3, "r == undefined || r.length == 3");
1704− if (r == undefined)
1705− r = new MJS_FLOAT_ARRAY_TYPE(3);
1706−
1707− var v0 = v[0], v1 = v[1], v2 = v[2];
1708− r[0] = m[0] * v0 + m[4] * v1 + m[8] * v2;
1709− r[1] = m[1] * v0 + m[5] * v1 + m[9] * v2;
1710− r[2] = m[2] * v0 + m[6] * v1 + m[10] * v2;
1711−
1712− return r;
1713− };
1714−
1715− M4x4.makeBasis = function M4x4_makeBasis(vx,vy,vz) {
1716−
1717− var r = new MJS_FLOAT_ARRAY_TYPE(16);
1718−
1719− r[0] = vx[0];
1720− r[1] = vx[1];
1721− r[2] = vx[2];
1722− r[3] = 0;
1723− r[4] = vy[0];
1724− r[5] = vy[1];
1725− r[6] = vy[2];
1726− r[7] = 0;
1727− r[8] = vz[0];
1728− r[9] = vz[1];
1729− r[10] = vz[2];
1730− r[11] = 0;
1731− r[12] = 0;
1732− r[13] = 0;
1733− r[14] = 0;
1734− r[15] = 1;
1735−
1736− return r;
1737−
1738− };
1739−
1740− return {
1741− V3: V3,
1742− v3: F3(V3.$),
1743− toTuple3: V3.toTuple3,
1744− v3add: F2(V3.add),
1745− v3sub: F2(V3.sub),
1746− v3neg: V3.neg,
1747− v3direction: F2(V3.direction),
1748− v3length: V3.length,
1749− v3lengthSquared: V3.lengthSquared,
1750− v3normalize: V3.normalize,
1751− v3scale: F2(V3.scale),
1752− v3dot: F2(V3.dot),
1753− v3cross: F2(V3.cross),
1754− v3mul4x4: F2(V3.mul4x4),
1755− M4x4:M4x4,
1756− m4x4identity: M4x4.identity,
1757− m4x4topLeft3x3: M4x4.topLeft3x3,
1758− m4x4inverseOrthonormal: M4x4.inverseOrthonormal,
1759− m4x4inverseTo3x3: M4x4.inverseTo3x3,
1760− m4x4makeFrustum: F6(M4x4.makeFrustum),
1761− m4x4makePerspective: F4(M4x4.makePerspective),
1762− m4x4makeOrtho: F6(M4x4.makeOrtho),
1763− m4x4makeOrtho2D: F4(M4x4.makeOrtho2D),
1764− m4x4mul: F2(M4x4.mul),
1765− m4x4Affine: F2(M4x4.mulAffine),
1766− m4x4makeRotate: F2(M4x4.makeRotate),
1767− m4x4rotate: F3(M4x4.rotate),
1768− m4x4makeScale3: F3(M4x4.makeScale3),
1769− m4x4makeScale1: M4x4.makeScale1,
1770− m4x4makeScale: M4x4.makeScale,
1771− m4x4scale3: F4(M4x4.scale3),
1772− m4x4scale: F2(M4x4.scale),
1773− m4x4makeTranslate3: F3(M4x4.makeTranslate3),
1774− m4x4makeTranslate: M4x4.makeTranslate,
1775− m4x4translate3: F4(M4x4.translate3),
1776− m4x4translate: F2(M4x4.translate),
1777− m4x4makeLookAt: F3(M4x4.makeLookAt),
1778− m4x4transpose: M4x4.transpose,
1779− m4x4transformPoint: F2(M4x4.transformPoint),
1780− m4x4makeBasis: F3(M4x4.makeBasis),
1781− };
1782−
1783−}
libraries/Native/Regex.js+2−2
@@ -43,7 +43,7 @@ Elm.Native.Regex.make = function(elm) {
43 match: result[0],
43 match: result[0],
44 submatches: List.fromArray(subs),
44 submatches: List.fromArray(subs),
45 index: result.index,
45 index: result.index,
46− number: number,
46+ number: number
47 });
47 });
48 }
48 }
49 return List.fromArray(out);
49 return List.fromArray(out);
@@ -98,6 +98,6 @@ Elm.Native.Regex.make = function(elm) {
98 contains: F2(contains),
98 contains: F2(contains),
99 find: F3(find),
99 find: F3(find),
100 replace: F4(replace),
100 replace: F4(replace),
101− split: F3(split),
101+ split: F3(split)
102 };
102 };
103};
103};
libraries/Native/String.js+4−4
@@ -73,7 +73,7 @@ Elm.Native.String.make = function(elm) {
73 return result;
73 return result;
74 }
74 }
75
75
76− function sub(start, end, str) {
76+ function slice(start, end, str) {
77 return str.slice(start,end);
77 return str.slice(start,end);
78 }
78 }
79 function left(n, str) {
79 function left(n, str) {
@@ -111,7 +111,7 @@ Elm.Native.String.make = function(elm) {
111 }
111 }
112
112
113 function words(str) {
113 function words(str) {
114− return List.fromArray(str.split(/\s+/g));
114+ return List.fromArray(str.trim().split(/\s+/g));
115 }
115 }
116 function lines(str) {
116 function lines(str) {
117 return List.fromArray(str.split(/\r\n|\r|\n/g));
117 return List.fromArray(str.split(/\r\n|\r|\n/g));
@@ -216,7 +216,7 @@ Elm.Native.String.make = function(elm) {
216 join: F2(join),
216 join: F2(join),
217 repeat: F2(repeat),
217 repeat: F2(repeat),
218
218
219− sub: F3(sub),
219+ slice: F3(slice),
220 left: F2(left),
220 left: F2(left),
221 right: F2(right),
221 right: F2(right),
222 dropLeft: F2(dropLeft),
222 dropLeft: F2(dropLeft),
@@ -247,6 +247,6 @@ Elm.Native.String.make = function(elm) {
247 toInt: toInt,
247 toInt: toInt,
248 toFloat: toFloat,
248 toFloat: toFloat,
249 toList: toList,
249 toList: toList,
250− fromList: fromList,
250+ fromList: fromList
251 };
251 };
252};
252};
libraries/Native/Text.js+3−3
@@ -123,7 +123,7 @@ Elm.Native.Text.make = function(elm) {
123 html : Utils.makeText(text),
123 html : Utils.makeText(text),
124 align: align,
124 align: align,
125 guid : null,
125 guid : null,
126− args : [],
126+ args : []
127 };
127 };
128 var pos = A2(Utils.htmlHeight, 0, raw);
128 var pos = A2(Utils.htmlHeight, 0, raw);
129 return A3(Element.newElement, pos._0, pos._1, raw);
129 return A3(Element.newElement, pos._0, pos._1, raw);
@@ -136,7 +136,7 @@ Elm.Native.Text.make = function(elm) {
136 html: text,
136 html: text,
137 align: null,
137 align: null,
138 guid: guid,
138 guid: guid,
139− args: [],
139+ args: []
140 };
140 };
141 var pos = A2(Utils.htmlHeight, 0, raw);
141 var pos = A2(Utils.htmlHeight, 0, raw);
142 return A3(Element.newElement, pos._0, pos._1, raw);
142 return A3(Element.newElement, pos._0, pos._1, raw);
@@ -162,6 +162,6 @@ Elm.Native.Text.make = function(elm) {
162 markdown : markdown,
162 markdown : markdown,
163
163
164 toTypefaces:toTypefaces,
164 toTypefaces:toTypefaces,
165− toLine:toLine,
165+ toLine:toLine
166 };
166 };
167};
167};
libraries/Native/Utils.js+10−1
@@ -16,7 +16,16 @@ Elm.Native.Utils.make = function(elm) {
16 var c = 0;
16 var c = 0;
17 for (var i in x) {
17 for (var i in x) {
18 ++c;
18 ++c;
19+ if (i in y) {
20+ if (i !== 'ctor') {
19− stack.push({ 'x': x[i], 'y': y[i] });
21+ stack.push({ 'x': x[i], 'y': y[i] });
22+ }
23+ } else {
24+ return false;
25+ }
26+ }
27+ if ('ctor' in x) {
28+ stack.push({'x': x.ctor, 'y': y.ctor});
20 }
29 }
21 if (c !== Object.keys(y).length) {
30 if (c !== Object.keys(y).length) {
22 return false;
31 return false;
libraries/String.elm+8−8
@@ -6,10 +6,10 @@ are enclosed in `"double quotes"`. Strings are *not* lists of characters.
6@docs isEmpty, length, reverse, repeat
6@docs isEmpty, length, reverse, repeat
7
7
8# Building and Splitting
8# Building and Splitting
9−@docs cons, uncons, append, concat, split, join, words, lines
9+@docs cons, uncons, append, concat, split, join, words, lines
10
10
11# Get Substrings
11# Get Substrings
12−@docs sub, left, right, dropLeft, dropRight
12+@docs slice, left, right, dropLeft, dropRight
13
13
14# Check for Substrings
14# Check for Substrings
15@docs contains, startsWith, endsWith, indexes, indices
15@docs contains, startsWith, endsWith, indexes, indices
@@ -139,13 +139,13 @@ repeat = Native.String.repeat
139{-| Take a substring given a start and end index. Negative indexes
139{-| Take a substring given a start and end index. Negative indexes
140are taken starting from the *end* of the list.
140are taken starting from the *end* of the list.
141
141
142− sub 7 9 "snakes on a plane!" == "on"
142+ slice 7 9 "snakes on a plane!" == "on"
143− sub 0 6 "snakes on a plane!" == "snakes"
143+ slice 0 6 "snakes on a plane!" == "snakes"
144− sub 0 -7 "snakes on a plane!" == "snakes on a"
144+ slice 0 -7 "snakes on a plane!" == "snakes on a"
145− sub -6 -1 "snakes on a plane!" == "plane"
145+ slice -6 -1 "snakes on a plane!" == "plane"
146-}
146-}
147−sub : Int -> Int -> String -> String
147+slice : Int -> Int -> String -> String
148−sub = Native.String.sub
148+slice = Native.String.slice
149
149
150{-| Take N characters from the left side of a string. -}
150{-| Take N characters from the left side of a string. -}
151left : Int -> String -> String
151left : Int -> String -> String
libraries/elm_dependencies.json−2
@@ -18,7 +18,6 @@
18 , "Graphics.Element"
18 , "Graphics.Element"
19 , "Graphics.Collage"
19 , "Graphics.Collage"
20 , "Graphics.Input"
20 , "Graphics.Input"
21− , "Graphics.WebGL"
22 , "Graphics.Input.Field"
21 , "Graphics.Input.Field"
23 , "Http"
22 , "Http"
24 , "JavaScript.Experimental"
23 , "JavaScript.Experimental"
@@ -26,7 +25,6 @@
26 , "Keyboard"
25 , "Keyboard"
27 , "List"
26 , "List"
28 , "Maybe"
27 , "Maybe"
29− , "MJS"
30 , "Mouse"
28 , "Mouse"
31 , "Random"
29 , "Random"
32 , "Regex"
30 , "Regex"
runtime/Render/Collage.js+4−4
@@ -5,7 +5,7 @@ var Render = ElmRuntime.use(ElmRuntime.Render.Element);
5var Transform = Elm.Transform2D.make({});
5var Transform = Elm.Transform2D.make({});
6var Utils = ElmRuntime.use(ElmRuntime.Render.Utils);
6var Utils = ElmRuntime.use(ElmRuntime.Render.Utils);
7var newElement = Utils.newElement,
7var newElement = Utils.newElement,
8− extract = Utils.extract, fromList = Utils.fromList,
8+ colorToCss = Utils.colorToCss, fromList = Utils.fromList,
9 fromString = Utils.fromString, addTransform = Utils.addTransform;
9 fromString = Utils.fromString, addTransform = Utils.addTransform;
10
10
11function trace(ctx, path) {
11function trace(ctx, path) {
@@ -70,7 +70,7 @@ function drawLine(ctx, style, path) {
70 ctx.lineJoin = join === 'Smooth' ? 'round' :
70 ctx.lineJoin = join === 'Smooth' ? 'round' :
71 join === 'Sharp' ? 'miter' : 'bevel';
71 join === 'Sharp' ? 'miter' : 'bevel';
72 ctx.miterLimit = style.join._0 || 10;
72 ctx.miterLimit = style.join._0 || 10;
73− ctx.strokeStyle = extract(style.color);
73+ ctx.strokeStyle = colorToCss(style.color);
74 return line(ctx, style, path);
74 return line(ctx, style, path);
75}
75}
76
76
@@ -96,7 +96,7 @@ function gradient(ctx, grad) {
96 var len = stops.length;
96 var len = stops.length;
97 for (var i = 0; i < len; ++i) {
97 for (var i = 0; i < len; ++i) {
98 var stop = stops[i];
98 var stop = stops[i];
99− g.addColorStop(stop._0, extract(stop._1));
99+ g.addColorStop(stop._0, colorToCss(stop._1));
100 }
100 }
101 return g;
101 return g;
102}
102}
@@ -105,7 +105,7 @@ function drawShape(redo, ctx, style, path) {
105 trace(ctx, path);
105 trace(ctx, path);
106 var sty = style.ctor;
106 var sty = style.ctor;
107 ctx.fillStyle =
107 ctx.fillStyle =
108− sty === 'Solid' ? extract(style._0) :
108+ sty === 'Solid' ? colorToCss(style._0) :
109 sty === 'Texture' ? texture(redo, ctx, style._0) : gradient(ctx, style._0);
109 sty === 'Texture' ? texture(redo, ctx, style._0) : gradient(ctx, style._0);
110 ctx.scale(1,-1);
110 ctx.scale(1,-1);
111 ctx.fill();
111 ctx.fill();
runtime/Render/Element.js+33−27
@@ -3,7 +3,7 @@ ElmRuntime.Render.Element = function() {
3'use strict';
3'use strict';
4
4
5var Utils = ElmRuntime.use(ElmRuntime.Render.Utils);
5var Utils = ElmRuntime.use(ElmRuntime.Render.Utils);
6−var newElement = Utils.newElement, extract = Utils.extract,
6+var newElement = Utils.newElement, colorToCss = Utils.colorToCss,
7 addTransform = Utils.addTransform, removeTransform = Utils.removeTransform,
7 addTransform = Utils.addTransform, removeTransform = Utils.removeTransform,
8 fromList = Utils.fromList, eq = Utils.eq;
8 fromList = Utils.fromList, eq = Utils.eq;
9
9
@@ -18,7 +18,7 @@ function setProps(elem, e) {
18 e.style.opacity = props.opacity;
18 e.style.opacity = props.opacity;
19 }
19 }
20 if (props.color.ctor === 'Just') {
20 if (props.color.ctor === 'Just') {
21− e.style.backgroundColor = extract(props.color._0);
21+ e.style.backgroundColor = colorToCss(props.color._0);
22 }
22 }
23 if (props.tag !== '') { e.id = props.tag; }
23 if (props.tag !== '') { e.id = props.tag; }
24 if (props.href !== '') {
24 if (props.href !== '') {
@@ -143,29 +143,37 @@ function croppedImage(elem, w, h, src) {
143 return e;
143 return e;
144}
144}
145
145
146−function goIn(e) { e.style.position = 'absolute'; return e; }
146+function goOut(e) { e.style.position = 'absolute'; return e; }
147function goDown(e) { return e }
147function goDown(e) { return e }
148function goRight(e) { e.style.styleFloat = e.style.cssFloat = "left"; return e; }
148function goRight(e) { e.style.styleFloat = e.style.cssFloat = "left"; return e; }
149−function flowWith(f, array) {
150− var container = newElement('div');
151− if (f == goIn) container.style.pointerEvents = 'none';
152
149
153− for (var i = array.length; i--; ) {
150+var directionTable = {
154− container.appendChild(f(render(array[i])));
151+ DUp : goDown,
152+ DDown : goDown,
153+ DLeft : goRight,
154+ DRight : goRight,
155+ DIn : goOut,
156+ DOut : goOut
155− }
157+};
156− return container;
158+function needsReversal(dir) {
159+ return dir == 'DUp' || dir == 'DLeft' || dir == 'DIn';
157}
160}
158
161
159function flow(dir,elist) {
162function flow(dir,elist) {
160 var array = fromList(elist);
163 var array = fromList(elist);
161− switch(dir.ctor) {
164+ var container = newElement('div');
162− case "DDown": array.reverse();
165+ var goDir = directionTable[dir];
163− case "DUp": return flowWith(goDown,array);
166+ if (goDir == goOut) {
164− case "DRight": array.reverse();
167+ container.style.pointerEvents = 'none';
165− case "DLeft": return flowWith(goRight,array);
166− case "DOut": array.reverse();
167− case "DIn": return flowWith(goIn,array);
168 }
168 }
169+ if (needsReversal(dir)) {
170+ array.reverse();
171+ }
172+ var len = array.length;
173+ for (var i = 0; i < len; ++i) {
174+ container.appendChild(goDir(render(array[i])));
175+ }
176+ return container;
169}
177}
170
178
171function toPos(pos) {
179function toPos(pos) {
@@ -245,7 +253,7 @@ function makeElement(e) {
245 var elem = e.element;
253 var elem = e.element;
246 switch(elem.ctor) {
254 switch(elem.ctor) {
247 case 'Image': return image(e.props, elem);
255 case 'Image': return image(e.props, elem);
248− case 'Flow': return flow(elem._0, elem._1);
256+ case 'Flow': return flow(elem._0.ctor, elem._1);
249 case 'Container': return container(elem._0, elem._1);
257 case 'Container': return container(elem._0, elem._1);
250 case 'Spacer': return newElement('div');
258 case 'Spacer': return newElement('div');
251 case 'RawHtml': return rawHtml(elem);
259 case 'RawHtml': return rawHtml(elem);
@@ -321,14 +329,12 @@ function update(node, curr, next) {
321 return true;
329 return true;
322 }
330 }
323 var currs = fromList(currE._1);
331 var currs = fromList(currE._1);
324− var goDir = function(x) { return x; };
325− switch(nextE._0.ctor) {
332+ var dir = nextE._0.ctor;
326− case "DDown": case "DUp": goDir = goDown; break;
333+ var goDir = directionTable[dir];
327− case "DRight": case "DLeft": goDir = goRight; break;
334+ var toReverse = needsReversal(dir);
328− case "DOut": case "DIn": goDir = goIn; break;
335+ var len = kids.length;
329− }
330− for (var i = kids.length; i-- ;) {
336+ for (var i = len; i-- ;) {
331− update(kids[i],currs[i],nexts[i]);
337+ update(kids[toReverse ? len - i - 1 : i],currs[i],nexts[i]);
332 goDir(kids[i]);
338 goDir(kids[i]);
333 }
339 }
334 break;
340 break;
@@ -364,7 +370,7 @@ function updateProps(node, curr, next) {
364 e.style.opacity = props.opacity;
370 e.style.opacity = props.opacity;
365 }
371 }
366 var nextColor = (props.color.ctor === 'Just' ?
372 var nextColor = (props.color.ctor === 'Just' ?
367− extract(props.color._0) : '');
373+ colorToCss(props.color._0) : '');
368 if (e.style.backgroundColor !== nextColor) {
374 if (e.style.backgroundColor !== nextColor) {
369 e.style.backgroundColor = (nextColor === '' ? 'transparent' : nextColor);
375 e.style.backgroundColor = (nextColor === '' ? 'transparent' : nextColor);
370 }
376 }
runtime/Render/Utils.js+2−7
@@ -10,11 +10,6 @@ ElmRuntime.Render.Utils = function() {
10 container.appendChild(elem);
10 container.appendChild(elem);
11 }
11 }
12
12
13− function extract(c) {
14− if (c._3 === 1) { return 'rgb(' + c._0 + ', ' + c._1 + ', ' + c._2 + ')'; }
15− return 'rgba(' + c._0 + ', ' + c._1 + ', ' + c._2 + ', ' + c._3 + ')';
16− }
17−
18 function addTransform(style, trans) {
13 function addTransform(style, trans) {
19 style.transform = trans;
14 style.transform = trans;
20 style.msTransform = trans;
15 style.msTransform = trans;
@@ -34,8 +29,8 @@ ElmRuntime.Render.Utils = function() {
34 var List = Elm.Native.List.make({});
29 var List = Elm.Native.List.make({});
35
30
36 return {addTo:addTo,
31 return {addTo:addTo,
37− newElement:newElement,
32+ newElement: newElement,
38− extract : extract,
33+ colorToCss: Elm.Native.Color.make({}).toCss,
39 fromList: List.toArray,
34 fromList: List.toArray,
40 fromString: function(s) { return s; },
35 fromString: function(s) { return s; },
41 toString: function(s) { return s; },
36 toString: function(s) { return s; },
tests/hs/CompilerTest.hs → tests/compiler/CompilerTest.hsrenamed

The content is the same.

tests/hs/Tests/Compiler.hs → tests/compiler/Tests/Compiler.hsrenamed

The content is the same.

tests/hs/Tests/Property.hs → tests/compiler/Tests/Property.hsrenamed

The content is the same.

tests/hs/Tests/Property/Arbitrary.hs → tests/compiler/Tests/Property/Arbitrary.hsrenamed

The content is the same.

tests/hs/test-files/bad/BBTArgs → tests/compiler/test-files/bad/BBTArgsrenamed

The content is the same.

tests/hs/test-files/bad/InfiniteType.elm → tests/compiler/test-files/bad/InfiniteType.elmrenamed

The content is the same.

tests/hs/test-files/bad/NonElementMain.elm → tests/compiler/test-files/bad/NonElementMain.elmrenamed

The content is the same.

tests/hs/test-files/bad/Strings/ExtraClose.elm → tests/compiler/test-files/bad/Strings/ExtraClose.elmrenamed

The content is the same.

tests/hs/test-files/good/AliasSubstitution.elm → tests/compiler/test-files/good/AliasSubstitution.elmrenamed

The content is the same.

tests/compiler/test-files/good/Box.elmnew file+89
@@ -0,0 +1,89 @@
1+
2+module Box where
3+
4+import Math.Vector3 (..)
5+import Math.Matrix4 (..)
6+import Graphics.WebGL (Triangle, zipTriangle, Shader, Model, model, webgl)
7+import Window(dimensions)
8+
9+-- Create a cube in which each point has a color
10+
11+type ColorPoint = { color:Vec3, point:Vec3 }
12+
13+face : Color -> Vec3 -> Vec3 -> Vec3 -> Vec3 -> [Triangle ColorPoint]
14+face color a b c d =
15+ let toV3 color =
16+ let c = toRgb color
17+ in v3 (toFloat c.red / 255) (toFloat c.green / 255) (toFloat c.blue / 255)
18+ p = ColorPoint (toV3 color)
19+ in
20+ [ (p a, p b, p c), (p c, p d, p a) ]
21+
22+cube : [Triangle ColorPoint]
23+cube =
24+ let rft = v3 1 1 1 -- right, front, top
25+ lft = v3 -1 1 1 -- left, front, top
26+ lbt = v3 -1 -1 1
27+ rbt = v3 1 -1 1
28+ rbb = v3 1 -1 -1
29+ rfb = v3 1 1 -1
30+ lfb = v3 -1 1 -1
31+ lbb = v3 -1 -1 -1
32+ in
33+ concat [ face green rft rfb rbb rbt -- right
34+ , face blue rft rfb lfb lft -- front
35+ , face purple lft lfb lbb lbt -- left
36+ , face orange rbt rbb lbb lbt -- back
37+ ]
38+
39+-- Create the scene
40+
41+main : Signal Element
42+main = webgl (400,400) <~ lift scene angle
43+
44+angle : Signal Float
45+angle = foldp (\dt theta -> theta + dt / 5000) 0 (fps 25)
46+
47+scene : Float -> [Model]
48+scene angle =
49+ [ model vertexShader fragmentShader cube (uniforms angle) ]
50+
51+uniforms : Float -> { rotation:Mat4, perspective:Mat4, camera:Mat4, shade:Float }
52+uniforms t =
53+ { rotation = mul (makeRotate (3*t) (v3 0 1 0)) (makeRotate (2*t) (v3 1 0 0))
54+ , perspective = makePerspective 45 1 0.01 100
55+ , camera = makeLookAt (v3 0 0 5) (v3 0 0 0) (v3 0 1 0)
56+ , shade = 0.8
57+ }
58+
59+-- Shaders
60+
61+vertexShader : Shader { attr | point:Vec3, color:Vec3 }
62+ { unif | rotation:Mat4, perspective:Mat4, camera:Mat4 }
63+ { vcolor:Vec3 }
64+vertexShader = [glShader|
65+
66+attribute vec3 point;
67+attribute vec3 color;
68+uniform mat4 perspective;
69+uniform mat4 camera;
70+uniform mat4 rotation;
71+varying vec3 vcolor;
72+void main () {
73+ gl_Position = perspective * camera * rotation * vec4(point, 1.0);
74+ vcolor = color;
75+}
76+
77+|]
78+
79+fragmentShader : Shader {} { u | shade:Float } { vcolor:Vec3 }
80+fragmentShader = [glShader|
81+
82+precision mediump float;
83+uniform float shade;
84+varying vec3 vcolor;
85+void main () {
86+ gl_FragColor = shade * vec4(vcolor, 1.0);
87+}
88+
89+|]
tests/compiler/test-files/good/Crate.elmnew file+85
@@ -0,0 +1,85 @@
1+
2+module Crate where
3+
4+import Http (..)
5+import Math.Vector2 (Vec2)
6+import Math.Vector3 (..)
7+import Math.Matrix4 (..)
8+import Graphics.WebGL (..)
9+
10+-- Define the mesh for a crate
11+crate : [Triangle { pos:Vec3, coord:Vec3 }]
12+crate = concatMap rotatedFace [ (0,0), (90,0), (180,0), (270,0), (0,90), (0,-90) ]
13+
14+rotatedFace : (Float,Float) -> [Triangle { pos:Vec3, coord:Vec3 }]
15+rotatedFace (angleX,angleY) =
16+ let x = makeRotate (degrees angleX) (v3 1 0 0)
17+ y = makeRotate (degrees angleY) (v3 0 1 0)
18+ t = x `mul` y `mul` makeTranslate (v3 0 0 1)
19+ in
20+ map (mapTriangle (\x -> {x | pos <- mulVec3 t x.pos })) face
21+
22+face : [Triangle { pos:Vec3, coord:Vec3 }]
23+face =
24+ let topLeft = { pos = v3 -1 1 0, coord = v3 0 1 0 }
25+ topRight = { pos = v3 1 1 0, coord = v3 1 1 0 }
26+ bottomLeft = { pos = v3 -1 -1 0, coord = v3 0 0 0 }
27+ bottomRight = { pos = v3 1 -1 0, coord = v3 1 0 0 }
28+ in
29+ [ (topLeft,topRight,bottomLeft), (bottomLeft,topRight,bottomRight) ]
30+
31+-- View
32+view : Float -> Mat4
33+view angle =
34+ foldr1 mul [ perspective
35+ , camera
36+ , makeRotate (3*angle) (v3 0 1 0)
37+ , makeRotate (2*angle) (v3 1 0 0)
38+ ]
39+
40+perspective : Mat4
41+perspective = makePerspective 45 1 0.01 100
42+
43+camera : Mat4
44+camera = makeLookAt (v3 0 0 5) (v3 0 0 0) (v3 0 1 0)
45+
46+-- Putting it together
47+main : Signal Element
48+main = webgl (400,400) <~ lift2 scene (loadTex "woodCrate.jpg") (view <~ angle)
49+
50+angle : Signal Float
51+angle = foldp (\dt theta -> theta + dt / 10000) 0 (fps 25)
52+
53+scene : Response Texture -> Mat4 -> [Model]
54+scene response view =
55+ case response of
56+ Waiting -> []
57+ Failure _ _ -> []
58+ Success tex -> [model vertexShader fragmentShader crate { crate = tex, view = view }]
59+
60+-- Shaders
61+vertexShader : Shader { pos:Vec3, coord:Vec3 } { u | view:Mat4 } { vcoord:Vec2 }
62+vertexShader = [glShader|
63+
64+attribute vec3 pos;
65+attribute vec3 coord;
66+uniform mat4 view;
67+varying vec2 vcoord;
68+void main () {
69+ gl_Position = view * vec4(pos, 1.0);
70+ vcoord = coord.xy;
71+}
72+
73+|]
74+
75+fragmentShader : Shader {} { u | crate:Texture } { vcoord:Vec2 }
76+fragmentShader = [glShader|
77+
78+precision mediump float;
79+uniform sampler2D crate;
80+varying vec2 vcoord;
81+void main () {
82+ gl_FragColor = texture2D(crate, vcoord);
83+}
84+
85+|]
tests/hs/test-files/good/NoExpressions.elm → tests/compiler/test-files/good/NoExpressions.elmrenamed

The content is the same.

tests/hs/test-files/good/Otherwise.elm → tests/compiler/test-files/good/Otherwise.elmrenamed

The content is the same.

tests/hs/test-files/good/Ports.elm → tests/compiler/test-files/good/Ports.elmrenamed

The content is the same.

tests/hs/test-files/good/QuotesAndComments.elm → tests/compiler/test-files/good/QuotesAndComments.elmrenamed

The content is the same.

tests/hs/test-files/good/Soundness/Apply.elm → tests/compiler/test-files/good/Soundness/Apply.elmrenamed

The content is the same.

tests/hs/test-files/good/Soundness/ApplyAnnotated.elm → tests/compiler/test-files/good/Soundness/ApplyAnnotated.elmrenamed

The content is the same.

tests/hs/test-files/good/Soundness/Id.elm → tests/compiler/test-files/good/Soundness/Id.elmrenamed

The content is the same.

tests/hs/test-files/good/Soundness/IdAnnotated.elm → tests/compiler/test-files/good/Soundness/IdAnnotated.elmrenamed

The content is the same.

tests/hs/test-files/good/Soundness/TrickyId.elm → tests/compiler/test-files/good/Soundness/TrickyId.elmrenamed

The content is the same.

tests/hs/test-files/good/Soundness/TrickyIdAnnotated.elm → tests/compiler/test-files/good/Soundness/TrickyIdAnnotated.elmrenamed

The content is the same.

tests/hs/test-files/good/Strings/Multiline.elm → tests/compiler/test-files/good/Strings/Multiline.elmrenamed

The content is the same.

tests/hs/test-files/good/Strings/MultilineNormal.elm → tests/compiler/test-files/good/Strings/MultilineNormal.elmrenamed

The content is the same.

tests/hs/test-files/good/Unify/LockedVars.elm → tests/compiler/test-files/good/Unify/LockedVars.elmrenamed

The content is the same.

tests/hs/test-files/good/Unify/NonHomogeneousRecords.elm → tests/compiler/test-files/good/Unify/NonHomogeneousRecords.elmrenamed

The content is the same.

tests/test-files/good/woodCrate.JPG → tests/compiler/test-files/good/woodCrate.JPGrenamed

Binary file not shown.

tests/elm/Test/Array.elmdeleted−54
@@ -1,54 +0,0 @@
1−module Test.Array (tests) where
2−
3−import List
4−import Array
5−
6−import ElmTest.Assertion (..)
7−import ElmTest.Test (..)
8−
9−tests : Test
10−tests =
11− let creationTests = suite "Creation"
12− [ test "empty" <| assertEqual Array.empty (Array.fromList [])
13− , test "initialize" <| assertEqual (Array.initialize 4 id) (Array.fromList [0,1,2,3])
14− , test "initialize 2" <| assertEqual (Array.initialize 4 (\n -> n*n)) (Array.fromList [0,1,4,9])
15− , test "initialize 3" <| assertEqual (Array.initialize 4 (always 0)) (Array.fromList [0,0,0,0])
16− , test "initialize Empty" <| assertEqual (Array.initialize 0 id) Array.empty
17− , test "initialize 4" <| assertEqual (Array.initialize 2 (always 0)) (Array.fromList [0,0])
18− , test "repeat" <| assertEqual (Array.repeat 5 40) (Array.fromList [40,40,40,40,40])
19− , test "repeat 2" <| assertEqual (Array.repeat 5 0) (Array.fromList [0,0,0,0,0])
20− , test "repeat 3" <| assertEqual (Array.repeat 3 "cat") (Array.fromList ["cat","cat","cat"])
21− , test "fromList" <| assertEqual (Array.fromList []) Array.empty
22− ]
23− basicsTests = suite "Basics"
24− [ test "length" <| assertEqual (Array.length (Array.fromList [1,2,3])) 3
25− , test "length - Long" <| assertEqual (Array.length (Array.repeat 10000 0)) 10000
26− , test "push" <| assertEqual (Array.push 3 (Array.fromList [1,2])) (Array.fromList [1,2,3])
27− , test "append" <| assertEqual (Array.toList <| Array.append (Array.repeat 2 42) (Array.repeat 3 81)) ([42,42,81,81,81])
28− ]
29− getAndSetTests = suite "Get and Set"
30− [ test "get" <| assertEqual (Array.get 1 (Array.fromList [3,2,1])) (Just 2)
31− , test "get 2" <| assertEqual (Array.get 5 (Array.fromList [3,2,1])) Nothing
32− , test "get 3" <| assertEqual (Array.get -1 (Array.fromList [3,2,1])) Nothing
33− , test "getOrElse 1" <| assertEqual (Array.getOrElse 0 2 (Array.fromList [3,2,1])) 1
34− , test "getOrElse 2" <| assertEqual (Array.getOrElse 0 5 (Array.fromList [3,2,1])) 0
35− , test "getOrFail" <| assertEqual (Array.getOrFail 2 (Array.fromList [3,2,1])) 1
36− , test "set" <| assertEqual (Array.set 1 7 (Array.fromList [1,2,3])) (Array.fromList [1,7,3])
37− ]
38− takingArraysApartTests = suite "Taking Arrays Apart"
39− [ test "toList" <| assertEqual (Array.toList (Array.fromList [3,5,8])) [3,5,8]
40− , test "toIndexedList" <| assertEqual (Array.toIndexedList (Array.fromList ["cat","dog"])) [(0,"cat"), (1,"dog")]
41− , test "slice" <| assertEqual (Array.slice 1 2 (Array.fromList [0,1,2,3,4])) (Array.fromList [1,2])
42− , test "slice 2" <| assertEqual (Array.slice 1 -2 (Array.fromList [0,1,2,3,4])) (Array.fromList [1,2,3])
43− , test "slice 3" <| assertEqual (Array.slice -3 -2 (Array.fromList [0,1,2,3,4])) (Array.fromList [2,3])
44− ]
45− mappingAndFoldingTests = suite "Mapping and Folding"
46− [ test "map" <| assertEqual (Array.map sqrt (Array.fromList [1,4,9])) (Array.fromList [1,2,3])
47− , test "indexedMap" <| assertEqual (Array.indexedMap (*) (Array.fromList [5,5,5])) (Array.fromList [0,5,10])
48− , test "foldl" <| assertEqual (Array.foldl (::) [] (Array.fromList [1,2,3])) [3,2,1]
49− , test "foldr" <| assertEqual (Array.foldr (+) 0 (Array.repeat 3 5)) 15
50− , test "foldr 2" <| assertEqual (Array.foldr (::) [] (Array.fromList [1,2,3])) [1,2,3]
51− , test "filter" <| assertEqual (Array.filter (\x -> x `mod` 2 == 0) (Array.fromList [1..6])) (Array.fromList [2,4,6])
52− ]
53− in
54− suite "Array Tests" [creationTests, basicsTests, getAndSetTests, takingArraysApartTests, mappingAndFoldingTests]
tests/elm/Test/String.elmdeleted−34
@@ -1,34 +0,0 @@
1−module Test.String (tests) where
2−
3−import List
4−import String (..)
5−
6−import ElmTest.Assertion (..)
7−import ElmTest.Test (..)
8−
9−tests : Test
10−tests =
11− let isEmptyTests = suite "isEmpty Tests" [
12− test "empty is empty" <| assert <| isEmpty "",
13− test "not empty" <| assert <| not . isEmpty <| "the world"
14− ]
15− lengthTest = test "length of innumerable" <| assertEqual 11 (length "innumerable")
16− reverseTest = test "reverse test" <| assertEqual "desserts" (reverse "stressed")
17− repeatTest = test "repeat test" <| assertEqual "hahaha" (repeat 3 "ha")
18− unconsTests = suite "uncons Tests" [
19− test "nonempty uncons" <| assertEqual (Just ('a',"bc")) (uncons "abc"),
20− test "empty uncons" <| assertEqual Nothing (uncons "")
21− ]
22− appendTest = test "append test" <| assertEqual "butterfly" (append "butter" "fly")
23− concatTest = test "concat test" <| assertEqual "nevertheless" (concat ["never","the","less"])
24− splitTests = suite "split Tests" [
25− test "split commas" <| assertEqual ["cat","dog","cow"] (split "," "cat,dog,cow"),
26− test "split slashes"<| assertEqual ["home","evan","Desktop", ""] (split "/" "home/evan/Desktop/")
27− ]
28− joinTests = suite "join Tests" [
29− test "join spaces" <| assertEqual "cat dog cow" (join " " ["cat","dog","cow"]),
30− test "join slashes" <| assertEqual "home/evan/Desktop" (join "/" ["home","evan","Desktop"])
31− ]
32−
33− endsWithTest = test "endsWith Check" (assert <| endsWith "h" "th")
34− in suite "String Tests" [isEmptyTests, lengthTest, reverseTest, repeatTest, unconsTests, appendTest, concatTest, splitTests, joinTests, endsWithTest]
tests/hs/LibTest.hsdeleted−30
@@ -1,30 +0,0 @@
1−module Main where
2−
3−import Control.Monad (unless)
4−import Data.List (isInfixOf)
5−import System.Directory
6−import System.Exit
7−import System.FilePath
8−import System.Process
9−
10−import Elm.Internal.Paths as Elm
11−
12−main :: IO ()
13−main = do
14− top <- getCurrentDirectory
15− let ioScript s = top</>"IO"</>s
16− runCmd "git submodule update --init"
17− out <- readProcess "npm" ["ls", "--parseable"] ""
18− unless ("jsdom" `isInfixOf` out) $ runCmd "npm install jsdom"
19− setCurrentDirectory $ top</>"tests"</>"elm"
20− runCmd $ concat [top</>"dist"</>"build"</>"elm"</>"elm --make --only-js --src-dir=" , top</>"automaton", " --src-dir=", top</>"IO", " --src-dir=", top</>"Elm-Test", " Test.elm"]
21− runCmd $ unwords ["cat ", ioScript "prescript.js", Elm.runtime, "build"</>"Test.js", ioScript "handler.js", "> exe.js"]
22− exitWith =<< waitForProcess =<< (runCommand "node exe.js")
23− where runCmd cmd = do
24− putStrLn cmd
25− exitCode <- waitForProcess =<< runCommand cmd
26− case exitCode of
27− ExitSuccess -> return ()
28− ExitFailure _ -> error "something went wrong"
29−
30−
tests/libraries/LibraryTest.hsnew file+49
@@ -0,0 +1,49 @@
1+module Main where
2+
3+import Control.Monad (unless)
4+import Data.List (isInfixOf)
5+import System.Directory
6+import System.Exit
7+import System.FilePath
8+import System.Process
9+
10+import Elm.Internal.Paths as Elm
11+
12+main :: IO ()
13+main = do
14+ top <- getCurrentDirectory
15+
16+ -- setup submodules and npm
17+ runCmd "git" ["submodule", "update", "--init"]
18+ out <- readProcess "npm" ["ls", "--parseable"] ""
19+ unless ("jsdom" `isInfixOf` out) $ runCmd "npm" ["install","jsdom"]
20+
21+ -- setup actual library tests
22+ setCurrentDirectory $ top </> "tests" </> "libraries"
23+ let localCompiler = joinPath [ top, "dist", "build", "elm", "elm" ]
24+ runCmd localCompiler [ "--make"
25+ , "--only-js"
26+ , "--src-dir=" ++ top </> "automaton"
27+ , "--src-dir=" ++ top </> "IO"
28+ , "--src-dir=" ++ top </> "Elm-Test"
29+ , "Test.elm"
30+ ]
31+
32+ -- run tests
33+ let ioScript s = top </> "IO" </> s
34+ files = [ ioScript "prescript.js"
35+ , Elm.runtime
36+ , "build" </> "Test.js"
37+ , ioScript "handler.js"
38+ ]
39+ exe <- readProcess "cat" files ""
40+ writeFile "exe.js" exe
41+ exitWith =<< waitForProcess =<< (runCommand "node exe.js")
42+
43+runCmd :: String -> [String] -> IO ()
44+runCmd cmd args = do
45+ putStrLn (cmd ++ " " ++ unwords args)
46+ (exitCode, _stdout, stderr) <- readProcessWithExitCode cmd args ""
47+ case exitCode of
48+ ExitSuccess -> return ()
49+ ExitFailure _ -> error stderr
tests/elm/Test.elm → tests/libraries/Test.elmrenamed+10−7
@@ -11,19 +11,22 @@ import IO.Runner as Run
11
11
12import Test.Array as Array
12import Test.Array as Array
13import Test.Dict as Dict
13import Test.Dict as Dict
14+import Test.Equality as Equality
14import Test.List as List
15import Test.List as List
15import Test.Set as Set
16import Test.Set as Set
16import Test.String as String
17import Test.String as String
17import Test.Trampoline as Trampoline
18import Test.Trampoline as Trampoline
18
19
19tests : Test
20tests : Test
20−tests = suite "Elm Standard Library Tests" [ List.tests,
21+tests = suite "Elm Standard Library Tests"
22+ [ Array.tests
23+ , Dict.tests
24+ , Equality.tests
25+ , List.tests
26+ , Set.tests
21− String.tests,
27+ , String.tests
22− Trampoline.tests,
28+ , Trampoline.tests
23− Array.tests,
24− Dict.tests,
25− Set.tests
26− ]
29+ ]
27
30
28console : IO ()
31console : IO ()
29console = runDisplay tests
32console = runDisplay tests
tests/libraries/Test/Array.elmnew file+63
@@ -0,0 +1,63 @@
1+module Test.Array (tests) where
2+
3+import List
4+import Array
5+import Native.Array
6+
7+import ElmTest.Assertion (..)
8+import ElmTest.Test (..)
9+
10+tests : Test
11+tests =
12+ let creationTests = suite "Creation"
13+ [ test "empty" <| assertEqual Array.empty (Array.fromList [])
14+ , test "initialize" <| assertEqual (Array.initialize 4 id) (Array.fromList [0,1,2,3])
15+ , test "initialize 2" <| assertEqual (Array.initialize 4 (\n -> n*n)) (Array.fromList [0,1,4,9])
16+ , test "initialize 3" <| assertEqual (Array.initialize 4 (always 0)) (Array.fromList [0,0,0,0])
17+ , test "initialize Empty" <| assertEqual (Array.initialize 0 id) Array.empty
18+ , test "initialize 4" <| assertEqual (Array.initialize 2 (always 0)) (Array.fromList [0,0])
19+ , test "repeat" <| assertEqual (Array.repeat 5 40) (Array.fromList [40,40,40,40,40])
20+ , test "repeat 2" <| assertEqual (Array.repeat 5 0) (Array.fromList [0,0,0,0,0])
21+ , test "repeat 3" <| assertEqual (Array.repeat 3 "cat") (Array.fromList ["cat","cat","cat"])
22+ , test "fromList" <| assertEqual (Array.fromList []) Array.empty
23+ ]
24+ basicsTests = suite "Basics"
25+ [ test "length" <| assertEqual 3 (Array.length (Array.fromList [1,2,3]))
26+ , test "length - Long" <| assertEqual 10000 (Array.length (Array.repeat 10000 0))
27+ , test "push" <| assertEqual (Array.fromList [1,2,3]) (Array.push 3 (Array.fromList [1,2]))
28+ , test "append" <| assertEqual [42,42,81,81,81] (Array.toList (Array.append (Array.repeat 2 42) (Array.repeat 3 81)))
29+ ]
30+ getAndSetTests = suite "Get and Set"
31+ [ test "get" <| assertEqual (Just 2) (Array.get 1 (Array.fromList [3,2,1]))
32+ , test "get 2" <| assertEqual Nothing (Array.get 5 (Array.fromList [3,2,1]))
33+ , test "get 3" <| assertEqual Nothing (Array.get -1 (Array.fromList [3,2,1]))
34+ , test "getOrElse 1" <| assertEqual 1 (Array.getOrElse 0 2 (Array.fromList [3,2,1]))
35+ , test "getOrElse 2" <| assertEqual 0 (Array.getOrElse 0 5 (Array.fromList [3,2,1]))
36+ , test "getOrFail" <| assertEqual 1 (Array.getOrFail 2 (Array.fromList [3,2,1]))
37+ , test "set" <| assertEqual (Array.fromList [1,7,3]) (Array.set 1 7 (Array.fromList [1,2,3]))
38+ ]
39+ takingArraysApartTests = suite "Taking Arrays Apart"
40+ [ test "toList" <| assertEqual [3,5,8] (Array.toList (Array.fromList [3,5,8]))
41+ , test "toIndexedList" <| assertEqual [(0,"cat"), (1,"dog")] (Array.toIndexedList (Array.fromList ["cat","dog"]))
42+ , test "slice 1" <| assertEqual (Array.fromList [0,1,2]) (Array.slice 0 3 (Array.fromList [0,1,2,3,4]))
43+ , test "slice 2" <| assertEqual (Array.fromList [1,2,3]) (Array.slice 1 4 (Array.fromList [0,1,2,3,4]))
44+ , test "slice 3" <| assertEqual (Array.fromList [1,2,3]) (Array.slice 1 -1 (Array.fromList [0,1,2,3,4]))
45+ , test "slice 4" <| assertEqual (Array.fromList [2]) (Array.slice -3 -2 (Array.fromList [0,1,2,3,4]))
46+ ]
47+ mappingAndFoldingTests = suite "Mapping and Folding"
48+ [ test "map" <| assertEqual (Array.fromList [1,2,3]) (Array.map sqrt (Array.fromList [1,4,9]))
49+ , test "indexedMap 1" <| assertEqual (Array.fromList [0,5,10]) (Array.indexedMap (*) (Array.fromList [5,5,5]))
50+ , test "indexedMap 2" <| assertEqual [0..99] (Array.toList (Array.indexedMap always (Array.repeat 100 0)))
51+ , test "foldl" <| assertEqual [3,2,1] (Array.foldl (::) [] (Array.fromList [1,2,3]))
52+ , test "foldr 1" <| assertEqual 15 (Array.foldr (+) 0 (Array.repeat 3 5))
53+ , test "foldr 2" <| assertEqual [1,2,3] (Array.foldr (::) [] (Array.fromList [1,2,3]))
54+ , test "filter" <| assertEqual (Array.fromList [2,4,6]) (Array.filter (\x -> x `mod` 2 == 0) (Array.fromList [1..6]))
55+ ]
56+ nativeTests = suite "Conversion to JS Arrays"
57+ [ test "jsArrays" <| assertEqual (Array.fromList [1..1100]) (Native.Array.fromJSArray (Native.Array.toJSArray (Array.fromList [1..1100])))
58+ ]
59+ in
60+ suite "Array"
61+ [ creationTests, basicsTests, getAndSetTests
62+ , takingArraysApartTests, mappingAndFoldingTests, nativeTests
63+ ]
tests/elm/Test/Dict.elm → tests/libraries/Test/Dict.elmrenamed

The content is the same.

tests/libraries/Test/Equality.elmnew file+23
@@ -0,0 +1,23 @@
1+module Test.Equality (tests) where
2+
3+import ElmTest.Assertion (..)
4+import ElmTest.Test (..)
5+
6+data Different = A String
7+ | B [Int]
8+
9+tests : Test
10+tests =
11+ let diffTests = suite "ADT equality"
12+ [ test "As eq" <| assert (A "a" == A "a")
13+ , test "Bs eq" <| assert (B [1] == B [1])
14+ , test "A left neq" <| assert . not <| (A "a" == B [1])
15+ , test "A left neq" <| assert . not <| (B [1] == A "a")
16+ ]
17+ recordTests = suite "Record equality"
18+ [ test "empty same" <| assert ({} == {})
19+ , test "ctor same" <| assert ({ctor = Just 3} == {ctor = Just 3})
20+ , test "ctor diff" . assert . not <| ({ctor = Just 3} == {ctor = Nothing})
21+ ]
22+ in
23+ suite "Equality Tests" [diffTests, recordTests]
tests/elm/Test/List.elm → tests/libraries/Test/List.elmrenamed

The content is the same.

tests/elm/Test/Set.elm → tests/libraries/Test/Set.elmrenamed

The content is the same.

tests/libraries/Test/String.elmnew file+37
@@ -0,0 +1,37 @@
1+module Test.String (tests) where
2+
3+import List
4+import String (..)
5+
6+import ElmTest.Assertion (..)
7+import ElmTest.Test (..)
8+
9+tests : Test
10+tests =
11+ let simpleTests = suite "Simple Stuff"
12+ [ test "is empty" <| assert (isEmpty "")
13+ , test "is not empty" <| assert (not (isEmpty ("the world")))
14+ , test "length" <| assertEqual 11 (length "innumerable")
15+ , test "endsWith" (assert <| endsWith "ship" "spaceship")
16+ , test "reverse" <| assertEqual "desserts" (reverse "stressed")
17+ , test "repeat" <| assertEqual "hahaha" (repeat 3 "ha")
18+ ]
19+
20+ combiningTests = suite "Combining Strings"
21+ [ test "uncons non-empty" <| assertEqual (Just ('a',"bc")) (uncons "abc")
22+ , test "uncons empty" <| assertEqual Nothing (uncons "")
23+ , test "append 1" <| assertEqual "butterfly" (append "butter" "fly")
24+ , test "append 2" <| assertEqual "butter" (append "butter" "")
25+ , test "append 3" <| assertEqual "butter" (append "" "butter")
26+ , test "concat" <| assertEqual "nevertheless" (concat ["never","the","less"])
27+ , test "split commas" <| assertEqual ["cat","dog","cow"] (split "," "cat,dog,cow")
28+ , test "split slashes"<| assertEqual ["home","steve","Desktop", ""] (split "/" "home/steve/Desktop/")
29+ , test "join spaces" <| assertEqual "cat dog cow" (join " " ["cat","dog","cow"])
30+ , test "join slashes" <| assertEqual "home/steve/Desktop" (join "/" ["home","steve","Desktop"])
31+ , test "slice 1" <| assertEqual "c" (slice 2 3 "abcd")
32+ , test "slice 2" <| assertEqual "abc" (slice 0 3 "abcd")
33+ , test "slice 3" <| assertEqual "abc" (slice 0 -1 "abcd")
34+ , test "slice 4" <| assertEqual "cd" (slice -2 4 "abcd")
35+ ]
36+ in
37+ suite "String" [ simpleTests, combiningTests ]
tests/elm/Test/Trampoline.elm → tests/libraries/Test/Trampoline.elmrenamed

The content is the same.

tests/test-files/good/Box.elmdeleted−82
@@ -1,82 +0,0 @@
1−
2−module Box where
3−
4−import MJS (V3,M4x4,v3,makeRotate,makePerspective,makeLookAt,mul)
5−import Graphics.WebGL (Triangle, zipTriangle, Shader, Model, model, webgl)
6−import Window(dimensions)
7−
8−-- Define what our geometry looks like
9−
10−p0 = v3 1 1 1
11−p1 = v3 -1 1 1
12−p2 = v3 -1 -1 1
13−p3 = v3 1 -1 1
14−p4 = v3 1 -1 -1
15−p5 = v3 1 1 -1
16−p6 = v3 -1 1 -1
17−p7 = v3 -1 -1 -1
18−
19−front = [(p0,p1,p2),(p2,p3,p0)]
20−back = [(p5,p6,p7),(p7,p4,p5)]
21−right = [(p0,p3,p4),(p4,p5,p0)]
22−left = [(p1,p2,p7),(p7,p6,p1)]
23−top = [(p0,p5,p6),(p6,p1,p0)]
24−bottom = [(p3,p4,p7),(p7,p2,p3)]
25−
26−positions = front ++ back ++ right ++ left ++ top ++ bottom
27−
28−gray = v3 0.7 0.7 0.7
29−red = v3 1 0 0
30−green = v3 0 1 0
31−blue = v3 0 0 1
32−yellow = v3 1 1 0
33−purple = v3 0 1 1
34−
35−repeat n elem = map (\_ -> elem) [0..n-1]
36−
37−colors = concat . map (\c -> repeat 2 (c,c,c)) <| [gray,red,green,blue,yellow,purple]
38−
39−mesh : [Triangle {pos : V3, color : V3}]
40−mesh = zipWith (zipTriangle (\pos color -> { pos = pos, color = color })) positions colors
41−
42−vert : Shader {a | pos : V3, color : V3} {b | rot : M4x4, per : M4x4, cam : M4x4} {vcolor : V3}
43−vert = [glShader|
44−attribute vec3 pos;
45−attribute vec3 color;
46−uniform mat4 per;
47−uniform mat4 cam;
48−uniform mat4 rot;
49−varying vec3 vcolor;
50−void main () {
51− gl_Position = per * cam * rot * vec4(pos, 1.0);
52− vcolor = color;
53−}
54−|]
55−
56−frag : Shader {} {b | shade : Float} {vcolor : V3}
57−frag = [glShader|
58−precision mediump float;
59−uniform float shade;
60−varying vec3 vcolor;
61−void main () {
62− gl_FragColor = shade * vec4(vcolor, 1.0);
63−}
64−|]
65−
66−per : M4x4
67−per = makePerspective 45 1 0.01 100
68−
69−cam : M4x4
70−cam = makeLookAt (v3 0 0 5) (v3 0 0 0) (v3 0 1 0)
71−
72−angle : Signal Float
73−angle = foldp (\_ n -> n + 0.02) 0 (fps 25)
74−
75−rot : Signal { rot : M4x4, per : M4x4, cam : M4x4, shade : Float }
76−rot = (\t -> { rot = mul (makeRotate (3*t) (v3 0 1 0)) (makeRotate (2*t) (v3 1 0 0)), per = per, cam = cam, shade = 0.8 }) <~ angle
77−
78−draw : Signal [Model]
79−draw = combine [ (\rot -> (model vert frag mesh rot)) <~ rot ]
80−
81−main = webgl <~ dimensions ~ draw
82−
tests/test-files/good/Crate.elmdeleted−84
@@ -1,84 +0,0 @@
1−
2−module Crate where
3−
4−import Http (..)
5−import MJS (..)
6−import Graphics.WebGL (..)
7−
8−pul = {pos=v3 -1 1 0, coord=v3 0 1 0}
9−pur = {pos=v3 1 1 0, coord=v3 1 1 0}
10−pbl = {pos=v3 -1 -1 0, coord=v3 0 0 0}
11−pbr = {pos=v3 1 -1 0, coord=v3 1 0 0}
12−
13−face : [Triangle { pos : V3, coord : V3 }]
14−face = [(pul,pur,pbl),(pbl,pur,pbr)]
15−
16−rotFace : Float -> Float -> [Triangle { pos : V3, coord : V3 }]
17−rotFace turnH turnV =
18− let x = makeRotate (turnV * pi / 2) (v3 1 0 0)
19− y = makeRotate (turnH * pi / 2) (v3 0 1 0)
20− s = makeTranslate (v3 0 0 1)
21− t = mul (mul x y) s
22− in map (mapTriangle (\x -> {x | pos <- mul4x4 t x.pos })) face
23−
24−mesh : [Triangle { pos : V3, coord : V3 }]
25−mesh = concat . map (uncurry rotFace) <|
26− [ (0,0)
27− , (1,0)
28− , (2,0)
29− , (3,0)
30− , (0,1)
31− , (0,-1)
32− ]
33−
34−vert : Shader { pos : V3, coord : V3 } { u | view : M4x4 } { vcoord : V2 }
35−vert = [glShader|
36−attribute vec3 pos;
37−attribute vec3 coord;
38−uniform mat4 view;
39−varying vec2 vcoord;
40−void main () {
41− gl_Position = view * vec4(pos, 1.0);
42− vcoord = coord.xy;
43−}
44−|]
45−
46−frag : Shader {} { u | crate : Texture } { vcoord : V2 }
47−frag = [glShader|
48−precision mediump float;
49−uniform sampler2D crate;
50−varying vec2 vcoord;
51−void main () {
52− gl_FragColor = texture2D(crate, vcoord);
53−}
54−|]
55−
56−crateTex : Signal (Response Texture)
57−crateTex = loadTex "woodCrate.JPG"
58−
59−per : M4x4
60−per = makePerspective 45 1 0.01 100
61−
62−cam : M4x4
63−cam = makeLookAt (v3 0 0 5) (v3 0 0 0) (v3 0 1 0)
64−
65−angle : Signal Float
66−angle = foldp (\_ n -> n + 0.02) 0 (fps 25)
67−
68−view : Float -> M4x4
69−view t =
70− let x = makeRotate (2*t) (v3 1 0 0)
71− y = makeRotate (3*t) (v3 0 1 0)
72− in foldr mul identity [per,cam,y,x]
73−
74−content : Response Texture -> M4x4 -> [Model]
75−content response view = case response of
76− Waiting -> []
77− Failure i s -> []
78− Success tex -> [model vert frag mesh { crate = tex, view = view }]
79−
80−main = webgl (400,400) <~ (content <~ crateTex ~ (view <~ angle))
81−
82−--main = asText (List.length mesh)
83−
84−