Skip to content

Commit

Permalink
Merge pull request #1102 from axch/precedence
Browse files Browse the repository at this point in the history
Refine and implement the Syntax Philosphy proposal
  • Loading branch information
axch committed Oct 3, 2022
2 parents dfef516 + 2129a9e commit 932975b
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 24 deletions.
11 changes: 9 additions & 2 deletions doc/syntax-philosophy.md
Expand Up @@ -27,6 +27,7 @@ tightest-binding to loosest-binding.
| . ! | indexing, reference slicing | Left |
| juxtaposition (space) | function application | Left |
| unary + - | negation, integer literals | Prefix |
| backquoted functions | infix application of binary functions | Left |
| other | user-defined operators | Left |
| * / | scalar multiplication, division | Left |
| .* *. | scalar * vector and vector * scalar | Left |
Expand Down Expand Up @@ -212,8 +213,14 @@ Specifially, we want the following things:
record with anonymous fields.

- The double colon `::` type-annotates an arbitrary expression without
otherwise changing its meaning. Since it can go anywhere, we follow Haskell
in making it looser than all expression operators, including `$`.
otherwise changing its meaning. Since it can go anywhere, we make it looser
than all expression operators, except `|>` and `$`. The exception supports
the common concept that `$` breaks up formulas completely (by being the
loosest expression-like operator).

- We make backquoted functions and user-defined operators bind tightly by
default, but for no particularly good reason. They are currently rare in
Dex, so it doesn't really matter.

6. Next, we have the special snowflakes that interact with almost nothing

Expand Down
67 changes: 45 additions & 22 deletions src/lib/ConcreteSyntax.hs
Expand Up @@ -755,27 +755,44 @@ replaceOp name op tbl = map (map replace) tbl where

ops :: PrecTable Group
ops =
[ [symOpL ".", symOpL "!"]
, [("space", Expr.InfixL $ opWithSrc $ sc $> (binApp Juxtapose))]
, [unOpPre "-", unOpPre "+"]
, [("other", anySymOp)] -- other ops with default fixity
, [symOpL "+", symOpL "-", symOpL "||", symOpL "&&",
symOpR "=>",
("backquote", Expr.InfixL $ opWithSrc $ backquoteName >>= (return . binApp . EvalBinOp)),
symOpL "<<<", symOpL ">>>", symOpL "<<&", symOpL "&>>"]
, [unOpPre "..", unOpPre "..<",
unOpPost "..", unOpPost "<.."]
, [symOpR "->", symOpR "--o", symOpR "?->", symOpR "?=>"]
, [symOpL "@"]
[ [symOpL ".", symOpL "!"]
, [juxtaposition]
, [unOpPre "-", unOpPre "+"]
, [backquote]
-- Other ops with default fixity
, [other]
, [symOpL "*", symOpL "/"]
, [symOpL ".*", symOpL "*."]
, [symOpL ".**", symOpL "**."]
, [symOpL "**"]
, [symOpL "+", symOpL "-"]
, [symOpL "-|"]
, [symOpL "+>>"]
, [symOpL "<>"]
, [symOpN "~~"]
, [symOpN "<", symOpN "<=", symOpN ">", symOpN ">="]
, [symOpN "==", symOpN "!="]
, [symOpL "&&"]
, [symOpL "||"]
, [unOpPre "..", unOpPre "..<", unOpPost "..", unOpPost "<.."]
, [symOpR "=>"]
, [symOpR "->", symOpR "--o", symOpR "?->", symOpR "?=>"]
, [symOpL ">>>"]
, [symOpL "<<<"]
, [symOpL "&>>"]
, [symOpL "<<&"]
, [symOpL "@"]
, [unOpPre "@"]
, [unOpPre "@..."]
, [unOpPre "..."]
, [symOpL "::"]
, [symOpR "$"]
, [symOpL "+=", symOpL ":="]
, [symOpN "::"]
, [symOpL "|>"]
, [symOpR "$"]
, [symOpN "+=", symOpN ":="]
-- Associate right so the mistaken utterance foo : i:Fin 4 => (..i)
-- groups as a bad pi type rather than a bad binder
, [symOpR ":"]
, [symOpL "="]
, [symOpR ":"]
, [symOpL "="]
-- Single-expression bodies for if, lambda, for, case, and do
-- notionally have this precedence.
-- This means that, for example,
Expand All @@ -786,14 +803,17 @@ ops =
-- \x y. (foo bar baz, stuff)
-- We do this so that lambdas may be written inside pairs and records.
-- This is achieved by cBlock invoking cGroupNoSeparators rather than cGroup.
, [symOpL "?"]
, [symOpL "?"]
-- Weak decision to associate `,` and `&` to the right because n-ary
-- tuples are internally represented curried, so this puts the new
-- element in front.
, [symOpR ","]
, [symOpR "&"]
, [symOpL "|"]
]
, [symOpR ","]
, [symOpR "&"]
, [symOpL "|"]
] where
juxtaposition = ("space", Expr.InfixL $ opWithSrc $ sc $> (binApp Juxtapose))
other = ("other", anySymOp)
backquote = ("backquote", Expr.InfixL $ opWithSrc $ backquoteName >>= (return . binApp . EvalBinOp))

labelPrefix :: Parser LabelPrefix
labelPrefix = sym "#" $> RecordIsoLabel
Expand All @@ -817,6 +837,9 @@ anySymOp = Expr.InfixL $ opWithSrc $ do
infixSym :: SourceName -> Parser ()
infixSym s = mayBreak $ sym $ T.pack s

symOpN :: SourceName -> (SourceName, Expr.Operator Parser Group)
symOpN s = (s, Expr.InfixN $ symOp s)

symOpL :: SourceName -> (SourceName, Expr.Operator Parser Group)
symOpL s = (s, Expr.InfixL $ symOp s)

Expand Down

0 comments on commit 932975b

Please sign in to comment.