diff --git a/ztl-mode.el b/ztl-mode.el index 3a5e386..a7cc1fb 100644 --- a/ztl-mode.el +++ b/ztl-mode.el @@ -1,19 +1,16 @@ ;;; ztl-mode.el --- Major mode for editing Ztl code -*- lexical-binding: t; -*- ;; ;; Licensed under the GPLv3 License. -(require 'font-lock) (defvar ztl-keywords - '("fn" "to" "in" "is" "as" "use" "set" "if" "else" "for" "loop" "concurrent" - "while" "push" "pop" "return" "const" "type" "this" "eq" "ne" "do" "panic" - "mod" "not" "and" "or" "xor" "band" "bor" "bxor" "srl" "sll" "let") + '("fn" "to" "in" "is" "as" "use" "set" "if" "else" + "for" "loop" "concurrent" "while" "do" "exits" "exit" + "return" "const" "type" "this" "panic" + "break" "mod" "not" "and" "or" "print" "let") "Keywords in Ztl.") (defvar ztl-types - '("byte" "str" "int" "real" - "logical" "bool" "err" - "i8" "i16" "i32" "i64" "i128" - "f8" "f16" "f32" "f64" "f128") + '("byte" "str" "real" "bool" "err" "any") "Types in Ztl.") (defvar ztl-constants @@ -21,41 +18,96 @@ "Constants in Ztl.") (defvar ztl-font-lock-keywords - (list - ;; Constants - (cons (regexp-opt ztl-constants 'words) font-lock-constant-face) - ;; Keywords - (cons (regexp-opt ztl-keywords 'words) font-lock-keyword-face) - ;; Types - (cons (regexp-opt ztl-types 'words) font-lock-type-face) - ;; Structs (PascalCase) - '("\\b[A-Z][A-Za-z0-9_]*\\b" . font-lock-type-face) - ;; Numbers - '("\\b\\([0-9]+\\(?:\\.[0-9]*\\)?\\)\\b" . font-lock-number-face) - ;; Function calls - '("\\b\\([a-zA-Z_][a-zA-Z0-9_]*\\)\\s-*(" (1 font-lock-function-name-face)) - ) - "Font lock definitions for Ztl.") + `( + ;; Keywords + (,(regexp-opt ztl-keywords 'words) . font-lock-keyword-face) -(defvar ztl-syntax-table - (let ((table (make-syntax-table))) - ;; Comments: C and C++ style - (modify-syntax-entry ?/ ". 14b" table) - (modify-syntax-entry ?* ". 23" table) - (modify-syntax-entry ?\n ">" table) + ;; Types + (,(regexp-opt ztl-types 'words) . font-lock-type-face) + + ;; Constants + (,(regexp-opt ztl-constants 'words) . font-lock-constant-face) + + ;; Structs: CamelCase identifiers + ("\\b[A-Z][a-zA-Z0-9_]*\\b" . font-lock-type-face) + + ;; Floating point numbers + ("-?[0-9]+\\.[0-9]+" . font-lock-constant-face) + + ;; Ints + ("-?[0-9]+" . font-lock-constant-face) + + ;; Strings with double quotes + ("\"[^\"\n]*\"" . font-lock-string-face) + + ;; Strings with backticks + ("`[^`]*`" . font-lock-string-face) + + ;; Function definitions + ("\\_\\s-+\\(\\w+\\)(" (1 font-lock-function-name-face)) + + ;; Function calls + ("\\_<\\([a-zA-Z_][a-zA-Z0-9_]*\\)\\s-*(" (1 font-lock-function-name-face)) + + ) + "Font lock keywords for Ztl mode.") + +(defvar ztl-mode-syntax-table + (let ((st (make-syntax-table))) + ;; C++-style comments + (modify-syntax-entry ?/ ". 14b" st) + ;; C-style comments + (modify-syntax-entry ?* ". 23" st) ;; Strings - (modify-syntax-entry ?\" "\"" table) - (modify-syntax-entry ?\\ "\\" table) - table) - "Syntax table for `ztl-mode'.") + (modify-syntax-entry ?\" "\"" st) + (modify-syntax-entry ?` "\"" st) + st) + "Syntax table for Ztl mode.") -(define-derived-mode ztl-mode prog-mode "ZTL" - "Major mode for editing Ztl source files." - :syntax-table ztl-syntax-table - :group 'ztl +(defun ztl-indent-line () + "Indent current line as Ztl code." + (interactive) + (let ((indent (calculate-ztl-indent))) + (if (null indent) + (setq indent 0)) + (indent-line-to indent))) + +(defun calculate-ztl-indent () + "Calculate the proper indentation for the current line." + (save-excursion + (beginning-of-line) + (let ((pos (point-marker)) + (indent 0)) + (skip-chars-forward " \t") + (if (looking-at "\\s)\\|\\s(") + (setq indent 0) + (condition-case nil + (progn + (backward-up-list 1) + (while (and (> (point) (point-min)) + (progn + (forward-line -1) + (skip-chars-forward " \t") + (or (looking-at "\\s<") ; comment + (looking-at "\\s\"") ; string + (looking-at "\\s$")))) ; skip to previous line + nil) + (setq indent (current-indentation)) + (forward-line 0) + (skip-chars-forward " \t") + (if (looking-at "\\s(") ; opening brace + (setq indent (+ indent tab-width)))) + (error nil))) + indent))) + +(define-derived-mode ztl-mode prog-mode "Ztl" + "Major mode for editing Ztl code." + :syntax-table ztl-mode-syntax-table (setq-local font-lock-defaults '(ztl-font-lock-keywords)) - (setq-local comment-start "//") + (setq-local comment-start "// ") (setq-local comment-end "") + (setq-local parse-sexp-ignore-comments t) + (setq-local indent-line-function 'ztl-indent-line) (setq-local syntax-propertize-function (syntax-propertize-rules ;; Line comments starting with // @@ -65,5 +117,4 @@ (add-to-list 'auto-mode-alist '("\\.ztl\\'" . ztl-mode)) (provide 'ztl-mode) - -;; End of ztl-mode.el +;;; ztl-mode.el ends here