Skip to content

Commit 7bb3b2f

Browse files
Merge pull request #41 from Janiczek/janiczek/port-gren-251
Port "Direct function calls" from Gren
2 parents 3b69065 + 48ff9b3 commit 7bb3b2f

File tree

7 files changed

+441
-130
lines changed

7 files changed

+441
-130
lines changed

compiler/src/Generate/JavaScript.hs

Lines changed: 114 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import qualified Lamdera.Injection
3838

3939

4040
type Graph = Map.Map Opt.Global Opt.Node
41+
type FnArgLookup = ModuleName.Canonical -> Name.Name -> Maybe Int
4142
type Mains = Map.Map ModuleName.Canonical Opt.Main
4243

4344

@@ -191,19 +192,35 @@ addGlobalHelp mode graph global state =
191192
let
192193
addDeps deps someState =
193194
Set.foldl' (addGlobal mode graph) someState deps
195+
196+
argLookup = makeArgLookup graph
194197
in
195198
case graph ! global of
199+
-- @LAMDERA
200+
Opt.Define (Opt.Function args body) deps
201+
| length args > 1 ->
202+
addStmt
203+
(addDeps deps state)
204+
(fn global args (Expr.generateFunctionImplementation mode argLookup args body))
205+
196206
Opt.Define expr deps ->
197207
addStmt (addDeps deps state) (
198-
var global (Expr.generate mode expr)
208+
var global (Expr.generate mode argLookup expr)
199209
)
200210

201211
Opt.DefineTailFunc argNames body deps ->
202212
addStmt (addDeps deps state) (
203213
let (Opt.Global _ name) = global in
204-
var global (Expr.generateTailDef mode name argNames body)
214+
var global (Expr.generateTailDef mode argLookup name argNames body)
205215
)
206216

