@@ -45,7 +45,8 @@ import Language.PureScript.CodeGen.Common
4545import Language.PureScript.TypeChecker.Monad (canonicalizeDataConstructor)
4646
4747-- |
48−-- Generate code in the simplified Javascript intermediate representation for all declarations in a module
48+-- Generate code in the simplified Javascript intermediate representation for all declarations in a
49+-- module.
4950--
5051moduleToJs :: Options -> Module -> Environment -> [JS]
5152moduleToJs opts (Module pname@(ProperName name) decls) env =
@@ -85,6 +86,10 @@ declToJs _ mp (ExternDeclaration importTy ident (Just js) _) _ =
8586 Just $ js : setProperty ident (var ident) mp
8687declToJs _ _ _ _ = Nothing
8788
89+-- |
90+-- Generate code in the simplified Javascript intermediate representation for setting the property
91+-- of an object.
92+--
8893setProperty :: Ident -> JS -> ModuleName -> [JS]
8994setProperty ident@(Op op) val (ModuleName (ProperName moduleName)) =
9095 [ JSAssignment (accessor ident (JSVar moduleName)) val
@@ -92,13 +97,25 @@ setProperty ident@(Op op) val (ModuleName (ProperName moduleName)) =
9297setProperty ident val (ModuleName (ProperName moduleName)) =
9398 [ JSAssignment (accessor ident (JSVar moduleName)) val ]
9499
100+-- |
101+-- Generate code in the simplified Javascript intermediate representation for a variable based on a
102+-- PureScript identifier.
103+--
95104var :: Ident -> JS
96105var = JSVar . identToJs
97106
107+-- |
108+-- Generate code in the simplified Javascript intermediate representation for an accessor based on
109+-- a PureScript identifier. If the name is not valid in Javascript (symbol based, reserved name) an
110+-- indexer is returned.
111+--
98112accessor :: Ident -> JS -> JS
99113accessor (Ident name) | nameIsJsReserved name = JSIndexer (JSStringLiteral name)
100114accessor ident = JSAccessor (identToJs ident)
101115
116+-- |
117+-- Generate code in the simplified Javascript intermediate representation for a value or expression.
118+--
102119valueToJs :: Options -> ModuleName -> Environment -> Value -> JS
103120valueToJs _ _ _ (NumericLiteral n) = JSNumericLiteral n
104121valueToJs _ _ _ (StringLiteral s) = JSStringLiteral s
@@ -130,6 +147,9 @@ valueToJs _ _ _ _ = error "Invalid argument to valueToJs"
130147bindName :: ModuleName -> Ident -> Environment -> Environment
131148bindName m ident env = env { names = M.insert (m, ident) (unit, LocalVariable) $ names env }
132149
150+-- |
151+-- Generate code in the simplified Javascript intermediate representation for runtime type checks.
152+--
133153runtimeTypeChecks :: String -> Type -> [JS]
134154runtimeTypeChecks arg ty =
135155 let
@@ -159,6 +179,10 @@ runtimeTypeChecks arg ty =
159179 arrayCheck :: JS -> JS
160180 arrayCheck js = JSIfElse (JSUnary Not (JSApp (JSAccessor "isArray" (JSVar "Array")) [js])) (JSBlock [JSThrow (JSStringLiteral "Array expected")]) Nothing
161181
182+-- |
183+-- Generate code in the simplified Javascript intermediate representation for a reference to a
184+-- variable.
185+--
162186varToJs :: ModuleName -> Environment -> Qualified Ident -> JS
163187varToJs m e qual@(Qualified _ ident) = go qual
164188 where
@@ -174,10 +198,18 @@ varToJs m e qual@(Qualified _ ident) = go qual
174198 Nothing -> error "Undefined alias in varToJs"
175199 isExtern _ = False
176200
201+-- |
202+-- Generate code in the simplified Javascript intermediate representation for a reference to a
203+-- variable that may have a qualified name.
204+--
177205qualifiedToJS :: (a -> Ident) -> Qualified a -> JS
178206qualifiedToJS f (Qualified (Just (ModuleName (ProperName m))) a) = accessor (f a) (JSVar m)
179207qualifiedToJS f (Qualified Nothing a) = JSVar $ identToJs (f a)
180208
209+-- |
210+-- Generate code in the simplified Javascript intermediate representation for pattern match binders
211+-- and guards.
212+--
181213bindersToJs :: Options -> ModuleName -> Environment -> [([Binder], Maybe Guard, Value)] -> [JS] -> JS
182214bindersToJs opts m e binders vals = runGen (map identToJs (unusedNames (binders, vals))) $ do
183215 valNames <- replicateM (length vals) fresh
@@ -193,6 +225,10 @@ bindersToJs opts m e binders vals = runGen (map identToJs (unusedNames (binders,
193225 binderToJs m e v done'' b
194226 go _ _ _ _ = error "Invalid arguments to bindersToJs"
195227
228+-- |
229+-- Generate code in the simplified Javascript intermediate representation for a pattern match
230+-- binder.
231+--
196232binderToJs :: ModuleName -> Environment -> String -> [JS] -> Binder -> Gen [JS]
197233binderToJs _ _ _ done NullBinder = return done
198234binderToJs _ _ varName done (StringBinder str) =
@@ -256,6 +292,10 @@ binderToJs m e varName done (NamedBinder ident binder) = do
256292 js <- binderToJs m e varName done binder
257293 return (JSVariableIntroduction (identToJs ident) (Just (JSVar varName)) : js)
258294
295+-- |
296+-- Checks whether a data constructor is the only constructor for that type, used to simplify the
297+-- check when generating code for binders.
298+--
259299isOnlyConstructor :: ModuleName -> Environment -> Qualified ProperName -> Bool
260300isOnlyConstructor m e ctor =
261301 let (ty, _) = fromMaybe (error "Data constructor not found") $ qualify m ctor `M.lookup` dataConstructors e
@@ -268,6 +308,10 @@ isOnlyConstructor m e ctor =
268308 typeConstructor (TypeApp ty _) = typeConstructor ty
269309 typeConstructor fn = error $ "Invalid arguments to typeConstructor: " ++ show fn
270310
311+-- |
312+-- Generate code in the simplified Javascript intermediate representation for a statement in a
313+-- PureScript block.
314+--
271315statementToJs :: Options -> ModuleName -> Environment -> Statement -> JS
272316statementToJs opts m e (VariableIntroduction ident value) = JSVariableIntroduction (identToJs ident) (Just (valueToJs opts m e value))
273317statementToJs opts m e (Assignment target value) = JSAssignment (JSVar (identToJs target)) (valueToJs opts m e value)