[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/haskell-tng-mode 79aeb82 076/385: most of the grammar
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/haskell-tng-mode 79aeb82 076/385: most of the grammar |
Date: |
Tue, 5 Oct 2021 23:59:05 -0400 (EDT) |
branch: elpa/haskell-tng-mode
commit 79aeb82f3d5bdaa3e6e84a4f5ace0f294f9bd1bf
Author: Tseen She <ts33n.sh3@gmail.com>
Commit: Tseen She <ts33n.sh3@gmail.com>
most of the grammar
---
haskell-tng-smie.el | 97 ++++++++++++++-----------------------------
test/haskell-tng-sexp-test.el | 49 +++++++++++-----------
test/src/layout.hs.sexps | 30 ++++++-------
3 files changed, 71 insertions(+), 105 deletions(-)
diff --git a/haskell-tng-smie.el b/haskell-tng-smie.el
index 56c329a..bc729ac 100644
--- a/haskell-tng-smie.el
+++ b/haskell-tng-smie.el
@@ -22,11 +22,13 @@
(require 'haskell-tng-font-lock)
(require 'haskell-tng-lexer)
-;; FIXME a haskell grammar that doesn't have warnings during the tests
-
;; https://www.gnu.org/software/emacs/manual/html_mono/elisp.html#SMIE-Grammar
;; https://www.haskell.org/onlinereport/haskell2010/haskellch3.html
;;
+;; Transcribed here. Many of these grammar rules cannot be expressed in SMIE
+;; because Haskell uses whitespace separators a lot, whereas the BNF must use
+;; non-terminals.
+;;
;; exp infixexp :: [context =>] type (expression type signature)
;; | infixexp
;;
@@ -60,80 +62,43 @@
(smie-bnf->prec2
'((id)
(exp
- ;; TODO context
- ;;(infixexp "::" context "=>" type)
+ (infixexp "::" context "=>" type)
(infixexp "::" type)
- (infixexp)
- )
+ (infixexp))
- ;; TODO update the lexer to provide a virtual token for infix but keep
- ;; popular operators with important fixity.
+ (context
+ ("(" context ")")
+ (context "," context))
+
+ ;; TODO the lexer should provide virtual infix operators
(infixexp
(lexp "$" infixexp)
- (lexp "+" infixexp)
- (lexp "-" infixexp)
- ;; (lexp "*" infixexp)
- ;; (lexp "/" infixexp)
- ;; (lexp "<$>" infixexp)
- ;; (lexp "<*>" infixexp)
- ;; (lexp ">>=" infixexp)
- ;; (lexp "`should`" infixexp)
- ;; (lexp "&" infixexp)
-
- ;;("-" infixexp) ;; can't be opener and neither
- (lexp)
- )
-
- ;; TODO should we support terminators as separators?
- ;;(insts (insts ";" insts) (inst))
+ (lexp))
(lexp
("if" exp "then" exp "else" exp)
- ;; TODO apats
- ;;("let" decls "in" exp)
- ;;("case" exp "of" alts)
- ;;("do" stmts)
- ;; TODO where?
- ;; TODO fexp
- )
-
- ;; (decls
- ;; ;;("{" decls "}")
- ;; (decls ";" decls)
- ;; (decl))
- ;; (decl
- ;; (id "=" exp))
- ;; (alts
- ;; ;;("{" alts "}")
- ;; (alts ";" alts)
- ;; (alt))
- ;; (alt
- ;; (id "->" exp))
- ;; (stmts
- ;; ;;("{" stmts "}")
- ;; (stmts ";" stmts)
- ;; (stmt))
- ;; (stmt
- ;; (id "<-" exp))
-
+ ("where" decls)
+ ("let" decls "in" exp)
+ ("do" stmts)
+ ("case" exp "of" alts))
+
+ (decls
+ ("{" decls "}")
+ (decls ";" decls)
+ (id "=" exp))
+ (alts
+ ("{" alts "}")
+ (alts ";" alts)
+ (id "->" exp))
+ (stmts
+ ("{" stmts "}")
+ (stmts ";" stmts)
+ (id "<-" exp))
)
;; operator precedences
- ;;'((assoc ";"))
- ;;'((assoc ","))
- '((assoc "else" "::") ;; TODO keywords here
- (assoc "$")
- ;; TODO arrange by fixity
- (assoc "+" "-"))
- ;; '((assoc "*"))
- ;; '((assoc "/"))
- ;; '((assoc "<$>"))
- ;; '((assoc "<*>"))
- ;; '((assoc ">>="))
- ;; '((assoc "&"))
-
-;; Read the "<" and ">" as parentheses: when confronted with "... else E $ ..."
-;;SMIE is not sure if you meant "... else E) $ ..." or "... else (E $ ...".
+ '((left ";" "," "::" "else" "in" "of" "->" "do" "<-" "where" "=")
+ (left "$"))
)))
diff --git a/test/haskell-tng-sexp-test.el b/test/haskell-tng-sexp-test.el
index dc3a15f..7332243 100644
--- a/test/haskell-tng-sexp-test.el
+++ b/test/haskell-tng-sexp-test.el
@@ -21,9 +21,10 @@
;; tokens.
(ert-deftest haskell-tng-sexp-file-tests ()
+ ;; the baselines have some pretty funky stuff in them...
(should (have-expected-sexps (testdata "src/layout.hs")))
- ;; TODO enable when layout.hs gives better results...
+ ;; to the extent that they aren't even useful
;;(should (have-expected-sexps (testdata "src/medley.hs")))
)
@@ -37,24 +38,24 @@
;; and `backward-sexp', provided by SMIE.
(defun haskell-tng-sexp-test:sexps-at-point (p)
"Return a list of cons cells (start . end)"
- (let* (sexps
- (forward-backward
- (ignore-errors
- (save-excursion
- (goto-char p)
- (forward-sexp)
- (let ((forward (point)))
- (backward-sexp)
- (unless (= (point) forward)
- (cons (point) forward))))))
- (backward-forward
- (ignore-errors
- (save-excursion
- (goto-char p)
- (backward-sexp)
- (let ((backward (point)))
- (forward-sexp)
- (unless (= backward (point))
+ (let (sexps
+ (forward-backward
+ (ignore-errors
+ (save-excursion
+ (goto-char p)
+ (forward-sexp)
+ (let ((forward (point)))
+ (backward-sexp)
+ (unless (= (point) forward)
+ (cons (point) forward))))))
+ (backward-forward
+ (ignore-errors
+ (save-excursion
+ (goto-char p)
+ (backward-sexp)
+ (let ((backward (point)))
+ (forward-sexp)
+ (unless (= backward (point))
(cons backward (point))))))))
(when forward-backward
(push forward-backward sexps))
@@ -67,9 +68,8 @@
(goto-char (point-min))
(let (sexps)
(while (not (eobp))
- (unless (nth 8 (syntax-ppss)) ;; don't query in comments/strings
- (let ((here (haskell-tng-sexp-test:sexps-at-point (point))))
- (setq sexps (append here sexps))))
+ (let ((here (haskell-tng-sexp-test:sexps-at-point (point))))
+ (setq sexps (append here sexps)))
(forward-char))
(delete-dups sexps)))
@@ -78,10 +78,11 @@
(let (chars exit)
(goto-char (point-min))
(while (not exit)
- (--each sexps
+ ;; there is ambiguity around multiple parens at the same point
+ (--each (reverse sexps)
(cond
- ((= (point) (car it)) (push "(" chars))
((= (point) (cdr it)) (push ")" chars))
+ ((= (point) (car it)) (push "(" chars))
(t nil)))
(if (eobp)
(setq exit 't)
diff --git a/test/src/layout.hs.sexps b/test/src/layout.hs.sexps
index a412dc4..b260243 100644
--- a/test/src/layout.hs.sexps
+++ b/test/src/layout.hs.sexps
@@ -1,20 +1,20 @@
-(-- Figure 2.1 from the Haskell2010 report
-(((((module)) (AStack()( (Stack(),) (push(),) (pop(),) (top(),) (size) ))
(where)
-(data) (Stack) (a) (=) (Empty)
+((--) (Figure) (2.1) (from) (the) (Haskell2010) (report)
+(module)) (AStack)(( (Stack), (push), (pop), (top), (size) )) (where
+(((data) (Stack) (a) = (Empty)
(|) (MkStack) (a) (((Stack) (a)))
-(push) (::) (a) (->) (Stack) (a) (->) (Stack) (a)
-(push) (x) (s) (=) (MkStack) (x) (s)
+(push) (::) (((a) (->) ((Stack) (a) (->) (Stack) (a)))
+((push) (x) (s) = (MkStack) (x) (s))
-(size)) (::) (Stack) (a) (->) (Int)
-(size) (s) (=) (length) (((stkToLst) (s))) (where)
- (stkToLst) (Empty) (=) ([])
- (stkToLst) (((MkStack) (x) (s))) (=) (x:xs) (where) (xs) (=)
(stkToLst) (s)
+(size) (::) ((((Stack) (a) (->) (Int))
+((size) (s) = (length) (((stkToLst) (s))) (where
+ ((stkToLst) (Empty) = ([])
+ ((stkToLst) (((MkStack) (x) (s))) = (x:xs) (where ((xs) =
(stkToLst) (s)
-(pop)) (::) (Stack) (a) (->) (((a(),) (Stack) (a)))
-(pop) (((MkStack) (x) (s)))
- (=) (((x)(,) (case) (s) (of) r (->) (i) (r) (where) i (x) (=) x)) -- (pop
Empty) is an error
+)))))))(pop) (::) (((Stack) (a) (->) (((a), (Stack) (a))))
+((pop) (((MkStack) (x) (s)))
+ = (((x), ((case (s) (of) ((r (->) (i) (r) (where (i (x) = x))))))))) ((--)
(((pop) (Empty))) (is) (an) (error)
-(top)) (::) (Stack) (a) (->) (a)
-(top) (((MkStack) (x) (s))) (=) (x) -- (top Empty) is an
error
-)
\ No newline at end of file
+(top)) (::) ((Stack) (a) (->) (a))
+((top) (((MkStack) (x) (s))) = (x)))))) (--) (((top)
(Empty))) (is) (an) (error)
+))
\ No newline at end of file
- [nongnu] elpa/haskell-tng-mode 3449847 162/385: no need to special-case dollar, (continued)
- [nongnu] elpa/haskell-tng-mode 3449847 162/385: no need to special-case dollar, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 8b5a4d4 177/385: improve indentation tests, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode cb801b4 015/385: moar multiline type search, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode de48840 030/385: multiline import anchors, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 5c50be0 044/385: remove redundant TODOs, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 174c63b 046/385: laying the foundations for SMIE, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 97ce717 058/385: improve the testing, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 2a2afee 064/385: cache invalidation and tests for layout invalidation, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 3ca869f 067/385: code reorganisation, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 0ffb885 071/385: a thought, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 79aeb82 076/385: most of the grammar,
ELPA Syncer <=
- [nongnu] elpa/haskell-tng-mode 7eaef51 078/385: optimisation in the sexp test, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode cb0f3d2 082/385: starting indentation rules, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode cfbdae1 084/385: simplify the lexer assertion language, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 0c5acb7 087/385: lexer and grammar supports symid, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 6c520bc 093/385: fixes for type level lists, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode f085f16 097/385: indentation regression tests, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 01ea0b8 103/385: heuristic alternative indentation levels, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode c20ea4f 096/385: infix varid as symid, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode bfe859a 095/385: notes about lexers, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 0506391 109/385: module ... where indents to 0, ELPA Syncer, 2021/10/06