Skip to content

vim-jp/vim-vim9parser

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

39 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Vim9 Script Parser

A high-performance parser for Vim9script that generates Abstract Syntax Trees (AST).

Project Goal

Enable Vim9script support in vim-language-server by providing:

  1. Accurate Vim9 syntax parsing - Complete AST generation for all vim9script constructs
  2. Language Server integration - Symbol tables and completion support for LSP clients
  3. Cooperative parsing - Work alongside vim-vimlparser in a dispatcher pattern for hybrid VimL/Vim9 files

Vision: LSP Completion Flow

vim-language-server
    ↓
Detect language (vim9script vs legacy VimL)
    ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”œβ”€ Legacy VimL ──────→ vim-vimlparser       β”‚
└─ Vim9script ───────→ vim-vim9parser       β”‚
                      (this project)         β”‚
                      ↓                      β”‚
                      AST generation        β”‚
                      ↓                      β”‚
                      Symbol Table          β”‚
                      ↓                      β”‚
                      Completion candidates β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Supported Languages

  • Vim9script - Modern Vim scripting language (with :vim9script declaration)

Usage

Parse Vim9 Script

let p = vim9parser#Import()
let lines = ['var x = 1 + 2']
let reader = p.StringReader.new(lines)
let parser = p.Vim9Parser.new()
let ast = parser.Parse(reader)

Compile to AST Representation

let compiler = p.Compiler.new()
echo join(compiler.Compile(ast), "\n")

Compile to JavaScript

let js_compiler = p.JSCompiler.new()
let js_lines = js_compiler.Compile(ast)
echo join(js_lines, "\n")

Note: Full JavaScript code generation for the entire parser is currently not automated due to vim9script execution limitations in batch mode. The JSCompiler class is available for API-level transpilation. See js/jscompiler.vim for manual compilation if needed.

Vim9Script Extensions

Compared to legacy VimL, vim9script adds:

  • Type annotations for variables and functions
  • Classes and objects
  • New syntax: var, const, def, class
  • No more : prefix for options access
  • import and export statements
  • Lambda expressions: (x) => x * 2
  • Ternary operator: condition ? true_val : false_val
  • Bitwise operators: <<, >>, &, |, ^

Supported Features

Declarations

  • var - variable declarations with optional type annotations
  • const - constant declarations
  • def / enddef - function definitions with parameter and return types
  • class / endclass - class definitions

Control Flow

  • if / elseif / else / endif
  • while / endwhile
  • for / endfor
  • try / catch / finally / endtry
  • return

Expressions

  • Arithmetic operators: +, -, *, /, %
  • Compound assignment operators: +=, -=, *=, /=, %=
  • Comparison operators: ==, !=, <, >, <=, >=
  • Logical operators: &&, ||, !
  • Bitwise operators: &, |, ^, <<, >>
  • Ternary operator: condition ? true_expr : false_expr
  • Member access: obj.field
  • Array/Dict subscript: arr[index], dict[key]
  • Function call: func(arg1, arg2)
  • Lambda expressions: (x, y) => x + y
  • String interpolation: $"Hello, {name}!"
  • List comprehensions: [for i in range(10): i * i], [for i in list if i > 5: i]
  • Destructuring assignment: var [a, b] = [1, 2], var {x, y} = dict

Literals

  • Numbers: 42, 3.14
  • Strings: "hello", 'world'
  • Booleans: true, false
  • Null: null
  • Lists: [1, 2, 3]
  • Dictionaries: {key: value}

Module System

  • import statements
  • export declarations

Recently Implemented Features

Recently Added (Latest)

  • JavaScript Compiler: Generate JavaScript code from Vim9 AST
    • JSCompiler class for transpiling to JavaScript
    • Support for variables, functions, classes, control flow
    • List comprehensions compile to JavaScript .map() and .filter()
    • Lambda expressions compile to arrow functions
  • Line Continuation: Both explicit \ continuation and operator-based continuation across lines
    • var x = 1 +\ (explicit backslash)
    • var x = 1 + (operator-based, continues to next line)
    • Function calls and subscripts continue naturally across lines
  • Compound Assignment Operators: +=, -=, *=, /=, %= are now fully supported
  • String Interpolation: $"Hello, {name}!" syntax is now parsed (preserves interpolation expressions)
  • Error Recovery: Parser now tracks errors without throwing immediately, allowing for multiple error reporting
  • Destructuring Assignment: Both list var [a, b] = [1, 2] and dict var {x, y} = dict patterns
  • List Comprehensions: [for i in range(10): i * i] and with filters [for i in list if i > 5: i]

Bug Fixes (Latest Session)

  • Syntax Error Fixes: Fixed multiple critical parsing errors in vim9parser.vim
    • Fixed class definition indentation and missing enddef statements
    • Fixed undefined variable references in type error messages
    • Fixed empty throw statement (now includes exception value)
    • Added proper export keywords to parser classes
  • Type System: Corrected ParseType/ParseTypeString confusion throughout codebase
    • Type annotations now properly distinguished from type declarations
    • Generic type parsing (e.g., list<string>) now works correctly
  • New Operators: Added support for additional Vim9 operators
    • Method chaining with -> operator
    • Regex matching operators =~ and !~
  • Advanced Features: Implemented missing Vim9 language features
    • Default parameter values: def func(x: number = 0)
    • String/list slicing: str[start:end]
    • Proper handling of method calls and chaining

Known Limitations and TODO

Unsupported Syntax

Type Aliases

type MyList = list<string>  # Not supported

Interfaces

interface Drawable  # Not supported
  def Draw(): void
endinterface

Enum (Partial Support)

enum Color  # Token recognized but full semantics not implemented
  RED
  GREEN
  BLUE
endenum

Decorators/Annotations

@cached  # Not supported
def MyFunc(): void
enddef

Semantic Features (Critical for LSP)

  • Symbol Table: ⚠️ MISSING - No tracking of defined functions/variables/classes (REQUIRED FOR COMPLETION)
  • Scope Resolution: Not tracked - Variable/function scoping is not analyzed
  • Type Checking: Type annotations are parsed but not validated
  • Undefined Reference Detection: References to undefined symbols are not flagged

Parsing Limitations

  • Incremental Parsing: Not supported - full file re-parse on every change
  • Hybrid Files: Limited support for files that mix legacy VimL and vim9script
  • Error Handling: Limited error messages; parser stops at first syntax error
  • Comment Handling: βœ… FIXED - Comments after statements now properly skipped via SkipComments()

JavaScript Compilation Status

  • StringReader: βœ… Complete - Full implementation in js/vim9parser.js
  • Vim9Tokenizer: βœ… Complete - All token types and keyword detection
  • Vim9Parser: ⚠️ Partial - Basic class structure, var/const/def/class/import/export parsing
    • ❌ Missing: Expression parsing (binary operators, function calls, subscripts)
    • ❌ Missing: Statement parsing (if/while/for/try blocks)
    • ❌ Missing: Type string parsing
    • ❌ Missing: Full lambda and comprehension support
  • JSCompiler: βœ… Complete - Compiles Vim9 AST to JavaScript code
    • βœ… Supports: var/const declarations, function definitions, classes
    • βœ… Supports: Arithmetic operators, comparisons, logical operators
    • βœ… Supports: List literals and comprehensions
    • ❌ Missing: Comment preservation in output
    • ❌ Missing: Type annotation translation

Future Work (Prioritized for LSP Goal)

