;;; baba-yaga-mode.el --- Major mode for Baba Yaga programming language -*- lexical-binding: t; -*- ;; Copyright (C) 2024 Your Name ;; Author: Your Name ;; Version: 1.0.0 ;; Keywords: languages, baba-yaga ;; URL: https://github.com/your-username/baba-yaga ;; This file is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 3, or (at your option) ;; any later version. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;;; Commentary: ;; Major mode for editing Baba Yaga programming language files. ;; Provides syntax highlighting, indentation, and basic editing features. ;;; Code: (defgroup baba-yaga nil "Major mode for Baba Yaga programming language." :group 'languages) (defcustom baba-yaga-indent-width 2 "Indentation width for Baba Yaga mode." :type 'integer :group 'baba-yaga) (defvar baba-yaga-mode-syntax-table (let ((table (make-syntax-table))) ;; Comments (modify-syntax-entry ?/ ". 124b" table) (modify-syntax-entry ?* ". 23" table) (modify-syntax-entry ?\n "> b" table) ;; Strings (modify-syntax-entry ?\" "\"" table) ;; Operators (modify-syntax-entry ?+ "." table) (modify-syntax-entry ?- "." table) (modify-syntax-entry ?* "." table) (modify-syntax-entry ?/ "." table) (modify-syntax-entry ?% "." table) (modify-syntax-entry ?= "." table) (modify-syntax-entry ?> "." table) (modify-syntax-entry ?< "." table) (modify-syntax-entry ?: "." table) (modify-syntax-entry ?. "." table) (modify-syntax-entry ?_ "w" table) ;; Brackets (modify-syntax-entry ?\( "()" table) (modify-syntax-entry ?\) ")(" table) (modify-syntax-entry ?\[ "(]" table) (modify-syntax-entry ?\] ")[" table) (modify-syntax-entry ?\{ "(}" table) (modify-syntax-entry ?\} "){" table) table) "Syntax table for Baba Yaga mode.") (defvar baba-yaga-keywords '("when" "then" "is" "Ok" "Err") "Keywords in Baba Yaga.") (defvar baba-yaga-with-keywords '("with" "rec") "With block keywords in Baba Yaga.") (defvar baba-yaga-types '("Bool" "Int" "Float" "String" "List" "Table" "Result" "Number") "Types in Baba Yaga.") (defvar baba-yaga-operators '("append" "set" "merge" "shape") "Operators in Baba Yaga.") (defvar baba-yaga-io-functions '("io.out" "io.in" "io.emit" "io.listen") "IO functions in Baba Yaga.") (defvar baba-yaga-functions '("map" "filter" "reduce" "pipe") "Built-in functions in Baba Yaga.") (defvar baba-yaga-font-lock-keywords `( ;; Comments - must come first to override other highlighting ("//.*$" . font-lock-comment-face) ("/\\*.*?\\*/" . font-lock-comment-face) ;; Keywords (,(regexp-opt baba-yaga-keywords 'words) . font-lock-keyword-face) ;; With block keywords (,(regexp-opt baba-yaga-with-keywords 'words) . font-lock-keyword-face) ;; With blocks ("\\bwith\\b\\s*\\(?:rec\\s*\\)?(" . font-lock-keyword-face) ("\\)\\s*->" . font-lock-keyword-face) ;; With block entries ("\\b\\([a-zA-Z_][a-zA-Z0-9_]*\\)\\s*:" 1 font-lock-variable-name-face) ;; Types (,(regexp-opt baba-yaga-types 'words) . font-lock-type-face) ;; Operators (,(regexp-opt baba-yaga-operators 'words) . font-lock-function-name-face) ;; IO functions (,(regexp-opt baba-yaga-io-functions 'words) . font-lock-preprocessor-face) ;; Built-in functions (,(regexp-opt baba-yaga-functions 'words) . font-lock-builtin-face) ;; Function definitions ("\\b\\([a-zA-Z_][a-zA-Z0-9_]*\\)\\s*:" 1 font-lock-function-name-face) ;; Operators ("\\(->\\|=>\\|\\.\\.\\|[=><+\\-*/%]\\)" . font-lock-keyword-face) ;; Assignment operator (":" . font-lock-keyword-face) ;; Wildcard ("\\b_\\b" . font-lock-constant-face) ;; Numbers ("\\b\\([0-9]+\\)\\b" 1 font-lock-constant-face) ("\\b\\([0-9]+\\.[0-9]+\\)\\b" 1 font-lock-constant-face) ;; Strings ("\"[^\"]*\"" . font-lock-string-face) ) "Font lock keywords for Baba Yaga mode.") (defvar baba-yaga-font-lock-syntactic-keywords `( ;; Comments - syntactic highlighting takes precedence ("//.*$" . font-lock-comment-face) ("/\\*.*?\\*/" . font-lock-comment-face) ) "Syntactic font lock keywords for Baba Yaga mode.") (defun baba-yaga-indent-line () "Indent current line in Baba Yaga mode." (interactive) (let ((indent-col 0)) (save-excursion (beginning-of-line) (cond ;; Indent after opening brackets ((looking-at ".*[{([]") (setq indent-col (+ (current-indentation) baba-yaga-indent-width))) ;; Dedent after closing brackets ((looking-at ".*[})\]]") (setq indent-col (max 0 (- (current-indentation) baba-yaga-indent-width)))) ;; Default indentation (t (setq indent-col (current-indentation))))) (indent-line-to indent-col))) (defvar baba-yaga-mode-map (let ((map (make-sparse-keymap))) (define-key map (kbd "RET") 'newline-and-indent) map) "Keymap for Baba Yaga mode.") ;;;###autoload (define-derived-mode baba-yaga-mode prog-mode "Baba Yaga" "Major mode for editing Baba Yaga programming language files." :group 'baba-yaga ;; Syntax table (set-syntax-table baba-yaga-mode-syntax-table) ;; Font lock (setq font-lock-defaults '(baba-yaga-font-lock-keywords)) (setq font-lock-syntactic-keywords baba-yaga-font-lock-syntactic-keywords) ;; Indentation (setq-local indent-line-function 'baba-yaga-indent-line) (setq-local tab-width baba-yaga-indent-width) ;; Comments (setq-local comment-start "// ") (setq-local comment-end "") (setq-local comment-start-skip "//+\\s-*") ;; Keymap (use-local-map baba-yaga-mode-map)) ;;;###autoload (add-to-list 'auto-mode-alist '("\\.baba\\'" . baba-yaga-mode)) (provide 'baba-yaga-mode) ;;; baba-yaga-mode.el ends here