Skip to content

Instantly share code, notes, and snippets.

@susliko
Created December 5, 2021 18:17
Show Gist options
  • Save susliko/371d1217836ee272e18703d7caba62d9 to your computer and use it in GitHub Desktop.
Save susliko/371d1217836ee272e18703d7caba62d9 to your computer and use it in GitHub Desktop.
module.exports = grammar({
name: 'pluscal',
extras: $ => [
/\s|\r?\n/
],
rules: {
pcal_source_file: $ => $.pcal_algorithm,
pcal_algorithm: $ => seq(
choice('--algorithm', seq('--fair', 'algorithm')),
$.pcal_name,
optional($.pcal_var_decls),
optional($.pcal_definitions),
repeat($.pcal_macro),
repeat($.pcal_procedure),
choice($.pcal_algorithm_body, repeat1($.pcal_process)),
'end',
'algorithm'
),
pcal_stmt: $ => seq(
optional(seq($.pcal_label, ':', optional(choice('+', '-')))),
$.pcal_unlabeled_stmt
),
pcal_definitions: $ => seq(
'define',
$.pcal_defs,
'end',
'define',
optional(';')
),
pcal_macro: $ => seq(
'macro',
$.pcal_name,
'(',
optional(seq($.pcal_variable, repeat(seq(',', $.pcal_variable)))),
')',
$.pcal_algorithm_body,
'end',
'macro',
optional(';')
),
pcal_procedure: $ => seq(
'procedure',
$.pcal_name,
'(',
optional(seq($.pcal_p_var_decl, repeat(seq(',', $.pcal_p_var_decl)))),
')',
optional($.pcal_p_var_decls),
$.pcal_algorithm_body,
'end',
'procedure',
optional(';')
),
pcal_process: $ => seq(
optional(seq('fair', optional('+'))),
'process',
$.pcal_name,
choice('=', '\in'),
$.pcal_expr,
optional($.pcal_var_decls),
$.pcal_algorithm_body,
'end',
'process',
optional(';')
),
pcal_var_decls: $ => seq(
choice('variable', 'variables'),
repeat1($.pcal_var_decl)
),
pcal_var_decl: $ => seq(
$.pcal_variable,
optional(seq(choice('=', '\in'), $.pcal_expr)),
choice(';', ',')
),
pcal_p_var_decls: $ => seq(
choice('variable', 'variables'),
repeat1(seq($.pcal_p_var_decl, choice(';', ',')))
),
pcal_p_var_decl: $ => seq(
$.pcal_variable,
optional(seq('=', $.pcal_expr))
),
pcal_algorithm_body: $ => seq(
'begin',
repeat1($.pcal_stmt)
),
pcal_unlabeled_stmt: $ => choice(
$.pcal__assign,
$.pcal__if,
$.pcal__while,
$.pcal_either,
$.pcal__with,
$.pcal__await,
$.pcal_print,
$.pcal_assert,
$.pcal_skip,
$.pcal__return,
$.pcal__goto,
$.pcal_call,
$.pcal_macro_call,
),
pcal__assign: $ => seq(
$.pcal_lhs,
':=',
$.pcal_expr,
repeat(seq('||', $.pcal_lhs, ':=', $.pcal_expr))
),
pcal_lhs: $ => seq(
$.pcal_variable,
repeat(choice(
seq('[', $.pcal_expr, repeat(seq(',', $.pcal_expr)), ']'),
seq('.', $.pcal_field)
))
),
pcal__if: $ => seq(
'if',
$.pcal_expr,
'then',
repeat1($.pcal_stmt),
repeat(seq('elsif', $.pcal_expr, 'then', repeat1($.pcal_stmt))),
optional(seq('else', repeat1($.pcal_stmt))),
'end',
'if',
';'
),
pcal__while: $ => seq(
'while',
$.pcal_expr,
'do',
repeat1($.pcal_stmt),
'end',
'while',
';'
),
pcal_either: $ => seq(
'either',
repeat1($.pcal_stmt),
repeat1(seq('or', repeat1($.pcal_stmt))),
'end',
'either',
';'
),
pcal__with: $ => seq(
'with',
repeat1(seq(
$.pcal_variable,
choice('=', '\in'),
$.pcal_expr,
choice(',', ';')
)),
'do',
repeat1($.pcal_stmt),
'end',
'with',
';'
),
pcal__await: $ => seq(
choice('await', 'when'),
$.pcal_expr,
';'
),
pcal_print: $ => seq('print', $.pcal_expr, ';'),
pcal_assert: $ => seq('assert', $.pcal_expr, ';'),
pcal_skip: $ => seq('skip', ';'),
pcal__return: $ => seq('return', ';'),
pcal__goto: $ => seq('goto', $.pcal_label, ';'),
pcal_call: $ => seq('call', $.pcal_macro_call),
pcal_macro_call: $ => seq(
$.pcal_name,
'(',
optional(seq(
$.pcal_expr,
repeat(
seq(
',',
$.pcal_expr
)
)
)),
')',
';'
),
// pcal_TODO: proper definitions below
pcal_variable: $ => /\w*[A-Za-z]\w*/,
pcal_field: $ => /\w*[A-Za-z]\w*/,
pcal_name: $ => /\w*[A-Za-z]\w*/,
pcal_label: $ => /\w*[A-Za-z]\w*/,
pcal_expr: $ => /.*/,
pcal_defs: $ => /.*/,
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment