on master help sign in
Merge branch 'stable' into canonicalize

Conflicts: compiler/Build/Dependencies.hs compiler/Build/Print.hs compiler/Elm/Internal/Utils.hs compiler/Generate/JavaScript/Ports.hs compiler/Type/ExtraChecks.hs

commite99d840ed0c79c72c95f6a1500188cbf1bba8333 authorEvan Czaplicki <info@elm-lang.org> dateSun 18 May 2014, 15:54 (12 years ago) parentaa19d7b3ecb9fd
75 files changed+927−2983
.gitignore+1−3 .travis.yml+31−3 Elm.cabal+17−9 compiler/AST/Literal.hs+4−4 compiler/Build/Dependencies.hs+67−42 compiler/Build/Flags.hs+7−4 compiler/Build/Utils.hs+9 compiler/Compiler.hs+16−10 compiler/Elm/Internal/Dependencies.hs+39−37 compiler/Elm/Internal/Utils.hs+8−1 compiler/Generate/JavaScript.hs+2−1 compiler/Generate/JavaScript/Ports.hs+16−8 compiler/Type/ExtraChecks.hs+4−1 compiler/Type/Type.hs+2−2 libraries/Array.elm+22−13 libraries/Color.elm+186−88 libraries/Graphics/WebGL.elm−56 libraries/MJS.elm−129 libraries/Native/Array.js+53−7 libraries/Native/Bitwise.js+1−1 libraries/Native/Color.js+16−60 libraries/Native/Error.js+2−4 libraries/Native/Graphics/Input.js+1−1 libraries/Native/Graphics/WebGL.js−366 libraries/Native/Json.js+1−1 libraries/Native/MJS.js−1783 libraries/Native/Regex.js+2−2 libraries/Native/String.js+4−4 libraries/Native/Text.js+3−3 libraries/Native/Utils.js+10−1 libraries/String.elm+8−8 libraries/elm_dependencies.json−2 runtime/Render/Collage.js+4−4 runtime/Render/Element.js+33−27 runtime/Render/Utils.js+2−7 tests/hs/CompilerTest.hs → tests/compiler/CompilerTest.hs tests/hs/Tests/Compiler.hs → tests/compiler/Tests/Compiler.hs tests/hs/Tests/Property.hs → tests/compiler/Tests/Property.hs tests/hs/Tests/Property/Arbitrary.hs → tests/compiler/Tests/Property/Arbitrary.hs tests/hs/test-files/bad/BBTArgs → tests/compiler/test-files/bad/BBTArgs tests/hs/test-files/bad/InfiniteType.elm → tests/compiler/test-files/bad/InfiniteType.elm tests/hs/test-files/bad/NonElementMain.elm → tests/compiler/test-files/bad/NonElementMain.elm tests/hs/test-files/bad/Strings/ExtraClose.elm → tests/compiler/test-files/bad/Strings/ExtraClose.elm tests/hs/test-files/good/AliasSubstitution.elm → tests/compiler/test-files/good/AliasSubstitution.elm tests/compiler/test-files/good/Box.elm+89 tests/compiler/test-files/good/Crate.elm+85 tests/hs/test-files/good/NoExpressions.elm → tests/compiler/test-files/good/NoExpressions.elm tests/hs/test-files/good/Otherwise.elm → tests/compiler/test-files/good/Otherwise.elm tests/hs/test-files/good/Ports.elm → tests/compiler/test-files/good/Ports.elm tests/hs/test-files/good/QuotesAndComments.elm → tests/compiler/test-files/good/QuotesAndComments.elm tests/hs/test-files/good/Soundness/Apply.elm → tests/compiler/test-files/good/Soundness/Apply.elm tests/hs/test-files/good/Soundness/ApplyAnnotated.elm → tests/compiler/test-files/good/Soundness/ApplyAnnotated.elm tests/hs/test-files/good/Soundness/Id.elm → tests/compiler/test-files/good/Soundness/Id.elm tests/hs/test-files/good/Soundness/IdAnnotated.elm → tests/compiler/test-files/good/Soundness/IdAnnotated.elm tests/hs/test-files/good/Soundness/TrickyId.elm → tests/compiler/test-files/good/Soundness/TrickyId.elm tests/hs/test-files/good/Soundness/TrickyIdAnnotated.elm → tests/compiler/test-files/good/Soundness/TrickyIdAnnotated.elm tests/hs/test-files/good/Strings/Multiline.elm → tests/compiler/test-files/good/Strings/Multiline.elm tests/hs/test-files/good/Strings/MultilineNormal.elm → tests/compiler/test-files/good/Strings/MultilineNormal.elm tests/hs/test-files/good/Unify/LockedVars.elm → tests/compiler/test-files/good/Unify/LockedVars.elm tests/hs/test-files/good/Unify/NonHomogeneousRecords.elm → tests/compiler/test-files/good/Unify/NonHomogeneousRecords.elm tests/test-files/good/woodCrate.JPG → tests/compiler/test-files/good/woodCrate.JPG tests/elm/Test/Array.elm−54 tests/elm/Test/String.elm−34 tests/hs/LibTest.hs−30 tests/libraries/LibraryTest.hs+49 tests/elm/Test.elm → tests/libraries/Test.elm+10−7 tests/libraries/Test/Array.elm+63 tests/elm/Test/Dict.elm → tests/libraries/Test/Dict.elm tests/libraries/Test/Equality.elm+23 tests/elm/Test/List.elm → tests/libraries/Test/List.elm tests/elm/Test/Set.elm → tests/libraries/Test/Set.elm tests/libraries/Test/String.elm+37 tests/elm/Test/Trampoline.elm → tests/libraries/Test/Trampoline.elm tests/test-files/good/Box.elm−82 tests/test-files/good/Crate.elm−84
.gitignore+1−3
@@ -13,7 +13,5 @@ data
1313build
1414cache
1515*~
16−tests/elm/build/
17−tests/elm/cache/
18−tests/elm/exe.js
16+exe.js
1917node_modules/
.travis.yml+31−3
@@ -1,3 +1,31 @@
1−language: haskell
2−ghc:
3− - 7.6
1+# Based on https://github.com/hvr/multi-ghc-travis and https://github.com/ekmett/lens/blob/master/.travis.yml
2+
3+# NB: don't set `language: haskell` here
4+
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 @@
11Name: Elm
2−Version: 0.12.1
2+Version: 0.12.2
33Synopsis: The Elm language module.
44Description: Elm aims to make client-side web-development more pleasant.
55 It is a statically/strongly typed, functional reactive
@@ -113,10 +113,12 @@ Library
113113 pandoc >= 1.10,
114114 parsec >= 3.1.1,
115115 pretty,
116+ scientific,
116117 text,
117118 transformers >= 0.2,
118119 union-find,
119− unordered-containers
120+ unordered-containers,
121+ yaml
120122
121123Executable elm
122124 Main-is: Compiler.hs
@@ -197,11 +199,13 @@ Executable elm
197199 mtl >= 2,
198200 pandoc >= 1.10,
199201 parsec >= 3.1.1,
202+ scientific,
200203 pretty,
201204 text,
202205 transformers >= 0.2,
203206 union-find,
204− unordered-containers
207+ unordered-containers,
208+ yaml
205209
206210Executable elm-doc
207211 Main-is: Docs.hs
@@ -240,12 +244,14 @@ Executable elm-doc
240244 pandoc >= 1.10,
241245 parsec >= 3.1.1,
242246 pretty,
247+ scientific,
243248 text,
244− union-find
249+ union-find,
250+ yaml
245251
246252Test-Suite compiler-tests
247253 Type: exitcode-stdio-1.0
248− Hs-Source-Dirs: tests/hs, compiler
254+ Hs-Source-Dirs: tests/compiler, compiler
249255 Main-is: CompilerTest.hs
250256 other-modules: Tests.Compiler
251257 Tests.Property
@@ -278,15 +284,17 @@ Test-Suite compiler-tests
278284 pandoc >= 1.10,
279285 parsec >= 3.1.1,
280286 pretty,
287+ scientific,
281288 text,
282289 transformers >= 0.2,
283290 union-find,
284− unordered-containers
291+ unordered-containers,
292+ yaml
285293
286−Test-Suite lib-tests
294+Test-Suite library-tests
287295 Type: exitcode-stdio-1.0
288− Hs-Source-Dirs: tests/hs
289− Main-is: LibTest.hs
296+ Hs-Source-Dirs: tests/libraries
297+ Main-is: LibraryTest.hs
290298 build-depends: base,
291299 directory,
292300 Elm,
compiler/AST/Literal.hs+4−4
@@ -29,10 +29,10 @@ glTipeName glTipe =
2929 case glTipe of
3030 Int -> "Int"
3131 Float -> "Float"
32− V2 -> "MJS.V2"
33− V3 -> "MJS.V3"
34− V4 -> "MJS.V4"
35− M4 -> "MJS.M4x4"
32+ V2 -> "Math.Vector2.Vec2"
33+ V3 -> "Math.Vector3.Vec3"
34+ V4 -> "Math.Vector4.Vec4"
35+ M4 -> "Math.Matrix4.Mat4"
3636 Texture -> "Graphics.WebGL.Texture"
3737
3838data GLShaderTipe = GLShaderTipe
compiler/Build/Dependencies.hs+67−42
@@ -1,55 +1,57 @@
11{-# OPTIONS_GHC -W #-}
2−module Build.Dependencies (getSortedDependencies, readDeps) where
2+module Build.Dependencies (Recipe(..), getBuildRecipe, readDeps) where
33
4−import Control.Applicative
54import Control.Monad.Error
65import qualified Control.Monad.State as State
7−import qualified Data.Aeson as Json
8−import qualified Data.ByteString.Lazy.Char8 as BSC
96import qualified Data.Graph as Graph
107import qualified Data.List as List
118import qualified Data.Map as Map
12−import qualified Data.Maybe as Maybe
139import qualified Data.Set as Set
1410import System.Directory
1511import System.FilePath as FP
1612
17−import Build.Print (failure)
18−
1913import qualified AST.Module as Module
2014import qualified Parse.Parse as Parse
2115import qualified Elm.Internal.Paths as Path
2216import qualified Elm.Internal.Name as N
17+import qualified Elm.Internal.Version as V
2318import qualified Elm.Internal.Dependencies as Deps
2419
25−getSortedDependencies :: [FilePath] -> Module.Interfaces -> FilePath -> IO [String]
26−getSortedDependencies srcDirs builtIns root =
27− do extras <- extraDependencies
28− let allSrcDirs = srcDirs ++ Maybe.fromMaybe [] extras
29− result <- runErrorT $ readAllDeps allSrcDirs builtIns root
30− case result of
31− Right deps -> sortDeps deps
32− Left err -> failure err
33−
34−extraDependencies :: IO (Maybe [FilePath])
35−extraDependencies =
36− do exists <- doesFileExist Path.dependencyFile
37− if not exists then return Nothing else Just <$> getPaths
20+data Recipe = Recipe
21+ { _elmFiles :: [FilePath]
22+ , _jsFiles :: [FilePath]
23+ }
24+
25+getBuildRecipe :: [FilePath] -> Module.Interfaces -> FilePath -> ErrorT String IO Recipe
26+getBuildRecipe srcDirs builtIns root =
27+ do directories <- getDependencies
28+ jsFiles <- nativeFiles ("." : directories)
29+ let allSrcDirs = srcDirs ++ directories
30+ nodes <- collectDependencies allSrcDirs builtIns root
31+ elmFiles <- sortElmFiles nodes
32+ return (Recipe elmFiles jsFiles)
33+
34+-- | Based on the projects elm_dependencies.json, find all of the paths and
35+-- dependency information we might need.
36+getDependencies :: ErrorT String IO [FilePath]
37+getDependencies =
38+ do exists <- liftIO $ doesFileExist Path.dependencyFile
39+ if not exists then return [] else getPaths
3840 where
39− getPaths = do
40− raw <- BSC.readFile Path.dependencyFile
41− case Json.eitherDecode raw of
42− Right (Deps.Mini deps) -> mapM validate deps
43− Left err ->
44− failure $ "Error reading the " ++ Path.dependencyFile ++ " file:\n" ++ err
45−
46− validate (name,version) = do
47− let path = Path.dependencyDirectory </> toPath name version
48− exists <- doesDirectoryExist path
49− if exists then return path else failure (notFound name version)
50−
51− toPath name version = N.toFilePath name </> show version
52−
41+ getPaths :: ErrorT String IO [FilePath]
42+ getPaths =
43+ Deps.withDeps Path.dependencyFile $ \deps ->
44+ mapM getPath (Deps.dependencies deps)
45+
46+ getPath :: (N.Name, V.Version) -> ErrorT String IO FilePath
47+ getPath (name,version) = do
48+ let path = Path.dependencyDirectory </> N.toFilePath name </> show version
49+ exists <- liftIO $ doesDirectoryExist path
50+ if exists
51+ then return path
52+ else throwError (notFound name version)
53+
54+ notFound :: N.Name -> V.Version -> String
5355 notFound name version =
5456 unlines
5557 [ "Your " ++ Path.dependencyFile ++ " file says you depend on library"
@@ -58,27 +60,50 @@ extraDependencies =
5860 , ""
5961 , " elm-get install " ++ show name ++ " " ++ show version ]
6062
61−type Deps = (FilePath, String, [String])
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+
85+type DependencyNode = (FilePath, String, [String])
6286
63−sortDeps :: [Deps] -> IO [String]
64−sortDeps depends =
87+sortElmFiles :: [DependencyNode] -> ErrorT String IO [FilePath]
88+sortElmFiles depends =
6589 if null mistakes
6690 then return (concat sccs)
67− else failure $ msg ++ unlines (map show mistakes)
91+ else throwError $ msg ++ unlines (map show mistakes)
6892 where
6993 sccs = map Graph.flattenSCC $ Graph.stronglyConnComp depends
7094
7195 mistakes = filter (\scc -> length scc > 1) sccs
7296 msg = "A cyclical module dependency or was detected in:\n"
7397
74−readAllDeps :: [FilePath] -> Module.Interfaces -> FilePath -> ErrorT String IO [Deps]
75−readAllDeps srcDirs rawBuiltIns filePath =
98+collectDependencies :: [FilePath] -> Module.Interfaces -> FilePath
99+ -> ErrorT String IO [DependencyNode]
100+collectDependencies srcDirs rawBuiltIns filePath =
76101 State.evalStateT (go Nothing filePath) Set.empty
77102 where
78103 builtIns :: Set.Set String
79104 builtIns = Set.fromList $ Map.keys rawBuiltIns
80105
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]
82107 go parentModuleName filePath = do
83108 filePath' <- lift $ findSrcFile parentModuleName srcDirs filePath
84109 (moduleName, deps) <- lift $ readDeps filePath'
@@ -93,9 +118,9 @@ readDeps :: FilePath -> ErrorT String IO (String, [String])
93118readDeps path = do
94119 txt <- lift $ readFile path
95120 case Parse.dependencies txt of
121+ Right o -> return o
96122 Left err -> throwError $ msg ++ show err
97123 where msg = "Error resolving dependencies in " ++ path ++ ":\n"
98− Right o -> return o
99124
100125findSrcFile :: Maybe String -> [FilePath] -> FilePath -> ErrorT String IO FilePath
101126findSrcFile parentModuleName dirs path =
compiler/Build/Flags.hs+7−4
@@ -7,7 +7,8 @@ import System.Console.CmdArgs
77data Flags = Flags
88 { make :: Bool
99 , files :: [FilePath]
10− , runtime :: Maybe FilePath
10+ , set_runtime :: Maybe FilePath
11+ , get_runtime :: Bool
1112 , only_js :: Bool
1213 , print_types :: Bool
1314 , scripts :: [FilePath]
@@ -28,8 +29,10 @@ flags = Flags
2829 &= help "Do not import Prelude by default, used only when compiling standard libraries."
2930 , scripts = [] &= typFile
3031 &= help "Load JavaScript files in generated HTML. Files will be included in the given order."
31− , runtime = Nothing &= typFile
32− &= help "Specify a custom location for Elm's runtime system."
32+ , set_runtime = Nothing &= typFile
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."
3336 , cache_dir = "cache" &= typFile
3437 &= help "Directory for files cached to make builds faster. Defaults to cache/ directory."
3538 , build_dir = "build" &= typFile
@@ -37,7 +40,7 @@ flags = Flags
3740 , src_dir = ["."] &= typFile
3841 &= help "Additional source directories besides project root. Searched when using --make"
3942 , print_types = False
40− &= help "Print out infered types of top-level definitions."
43+ &= help "Print out inferred types of top-level definitions."
4144 } &= help "Compile Elm programs to HTML, CSS, and JavaScript."
4245 &= helpArg [explicit, name "help", name "h"]
4346 &= versionArg [explicit, name "version", name "v", summary (show Version.elmVersion)]
compiler/Build/Utils.hs+9
@@ -1,10 +1,12 @@
11{-# OPTIONS_GHC -W #-}
22module Build.Utils where
33
4+import Control.Monad.Error
45import System.Directory (doesFileExist)
56import System.Environment (getEnv)
67import System.FilePath ((</>), replaceExtension)
78import qualified Build.Flags as Flag
9+import qualified Build.Print as Print
810import qualified Paths_Elm as This
911
1012buildPath :: Flag.Flags -> FilePath -> String -> FilePath
@@ -33,3 +35,10 @@ getDataFile name = do
3335 else do
3436 env <- getEnv "ELM_HOME"
3537 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 @@
11{-# OPTIONS_GHC -W #-}
22module Main where
33
4−import Control.Monad (foldM)
4+import Control.Monad (foldM, when)
55import qualified Data.Maybe as Maybe
66import Text.Blaze.Html.Renderer.String (renderHtml)
77import qualified Data.ByteString.Lazy.Char8 as BS
88import qualified System.Console.CmdArgs as CmdArgs
99import System.Directory
10+import System.Exit (exitSuccess)
1011import System.FilePath
1112import GHC.Conc
1213
13−import Build.Dependencies (getSortedDependencies)
14+import Build.Dependencies (getBuildRecipe, Recipe(..))
1415import qualified Generate.Html as Html
1516import qualified Metadata.Prelude as Prelude
1617import qualified Build.Utils as Utils
@@ -24,7 +25,10 @@ main = do setNumCapabilities =<< getNumProcessors
2425
2526compileArgs :: Flag.Flags -> IO ()
2627compileArgs flags =
27− case Flag.files flags of
28+ do when (Flag.get_runtime flags) $
29+ do putStrLn Path.runtime
30+ exitSuccess
31+ case Flag.files flags of
2832 [] -> putStrLn "Usage: elm [OPTIONS] [FILES]\nFor more help: elm --help"
2933 fs -> mapM_ (build flags) fs
3034
@@ -33,13 +37,15 @@ build flags rootFile =
3337 do let noPrelude = Flag.no_prelude flags
3438 builtIns <- Prelude.interfaces noPrelude
3539
36− files <- if Flag.make flags
37− then getSortedDependencies (Flag.src_dir flags) builtIns rootFile
38− else return [rootFile]
40+ (Recipe elmFiles jsFiles) <-
41+ if Flag.make flags
42+ then Utils.run (getBuildRecipe (Flag.src_dir flags) builtIns rootFile)
43+ else return (Recipe [rootFile] [])
3944
40− moduleName <- File.build flags builtIns files
45+ moduleName <- File.build flags builtIns elmFiles
4146
42− js <- foldM appendToOutput BS.empty files
47+ let elmos = map (Utils.elmo flags) elmFiles
48+ js <- foldM appendToOutput BS.empty (elmos ++ jsFiles)
4349
4450 (extension, code) <-
4551 if Flag.only_js flags
@@ -56,12 +62,12 @@ build flags rootFile =
5662 where
5763 appendToOutput :: BS.ByteString -> FilePath -> IO BS.ByteString
5864 appendToOutput js filePath = do
59− src <- BS.readFile (Utils.elmo flags filePath)
65+ src <- BS.readFile filePath
6066 return (BS.append src js)
6167
6268 sources js = map Html.Link (Flag.scripts flags) ++ [ Html.Source js ]
6369
6470 makeHtml js moduleName = ("html", BS.pack $ renderHtml html)
6571 where
66− rtsPath = Maybe.fromMaybe Path.runtime (Flag.runtime flags)
72+ rtsPath = Maybe.fromMaybe Path.runtime (Flag.set_runtime flags)
6773 html = Html.generate rtsPath (takeBaseName rootFile) (sources js) moduleName ""
compiler/Elm/Internal/Dependencies.hs+39−37
@@ -2,10 +2,13 @@
22module Elm.Internal.Dependencies where
33
44import Control.Applicative
5+import Control.Arrow (first)
56import Control.Monad.Error
67import qualified Control.Exception as E
78import Data.Aeson
9+import Data.Aeson.Types (Parser)
810import Data.Aeson.Encode.Pretty
11+import Data.Maybe (fromMaybe)
912import qualified Data.List as List
1013import qualified Data.ByteString.Lazy as BS
1114import qualified Data.HashMap.Strict as Map
@@ -23,33 +26,28 @@ data Deps = Deps
2326 , license :: String
2427 , repo :: String
2528 , exposed :: [String]
29+ , native :: [String]
2630 , elmVersion :: V.Version
2731 , dependencies :: [(N.Name,V.Version)]
2832 } deriving (Show, Eq, Ord)
2933
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−
4034instance ToJSON Deps where
41− toJSON d = object [
42− "version" .= version d,
43− "summary" .= summary d,
44− "description" .= description d,
45− "license" .= license d,
46− "repository" .= repo d,
47− "exposed-modules" .= exposed d,
48− "elm-version" .= elmVersion d,
49− "dependencies" .= (jsonDeps . dependencies $ d)
50− ]
51− where jsonDeps = Map.fromList . map (mapFst (T.pack . show))
52− mapFst f (a,b) = (f a, b)
35+ toJSON d =
36+ object $
37+ [ "version" .= version d
38+ , "summary" .= summary d
39+ , "description" .= description d
40+ , "license" .= license d
41+ , "repository" .= repo d
42+ , "exposed-modules" .= exposed d
43+ , "elm-version" .= elmVersion d
44+ , "dependencies" .= (jsonDeps . dependencies $ d)
45+ ] ++ nativeModules
46+ where
47+ jsonDeps = Map.fromList . map (first (T.pack . show))
48+ nativeModules
49+ | null (native d) = []
50+ | otherwise = [ "native-modules" .= native d ]
5351
5452instance FromJSON Deps where
5553 parseJSON (Object obj) =
@@ -69,15 +67,18 @@ instance FromJSON Deps where
6967 Right nm -> return nm
7068
7169 exposed <- get obj "exposed-modules" "a list of modules exposed to users"
70+
71+ native <- fromMaybe [] <$> (obj .:? "native-modules")
7272
7373 elmVersion <- get obj "elm-version" "the version of the Elm compiler you are using"
7474
7575 deps <- getDependencies obj
7676
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
7878
7979 parseJSON _ = mzero
8080
81+getDependencies :: Object -> Parser [(N.Name, V.Version)]
8182getDependencies obj =
8283 toDeps =<< get obj "dependencies" "a listing of your project's dependencies"
8384 where
@@ -88,7 +89,7 @@ getDependencies obj =
8889 (Nothing, _) -> fail $ N.errorMsg f
8990 (_, Nothing) -> fail $ "invalid version number " ++ v
9091
91−
92+get :: FromJSON a => Object -> T.Text -> String -> Parser a
9293get obj field desc =
9394 do maybe <- obj .:? field
9495 case maybe of
@@ -117,12 +118,12 @@ repoToName repo
117118 \like <https://github.com/USER/PROJECT.git> where USER is your GitHub name\n\
118119 \and PROJECT is the repo you want to upload."
119120
120−withDeps :: (Deps -> a) -> FilePath -> ErrorT String IO a
121−withDeps handle path =
121+withDeps :: FilePath -> (Deps -> ErrorT String IO a) -> ErrorT String IO a
122+withDeps path handle =
122123 do json <- readPath
123124 case eitherDecode json of
124125 Left err -> throwError $ "Error reading file " ++ path ++ ":\n " ++ err
125− Right ds -> return (handle ds)
126+ Right ds -> handle ds
126127 where
127128 readPath :: ErrorT String IO BS.ByteString
128129 readPath = do
@@ -136,19 +137,20 @@ withDeps handle path =
136137 " <https://github.com/evancz/automaton/blob/master/elm_dependencies.json>"
137138
138139depsAt :: FilePath -> ErrorT String IO Deps
139−depsAt = withDeps id
140+depsAt filePath = withDeps filePath return
140141
141142-- | Encode dependencies in a canonical JSON format
142143prettyJSON :: Deps -> BS.ByteString
143144prettyJSON = encodePretty' config
144145 where config = defConfig { confCompare = order }
145− order = keyOrder [ "name",
146− "version",
147− "summary",
148− "description",
149− "license",
150− "repo",
151− "exposed-modules",
152− "elm-version",
153− "dependencies"
146+ order = keyOrder [ "name"
147+ , "version"
148+ , "summary"
149+ , "description"
150+ , "license"
151+ , "repo"
152+ , "exposed-modules"
153+ , "native-modules"
154+ , "elm-version"
155+ , "dependencies"
154156 ]
compiler/Elm/Internal/Utils.hs+8−1
@@ -1,12 +1,13 @@
11{- | This module exports functions for compiling Elm to JS.
22-}
3−module Elm.Internal.Utils (compile, moduleName) where
3+module Elm.Internal.Utils (compile, moduleName, nameAndImports) where
44
55import qualified Data.List as List
66import qualified Generate.JavaScript as JS
77import qualified Build.Source as Source
88import qualified Parse.Module as Parser
99import qualified AST.Module as M
10+import Parse.Parse (dependencies)
1011import qualified Text.PrettyPrint as P
1112import qualified Metadata.Prelude as Prelude
1213import System.IO.Unsafe
@@ -26,3 +27,9 @@ interfaces = unsafePerformIO $ Prelude.interfaces False
2627-- |This function extracts the module name of a given source program.
2728moduleName :: String -> Maybe String
2829moduleName = 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 =
3636
3737internalImports :: String -> Statement ()
3838internalImports name =
39− VarDeclStmt ()
39+ VarDeclStmt ()
4040 [ varDecl "_N" (obj "Elm.Native")
4141 , include "_U" "_N.Utils"
4242 , include "_L" "_N.List"
43+ , include "_A" "_N.Array"
4344 , include "_E" "_N.Error"
4445 , varDecl "$moduleName" (string name)
4546 ]
compiler/Generate/JavaScript/Ports.hs+16−8
@@ -44,7 +44,7 @@ inc tipe x =
4444
4545 Data (Var.Canonical (Var.Module "Json") "Value") [] ->
4646 obj "Native.Json.fromJS" <| x
47−
47+
4848 Data (Var.Canonical Var.BuiltIn ctor) []
4949 | ctor == "Int" -> from JSNumber
5050 | ctor == "Float" -> from JSNumber
@@ -58,8 +58,13 @@ inc tipe x =
5858 (obj "Maybe.Nothing")
5959 (obj "Maybe.Just" <| inc t x)
6060
61− Data (Var.Canonical Var.BuiltIn "_List") [t] ->
62− check x JSArray (obj "_L.fromArray" <| array)
61+ Data (Var.Canonical Var.BuiltIn ctor) [t]
62+ | ctor == "_List" ->
63+ check x JSArray (obj "_L.fromArray" <| array)
64+
65+ | ctor == "Array.Array" ->
66+ check x JSArray (obj "_A.fromJSArray" <| array)
67+
6368 where
6469 array = DotRef () x (var "map") <| incoming t
6570
@@ -72,10 +77,10 @@ inc tipe x =
7277 , inc t (BracketRef () x (IntLit () n)))
7378
7479 Data _ _ ->
75− error "bad ADT got to port generation code"
80+ error "bad ADT got to incoming port generation code"
7681
7782 Record _ (Just _) ->
78− error "bad record got to port generation code"
83+ error "bad record got to incoming port generation code"
7984
8085 Record fields Nothing ->
8186 check x (JSObject (map fst fields)) object
@@ -126,6 +131,9 @@ out tipe x =
126131 (NullLit ())
127132 (out t (DotRef () x (var "_0")))
128133
134+ Data (Var.Canonical (Var.Module "Array") "Array") [t] ->
135+ DotRef () (obj "_A.toJSArray" <| x) (var "map") <| outgoing t
136+
129137 Data (Var.Canonical Var.BuiltIn "_List") [t] ->
130138 DotRef () (obj "_L.toArray" <| x) (var "map") <| outgoing t
131139
@@ -133,12 +141,12 @@ out tipe x =
133141 | Help.isTuple ctor ->
134142 let convert n t = out t $ DotRef () x $ var ('_':show n)
135143 in ArrayLit () $ zipWith convert [0..] ts
136−
144+
137145 Data _ _ ->
138− error "bad ADT got to port generation code"
146+ error "bad ADT got to outgoing port generation code"
139147
140148 Record _ (Just _) ->
141− error "bad record got to port generation code"
149+ error "bad record got to outgoing port generation code"
142150
143151 Record fields Nothing ->
144152 ObjectLit () keys
compiler/Type/ExtraChecks.hs+4−1
@@ -62,6 +62,9 @@ portTypes rules expr =
6262 ST.Data (V.Canonical (V.Module "Maybe") "Maybe") [t] ->
6363 valid t
6464
65+ ST.Data (V.Canonical (V.Module "Array") "Array") [t] ->
66+ valid t
67+
6568 ST.Data (V.Canonical (V.Module "Json") "Value") [] ->
6669 return ()
6770
@@ -109,7 +112,7 @@ portTypes rules expr =
109112 , txt [ "It contains ", kind, ":\n" ]
110113 , (P.nest 4 . PP.pretty $ Alias.realias rules tipe) <> P.text "\n"
111114 , 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," ]
113116 , txt [ " Json.Values, ", dir "" "first-order functions, ", "and concrete records." ]
114117 ] ++ if couldBeAlias then aliasWarning else []
115118
compiler/Type/Type.hs+2−2
@@ -188,7 +188,7 @@ instance PrettyType a => PrettyType (Term1 a) where
188188 prettyExt = prty ext
189189 extend | P.render prettyExt == "{}" = P.empty
190190 | 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
192192 prettyFields = concatMap (\(f,ts) -> map (mkPretty f) ts) (Map.toList fields)
193193
194194
@@ -203,7 +203,7 @@ instance PrettyType Descriptor where
203203 pretty when desc =
204204 case (structure desc, name desc) of
205205 (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
207207 P.parens . P.text $ replicate (read (drop 6 name) - 1) ','
208208 _ -> P.text "?"
209209
libraries/Array.elm+22−13
@@ -14,7 +14,7 @@ reads, updates, and appends.
1414@docs get, getOrElse, getOrFail, set
1515
1616# Taking Arrays Apart
17−@docs toList, toIndexedList, slice
17+@docs slice, toList, toIndexedList
1818
1919# Mapping and Folding
2020@docs map, indexedMap, foldl, foldr
@@ -122,7 +122,7 @@ push = Native.Array.push
122122
123123{-| Get the element at a particular index.
124124
125− getOrFail 2 (A.fromList [3,2,1]) == 1
125+ getOrFail 0 (A.fromList [0,1,2]) == 0
126126
127127Warning: this function will result in a runtime error if the index is not found,
128128so it is best to use `get` or `getOrElse` unless you are sure the index will be
@@ -133,9 +133,10 @@ getOrFail = Native.Array.get
133133
134134{-| Return Just the element at the index or Nothing if the index is out of range.
135135
136− get 2 (fromList [3,2,1]) == Just 2
137− get 5 (fromList [3,2,1]) == Nothing
138− get -1 (fromList [3,2,1]) == Nothing
136+ get 0 (fromList [0,1,2]) == Just 0
137+ get 2 (fromList [0,1,2]) == Just 2
138+ get 5 (fromList [0,1,2]) == Nothing
139+ get -1 (fromList [0,1,2]) == Nothing
139140-}
140141get : Int -> Array a -> Maybe a
141142get i array =
@@ -146,8 +147,8 @@ get i array =
146147{-| Get the element at the index. Or if the index is out of range, a default
147148value is returned.
148149
149− getOrElse 0 2 (fromList [3,2,1]) == 1
150− getOrElse 0 5 (fromList [3,2,1]) == 0
150+ getOrElse 0 2 (fromList [0,1,2]) == 2
151+ getOrElse 0 5 (fromList [0,1,2]) == 0
151152-}
152153getOrElse : a -> Int -> Array a -> a
153154getOrElse default i array =
@@ -163,13 +164,21 @@ If the index is out of range, the array is unaltered.
163164set : Int -> a -> Array a -> Array a
164165set = Native.Array.set
165166
166−{-| Slice an array given a range. The selection is inclusive, so the last
167−element in the selection will also be in the new array. This may change in the
168−future. You can select from the end by giving a negative Int.
167+{-| Get a sub-section of an array: `(slice start end array)`. The `start` is a
168+zero-based index where we will start our slice. The `end` is a zero-based index
169+that indicates the end of the slice. The slice extracts up to but not including
170+`end`.
169171
170− slice 1 2 (fromList [0,1,2,3,4]) == fromList [1,2]
171− slice 1 -2 (fromList [0,1,2,3,4]) == fromList [1,2,3]
172− slice -3 -2 (fromList [0,1,2,3,4]) == fromList [2,3]
172+ slice 0 3 (fromList [0,1,2,3,4]) == fromList [0,1,2]
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]
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`
173182-}
174183slice : Int -> Int -> Array a -> Array a
175184slice = Native.Array.slice
libraries/Color.elm+186−88
@@ -2,18 +2,18 @@ module Color where
22
33{-| Library for working with colors. Includes
44[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
66built-in names.
77
88# Creation
9−@docs rgb, rgba, hsv, hsva, greyscale, grayscale
10−
11−# From Other Colors
12−@docs complement
9+@docs rgb, rgba, hsl, hsla, greyscale, grayscale, complement
1310
1411# Gradients
1512@docs linear, radial
1613
14+# Extracting Colors
15+@docs toRgb, toHsl
16+
1717# Built-in Colors
1818These colors come from the [Tango
1919palette](http://tango.freedesktop.org/Tango_Icon_Theme_Guidelines)
@@ -24,12 +24,10 @@ comes with a light and dark version.
2424@docs red, orange, yellow, green, blue, purple, brown
2525
2626### Light
27−@docs lightRed, lightOrange, lightYellow, lightGreen, lightBlue, lightPurple,
28− lightBrown
27+@docs lightRed, lightOrange, lightYellow, lightGreen, lightBlue, lightPurple, lightBrown
2928
3029### Dark
31−@docs darkRed, darkOrange, darkYellow, darkGreen, darkBlue, darkPurple,
32− darkBrown
30+@docs darkRed, darkOrange, darkYellow, darkGreen, darkBlue, darkPurple, darkBrown
3331
3432### Eight Shades of Grey
3533These 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.
4240
4341-}
4442
45−import Native.Color
46−import Basics ((-))
43+import Basics (..)
4744
48−data Color = Color Int Int Int Float
45+data Color
46+ = RGBA Int Int Int Float
47+ | HSLA Float Float Float Float
4948
5049{-| Create RGB colors with an alpha component for transparency.
5150The alpha component is specified with numbers between 0 and 1. -}
5251rgba : Int -> Int -> Int -> Float -> Color
53−rgba = Color
52+rgba = RGBA
5453
5554{-| Create RGB colors from numbers between 0 and 255 inclusive. -}
5655rgb : 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
58198
59199lightRed : Color
60−lightRed = Color 239 41 41 1
200+lightRed = RGBA 239 41 41 1
61201red : Color
62−red = Color 204 0 0 1
202+red = RGBA 204 0 0 1
63203darkRed : Color
64−darkRed = Color 164 0 0 1
204+darkRed = RGBA 164 0 0 1
65205
66206lightOrange : Color
67−lightOrange = Color 252 175 62 1
207+lightOrange = RGBA 252 175 62 1
68208orange : Color
69−orange = Color 245 121 0 1
209+orange = RGBA 245 121 0 1
70210darkOrange : Color
71−darkOrange = Color 206 92 0 1
211+darkOrange = RGBA 206 92 0 1
72212
73213lightYellow : Color
74−lightYellow = Color 255 233 79 1
214+lightYellow = RGBA 255 233 79 1
75215yellow : Color
76−yellow = Color 237 212 0 1
216+yellow = RGBA 237 212 0 1
77217darkYellow : Color
78−darkYellow = Color 196 160 0 1
218+darkYellow = RGBA 196 160 0 1
79219
80220lightGreen : Color
81−lightGreen = Color 138 226 52 1
221+lightGreen = RGBA 138 226 52 1
82222green : Color
83−green = Color 115 210 22 1
223+green = RGBA 115 210 22 1
84224darkGreen : Color
85−darkGreen = Color 78 154 6 1
225+darkGreen = RGBA 78 154 6 1
86226
87227lightBlue : Color
88−lightBlue = Color 114 159 207 1
228+lightBlue = RGBA 114 159 207 1
89229blue : Color
90−blue = Color 52 101 164 1
230+blue = RGBA 52 101 164 1
91231darkBlue : Color
92−darkBlue = Color 32 74 135 1
232+darkBlue = RGBA 32 74 135 1
93233
94234lightPurple : Color
95−lightPurple = Color 173 127 168 1
235+lightPurple = RGBA 173 127 168 1
96236purple : Color
97−purple = Color 117 80 123 1
237+purple = RGBA 117 80 123 1
98238darkPurple : Color
99−darkPurple = Color 92 53 102 1
239+darkPurple = RGBA 92 53 102 1
100240
101241lightBrown : Color
102−lightBrown = Color 233 185 110 1
242+lightBrown = RGBA 233 185 110 1
103243brown : Color
104−brown = Color 193 125 17 1
244+brown = RGBA 193 125 17 1
105245darkBrown : Color
106−darkBrown = Color 143 89 2 1
246+darkBrown = RGBA 143 89 2 1
107247
108248black : Color
109−black = Color 0 0 0 1
249+black = RGBA 0 0 0 1
110250white : Color
111−white = Color 255 255 255 1
251+white = RGBA 255 255 255 1
112252
113253lightGrey : Color
114−lightGrey = Color 238 238 236 1
254+lightGrey = RGBA 238 238 236 1
115255grey : Color
116−grey = Color 211 215 207 1
256+grey = RGBA 211 215 207 1
117257darkGrey : Color
118−darkGrey = Color 186 189 182 1
258+darkGrey = RGBA 186 189 182 1
119259
120260lightGray : Color
121−lightGray = Color 238 238 236 1
261+lightGray = RGBA 238 238 236 1
122262gray : Color
123−gray = Color 211 215 207 1
263+gray = RGBA 211 215 207 1
124264darkGray : Color
125−darkGray = Color 186 189 182 1
265+darkGray = RGBA 186 189 182 1
126266
127267lightCharcoal : Color
128−lightCharcoal = Color 136 138 133 1
268+lightCharcoal = RGBA 136 138 133 1
129269charcoal : Color
130−charcoal = Color 85 87 83 1
270+charcoal = RGBA 85 87 83 1
131271darkCharcoal : Color
132−darkCharcoal = Color 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
272+darkCharcoal = RGBA 46 52 54 1
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 = {};
22Elm.Native.Array.make = function(elm) {
33 elm.Native = elm.Native || {};
44 elm.Native.Array = elm.Native.Array || {};
@@ -240,10 +240,16 @@ Elm.Native.Array.make = function(elm) {
240240
241241 // Maps a function over the elements with their index as first argument.
242242 function indexedMap(f, a) {
243+ return indexedMap_(f, a, 0);
244+ }
245+
246+ function indexedMap_(f, a, from) {
243247 var newA = { ctor:"_Array", height:a.height, table:new Array(a.table) };
244248 if (a.height > 0) { newA.lengths = a.lengths; }
245249 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]);
247253 }
248254 return newA;
249255 }
@@ -262,9 +268,6 @@ Elm.Native.Array.make = function(elm) {
262268 return b;
263269 }
264270
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.
268271 // TODO: currently, it slices the right, then the left. This can be
269272 // optimized.
270273 function slice(from, to, a) {
@@ -281,7 +284,7 @@ Elm.Native.Array.make = function(elm) {
281284 // Handle leaf level.
282285 if (a.height == 0) {
283286 var newA = { ctor:"_Array", height:0 };
284− newA.table = a.table.slice(0, to + 1);
287+ newA.table = a.table.slice(0, to);
285288 return newA;
286289 }
287290
@@ -576,6 +579,46 @@ Elm.Native.Array.make = function(elm) {
576579 , lengths:[length(a), length(a) + length(b)] };
577580 }
578581
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+
579622 Elm.Native.Array.values = {
580623 empty:empty,
581624 fromList:fromList,
@@ -590,7 +633,10 @@ Elm.Native.Array.make = function(elm) {
590633 indexedMap:F2(indexedMap),
591634 foldl:F3(foldl),
592635 foldr:F3(foldr),
593− length:length
636+ length:length,
637+
638+ toJSArray:toJSArray,
639+ fromJSArray:fromJSArray
594640 };
595641
596642 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) {
1919 complement: not,
2020 shiftLeft : F2(sll),
2121 shiftRightArithmatic: F2(sra),
22− shiftRightLogical : F2(srl),
22+ shiftRightLogical : F2(srl)
2323 };
2424
2525};
libraries/Native/Color.js+16−60
@@ -7,69 +7,25 @@ Elm.Native.Color.make = function(elm) {
77 var Utils = Elm.Native.Utils.make(elm);
88
99 function toCss(c) {
10− return (c._3 === 1)
11− ? ('rgb(' + c._0 + ', ' + c._1 + ', ' + c._2 + ')')
12− : ('rgba(' + c._0 + ', ' + c._1 + ', ' + c._2 + ', ' + c._3 + ')');
13− }
14−
15− function complement(rgb) {
16− var hsv = toHSV(rgb);
17− hsv.hue = (hsv.hue + 180) % 360;
18− return toRGB(hsv);
19− }
20−
21− function hsva(h,s,v,a) {
22− var degree = A2(Utils.mod, h * 180 / Math.PI, 360);
23− var clr = toRGB({hue:degree, saturation:s, value:v});
24− clr._3 = a;
25− return clr;
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 };
10+ var format = '';
11+ var colors = '';
12+ if (c.ctor === 'RGBA') {
13+ format = 'rgb';
14+ colors = c._0 + ', ' + c._1 + ', ' + c._2;
15+ } else {
16+ format = 'hsl';
17+ colors = (c._0 * 180 / Math.PI) + ', ' +
18+ (c._1 * 100) + '%, ' +
19+ (c._2 * 100) + '%';
20+ }
21+ if (c._3 === 1) {
22+ return format + '(' + colors + ')';
23+ } else {
24+ return format + 'a(' + colors + ', ' + c._3 + ')';
25+ }
6726 }
6827
6928 return elm.Native.Color.values = {
70− hsva:F4(hsva),
71− hsv:F3(hsv),
72− complement:complement,
7329 toCss:toCss
7430 };
7531
libraries/Native/Error.js+2−4
@@ -4,8 +4,6 @@ Elm.Native.Error.make = function(elm) {
44 elm.Native.Error = elm.Native.Error || {};
55 if (elm.Native.Error.values) return elm.Native.Error.values;
66
7− var fromString = Elm.Native.JavaScript.make(elm).fromString;
8−
97 function indent(lines) {
108 var msg = '';
119 for (var i = 0; i < lines.length; ++i) {
@@ -26,7 +24,7 @@ Elm.Native.Error.make = function(elm) {
2624 throw new Error('Runtime error in module ' + moduleName + ' (' + span + '):' + msg);
2725 }
2826
29− function raise(str) { throw new Error(fromString(str)); }
27+ function raise(str) { throw new Error(str); }
3028
3129 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) {
286286 start: start,
287287 end: end,
288288 direction: { ctor: direction }
289− },
289+ }
290290 }));
291291 }
292292
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) {
7979 toString : F2(toString),
8080 fromString : fromString,
8181 fromJS : fromJS,
82− toJS : toJS,
82+ toJS : toJS
8383 };
8484
8585};
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) {
4343 match: result[0],
4444 submatches: List.fromArray(subs),
4545 index: result.index,
46− number: number,
46+ number: number
4747 });
4848 }
4949 return List.fromArray(out);
@@ -98,6 +98,6 @@ Elm.Native.Regex.make = function(elm) {
9898 contains: F2(contains),
9999 find: F3(find),
100100 replace: F4(replace),
101− split: F3(split),
101+ split: F3(split)
102102 };
103103};
libraries/Native/String.js+4−4
@@ -73,7 +73,7 @@ Elm.Native.String.make = function(elm) {
7373 return result;
7474 }
7575
76− function sub(start, end, str) {
76+ function slice(start, end, str) {
7777 return str.slice(start,end);
7878 }
7979 function left(n, str) {
@@ -111,7 +111,7 @@ Elm.Native.String.make = function(elm) {
111111 }
112112
113113 function words(str) {
114− return List.fromArray(str.split(/\s+/g));
114+ return List.fromArray(str.trim().split(/\s+/g));
115115 }
116116 function lines(str) {
117117 return List.fromArray(str.split(/\r\n|\r|\n/g));
@@ -216,7 +216,7 @@ Elm.Native.String.make = function(elm) {
216216 join: F2(join),
217217 repeat: F2(repeat),
218218
219− sub: F3(sub),
219+ slice: F3(slice),
220220 left: F2(left),
221221 right: F2(right),
222222 dropLeft: F2(dropLeft),
@@ -247,6 +247,6 @@ Elm.Native.String.make = function(elm) {
247247 toInt: toInt,
248248 toFloat: toFloat,
249249 toList: toList,
250− fromList: fromList,
250+ fromList: fromList
251251 };
252252};
libraries/Native/Text.js+3−3
@@ -123,7 +123,7 @@ Elm.Native.Text.make = function(elm) {
123123 html : Utils.makeText(text),
124124 align: align,
125125 guid : null,
126− args : [],
126+ args : []
127127 };
128128 var pos = A2(Utils.htmlHeight, 0, raw);
129129 return A3(Element.newElement, pos._0, pos._1, raw);
@@ -136,7 +136,7 @@ Elm.Native.Text.make = function(elm) {
136136 html: text,
137137 align: null,
138138 guid: guid,
139− args: [],
139+ args: []
140140 };
141141 var pos = A2(Utils.htmlHeight, 0, raw);
142142 return A3(Element.newElement, pos._0, pos._1, raw);
@@ -162,6 +162,6 @@ Elm.Native.Text.make = function(elm) {
162162 markdown : markdown,
163163
164164 toTypefaces:toTypefaces,
165− toLine:toLine,
165+ toLine:toLine
166166 };
167167};
libraries/Native/Utils.js+10−1
@@ -16,7 +16,16 @@ Elm.Native.Utils.make = function(elm) {
1616 var c = 0;
1717 for (var i in x) {
1818 ++c;
19− stack.push({ 'x': x[i], 'y': y[i] });
19+ if (i in y) {
20+ if (i !== 'ctor') {
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});
2029 }
2130 if (c !== Object.keys(y).length) {
2231 return false;
libraries/String.elm+8−8
@@ -6,10 +6,10 @@ are enclosed in `"double quotes"`. Strings are *not* lists of characters.
66@docs isEmpty, length, reverse, repeat
77
88# Building and Splitting
9−@docs cons, uncons, append, concat, split, join, words, lines
9+@docs cons, uncons, append, concat, split, join, words, lines
1010
1111# Get Substrings
12−@docs sub, left, right, dropLeft, dropRight
12+@docs slice, left, right, dropLeft, dropRight
1313
1414# Check for Substrings
1515@docs contains, startsWith, endsWith, indexes, indices
@@ -139,13 +139,13 @@ repeat = Native.String.repeat
139139{-| Take a substring given a start and end index. Negative indexes
140140are taken starting from the *end* of the list.
141141
142− sub 7 9 "snakes on a plane!" == "on"
143− sub 0 6 "snakes on a plane!" == "snakes"
144− sub 0 -7 "snakes on a plane!" == "snakes on a"
145− sub -6 -1 "snakes on a plane!" == "plane"
142+ slice 7 9 "snakes on a plane!" == "on"
143+ slice 0 6 "snakes on a plane!" == "snakes"
144+ slice 0 -7 "snakes on a plane!" == "snakes on a"
145+ slice -6 -1 "snakes on a plane!" == "plane"
146146-}
147−sub : Int -> Int -> String -> String
148−sub = Native.String.sub
147+slice : Int -> Int -> String -> String
148+slice = Native.String.slice
149149
150150{-| Take N characters from the left side of a string. -}
151151left : Int -> String -> String
libraries/elm_dependencies.json−2
@@ -18,7 +18,6 @@
1818 , "Graphics.Element"
1919 , "Graphics.Collage"
2020 , "Graphics.Input"
21− , "Graphics.WebGL"
2221 , "Graphics.Input.Field"
2322 , "Http"
2423 , "JavaScript.Experimental"
@@ -26,7 +25,6 @@
2625 , "Keyboard"
2726 , "List"
2827 , "Maybe"
29− , "MJS"
3028 , "Mouse"
3129 , "Random"
3230 , "Regex"
runtime/Render/Collage.js+4−4
@@ -5,7 +5,7 @@ var Render = ElmRuntime.use(ElmRuntime.Render.Element);
55var Transform = Elm.Transform2D.make({});
66var Utils = ElmRuntime.use(ElmRuntime.Render.Utils);
77var newElement = Utils.newElement,
8− extract = Utils.extract, fromList = Utils.fromList,
8+ colorToCss = Utils.colorToCss, fromList = Utils.fromList,
99 fromString = Utils.fromString, addTransform = Utils.addTransform;
1010
1111function trace(ctx, path) {
@@ -70,7 +70,7 @@ function drawLine(ctx, style, path) {
7070 ctx.lineJoin = join === 'Smooth' ? 'round' :
7171 join === 'Sharp' ? 'miter' : 'bevel';
7272 ctx.miterLimit = style.join._0 || 10;
73− ctx.strokeStyle = extract(style.color);
73+ ctx.strokeStyle = colorToCss(style.color);
7474 return line(ctx, style, path);
7575}
7676
@@ -96,7 +96,7 @@ function gradient(ctx, grad) {
9696 var len = stops.length;
9797 for (var i = 0; i < len; ++i) {
9898 var stop = stops[i];
99− g.addColorStop(stop._0, extract(stop._1));
99+ g.addColorStop(stop._0, colorToCss(stop._1));
100100 }
101101 return g;
102102}
@@ -105,7 +105,7 @@ function drawShape(redo, ctx, style, path) {
105105 trace(ctx, path);
106106 var sty = style.ctor;
107107 ctx.fillStyle =
108− sty === 'Solid' ? extract(style._0) :
108+ sty === 'Solid' ? colorToCss(style._0) :
109109 sty === 'Texture' ? texture(redo, ctx, style._0) : gradient(ctx, style._0);
110110 ctx.scale(1,-1);
111111 ctx.fill();
runtime/Render/Element.js+33−27
@@ -3,7 +3,7 @@ ElmRuntime.Render.Element = function() {
33'use strict';
44
55var Utils = ElmRuntime.use(ElmRuntime.Render.Utils);
6−var newElement = Utils.newElement, extract = Utils.extract,
6+var newElement = Utils.newElement, colorToCss = Utils.colorToCss,
77 addTransform = Utils.addTransform, removeTransform = Utils.removeTransform,
88 fromList = Utils.fromList, eq = Utils.eq;
99
@@ -18,7 +18,7 @@ function setProps(elem, e) {
1818 e.style.opacity = props.opacity;
1919 }
2020 if (props.color.ctor === 'Just') {
21− e.style.backgroundColor = extract(props.color._0);
21+ e.style.backgroundColor = colorToCss(props.color._0);
2222 }
2323 if (props.tag !== '') { e.id = props.tag; }
2424 if (props.href !== '') {
@@ -143,29 +143,37 @@ function croppedImage(elem, w, h, src) {
143143 return e;
144144}
145145
146−function goIn(e) { e.style.position = 'absolute'; return e; }
146+function goOut(e) { e.style.position = 'absolute'; return e; }
147147function goDown(e) { return e }
148148function 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';
152149
153− for (var i = array.length; i--; ) {
154− container.appendChild(f(render(array[i])));
155− }
156− return container;
150+var directionTable = {
151+ DUp : goDown,
152+ DDown : goDown,
153+ DLeft : goRight,
154+ DRight : goRight,
155+ DIn : goOut,
156+ DOut : goOut
157+};
158+function needsReversal(dir) {
159+ return dir == 'DUp' || dir == 'DLeft' || dir == 'DIn';
157160}
158161
159162function flow(dir,elist) {
160163 var array = fromList(elist);
161− switch(dir.ctor) {
162− case "DDown": array.reverse();
163− case "DUp": return flowWith(goDown,array);
164− case "DRight": array.reverse();
165− case "DLeft": return flowWith(goRight,array);
166− case "DOut": array.reverse();
167− case "DIn": return flowWith(goIn,array);
164+ var container = newElement('div');
165+ var goDir = directionTable[dir];
166+ if (goDir == goOut) {
167+ container.style.pointerEvents = 'none';
168168 }
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;
169177}
170178
171179function toPos(pos) {
@@ -245,7 +253,7 @@ function makeElement(e) {
245253 var elem = e.element;
246254 switch(elem.ctor) {
247255 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);
249257 case 'Container': return container(elem._0, elem._1);
250258 case 'Spacer': return newElement('div');
251259 case 'RawHtml': return rawHtml(elem);
@@ -321,14 +329,12 @@ function update(node, curr, next) {
321329 return true;
322330 }
323331 var currs = fromList(currE._1);
324− var goDir = function(x) { return x; };
325− switch(nextE._0.ctor) {
326− case "DDown": case "DUp": goDir = goDown; break;
327− case "DRight": case "DLeft": goDir = goRight; break;
328− case "DOut": case "DIn": goDir = goIn; break;
329− }
330− for (var i = kids.length; i-- ;) {
331− update(kids[i],currs[i],nexts[i]);
332+ var dir = nextE._0.ctor;
333+ var goDir = directionTable[dir];
334+ var toReverse = needsReversal(dir);
335+ var len = kids.length;
336+ for (var i = len; i-- ;) {
337+ update(kids[toReverse ? len - i - 1 : i],currs[i],nexts[i]);
332338 goDir(kids[i]);
333339 }
334340 break;
@@ -364,7 +370,7 @@ function updateProps(node, curr, next) {
364370 e.style.opacity = props.opacity;
365371 }
366372 var nextColor = (props.color.ctor === 'Just' ?
367− extract(props.color._0) : '');
373+ colorToCss(props.color._0) : '');
368374 if (e.style.backgroundColor !== nextColor) {
369375 e.style.backgroundColor = (nextColor === '' ? 'transparent' : nextColor);
370376 }
runtime/Render/Utils.js+2−7
@@ -10,11 +10,6 @@ ElmRuntime.Render.Utils = function() {
1010 container.appendChild(elem);
1111 }
1212
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−
1813 function addTransform(style, trans) {
1914 style.transform = trans;
2015 style.msTransform = trans;
@@ -34,8 +29,8 @@ ElmRuntime.Render.Utils = function() {
3429 var List = Elm.Native.List.make({});
3530
3631 return {addTo:addTo,
37− newElement:newElement,
38− extract : extract,
32+ newElement: newElement,
33+ colorToCss: Elm.Native.Color.make({}).toCss,
3934 fromList: List.toArray,
4035 fromString: function(s) { return s; },
4136 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
1111
1212import Test.Array as Array
1313import Test.Dict as Dict
14+import Test.Equality as Equality
1415import Test.List as List
1516import Test.Set as Set
1617import Test.String as String
1718import Test.Trampoline as Trampoline
1819
1920tests : Test
20−tests = suite "Elm Standard Library Tests" [ List.tests,
21− String.tests,
22− Trampoline.tests,
23− Array.tests,
24− Dict.tests,
25− Set.tests
26− ]
21+tests = suite "Elm Standard Library Tests"
22+ [ Array.tests
23+ , Dict.tests
24+ , Equality.tests
25+ , List.tests
26+ , Set.tests
27+ , String.tests
28+ , Trampoline.tests
29+ ]
2730
2831console : IO ()
2932console = 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−