emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

SMIE help


From: Ivan Andrus
Subject: SMIE help
Date: Thu, 28 Nov 2013 00:00:44 -0700

I'm trying to write a SMIE grammar for the GAP language [1], since it will be 
much better than what I have at the moment.  GAP is a fairly simple language, 
similar to ruby (and maybe Pascal).  Because of that I foolishly thought I 
would be able to figure it out.  I started with the example grammar and stole 
some from ruby-mode.

What I have works in many ways (though it could no doubt be simplified).  My 
indentation is wildly off however in at least one case, and I have no idea how 
to fix it.  The case of interest is the first line inside of a function (in the 
example the line starting with local).  Interestingly other lines in a function 
are fine.

Feel free to point me at other documentation or discussions that may be of use. 
 Any other tips would be appreciated as well.

Thanks,
Ivan

[1] http://www.gap-system.org/Manuals/doc/ref/chap4.html


;; One variation of the lisp code that I have used
(defvar gap-indent-step 4)

;; This sort of works
(defconst gap-smie-grammar
  (smie-prec2->grammar
   (smie-bnf->prec2
    '((id)
      (inst (exp) ;not technically, but probably makes sense
            ;; (exp ":=" exp)
            (id ":=" exp)
            ("function" insts "end")
            ("repeat" insts "until" exp)
            ("while" exp "do" insts "od")
            ("for" id "in" exp "do" insts "od")
            ("if" if-body "fi")
            ("return" exp)
            ("local" exps)
            )
      (insts (insts ";" insts) (inst))
      (exp ("(" exps ")")
           ("[" exps "]")
           ("{" exps "}")

           ("not" exp)

           (exp ".." exp)
           (exp "and" exp)
           (exp "or" exp)
           (exp "<" exp)
           (exp "<=" exp)
           (exp "=" exp)
           (exp ">=" exp)
           (exp ">" exp)
           (exp "<>" exp)
           ;; (exp "in" exp)
           (exp "+" exp)
           (exp "-" exp)
           (exp "*" exp)
           (exp "/" exp)
           (exp "mod" exp)
           (exp "^" exp)
           )
      (exps (exps "," exps) (exp))
      (itheni (insts) (exp "then" insts))
      (ielsei (itheni) (itheni "else" insts))
      (if-body (ielsei) (if-body "elif" if-body)))

    '((assoc ";"))
    '((assoc ","))
    '((assoc "elif"))
    '((assoc "not")
      (assoc "..")
      (assoc "and" "or")
      (assoc "<" "<=" "=" ">=" ">" "<>" ;; "in"
             )
      (assoc "+" "-")
      (assoc "*" "/" "mod")
      (assoc "^")))))


(defun gap-smie-rules (kind token)
  (pcase (cons kind token)
    (`(:list-intro . "function")
     gap-indent-step)
    (`(:after . "function")
     gap-indent-step)

    (`(:after . ,(or `"if" `"else" `"then" `"elif" `"do" `"repeat" `"while"))
     gap-indent-step)

    (`(:before . ";")
     (cond
      ((smie-rule-parent-p "function" "repeat" "while" "for"
                           "if" "then" "elif" "else" "when")
       (smie-rule-parent gap-indent-step))
      ))

    (`(:after . ,(or "=" ":=" "+" "-" "*" "/" "^"
                     ">" "<" ">=" "<=" "<>" "and" "or"))
     (if (smie-rule-parent-p ";" nil) gap-indent-step))
    ))

(smie-setup gap-smie-grammar #'gap-smie-rules)




# example of well indented GAP code
FittingHeight := function (G)
    local  fittingLength, F;

    fittingLength := 0;
    F := FittingSubgroup( G );
    while Order(F) > 1 do
        G := G / F;

        F := FittingSubgroup( G );
        fittingLength := fittingLength+1;
    od;

    if Order(G) > 1 then
        return fail;
    fi;
    return fittingLength;
end;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]