121 lines
2.0 KiB
JavaScript
121 lines
2.0 KiB
JavaScript
module.exports = grammar({
|
|
name: 'lila',
|
|
|
|
word: $ => $.identifier,
|
|
|
|
rules: {
|
|
source_file: $ => repeat($._definition),
|
|
|
|
_definition: $ => choice(
|
|
$.function_definition
|
|
),
|
|
|
|
function_definition: $ => seq(
|
|
'func',
|
|
field('name', $.identifier),
|
|
field('parameters', $.parameters),
|
|
field('return_type', optional($._type)),
|
|
field('body', $.block),
|
|
),
|
|
|
|
parameters: $ => seq(
|
|
'(',
|
|
optional(seq(
|
|
repeat(seq($.parameter, ',')),
|
|
seq($.parameter, optional(',')),
|
|
)),
|
|
')',
|
|
),
|
|
|
|
parameter: $ => seq(
|
|
$.identifier,
|
|
' ',
|
|
$._type,
|
|
),
|
|
|
|
block: $ => seq(
|
|
'{',
|
|
repeat($._statement),
|
|
optional($._expression),
|
|
'}',
|
|
),
|
|
|
|
_statement: $ => choice(
|
|
$.return_statement,
|
|
$.assign_statement,
|
|
$.if_statement,
|
|
),
|
|
|
|
if_statement: $ => seq(
|
|
'if',
|
|
field('condition', $._expression),
|
|
field('body', $.block),
|
|
';'
|
|
),
|
|
|
|
if_expression: $ => seq(
|
|
'if',
|
|
field('condition', $._expression),
|
|
field('body', $.block),
|
|
field('else',
|
|
seq('else', choice(
|
|
$._expression,
|
|
$.block,
|
|
))
|
|
),
|
|
),
|
|
|
|
return_statement: $ => seq(
|
|
'return',
|
|
optional($._expression),
|
|
';',
|
|
),
|
|
|
|
assign_statement: $ => seq(
|
|
$.identifier,
|
|
'=',
|
|
$._expression,
|
|
';',
|
|
),
|
|
|
|
_expression: $ => choice(
|
|
$.unary_expression,
|
|
$.binary_expression,
|
|
$.if_expression,
|
|
$.boolean_literal,
|
|
$.integer_literal,
|
|
$.identifier,
|
|
),
|
|
|
|
unary_expression: $ => prec(10, choice(
|
|
seq('-', $._expression),
|
|
seq('!', $._expression),
|
|
)),
|
|
|
|
binary_expression: $ => choice(
|
|
prec.left(4, seq($._expression, '*', $._expression)),
|
|
prec.left(3, seq($._expression, '+', $._expression)),
|
|
prec.left(2, seq($._expression, '||', $._expression)),
|
|
prec.left(1, seq($._expression, '&&', $._expression)),
|
|
),
|
|
|
|
identifier: $ => /[a-z_]+[a-zA-Z0-9_]*/,
|
|
|
|
integer_literal: $ => /\d+/,
|
|
|
|
boolean_literal: $ => choice('true', 'false'),
|
|
|
|
//string_literal: $ => /"[]"/,
|
|
|
|
_type: $ => choice(
|
|
$.primitive_type,
|
|
),
|
|
|
|
primitive_type: $ => choice(
|
|
'bool',
|
|
'int',
|
|
'uint',
|
|
),
|
|
}
|
|
});
|