Skip to content

Instantly share code, notes, and snippets.

@dahu
Created July 31, 2012 13:35
Show Gist options
  • Select an option

  • Save dahu/3217078 to your computer and use it in GitHub Desktop.

Select an option

Save dahu/3217078 to your computer and use it in GitHub Desktop.
Simple VimL AST walker with visitor
" VimL Example of Walking an AST
" Barry Arthur, 2012 07 31
" simple AST walker with a visitor, applied to each node in the tree
func! Walk(ast, visitor)
return type(a:ast) == type([]) ? call(a:visitor[a:ast[0]], [a:ast[1]], a:visitor) : a:ast
endfunc
" one way to define a VimLPOO object
let eval_visitor = {}
func! eval_visitor.add(args) dict
return Walk(a:args[0], self) + Walk(a:args[1], self)
endfunc
func! eval_visitor.mul(args) dict
return Walk(a:args[0], self) * Walk(a:args[1], self)
endfunc
" alternative (more verbose) VimLPOO
function! PrintVisitor()
let visitor = {}
func visitor.add(args) dict
let op1 = Walk(a:args[0], self)
let op2 = Walk(a:args[1], self)
echo "Adding " . op1 . '+' . op2
return op1 + op2
endfunc
func visitor.mul(args) dict
let op1 = Walk(a:args[0], self)
let op2 = Walk(a:args[1], self)
echo "Multiplying " . op1 . '*' . op2
return op1 * op2
endfunc
return visitor
endfunction
" these AST are logical reductions of the parse tree generated
" by VimPEG for the given arithmetic expressions
" 2 * 3 + 1
let ast_1 = ['add', [['mul', [2, 3]], 1]]
" 2 * 3 * 2 + 1
let ast_2 = ['add', [['mul', [['mul', [2, 3]], 2]], 1]]
for ast in [ast_1, ast_2]
echo "Printer:"
echo Walk(ast, PrintVisitor())
echo "Evaluator"
echo Walk(ast, eval_visitor)
endfor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment