Skip to content

Commit

Permalink
WIP Allow for tuple with 3+ elements
Browse files Browse the repository at this point in the history
  • Loading branch information
decioferreira committed Feb 12, 2025
1 parent 4be7ff7 commit 0b5dc8f
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 16 deletions.
6 changes: 3 additions & 3 deletions src/Compiler/AST/Canonical.elm
Original file line number Diff line number Diff line change
Expand Up @@ -1002,12 +1002,12 @@ pattern_Encoder pattern_ =
[ ( "type", Encode.string "PUnit" )
]

PTuple pattern1 pattern2 patterns3 ->
PTuple pattern1 pattern2 otherPatterns ->
Encode.object
[ ( "type", Encode.string "PTuple" )
, ( "pattern1", patternEncoder pattern1 )
, ( "pattern2", patternEncoder pattern2 )
, ( "patterns3", Encode.list patternEncoder patterns3 )
, ( "otherPatterns", Encode.list patternEncoder otherPatterns )
]

PList patterns ->
Expand Down Expand Up @@ -1089,7 +1089,7 @@ pattern_Decoder =
Decode.map3 PTuple
(Decode.field "pattern1" patternDecoder)
(Decode.field "pattern2" patternDecoder)
(Decode.field "patterns3" (Decode.list patternDecoder))
(Decode.field "otherPatterns" (Decode.list patternDecoder))

"PList" ->
Decode.map PList
Expand Down
23 changes: 19 additions & 4 deletions src/Compiler/Canonicalize/Expression.elm
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import Compiler.Data.Index as Index
import Compiler.Data.Name as Name exposing (Name)
import Compiler.Elm.ModuleName as ModuleName
import Compiler.Elm.Package as Pkg
import Compiler.Parse.SyntaxVersion as SV
import Compiler.Reporting.Annotation as A
import Compiler.Reporting.Error.Canonicalize as Error
import Compiler.Reporting.Result as R
Expand Down Expand Up @@ -170,15 +171,29 @@ canonicalize env (A.At region expression) =
R.pure Can.Tuple
|> R.apply (canonicalize env a)
|> R.apply (canonicalize env b)
|> R.apply (canonicalizeTupleExtras env cs)
|> R.apply (canonicalizeTupleExtras region env cs)

Src.Shader src tipe ->
R.ok (Can.Shader src tipe)


canonicalizeTupleExtras : Env.Env -> List Src.Expr -> EResult FreeLocals (List W.Warning) (List Can.Expr)
canonicalizeTupleExtras env extras =
R.traverse (canonicalize env) extras
canonicalizeTupleExtras : A.Region -> Env.Env -> List Src.Expr -> EResult FreeLocals (List W.Warning) (List Can.Expr)
canonicalizeTupleExtras region env extras =
case extras of
[] ->
R.ok []

[ three ] ->
R.fmap List.singleton <| canonicalize env three

_ ->
-- FIXME
case SV.Guida of
SV.Elm ->
R.throw (Error.TupleLargerThanThree region)

SV.Guida ->
R.traverse (canonicalize env) extras



Expand Down
23 changes: 19 additions & 4 deletions src/Compiler/Canonicalize/Pattern.elm
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Compiler.Canonicalize.Environment.Dups as Dups
import Compiler.Data.Index as Index
import Compiler.Data.Name as Name
import Compiler.Elm.ModuleName as ModuleName
import Compiler.Parse.SyntaxVersion as SV
import Compiler.Reporting.Annotation as A
import Compiler.Reporting.Error.Canonicalize as Error
import Compiler.Reporting.Result as R
Expand Down Expand Up @@ -83,7 +84,7 @@ canonicalize env (A.At region pattern) =
R.ok Can.PTuple
|> R.apply (canonicalize env a)
|> R.apply (canonicalize env b)
|> R.apply (canonicalizeTuple env cs)
|> R.apply (canonicalizeTuple region env cs)

Src.PCtor nameRegion name patterns ->
Env.findCtor nameRegion env name
Expand Down Expand Up @@ -144,9 +145,23 @@ canonicalizeCtor env region name patterns ctor =
R.throw (Error.PatternHasRecordCtor region name)


canonicalizeTuple : Env.Env -> List Src.Pattern -> PResult DupsDict w (List Can.Pattern)
canonicalizeTuple env =
R.traverse (canonicalize env)
canonicalizeTuple : A.Region -> Env.Env -> List Src.Pattern -> PResult DupsDict w (List Can.Pattern)
canonicalizeTuple tupleRegion env extras =
case extras of
[] ->
R.ok []

[ three ] ->
R.fmap List.singleton (canonicalize env three)

_ ->
-- FIXME
case SV.Guida of
SV.Elm ->
R.throw (Error.TupleLargerThanThree tupleRegion)

SV.Guida ->
R.traverse (canonicalize env) extras


canonicalizeList : Env.Env -> List Src.Pattern -> PResult DupsDict w (List Can.Pattern)
Expand Down
19 changes: 17 additions & 2 deletions src/Compiler/Canonicalize/Type.elm
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Compiler.AST.Source as Src
import Compiler.Canonicalize.Environment as Env
import Compiler.Canonicalize.Environment.Dups as Dups
import Compiler.Data.Name as Name
import Compiler.Parse.SyntaxVersion as SV
import Compiler.Reporting.Annotation as A
import Compiler.Reporting.Error.Canonicalize as Error
import Compiler.Reporting.Result as R
Expand Down Expand Up @@ -75,8 +76,22 @@ canonicalize env (A.At typeRegion tipe) =
|> R.bind (\tTuple -> R.fmap tTuple (canonicalize env b))
|> R.bind
(\tTuple ->
R.traverse (canonicalize env) cs
|> R.fmap tTuple
case cs of
[] ->
R.ok (tTuple [])

[ c ] ->
canonicalize env c
|> R.fmap (tTuple << List.singleton)

_ ->
case SV.Guida of
SV.Elm ->
R.throw <| Error.TupleLargerThanThree typeRegion

SV.Guida ->
R.traverse (canonicalize env) cs
|> R.fmap tTuple
)


Expand Down
25 changes: 24 additions & 1 deletion src/Compiler/Nitpick/PatternMatches.elm
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,16 @@ simplify (A.At _ pattern) =
Can.PUnit ->
Ctor unit unitName []

Can.PTuple a b [] ->
Ctor pair pairName [ simplify a, simplify b ]

Can.PTuple a b [ c ] ->
Ctor triple tripleName [ simplify a, simplify b, simplify c ]

Can.PTuple a b cs ->
Ctor triple tripleName (List.map simplify (a :: b :: cs))
-- FIXME this is a hack to make sure that the triple ctor is used
-- Ctor triple tripleName (List.map simplify (a :: b :: cs))
Debug.todo "Nitpick: simplify tuple with more than 3 elements"

Can.PCtor { union, name, args } ->
Ctor union name <|
Expand Down Expand Up @@ -125,6 +133,16 @@ unit =
Can.Union [] [ ctor ] 1 Can.Normal


pair : Can.Union
pair =
let
ctor : Can.Ctor
ctor =
Can.Ctor pairName Index.first 2 [ Can.TVar "a", Can.TVar "b" ]
in
Can.Union [ "a", "b" ] [ ctor ] 1 Can.Normal


triple : Can.Union
triple =
let
Expand Down Expand Up @@ -159,6 +177,11 @@ unitName =
"#0"


pairName : Name.Name
pairName =
"#2"


tripleName : Name.Name
tripleName =
"#3"
Expand Down
22 changes: 22 additions & 0 deletions src/Compiler/Reporting/Error/Canonicalize.elm
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ type Error
| RecursiveDecl A.Region Name (List Name)
| RecursiveLet (A.Located Name) (List Name)
| Shadowing Name A.Region A.Region
| TupleLargerThanThree A.Region
| TypeVarsUnboundInUnion A.Region Name (List Name) ( Name, A.Region ) (List ( Name, A.Region ))
| TypeVarsMessedUpInAlias A.Region Name (List Name) (List ( Name, A.Region )) (List ( Name, A.Region ))

Expand Down Expand Up @@ -859,6 +860,18 @@ toReport source err =
, advice
)

TupleLargerThanThree region ->
Report.Report "BAD TUPLE" region [] <|
Code.toSnippet source
region
Nothing
( D.fromChars "I only accept tuples with two or three items. This has too many:"
, D.stack
[ D.reflow <| "I recommend switching to records. Each item will be named, and you can use the `point.x` syntax to access them."
, D.link "Note" "Read" "tuples" "for more comprehensive advice on working with large chunks of data in Elm."
]
)

TypeVarsUnboundInUnion unionRegion typeName allVars unbound unbounds ->
unboundTypeVars source unionRegion [ D.fromChars "type" ] typeName allVars unbound unbounds

Expand Down Expand Up @@ -1583,6 +1596,12 @@ errorEncoder error =
, ( "r2", A.regionEncoder r2 )
]

TupleLargerThanThree region ->
Encode.object
[ ( "type", Encode.string "TupleLargerThanThree" )
, ( "region", A.regionEncoder region )
]

TypeVarsUnboundInUnion unionRegion typeName allVars unbound unbounds ->
Encode.object
[ ( "type", Encode.string "TypeVarsUnboundInUnion" )
Expand Down Expand Up @@ -1835,6 +1854,9 @@ errorDecoder =
(Decode.field "r1" A.regionDecoder)
(Decode.field "r2" A.regionDecoder)

"TupleLargerThanThree" ->
Decode.map TupleLargerThanThree (Decode.field "region" A.regionDecoder)

"TypeVarsUnboundInUnion" ->
Decode.map5 TypeVarsUnboundInUnion
(Decode.field "unionRegion" A.regionDecoder)
Expand Down
1 change: 0 additions & 1 deletion src/Compiler/Reporting/Render/Type.elm
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import Compiler.Reporting.Annotation as A
import Compiler.Reporting.Doc as D
import Compiler.Reporting.Render.Type.Localizer as L
import List.Extra as List
import Maybe.Extra as Maybe



Expand Down
1 change: 0 additions & 1 deletion src/Compiler/Type/Error.elm
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import Compiler.Reporting.Render.Type.Localizer as L
import Data.Map as Dict exposing (Dict)
import Json.Decode as Decode
import Json.Encode as Encode
import Maybe.Extra as Maybe
import Prelude
import System.TypeCheck.IO as IO

Expand Down

0 comments on commit 0b5dc8f

Please sign in to comment.