@@ -10,6 +10,7 @@ import qualified Data.Graph as Graph
10import qualified Data.Map.Strict as Map
10import qualified Data.Map.Strict as Map
11import qualified Data.Set as Set
11import qualified Data.Set as Set
13+import qualified AST.Binop as Binop
13import qualified AST.Expression.Canonical as Can
14import qualified AST.Expression.Canonical as Can
14import qualified AST.Expression.Valid as Valid
15import qualified AST.Expression.Valid as Valid
15import qualified Canonicalize.Environment as Env
16import qualified Canonicalize.Environment as Env
@@ -53,15 +54,15 @@ canonicalize env (A.A region expression) =
53 Valid.List exprs ->
54 Valid.List exprs ->
54 Can.List <$> traverse (canonicalize env) exprs
55 Can.List <$> traverse (canonicalize env) exprs
56− Valid.Op name ->
57+ Valid.Op op ->
57− do (Env.Binop home func _ _) <- Env.findBinop region env name
58+ do (Env.Binop _ home name _ _) <- Env.findBinop region env op
58− return (Can.VarOperator name home func)
59+ return (Can.VarOperator op home name)
60 Valid.Negate expr ->
61 Valid.Negate expr ->
61 Can.Negate <$> canonicalize env expr
62 Can.Negate <$> canonicalize env expr
63 Valid.Binops ops final ->
64 Valid.Binops ops final ->
64− error "TODO"
65+ A.drop <$> canonicalizeBinops region env ops final
66 Valid.Lambda args body ->
67 Valid.Lambda args body ->
67 addLocals $
68 addLocals $
@@ -145,6 +146,89 @@ canonicalizeBranch env (condition, branch) =
149+-- CANONICALIZE BINOPS
152+canonicalizeBinops :: R.Region -> Env.Env -> [(Valid.Expr, A.Located N.Name)] -> Valid.Expr -> Result FreeLocals Can.Expr
153+canonicalizeBinops overallRegion env ops final =
155+ canonicalizeHelp (expr, A.A region op) =
157+ <$> canonicalize env expr
158+ <*> Env.findBinop region env op
160+ runBinopStepper overallRegion =<< (
162+ <$> traverse canonicalizeHelp ops
163+ <*> canonicalize env final
169+ | More [(Can.Expr, Env.Binop)] Can.Expr
170+ | Error Env.Binop Env.Binop
173+runBinopStepper :: R.Region -> Step -> Result FreeLocals Can.Expr
174+runBinopStepper overallRegion step =
182+ More ( (expr, op) : rest ) final ->
183+ runBinopStepper overallRegion $
184+ toBinopStep (toBinop op expr) op rest final
186+ Error (Env.Binop op1 _ _ _ _) (Env.Binop op2 _ _ _ _) ->
187+ Result.throw overallRegion (Error.Binop op1 op2)
190+toBinopStep :: (Can.Expr -> Can.Expr) -> Env.Binop -> [(Can.Expr, Env.Binop)] -> Can.Expr -> Step
191+toBinopStep makeBinop rootOp@(Env.Binop _ _ _ rootAssociativity rootPrecedence) middle final =
194+ Done (makeBinop final)
196+ ( expr, op@(Env.Binop _ _ _ associativity precedence) ) : rest ->
197+ if precedence < rootPrecedence then
199+ More ((makeBinop expr, op) : rest) final
201+ else if precedence > rootPrecedence then
203+ case toBinopStep (toBinop op expr) op rest final of
205+ Done (makeBinop newLast)
207+ More newMiddle newLast ->
208+ toBinopStep makeBinop rootOp newMiddle newLast
215+ case (rootAssociativity, associativity) of
216+ (Binop.Left, Binop.Left) ->
217+ toBinopStep (\right -> toBinop op (makeBinop expr) right) op rest final
219+ (Binop.Right, Binop.Right) ->
220+ toBinopStep (\right -> makeBinop (toBinop op expr right)) op rest final
226+toBinop :: Env.Binop -> Can.Expr -> Can.Expr -> Can.Expr
227+toBinop (Env.Binop op home name _ _) left right =
228+ A.merge left right (Can.Binop op home name left right)
148-- CANONICALIZE LET
232-- CANONICALIZE LET