Created
February 11, 2022 09:26
-
-
Save Munksgaard/409a9168de705154d82a7f62208907fc to your computer and use it in GitHub Desktop.
futhark tree-sitter grammar
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| module.exports = grammar({ | |
| name: 'futhark', | |
| rules: { | |
| source_file: $ => repeat($.dec), | |
| identifier: $ => /_?[A-Za-z][A-Za-z0-9_\']*/, | |
| _quals: $ => repeat1( | |
| seq($.identifier, '.') | |
| ), | |
| qualid: $ => choice( | |
| $.identifier, | |
| seq($._quals, $.identifier) | |
| ), | |
| binop: $ => seq( | |
| $.opstartchar, | |
| repeat($.opchar) | |
| ), | |
| qualbinop: $ => choice( | |
| $.binop, | |
| seq($._quals, $.binop), | |
| seq('`', $.qualid, '`') | |
| ), | |
| fieldid: $ => choice( | |
| $._decimal, | |
| $.identifier | |
| ), | |
| opstartchar: $ => choice( | |
| '+', | |
| '-', | |
| '*', | |
| '/', | |
| '%', | |
| '=', | |
| '!', | |
| '>', | |
| '>', | |
| '|', | |
| '&', | |
| '^' | |
| ), | |
| opchar: $ => choice( | |
| $.opstartchar, | |
| '.' | |
| ), | |
| constructor: $ => seq( | |
| '#', | |
| $.identifier | |
| ), | |
| literal: $ => choice( | |
| $.intnumber, | |
| $.floatnumber, | |
| 'true', | |
| 'false' | |
| ), | |
| int_type: $ => choice( | |
| 'i8', | |
| 'i16', | |
| 'i32', | |
| 'i64', | |
| 'u8', | |
| 'u16', | |
| 'u32', | |
| 'u64' | |
| ), | |
| float_type: $ => choice( | |
| 'f16', | |
| 'f32', | |
| 'f64' | |
| ), | |
| intnumber: $ => seq( | |
| choice($._decimal, | |
| $._hexadecimal, | |
| $._binary), | |
| optional($.int_type) | |
| ), | |
| _decimal: $ => /[0-9][0-9_]*/, | |
| _hexadecimal: $ => /0[xX][0-9a-fA-F][0-9a-fA-F_]*/, | |
| _binary: $ => /0[bB][01][01_]*/, | |
| floatnumber: $ => seq( | |
| choice($._pointfloat, $._exponentfloat, $._hexadecimalfloat), | |
| optional($.float_type) | |
| ), | |
| _pointfloat: $ => seq( | |
| optional($._decimal), | |
| $._fraction | |
| ), | |
| _exponentfloat: $ => seq( | |
| choice($._decimal, $._pointfloat), | |
| $._exponent | |
| ), | |
| _hexadecimalfloat: $ => seq( | |
| /0[xX]/, | |
| $._hexintpart, | |
| $._hexfraction, | |
| /[pP][\+\-]?[0-9]+/ | |
| ), | |
| _fraction: $ => /\.[0-9][0-9_]*/, | |
| _hexintpart: $ => /[0-9a-fA-F][0-9a-fA-F_]*/, | |
| _hexfraction: $ => /.[0-9a-fA-F][0-9a-fA-F_]*/, | |
| _exponent: $ => /[eE][\+\-]?[0-9]+/, | |
| type: $ => choice( | |
| $.qualid, | |
| $.array_type, | |
| $.tuple_type, | |
| $.record_type, | |
| $.sum_type, | |
| // $.function_type, | |
| // $.type_application, | |
| // $.existential_size | |
| ), | |
| tuple_type: $ => choice( | |
| seq('(', ')'), | |
| seq('(', $.type, repeat1(seq(',', $.type)), ')') | |
| ), | |
| array_type: $ => seq( | |
| '[', | |
| optional($.dim), | |
| ']', | |
| $.type | |
| ), | |
| dim: $ => choice( | |
| $.qualid, | |
| $._decimal | |
| ), | |
| sum_type: $ => prec.left(seq( | |
| $.constructor, | |
| repeat($.type), | |
| repeat(seq('|', | |
| $.constructor, | |
| repeat($.type))) | |
| )), | |
| record_type: $ => choice( | |
| seq('{', '}'), | |
| seq('{', | |
| $.fieldid, | |
| ':', | |
| $.type, | |
| repeat(seq(',', | |
| $.fieldid, | |
| ':', | |
| $.type)), | |
| '}') | |
| ), | |
| type_application: $ => prec.left(3, choice( | |
| seq($.type, $.type_arg), | |
| seq('*', $.type) | |
| )), | |
| type_arg: $ => choice( | |
| seq('[', optional($.dim), ']'), | |
| $.type | |
| ), | |
| function_type: $ => seq( | |
| $.param_type, | |
| '->', | |
| $.type | |
| ), | |
| param_type: $ => prec(2, choice( | |
| $.type, | |
| seq('(', $.identifier, ':', $.type, ')') | |
| )), | |
| stringlit: $ => token( | |
| seq('"', repeat(choice(/[^"\\\n]/, seq("\\", /([^\n]|[0-9]+)/))), '"') | |
| ), | |
| charlit: $ => token( | |
| seq('\'', repeat(choice(/[^'\\\n]/, seq("\\", /([^\n]|[0-9]+)/))), '\'') | |
| ), | |
| existential_size: $ => seq( | |
| '?', | |
| repeat1(seq('[', $.identifier, ']')), | |
| '.', | |
| $.type | |
| ), | |
| dec: $ => choice( | |
| // $.val_bind, | |
| $.type_bind, | |
| // $.mod_bind, | |
| // $.mod_type_bind, | |
| // seq('open', $.mod_exp), | |
| // seq('import', $.stringlit), | |
| // seq('local', $.dec), | |
| // seq('#[', $.attr, ']', $.dec), | |
| ), | |
| val_bind: $ => choice( | |
| seq(choice('def', 'entry', 'let'), | |
| choice($.identifier, seq('(', $.binop, ')')), | |
| repeat($.type_param), | |
| repeat1($.pat), | |
| optional(seq(':', $.type)), | |
| '=', | |
| $.exp), | |
| seq(choice('def', 'entry', 'let'), | |
| $.pat, | |
| $.binop, | |
| $.pat, | |
| optional(seq(':', $.type)), | |
| '=', | |
| $.exp) | |
| ), | |
| type_bind: $ => seq( | |
| 'type', | |
| optional(choice('^', '~')), | |
| $.identifier, | |
| repeat($.type_param), | |
| '=', | |
| $.type | |
| ), | |
| type_param: $ => choice( | |
| seq('[', $.identifier, ']'), | |
| seq('\'', $.identifier), | |
| seq('\'~', $.identifier), | |
| seq('\'^', $.identifier) | |
| ), | |
| atom: $ => choice( | |
| $.literal, | |
| seq($.qualid, repeat(seq('.', $.fieldid))), | |
| $.stringlit, | |
| $.charlit, | |
| seq('(', ')'), | |
| seq('(', $.exp, ')', repeat(seq('.', $.fieldid))), | |
| seq('(', $.exp, repeat(seq(',', $.exp)), ')'), | |
| seq('{', '}'), | |
| seq('{', $.field, repeat(seq(',', $.field)), '}'), | |
| seq($.qualid, '[', $.index, repeat(seq(',', $.index)), ']'), | |
| seq('(', $.exp, ')', '[', $.index, repeat(seq(',', $.index)), ']'), | |
| seq($._quals, '.', '(', $.exp, ')'), | |
| seq('[', $.exp, repeat(seq(',', $.exp)), ']'), | |
| seq('[', $.exp, optional(seq('..', $.exp)), '...', $.exp, ']'), | |
| seq('(', $.qualbinop, ')'), | |
| seq('(', $.exp, $.qualbinop, ')'), | |
| seq('(', $.qualbinop, $.exp, ')'), | |
| seq('(', repeat1(seq('.', $.field)), ')'), | |
| seq('(', '.', '[', $.index, repeat(seq(',', $.index)), ']', ')'), | |
| ), | |
| exp: $ => choice( | |
| $.atom, | |
| seq($.exp, $.qualbinop, $.exp), | |
| seq($.exp, $.exp), | |
| seq('!', $.exp), | |
| seq('-', $.exp), | |
| seq($.constructor, repeat($.exp)), | |
| seq($.exp, ':', $.type), | |
| seq($.exp, ':>', $.type), | |
| seq($.exp, optional(seq('..', $.exp)), '...', $.exp), | |
| seq($.exp, optional(seq('..', $.exp)), '..<', $.exp), | |
| seq($.exp, optional(seq('..', $.exp)), '..>', $.exp), | |
| seq('if', $.exp, 'then', $.exp, 'else', $.exp), | |
| seq('let', repeat($.size), $.pat, '=', $.exp, 'in', $.exp), | |
| seq('let', $.identifier, '[', $.index, repeat(seq(',', $.index)), ']', '=', $.exp, 'in', $.exp), | |
| seq('let', $.identifier, repeat($.type_param), repeat1($.pat), optional(seq(':', $.type)), '=', $.exp, 'in', $.exp), | |
| seq('(', '\\', repeat1($.pat), optional(seq('=', $.exp)), $.loopform, 'do', $.exp), | |
| seq('#[', $.attr, ']', $.exp), | |
| seq('unsafe', $.exp), | |
| seq('assert', $.atom, $.atom), | |
| seq($.exp, 'with', '[', $.index, repeat(seq(',', $.index)), ']', '=', $.exp), | |
| seq($.exp, 'with', $.fieldid, repeat(seq('.', $.fieldid)), '=', $.exp), | |
| seq('match', $.exp, repeat1(seq('case', $.pat, '->', $.exp))), | |
| ), | |
| index: $ => $.literal, | |
| loopform: $ => seq( | |
| 'for', | |
| $.identifier, | |
| '<', | |
| $.exp, | |
| ), | |
| field: $ => choice( | |
| seq($.fieldid, '=', $.exp), | |
| $.identifier | |
| ), | |
| size: $ => seq( | |
| '[', $.identifier, ']' | |
| ), | |
| pat: $ => choice( | |
| $.identifier, | |
| $.pat_literal, | |
| '_', | |
| seq('(', ')'), | |
| seq('(', $.pat, ')'), | |
| seq('(', $.pat, repeat1(seq(',', $.pat)), ')'), | |
| seq('{', '}'), | |
| seq('{', $.fieldid, optional(seq('=', $.pat)), repeat(seq(',', $.fieldid, optional(seq('=', $.pat)))), '}'), | |
| seq($.constructor, repeat($.pat)), | |
| seq($.pat, ':', $.type), | |
| seq('#[', $.attr, ']', $.pat), | |
| ), | |
| pat_literal: $ => seq( | |
| optional('-'), | |
| $.intnumber, | |
| ), | |
| mod_bind: $ => seq( | |
| 'module', | |
| $.identifier, | |
| repeat($.mod_param), | |
| '=', | |
| optional(seq(':', $.mod_type_exp)), | |
| '=', | |
| $.mod_exp, | |
| ), | |
| mod_param: $ => seq( | |
| '(', | |
| $.identifier, | |
| ':', | |
| $.mod_type_exp, | |
| ')', | |
| ), | |
| mod_type_bind: $ => seq( | |
| 'module', | |
| 'type', | |
| $.identifier, | |
| '=', | |
| $.mod_type_exp, | |
| ), | |
| mod_exp: $ => choice( | |
| $.qualid, | |
| seq($.mod_exp, ':', $.mod_type_exp), | |
| seq('\\', '(', $.identifier, ':', $.mod_type_exp, ')', optional(seq(':', $.mod_type_exp)), '->', $.mod_exp), | |
| seq($.mod_exp, $.mod_exp), | |
| seq('(', $.mod_exp, ')'), | |
| seq('{', repeat($.dec), '}'), | |
| seq('import', $.stringlit), | |
| ), | |
| mod_type_exp: $ => choice( | |
| $.qualid, | |
| seq('{', repeat($.spec), '}'), | |
| seq($.mod_type_exp, 'with', $.qualid, repeat($.type_param), '=', $.type), | |
| seq('(', $.mod_type_exp, ')'), | |
| seq('(', $.identifier, ':', $.mod_type_exp, ')', '->', $.mod_type_exp), | |
| seq($.mod_type_exp, '->', $.mod_type_exp), | |
| ), | |
| spec: $ => choice( | |
| seq('val', $.identifier, repeat($.type_param), ':', $.spec_type), | |
| seq('val', $.binop, repeat($.type_param), ':', $.spec_type), | |
| seq('type', optional('^'), $.identifier, repeat($.type_param), '=', $.type), | |
| seq('type', optional('^'), $.identifier, repeat($.type_param)), | |
| seq('module', $.identifier, ':', $.mod_type_exp), | |
| seq('include', $.mod_type_exp), | |
| seq('#[', $.attr, ']', $.spec), | |
| ), | |
| spec_type: $ => choice( | |
| $.type, | |
| seq($.type, '->', $.spec_type), | |
| ), | |
| attr: $ => choice( | |
| $.identifier, | |
| $._decimal, | |
| seq($.identifier, '(', optional(seq($.attr, repeat(seq(',', $.attr)))), ')'), | |
| ), | |
| } | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment