mirror of
https://github.com/soconnor0919/tree-sitter-hack-assembly.git
synced 2026-02-04 15:56:30 -05:00
98 lines
2.0 KiB
JavaScript
98 lines
2.0 KiB
JavaScript
module.exports = grammar({
|
|
name: 'hack_assembly',
|
|
|
|
rules: {
|
|
source_file: $ => repeat($._item),
|
|
|
|
_item: $ => choice(
|
|
$.a_instruction,
|
|
$.c_instruction,
|
|
$.label_declaration,
|
|
$.comment,
|
|
$._whitespace
|
|
),
|
|
|
|
// A-instruction: @value or @symbol
|
|
a_instruction: $ => seq(
|
|
'@',
|
|
choice(
|
|
$.constant,
|
|
$.symbol
|
|
)
|
|
),
|
|
|
|
// C-instruction: [dest=]comp[;jump]
|
|
c_instruction: $ => seq(
|
|
optional(seq($.dest, '=')),
|
|
$.comp,
|
|
optional(seq(';', $.jump))
|
|
),
|
|
|
|
// Label declaration: (SYMBOL)
|
|
label_declaration: $ => seq(
|
|
'(',
|
|
$.symbol,
|
|
')'
|
|
),
|
|
|
|
// Constants: -32768 to 32767 (16-bit signed)
|
|
constant: $ => /-?\d+/,
|
|
|
|
// Symbols: letters, digits, _, ., $, : (not starting with digit)
|
|
symbol: $ => choice(
|
|
$.predefined_symbol,
|
|
$.user_symbol
|
|
),
|
|
|
|
// Predefined symbols
|
|
predefined_symbol: $ => choice(
|
|
// Virtual registers R0-R15
|
|
/R(0|1[0-5]|[2-9])/,
|
|
// Special symbols
|
|
'SP', 'LCL', 'ARG', 'THIS', 'THAT',
|
|
// I/O symbols
|
|
'SCREEN', 'KBD'
|
|
),
|
|
|
|
// User-defined symbols
|
|
user_symbol: $ => /[A-Za-z_.$:][A-Za-z0-9_.$:]*/,
|
|
|
|
// Destination field
|
|
dest: $ => choice(
|
|
'M', 'D', 'MD', 'A', 'AM', 'AD', 'AMD'
|
|
),
|
|
|
|
// Computation field
|
|
comp: $ => choice(
|
|
// Zero and one
|
|
'0', '1', '-1',
|
|
// D register operations
|
|
'D', '!D', '-D', 'D+1', 'D-1',
|
|
// A register operations
|
|
'A', '!A', '-A', 'A+1', 'A-1',
|
|
// M register operations
|
|
'M', '!M', '-M', 'M+1', 'M-1',
|
|
// Two operand operations with D and A
|
|
'D+A', 'D-A', 'A-D', 'D&A', 'D|A',
|
|
// Two operand operations with D and M
|
|
'D+M', 'D-M', 'M-D', 'D&M', 'D|M'
|
|
),
|
|
|
|
// Jump field
|
|
jump: $ => choice(
|
|
'JGT', 'JEQ', 'JGE', 'JLT', 'JNE', 'JLE', 'JMP'
|
|
),
|
|
|
|
// Comments
|
|
comment: $ => token(seq('//', /.*/)),
|
|
|
|
// Whitespace
|
|
_whitespace: $ => /\s+/
|
|
},
|
|
|
|
extras: $ => [
|
|
/\s/,
|
|
$.comment
|
|
]
|
|
});
|