217+
-- @LAMDERA
218+
Opt.Ctor index arity
219+
| arity > 1 ->
220+
addStmt
221+
state
222+
(ctor global arity (Expr.generateCtorImplementation mode global index arity))
223+
207224
Opt.Ctor index arity ->
208225
addStmt state (
209226
var global (Expr.generateCtor mode global index arity)
@@ -214,7 +231,7 @@ addGlobalHelp mode graph global state =
214231

215232
Opt.Cycle names values functions deps ->
216233
addStmt (addDeps deps state) (
217-
generateCycle mode global names values functions
234+
generateCycle mode argLookup global names values functions
218235
)
219236

220237
Opt.Manager effectsType ->
@@ -276,11 +293,11 @@ isDebugger (Opt.Global (ModuleName.Canonical _ home) _) =
276293
-- GENERATE CYCLES
277294

278295

279-
generateCycle :: Mode.Mode -> Opt.Global -> [Name.Name] -> [(Name.Name, Opt.Expr)] -> [Opt.Def] -> JS.Stmt
280-
generateCycle mode (Opt.Global home _) names values functions =
296+
generateCycle :: Mode.Mode -> FnArgLookup -> Opt.Global -> [Name.Name] -> [(Name.Name, Opt.Expr)] -> [Opt.Def] -> JS.Stmt
297+
generateCycle mode argLookup (Opt.Global home _) names values functions =
281298
JS.Block
282-
[ JS.Block $ map (generateCycleFunc mode home) functions
283-
, JS.Block $ map (generateSafeCycle mode home) values
299+
[ JS.Block $ map (generateCycleFunc mode argLookup home) functions
300+
, JS.Block $ map (generateSafeCycle mode argLookup home) values
284301
, case map (generateRealCycle home) values of
285302
[] ->
286303
JS.EmptyStmt
@@ -300,20 +317,37 @@ generateCycle mode (Opt.Global home _) names values functions =
300317
]
301318

302319

303-
generateCycleFunc :: Mode.Mode -> ModuleName.Canonical -> Opt.Def -> JS.Stmt
304-
generateCycleFunc mode home def =
320+
generateCycleFunc :: Mode.Mode -> FnArgLookup -> ModuleName.Canonical -> Opt.Def -> JS.Stmt
321+
generateCycleFunc mode argLookup home def =
305322
case def of
323+
-- @LAMDERA
324+
Opt.Def name (Opt.Function args body)
325+
| length args > 1 ->
326+
fn (Opt.Global home name) args (Expr.generateFunctionImplementation mode argLookup args body)
327+
306328
Opt.Def name expr ->
307-
JS.Var (JsName.fromGlobal home name) (Expr.codeToExpr (Expr.generate mode expr))
308-
329+
JS.Var (JsName.fromGlobal home name) (Expr.codeToExpr (Expr.generate mode argLookup expr))
330+
331+
-- @LAMDERA
332+
Opt.TailDef name args expr
333+
| length args > 1 ->
334+
let
335+
directFnName = JsName.fromGlobalDirectFn home name
336+
argNames = map JsName.fromLocal args
337+
in
338+
JS.Block
339+
[ JS.Var directFnName (Expr.codeToExpr (Expr.generateTailDefImplementation mode argLookup name args expr))
340+
, JS.Var (JsName.fromGlobal home name) (Expr.codeToExpr (Expr.generateCurriedFunctionRef argNames directFnName))
341+
]
342+
309343
Opt.TailDef name args expr ->
310-
JS.Var (JsName.fromGlobal home name) (Expr.codeToExpr (Expr.generateTailDef mode name args expr))
344+
JS.Var (JsName.fromGlobal home name) (Expr.codeToExpr (Expr.generateTailDef mode argLookup name args expr))
311345

312346

313-
generateSafeCycle :: Mode.Mode -> ModuleName.Canonical -> (Name.Name, Opt.Expr) -> JS.Stmt
314-
generateSafeCycle mode home (name, expr) =
347+
generateSafeCycle :: Mode.Mode -> FnArgLookup -> ModuleName.Canonical -> (Name.Name, Opt.Expr) -> JS.Stmt
348+
generateSafeCycle mode argLookup home (name, expr) =
315349
JS.FunctionStmt (JsName.fromCycle home name) [] $
316-
Expr.codeToStmtList (Expr.generate mode expr)
350+
Expr.codeToStmtList (Expr.generate mode argLookup expr)
317351

318352

319353
generateRealCycle :: ModuleName.Canonical -> (Name.Name, expr) -> JS.Stmt
@@ -432,7 +466,7 @@ generatePort mode (Opt.Global home name) makePort converter =
432466
JS.Var (JsName.fromGlobal home name) $
433467
JS.Call (JS.Ref (JsName.fromKernel Name.platform makePort))
434468
[ JS.String (Name.toBuilder name)
435-
, Expr.codeToExpr (Expr.generate mode converter)
469+
, Expr.codeToExpr (Expr.generate mode (\_ _ -> Nothing) converter)
436470
]
437471

438472

@@ -523,7 +557,7 @@ generateExports mode (Trie maybeMain subs) =
523557

524558
Just (home, main) ->
525559
"{'init':"
526-
<> JS.exprToBuilder (Expr.generateMain mode home main)
560+
<> JS.exprToBuilder (Expr.generateMain mode (\_ _ -> Nothing) home main)
527561
<> end
528562
in
529563
case Map.toList subs of
@@ -591,3 +625,66 @@ checkedMerge a b =
591625

592626
(Just _, Just _) ->
593627
error "cannot have two modules with the same name"
628+
629+
630+
631+
-- @LAMDERA
632+
-- FUNCTION ARGUMENT LOOKUP
633+
634+
635+
makeArgLookup :: Graph -> FnArgLookup
636+
makeArgLookup graph home name =
637+
case Map.lookup (Opt.Global home name) graph of
638+
Just (Opt.Define (Opt.Function args _) _) ->
639+
Just (length args)
640+
641+
Just (Opt.Ctor _ arity) ->
642+
Just arity
643+
644+
Just (Opt.Link global) ->
645+
case Map.lookup global graph of
646+
Just (Opt.Cycle names _ defs _) ->
647+
case List.find (\d -> defName d == name) defs of
648+
Just (Opt.Def _ (Opt.Function args _)) ->
649+
Just (length args)
650+
651+
Just (Opt.TailDef _ args _) ->
652+
Just (length args)
653+
654+
_ ->
655+
error (show names)
656+
657+
_ ->
658+
Nothing
659+
660+
_ ->
661+
Nothing
662+
663+
664+
defName :: Opt.Def -> Name.Name
665+
defName (Opt.Def name _) = name
666+
defName (Opt.TailDef name _ _) = name
667+
668+
669+
fn :: Opt.Global -> [Name.Name] -> Expr.Code -> JS.Stmt
670+
fn (Opt.Global home name) args code =
671+
let
672+
directFnName = JsName.fromGlobalDirectFn home name
673+
argNames = map JsName.fromLocal args
674+
in
675+
JS.Block
676+
[ JS.Var directFnName (Expr.codeToExpr code)
677+
, JS.Var (JsName.fromGlobal home name) $ Expr.codeToExpr (Expr.generateCurriedFunctionRef argNames directFnName)
678+
]
679+
680+
681+
ctor :: Opt.Global -> Int -> Expr.Code -> JS.Stmt
682+
ctor (Opt.Global home name) arity code =
683+
let
684+
directFnName = JsName.fromGlobalDirectFn home name
685+
argNames = Index.indexedMap (\i _ -> JsName.fromIndex i) [1 .. arity]
686+
in
687+
JS.Block
688+
[ JS.Var directFnName (Expr.codeToExpr code)
689+
, JS.Var (JsName.fromGlobal home name) $ Expr.codeToExpr (Expr.generateCurriedFunctionRef argNames directFnName)
690+
]

0 commit comments

Comments
 (0)