;;; zelyra-mode.el --- Major mode for editing Zelyra source code -*- lexical-binding: t; -*-

;; Author: Zelyra Team
;; Keywords: languages, zelyra
;; Version: 0.2.0

(defvar zelyra-mode-hook nil)

(defconst zelyra-keywords
  '("fn" "let" "mut" "if" "else" "return" "match" "for" "in" "while" "loop" "break" "continue"
    "struct" "enum" "table" "contract" "requires" "ensures" "invariant" "import" "export" "use"
    "type" "pub" "const" "async" "await" "sql" "html" "view" "route" "test"))

(defconst zelyra-types
  '("Int" "Float" "String" "Bool" "Void" "Option" "Result" "Array" "Map" "Table" "Some" "None" "Ok" "Err"))

(defconst zelyra-constants
  '("true" "false" "null" "nil"))

(defvar zelyra-font-lock-keywords
  `(
    (,(regexp-opt zelyra-keywords 'words) . font-lock-keyword-face)
    (,(regexp-opt zelyra-types 'words) . font-lock-type-face)
    (,(regexp-opt zelyra-constants 'words) . font-lock-constant-face)
    ("\\b\\(fn\\)\\s-+\\([a-zA-Z_][a-zA-Z0-9_]*\\)"
     (1 font-lock-keyword-face)
     (2 font-lock-function-name-face))
    ("\\b\\(struct\\|table\\|enum\\|contract\\)\\s-+\\([a-zA-Z_][a-zA-Z0-9_]*\\)"
     (1 font-lock-keyword-face)
     (2 font-lock-type-face))
    ("\"\\(?:\\\\[\0-\377]\\|[^\"]\\)*\"" . font-lock-string-face)
    ("//.*$" . font-lock-comment-face)
    ("/\\*\\(?:[^*]\\|\\*[^/]\\)*\\*/" . font-lock-comment-face)
    ("\\b[0-9]+\\(?:\\.[0-9]+\\)?\\b" . font-lock-number-face)
    ))

(defvar zelyra-mode-syntax-table
  (let ((st (make-syntax-table)))
    (modify-syntax-entry ?_ "w" st)
    (modify-syntax-entry ?/ ". 124b" st)
    (modify-syntax-entry ?* ". 23" st)
    (modify-syntax-entry ?\n "> b" st)
    (modify-syntax-entry ?\" "\"" st)
    st)
  "Syntax table for `zelyra-mode`.")

;;;###autoload
(define-derived-mode zelyra-mode prog-mode "Zelyra"
  "Major mode for editing Zelyra source files."
  :syntax-table zelyra-mode-syntax-table
  (setq-local comment-start "// ")
  (setq-local comment-end "")
  (setq-local font-lock-defaults '(zelyra-font-lock-keywords))
  (setq-local tab-width 4)
  (setq-local indent-tabs-mode nil))

;;;###autoload
(add-to-list 'auto-mode-alist '("\\.zyl\\'" . zelyra-mode))

(provide 'zelyra-mode)
;;; zelyra-mode.el ends here
