git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Merge pull request #189 from garyb/master

Fix for the Math module (and others)

commit3b2638d5bf58f975f49fc73634cb6fe818bf867a authorPhil Freeman <paf31@cantab.net> dateTue 11 Feb 2014, 09:22 (13 years ago) parent4bb6219e24efbc
9 files changed+68−42
examples/passing/FunctionScope.purs+2−2 examples/passing/Math.purs+10 prelude/prelude.purs+9 psc/Main.hs+5−1 psci/Main.hs+1−1 src/Language/PureScript.hs+3−3 src/Language/PureScript/CodeGen/JS.hs+30−32 src/Language/PureScript/Options.hs+6−1 src/Language/PureScript/Parser/Common.hs+2−2
examples/passing/FunctionScope.purs+2−2
@@ -1,4 +1,4 @@
1−module RecordScope where
1+module FunctionScope where
22
33 import Prelude
44
@@ -8,7 +8,7 @@ module RecordScope where
88module Main where
99
1010 import Prelude
11− import RecordScope
11+ import FunctionScope
1212
1313 main = do
1414 let value = mkValue 1
examples/passing/Math.pursnew file+10
@@ -0,0 +1,10 @@
1+module Main where
2+
3+ import Prelude
4+ import Trace
5+ import Eff
6+
7+ main = do
8+ print $ Math.sin 0
9+ print $ Math.sin $ Math.pi * 0.5
10+ print $ Math.e / Math.ln2
prelude/prelude.purs+9
@@ -898,6 +898,15 @@ module Math where
898898 foreign import tan "function tan(n){\
899899 \ return Math.tan(n);\
900900 \}" :: Number -> Number
901+
902+ foreign import e "var e = Math.E;" :: Number
903+ foreign import ln2 "var ln2 = Math.LN2;" :: Number
904+ foreign import ln10 "var ln10 = Math.LN10;" :: Number
905+ foreign import log2e "var log2e = Math.LOG2E;" :: Number
906+ foreign import log10e "var log10e = Math.LOG10E;" :: Number
907+ foreign import pi "var pi = Math.PI;" :: Number
908+ foreign import sqrt1_2 "var sqrt1_2 = Math.SQRT1_2;" :: Number
909+ foreign import sqrt2 "var sqrt2 = Math.SQRT2;" :: Number
901910
902911module Eff where
903912
psc/Main.hs+5−1
@@ -94,8 +94,12 @@ noOpts :: Term Bool
9494noOpts = value $ flag $ (optInfo [ "no-opts" ])
9595 { optDoc = "Skip the optimization phase." }
9696
97+browserNamespace :: Term String
98+browserNamespace = value $ opt "PS" $ (optInfo [ "browser-namespace" ])
99+ { optDoc = "Specify the namespace that PureScript modules will be exported to when running in the browser." }
100+
97101options :: Term P.Options
98−options = P.Options <$> tco <*> performRuntimeTypeChecks <*> magicDo <*> runMain <*> noOpts
102+options = P.Options <$> tco <*> performRuntimeTypeChecks <*> magicDo <*> runMain <*> noOpts <*> browserNamespace
99103
100104stdInOrInputFiles :: FilePath -> Term (Maybe [FilePath])
101105stdInOrInputFiles prelude = combine <$> useStdIn <*> (not <$> noPrelude) <*> inputFiles
psci/Main.hs+1−1
@@ -35,7 +35,7 @@ getPreludeFilename :: IO FilePath
3535getPreludeFilename = Paths.getDataFileName "prelude/prelude.purs"
3636
3737options :: P.Options
38−options = P.Options True False True True True
38+options = P.Options True False True True True "PS"
3939
4040completion :: [P.Module] -> CompletionFunc IO
4141completion ms = completeWord Nothing " \t\n\r" findCompletions
src/Language/PureScript.hs+3−3
@@ -59,12 +59,12 @@ compile opts ms = do
5959 modify (\s -> s { checkCurrentModule = Just (ModuleName moduleName) })
6060 Module moduleName <$> typeCheckAll (ModuleName moduleName) decls
6161 regrouped <- createBindingGroupsModule . collapseBindingGroupsModule $ elaborated
62− let js = concatMap (flip (moduleToJs opts) env) $ regrouped
62+ let js = map (flip (moduleToJs opts) env) $ regrouped
6363 let exts = intercalate "\n" . map (flip moduleToPs env) $ regrouped
6464 js' <- case () of
6565 _ | optionsRunMain opts -> do
6666 when ((ModuleName (ProperName "Main"), Ident "main") `M.notMember` (names env)) $
6767 Left "Main.main is undefined"
68− return $ js ++ [JSApp (JSAccessor "main" (JSVar "Main")) []]
68+ return $ js ++ [JSApp (JSAccessor "main" (JSAccessor "Main" (JSVar "_ps"))) []]
6969 | otherwise -> return js
70− return (prettyPrintJS [(wrapExportsContainer js')], exts, env)
70+ return (prettyPrintJS [(wrapExportsContainer opts js')], exts, env)
src/Language/PureScript/CodeGen/JS.hs+30−32
@@ -51,31 +51,30 @@ import Language.PureScript.TypeChecker.Monad (canonicalizeDataConstructor)
5151-- Generate code in the simplified Javascript intermediate representation for all declarations in a
5252-- module.
5353--
54−moduleToJs :: Options -> Module -> Environment -> [JS]
54+moduleToJs :: Options -> Module -> Environment -> JS
5555moduleToJs opts (Module pname@(ProperName name) decls) env =
56− [ JSVariableIntroduction name Nothing
57− , JSApp (JSFunction Nothing [name]
58− (JSBlock (concat $ mapMaybe (\decl -> fmap (map $ optimize opts) $ declToJs opts (ModuleName pname) decl env) (decls))))
59− [JSAssignment (JSVar name)
60− (JSBinary Or (JSVar name) (JSObjectLiteral []))]
61− , JSAssignment (JSAccessor name (JSVar "exports")) (JSVar name)
62− ]
56+ JSAssignment (JSAccessor name (JSVar "_ps")) $ JSApp (JSFunction Nothing ["module"]
57+ (JSBlock $ jsDecls ++ [JSReturn $ JSVar "module"]))
58+ [(JSBinary Or (JSAccessor name (JSVar "_ps")) (JSObjectLiteral []))]
59+ where
60+ jsDecls = (concat $ mapMaybe (\decl -> fmap (map $ optimize opts) $ declToJs opts (ModuleName pname) decl env) (decls))
6361
6462-- |
6563-- Generate code in the simplified Javascript intermediate representation for a declaration
6664--
6765declToJs :: Options -> ModuleName -> Declaration -> Environment -> Maybe [JS]
6866declToJs opts mp (ValueDeclaration ident _ _ val) e =
69− Just $ JSVariableIntroduction (identToJs ident) (Just (valueToJs opts mp e val))
70− : setProperty ident (var ident) mp
67+ Just $ [ JSVariableIntroduction (identToJs ident) (Just (valueToJs opts mp e val))
68+ , setExportProperty ident (var ident) ]
7169declToJs opts mp (BindingGroupDeclaration vals) e =
7270 Just $ concatMap (\(ident, val) ->
73− JSVariableIntroduction (identToJs ident) (Just (valueToJs opts mp e val))
74− : setProperty ident (var ident) mp
71+ [ JSVariableIntroduction (identToJs ident) (Just (valueToJs opts mp e val))
72+ , setExportProperty ident (var ident) ]
7573 ) vals
7674declToJs _ mp (DataDeclaration _ _ ctors) _ =
7775 Just $ flip concatMap ctors $ \(pn@(ProperName ctor), tys) ->
78− JSVariableIntroduction ctor (Just (go pn 0 tys [])) : setProperty (Escaped ctor) (JSVar ctor) mp
76+ [ JSVariableIntroduction ctor (Just (go pn 0 tys []))
77+ , setExportProperty (Escaped ctor) (JSVar ctor) ]
7978 where
8079 go pn _ [] values =
8180 JSObjectLiteral [ ("ctor", JSStringLiteral (show (Qualified (Just mp) pn))), ("values", JSArrayLiteral $ reverse values) ]
@@ -85,19 +84,15 @@ declToJs _ mp (DataDeclaration _ _ ctors) _ =
8584declToJs opts mp (DataBindingGroupDeclaration ds) e =
8685 Just $ concat $ mapMaybe (flip (declToJs opts mp) e) ds
8786declToJs _ mp (ExternDeclaration importTy ident (Just js) _) _ =
88− Just $ js : setProperty ident (var ident) mp
87+ Just $ [js, setExportProperty ident (var ident)]
8988declToJs _ _ _ _ = Nothing
9089
9190-- |
92−-- Generate code in the simplified Javascript intermediate representation for setting the property
93−-- of an object.
91+-- Generate code in the simplified Javascript intermediate representation for exporting a
92+-- declaration from a module.
9493--
95−setProperty :: Ident -> JS -> ModuleName -> [JS]
96−setProperty ident@(Op op) val (ModuleName (ProperName moduleName)) =
97− [ JSAssignment (accessor ident (JSVar moduleName)) val
98− , JSAssignment (JSIndexer (JSStringLiteral op) (JSVar moduleName)) (accessor ident (JSVar moduleName)) ]
99−setProperty ident val (ModuleName (ProperName moduleName)) =
100− [ JSAssignment (accessor ident (JSVar moduleName)) val ]
94+setExportProperty :: Ident -> JS -> JS
95+setExportProperty ident val = JSAssignment (accessor ident (JSVar "module")) val
10196
10297-- |
10398-- Generate code in the simplified Javascript intermediate representation for a variable based on a
@@ -113,6 +108,7 @@ var = JSVar . identToJs
113108--
114109accessor :: Ident -> JS -> JS
115110accessor (Ident name) | nameIsJsReserved name = JSIndexer (JSStringLiteral name)
111+accessor (Op op) = JSIndexer (JSStringLiteral op)
116112accessor ident = JSAccessor (identToJs ident)
117113
118114-- |
@@ -127,9 +123,9 @@ valueToJs opts m e (ObjectLiteral ps) = JSObjectLiteral (map (second (valueToJs
127123valueToJs opts m e (ObjectUpdate o ps) = JSApp (JSAccessor "extend" (JSVar "Object")) [ valueToJs opts m e o, JSObjectLiteral (map (second (valueToJs opts m e)) ps)]
128124valueToJs _ m e (Constructor (Qualified Nothing name)) =
129125 case M.lookup (m, name) (dataConstructors e) of
130− Just (_, Alias aliasModule aliasIdent) -> qualifiedToJS id (Qualified (Just aliasModule) aliasIdent)
126+ Just (_, Alias aliasModule aliasIdent) -> qualifiedToJS m id (Qualified (Just aliasModule) aliasIdent)
131127 _ -> JSVar . runProperName $ name
132−valueToJs _ _ _ (Constructor name) = qualifiedToJS (Ident . runProperName) name
128+valueToJs _ m _ (Constructor name) = qualifiedToJS m (Ident . runProperName) name
133129valueToJs opts m e (Block sts) = JSApp (JSFunction Nothing [] (JSBlock (map (statementToJs opts m e) sts))) []
134130valueToJs opts m e (Case values binders) = bindersToJs opts m e binders (map (valueToJs opts m e) values)
135131valueToJs opts m e (IfThenElse cond th el) = JSConditional (valueToJs opts m e cond) (valueToJs opts m e th) (valueToJs opts m e el)
@@ -202,7 +198,7 @@ varToJs m e qual@(Qualified _ ident) = go qual
202198 Just (_, Alias aliasModule aliasIdent) -> go (Qualified (Just aliasModule) aliasIdent)
203199 _ -> case qual of
204200 Qualified Nothing _ -> var ident
205− _ -> qualifiedToJS id qual
201+ _ -> qualifiedToJS m id qual
206202 isExtern (Extern ForeignImport) = True
207203 isExtern (Alias m' ident') = case M.lookup (m', ident') (names e) of
208204 Just (_, ty') -> isExtern ty'
@@ -213,9 +209,9 @@ varToJs m e qual@(Qualified _ ident) = go qual
213209-- Generate code in the simplified Javascript intermediate representation for a reference to a
214210-- variable that may have a qualified name.
215211--
216−qualifiedToJS :: (a -> Ident) -> Qualified a -> JS
217−qualifiedToJS f (Qualified (Just (ModuleName (ProperName m))) a) = accessor (f a) (JSVar m)
218−qualifiedToJS f (Qualified Nothing a) = JSVar $ identToJs (f a)
212+qualifiedToJS :: ModuleName -> (a -> Ident) -> Qualified a -> JS
213+qualifiedToJS m f (Qualified (Just m'@(ModuleName (ProperName mn))) a) | m /= m' = accessor (f a) (JSAccessor mn $ JSVar "_ps")
214+qualifiedToJS m f (Qualified _ a) = JSVar $ identToJs (f a)
219215
220216-- |
221217-- Generate code in the simplified Javascript intermediate representation for pattern match binders
@@ -346,10 +342,12 @@ statementToJs opts m e (If ifst) = ifToJs ifst
346342 elseToJs (ElseIf elif) = ifToJs elif
347343statementToJs opts m e (Return value) = JSReturn (valueToJs opts m e value)
348344
349−wrapExportsContainer :: [JS] -> JS
350−wrapExportsContainer modules = JSApp (JSFunction Nothing ["exports"] $ JSBlock $ (JSStringLiteral "use strict") : modules) [exportSelector]
351− where exportSelector = JSConditional (JSBinary And (JSBinary NotEqualTo (JSTypeOf $ JSVar "module") (JSStringLiteral "undefined")) (JSAccessor "exports" (JSVar "module")))
345+wrapExportsContainer :: Options -> [JS] -> JS
346+wrapExportsContainer opts modules = JSApp (JSFunction Nothing ["_ps"] $ JSBlock $ (JSStringLiteral "use strict") : modules) [exportSelector]
347+ where
348+ exportSelector = JSConditional (JSBinary And (JSBinary NotEqualTo (JSTypeOf $ JSVar "module") (JSStringLiteral "undefined")) (JSAccessor "exports" (JSVar "module")))
352349 (JSAccessor "exports" (JSVar "module"))
353350 (JSConditional (JSBinary NotEqualTo (JSTypeOf $ JSVar "window") (JSStringLiteral "undefined"))
354− (JSAssignment (JSAccessor "PS" (JSVar "window")) (JSObjectLiteral []))
351+ (JSAssignment (JSAccessor browserNamespace (JSVar "window")) (JSBinary Or (JSAccessor browserNamespace (JSVar "window")) (JSObjectLiteral [])))
355352 (JSApp (JSFunction Nothing [] $ JSBlock [JSThrow $ JSStringLiteral "PureScript doesn't know how to export modules in the current environment"]) []))
353+ browserNamespace = optionsBrowserNamespace opts
src/Language/PureScript/Options.hs+6−1
@@ -39,10 +39,15 @@ data Options = Options {
3939 -- Skip all optimizations
4040 --
4141 , optionsNoOptimizations :: Bool
42+ -- |
43+ -- Specify the namespace that PureScript modules will be exported to when running in the
44+ -- browser.
45+ --
46+ , optionsBrowserNamespace :: String
4247 } deriving Show
4348
4449-- |
4550-- Default compiler options
4651--
4752defaultOptions :: Options
48−defaultOptions = Options False False False False False
53+defaultOptions = Options False False False False False "PS"
src/Language/PureScript/Parser/Common.hs+2−2
@@ -217,8 +217,8 @@ parseQualified parser = qual
217217-- Parse an integer or floating point value
218218--
219219integerOrFloat :: P.Parsec String u (Either Integer Double)
220−integerOrFloat = (Left <$> P.try (PT.natural tokenParser) <|>
221− Right <$> P.try (PT.float tokenParser)) P.<?> "number"
220+integerOrFloat = (Right <$> P.try (PT.float tokenParser) <|>
221+ Left <$> P.try (PT.natural tokenParser)) P.<?> "number"
222222
223223-- |
224224-- Parse an identifier or parenthesized operator