Files
tree-sitter-vm/grammar.js

115 lines
2.0 KiB
JavaScript

module.exports = grammar({
name: 'vm',
rules: {
source_file: $ => repeat($._item),
_item: $ => choice(
$.command,
$.comment,
$._whitespace
),
// VM commands
command: $ => choice(
$.arithmetic_command,
$.memory_command,
$.program_flow_command,
$.function_command
),
// Arithmetic and logical commands
arithmetic_command: $ => choice(
'add', 'sub', 'neg',
'eq', 'gt', 'lt',
'and', 'or', 'not'
),
// Memory access commands
memory_command: $ => choice(
$.push_command,
$.pop_command
),
push_command: $ => seq(
'push',
$.memory_segment,
$.index
),
pop_command: $ => seq(
'pop',
$.memory_segment,
$.index
),
// Memory segments
memory_segment: $ => choice(
'argument', 'local', 'static', 'constant',
'this', 'that', 'pointer', 'temp'
),
// Program flow commands
program_flow_command: $ => choice(
$.label_command,
$.goto_command,
$.if_goto_command
),
label_command: $ => seq(
'label',
$.label_name
),
goto_command: $ => seq(
'goto',
$.label_name
),
if_goto_command: $ => seq(
'if-goto',
$.label_name
),
// Function calling commands
function_command: $ => choice(
$.function_declaration,
$.call_command,
$.return_command
),
function_declaration: $ => seq(
'function',
$.function_name,
$.local_vars_count
),
call_command: $ => seq(
'call',
$.function_name,
$.args_count
),
return_command: $ => 'return',
// Identifiers and numbers
index: $ => /\d+/,
local_vars_count: $ => /\d+/,
args_count: $ => /\d+/,
label_name: $ => /[A-Za-z_][A-Za-z0-9_.$:]*/,
function_name: $ => /[A-Za-z_][A-Za-z0-9_.$:]*/,
// Comments
comment: $ => token(seq('//', /.*/)),
// Whitespace
_whitespace: $ => /\s+/
},
extras: $ => [
/\s/,
$.comment
]
});