Phase 1: LSP Foundation (CRITICAL)

  1. Symbol Table Implementation ⚠️ HIGHEST PRIORITY

    • REQUIREMENT: Must be compatible with vim-vimlparser Buffer interface
    • Implement Vim9Buffer class with same methods as vim-vimlparser's Buffer:
      • getGlobalFunctions(): Record<string, IFunction[]>
      • getScriptFunctions(): Record<string, IFunction[]>
      • getGlobalIdentifiers(): Record<string, IIdentifier[]>
      • getLocalIdentifiers(): Record<string, IIdentifier[]>
      • getFunctionLocalIdentifierItems(line): CompletionItem[]
    • Extract function definitions (name, args, startLine, startCol, endLine, endCol, range)
    • Extract variable declarations with scope (g:, s:, l:, a:, b:)
    • Track class/import definitions for vim9script
    • Why: vim-language-server expects this exact interface; without it, dispatcher pattern fails
    • See: ANALYSIS.md for detailed interface specification
  2. Scope Analysis

    • Function-local scope vs script-level scope
    • Parameter binding in function context
    • Closure support for nested functions
    • Why: Avoid suggesting symbols from wrong scope
  3. Public LSP Interface

    • Standardized API for vim-language-server integration
    • Return format compatible with LSP (SymbolInformation, CompletionItem)
    • Position-to-symbol lookup capability
    • Why: LSP clients need consistent interface
  4. Test Coverage for LSP Scenarios

    • Completion in function bodies
    • Completion with imported symbols
    • Hover information for variables/functions
    • Go-to-definition support
    • Why: Verify LSP integration works end-to-end

Phase 2: Advanced Features

  • Incremental parsing support for large files
  • Hybrid file support (VimL + Vim9 in same file)
  • Dict comprehensions: {for k in list: k: value}
  • Full enum support with proper semantics
  • Type aliases: type MyList = list<string>

Phase 3: Quality & Performance

  • Extended test coverage
  • Performance optimization for large files
  • Better error messages and error recovery
  • Code formatter based on AST

Phase 4: JavaScript/TypeScript Output

  • Complete Vim9Parser class export to JavaScript
  • Expression and statement parsing in JavaScript parser
  • Type annotation translation to TypeScript types
  • Comment preservation in compiled output
  • JSCompiler enhancements for complex expressions
  • Node.js module generation with proper exports

Phase 5: Optional Enhancements

  • Type checking system
  • Interface support
  • Language Server Protocol reference implementation
  • Production-grade JavaScript transpilation

Contributing

Contributions are welcome! Please feel free to submit pull requests for:

  • Bug fixes
  • New feature implementations
  • Test cases
  • Documentation improvements

Architecture & Integration

Cooperative Parsing with vim-vimlparser

This parser is designed to work alongside vim-vimlparser in a dispatcher pattern:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  vim-language-server (dispatcher)   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚
             β”œβ”€ Detect file type
             β”‚
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”
    β”‚                β”‚
    v                v
vim9script      Legacy VimL
    β”‚                β”‚
    v                v
vim-vim9parser  vim-vimlparser
    β”‚                β”‚
    v                v
vim9 AST       VimL AST
    β”‚                β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
             v
    Language Service Features
    (Completion, Hover, Go-to-def, etc.)

Implementation Strategy

  1. Detection: Check for :vim9script at file start or in first few lines
  2. Delegation: Route to appropriate parser
  3. Symbol Integration: Merge symbol tables from both parsers
  4. Unified LSP: Return consistent LSP responses regardless of source language

Current Status by Component

Component Status Notes
Vim9 Parsing βœ… Complete All major syntax supported in Vim9script
vim9 AST βœ… Complete Node types defined (200+ node types)
JavaScript Output ⚠️ Partial StringReader, Tokenizer, basic Parser exported
JSCompiler βœ… Complete Converts Vim9 AST to JavaScript
Symbol Table ❌ MISSING CRITICAL for LSP
Scope Analysis ❌ MISSING CRITICAL for Completion
LSP Interface ❌ MISSING Needs standardization
vim-vimlparser integration πŸš€ Pending Requires dispatcher in vim-language-server

Testing

The parser includes comprehensive test coverage:

  • Syntax parsing tests - All major vim9script constructs
  • Expression tests - Operators, precedence, types
  • Feature tests - Line continuation, comprehensions, destructuring, etc.
  • Compiler tests - JavaScript code generation

Run all tests: make test

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published