diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-10-05 00:26:05 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-10-05 01:00:50 +0200 |
| commit | a9f6cfb6a8b6d38057faca067c015da1f72cf62d (patch) | |
| tree | db4e740db52df8be62bda5d2101603910107b7d4 | |
| parent | 5b7f983b3912a8d0fbeaf22f7fe0e2c5f1e0ff01 (diff) | |
| download | elna-a9f6cfb6a8b6d38057faca067c015da1f72cf62d.tar.gz | |
Add a treesitter grammar
40 files changed, 2901 insertions, 0 deletions
@@ -2,3 +2,7 @@ build/ jit/ .cache/ /compile_commands.json + +*.o +*.so +node_modules/ diff --git a/rakelib/treesitter.rake b/rakelib/treesitter.rake new file mode 100644 index 0000000..7e48865 --- /dev/null +++ b/rakelib/treesitter.rake @@ -0,0 +1,65 @@ +# This Source Code Form is subject to the terms of the Mozilla Public License, +# v. 2.0. If a copy of the MPL was not distributed with this file, You can +# obtain one at https://mozilla.org/MPL/2.0/. -} +# frozen_string_literal: true + +require 'rake/clean' + +TREE_SITTER_BUILD = Pathname.new 'build/tree-sitter' +TREE_SITTER_TREE = Pathname.new 'tools/tree-sitter' + +CLEAN.include TREE_SITTER_BUILD + +namespace :ts do + directory TREE_SITTER_BUILD + + desc 'Generate a parser' + task :generate do + cp_r TREE_SITTER_TREE, TREE_SITTER_BUILD unless TREE_SITTER_BUILD.directory? + + sh 'tree-sitter', 'generate', + '--output', (TREE_SITTER_BUILD + 'src').to_path, + (TREE_SITTER_TREE + 'grammar.js').to_path + + build_test = TREE_SITTER_BUILD / 'test' + build_corpus = build_test / 'corpus' + + rm_r build_corpus + File.symlink (TREE_SITTER_TREE / 'test' / 'corpus').relative_path_from(build_test), build_corpus + end + + file "#{TREE_SITTER_BUILD}/parser.so" => "#{TREE_SITTER_BUILD}/src/parser.c" do |t| + sh 'build/host/install/bin/gcc', '-O2', '-Wall', '-fPIC', '-shared', + t.source, '-o', t.name + end + + desc 'Synchronize tree-sitter tests with the compilable tests' + task :sync do + corpus = TREE_SITTER_TREE / 'test' / 'corpus' + rm_r corpus + mkdir_p corpus + + FileList['testsuite/compilable/*.elna'].map do |test| + target = corpus / Pathname.new(test).basename.sub_ext('.txt').basename + + File.open target, 'w' do |output| + output.write "==================\n" + output.write(File.basename(test, '.elna') + "\n") + output.write "==================\n\n" + output.write File.read(test) + output.write "\n---\n\n" + end + end + sh 'tree-sitter', 'test', '--update', + '--grammar-path', TREE_SITTER_BUILD.to_path + end + + desc 'Test tree-sitter' + task :test do + sh 'tree-sitter', 'test', '--grammar-path', TREE_SITTER_BUILD.to_path + end +end + +desc 'Build a tree-sitter parser' +task ts: 'ts:generate' +task ts: "#{TREE_SITTER_BUILD}/parser.so" diff --git a/tools/tree-sitter/grammar.js b/tools/tree-sitter/grammar.js new file mode 100644 index 0000000..b7129df --- /dev/null +++ b/tools/tree-sitter/grammar.js @@ -0,0 +1,572 @@ +const PREC = { + ASSIGNMENT: 1, + LOGICAL: 2, // or, &, xor + RELATIONAL: 3, // =, <>, <, >, <=, >= + SHIFT: 4, // <<, >> + ADD: 5, // +, - + MULTIPLY: 6, // *, /, % + UNARY: 7, // @, ~, -, + + CALL: 8, // function calls + POSTFIX: 9, // ., [], [to], ^ +}; + +function commaSep1(rule) { + return seq(rule, repeat(seq(',', rule))); +} + +function sep1(rule, separator) { + return seq(rule, repeat(seq(separator, rule))); +} + +module.exports = grammar({ + name: 'elna', + + extras: $ => [ + /\s/, + $.comment, + ], + + word: $ => $.identifier, + + conflicts: $ => [ + [$._statement, $._expression], + ], + + rules: { + source_file: $ => seq( + choice( + $.module_declaration, + $.program_declaration, + ), + optional($.trailing_content), + ), + + trailing_content: $ => token(seq(/[^\s]/, repeat(/[\s\S]/))), + + comment: $ => token(seq('(*', /[^*]*\*+([^)*][^*]*\*+)*/, ')')), + + identifier: $ => /[A-Za-z_][A-Za-z0-9_]*/, + + trait: $ => token(seq('#', /[A-Za-z_][A-Za-z0-9_]*/)), + + module_declaration: $ => seq( + 'module', + repeat($._declaration), + 'end', + '.', + ), + + program_declaration: $ => seq( + 'program', + '(', + optional(field('parameters', commaSep1($.identifier))), + ')', + choice( + seq( + repeat1($._declaration), + optional(seq('begin', optional($._statements))), + ), + seq('begin', optional($._statements)), + optional($._statements), + ), + 'end', + '.', + ), + + _declaration: $ => choice( + $.import_declaration, + $.type_section, + $.var_section, + $.threadvar_section, + $.procedure_declaration, + ), + + import_declaration: $ => seq( + 'import', + commaSep1($.import_path), + ), + + import_path: $ => seq( + $.identifier, + repeat(seq('.', $.identifier)), + ), + + type_section: $ => seq( + 'type', + repeat1(seq($.type_declaration, optional(';'))), + ), + + type_declaration: $ => seq( + field('name', $.identifier_definition), + optional(field('type_parameters', $.type_parameters)), + '=', + field('type', choice($._type_expression, 'extern')), + ), + + identifier_definition: $ => seq( + field('name', $.identifier), + optional(field('exported', '*')), + repeat($.attribute), + ), + + attribute: $ => seq( + '#{', + field('name', $.identifier), + optional(field('arguments', commaSep1($._expression))), + '}', + ), + + type_parameters: $ => seq( + '#[', + commaSep1($.identifier), + ']', + ), + + var_section: $ => seq( + 'var', + repeat1(seq($.variable_declaration, optional(';'))), + ), + + threadvar_section: $ => seq( + 'threadvar', + repeat1(seq($.variable_declaration, optional(';'))), + ), + + variable_declaration: $ => seq( + field('names', commaSep1($.identifier_definition)), + ':', + field('type', $._type_expression), + optional(seq( + ':=', + field('value', choice($._expression, 'extern')), + )), + ), + + procedure_declaration: $ => seq( + 'proc', + field('name', $.identifier_definition), + optional(field('type_parameters', $.type_parameters)), + field('parameters', $.parameter_list), + repeat($.attribute), + optional(seq('->', field('return_type', $._type_expression))), + field('body', choice( + $.procedure_body, + 'extern', + )), + ), + + parameter_list: $ => seq( + '(', + optional(seq( + $.field_declaration, + repeat(seq(';', $.field_declaration)), + optional(';'), + )), + ')', + ), + + field_declaration: $ => seq( + field('names', commaSep1($.identifier_definition)), + ':', + field('type', $._type_expression), + ), + + procedure_body: $ => seq( + optional($.block), + $.return_clause, + ), + + return_clause: $ => seq( + 'return', + optional(field('value', $._expression)), + ), + + block: $ => choice( + seq( + $.var_section, + optional(seq('begin', optional($._statements))), + ), + seq( + 'begin', + optional($._statements), + ), + $._statements, + ), + + _statements: $ => repeat1(choice($._statement, ';')), + + _statement: $ => choice( + $.assignment_statement, + $.call_expression, + $.if_statement, + $.while_statement, + $.repeat_statement, + $.for_statement, + $.defer_statement, + $.block_statement, + $.break_statement, + $.case_statement, + ), + + assignment_statement: $ => prec.right(PREC.ASSIGNMENT, seq( + field('left', $._expression), + ':=', + field('right', $._expression), + )), + + if_statement: $ => seq( + 'if', + field('condition', $._expression), + 'then', + field('consequence', optional($.block)), + repeat($.elsif_clause), + optional($.else_clause), + 'end', + ), + + elsif_clause: $ => seq( + 'elsif', + field('condition', $._expression), + 'then', + field('consequence', optional($.block)), + ), + + else_clause: $ => seq( + 'else', + field('body', optional($.block)), + ), + + while_statement: $ => seq( + 'while', + field('condition', $._expression), + 'do', + field('body', optional($.block)), + repeat($.while_elsif_clause), + 'end', + ), + + while_elsif_clause: $ => seq( + 'elsif', + field('condition', $._expression), + 'do', + field('body', optional($.block)), + ), + + repeat_statement: $ => seq( + 'repeat', + field('body', optional($.block)), + 'until', + field('condition', $._expression), + ), + + for_statement: $ => seq( + 'for', + field('variable', $.identifier), + 'of', + field('iterable', $._expression), + optional(seq('with', field('counter', $.identifier))), + 'do', + field('body', optional($.block)), + 'end', + ), + + defer_statement: $ => seq( + 'defer', + field('body', optional($.block)), + 'end', + ), + + block_statement: $ => seq( + 'block', + field('name', $.identifier), + field('body', optional($.block)), + 'end', + ), + + break_statement: $ => seq( + 'break', + field('label', $.identifier), + ), + + case_statement: $ => seq( + 'case', + field('value', $._expression), + 'of', + optional('|'), + sep1($.case_arm, '|'), + optional($.else_clause), + 'end', + ), + + case_arm: $ => seq( + field('patterns', commaSep1($._expression)), + ':', + field('body', optional($.block)), + ), + + // Type expressions + _type_expression: $ => choice( + $.array_type, + $.slice_type, + $.const_type, + $.pointer_type, + $.record_type, + $.procedure_type, + $.enum_type, + $.generic_type, + $.identifier, + ), + + array_type: $ => prec(1, seq( + '[', + field('length', $._expression), + ']', + field('element_type', $._type_expression), + )), + + slice_type: $ => prec(1, seq( + '[', + ']', + field('element_type', $._type_expression), + )), + + const_type: $ => seq( + 'const', + field('type', $._type_expression), + ), + + pointer_type: $ => prec.right(seq( + '^', + field('type', $._type_expression), + )), + + record_type: $ => seq( + 'record', + optional(seq('(', field('base', choice($.identifier, $.generic_type)), ')')), + repeat($.attribute), + repeat(seq($.field_declaration, optional(';'))), + 'end', + ), + + procedure_type: $ => seq( + 'proc', + field('parameters', $.parameter_list), + repeat($.attribute), + optional(seq('->', field('return_type', $._type_expression))), + ), + + enum_type: $ => seq( + '(', + commaSep1(field('member', $.identifier)), + ')', + ), + + generic_type: $ => seq( + field('name', $.identifier), + field('type_arguments', $.type_arguments), + ), + + type_arguments: $ => seq( + '#[', + commaSep1($._type_expression), + ']', + ), + + // Expressions + _expression: $ => choice( + $.literal, + $.identifier, + $.generic_type, + $.unary_expression, + $.binary_expression, + $.call_expression, + $.index_expression, + $.slice_expression, + $.field_expression, + $.dereference_expression, + $.cast_expression, + $.traits_expression, + $.record_constructor, + $.array_constructor, + $.parenthesized_expression, + ), + + unary_expression: $ => prec.right(PREC.UNARY, seq( + field('operator', choice('@', '~', '-', '+')), + field('argument', $._expression), + )), + + binary_expression: $ => choice( + ...[ + ['or', PREC.LOGICAL], + ['&', PREC.LOGICAL], + ['xor', PREC.LOGICAL], + ['=', PREC.RELATIONAL], + ['<>', PREC.RELATIONAL], + ['<', PREC.RELATIONAL], + ['>', PREC.RELATIONAL], + ['<=', PREC.RELATIONAL], + ['>=', PREC.RELATIONAL], + ['<<', PREC.SHIFT], + ['>>', PREC.SHIFT], + ['+', PREC.ADD], + ['-', PREC.ADD], + ['*', PREC.MULTIPLY], + ['/', PREC.MULTIPLY], + ['%', PREC.MULTIPLY], + ].map(([operator, precedence]) => + prec.left(precedence, seq( + field('left', $._expression), + field('operator', operator), + field('right', $._expression), + )) + ) + ), + + call_expression: $ => prec(PREC.CALL, seq( + field('function', $._expression), + field('arguments', $.argument_list), + )), + + argument_list: $ => seq( + '(', + optional(commaSep1($._expression)), + ')', + ), + + index_expression: $ => prec(PREC.POSTFIX, seq( + field('array', $._expression), + '[', + field('index', $._expression), + ']', + )), + + slice_expression: $ => prec(PREC.POSTFIX, seq( + field('array', $._expression), + '[', + field('start', $._expression), + 'to', + field('end', $._expression), + ']', + )), + + field_expression: $ => prec(PREC.POSTFIX, seq( + field('operand', $._expression), + '.', + field('field', $.identifier), + )), + + dereference_expression: $ => prec(PREC.POSTFIX, seq( + field('operand', $._expression), + '^', + )), + + cast_expression: $ => seq( + 'cast', + '(', + field('value', $._expression), + ':', + field('type', $._type_expression), + ')', + ), + + traits_expression: $ => seq( + field('trait', $.trait), + '(', + field('arguments', commaSep1($._type_expression)), + ')', + ), + + record_constructor: $ => prec(PREC.CALL, seq( + field('type', choice($.identifier, $.generic_type)), + '{', + optional(commaSep1($.field_initializer)), + '}', + )), + + field_initializer: $ => seq( + field('name', $.identifier), + ':', + field('value', $._expression), + ), + + array_constructor: $ => seq( + '[', + commaSep1($._expression), + ']', + ), + + parenthesized_expression: $ => seq( + '(', + $._expression, + ')', + ), + + // Literals + literal: $ => choice( + $.integer, + $.float, + $.string, + $.byte, + $.character, + $.boolean, + $.nil, + ), + + boolean: $ => choice('true', 'false'), + nil: $ => 'nil', + + integer: $ => token(choice( + seq(/0[xX][0-9a-fA-F]+/, optional(choice('u8', 'u16', 'u32', 'u64'))), + seq(/0[bB][01]+/, optional(choice('u8', 'u16', 'u32', 'u64'))), + seq(/[0-9]+/, optional(choice('u', 'u8', 'u16', 'u32', 'u64', 'i8', 'i16', 'i32', 'i64'))), + )), + + float: $ => token(seq( + /[0-9]+/, + choice( + seq('.', /[0-9]+/, optional(/[eE][+-]?[0-9]+/)), + /[eE][+-]?[0-9]+/, + ), + optional('f'), + )), + + string: $ => seq( + '"', + repeat(choice( + token.immediate(prec(1, /[^"\\\n]+/)), + $.escape_sequence, + '\\\n', + )), + '"', + ), + + byte: $ => seq( + "'", + repeat1(choice( + token.immediate(prec(1, /[^'\\\n]+/)), + $.escape_sequence, + '\\\n', + )), + "'", + ), + + character: $ => seq( + '`', + repeat1(choice( + token.immediate(prec(1, /[^`\\\n]+/)), + $.escape_sequence, + '\\\n', + )), + '`', + ), + + escape_sequence: $ => token.immediate(seq( + '\\', + choice( + /[^0-9]/, + /[0-9]{1,3}/, + ), + )), + }, +}); diff --git a/tools/tree-sitter/queries/elna/folds.scm b/tools/tree-sitter/queries/elna/folds.scm new file mode 100644 index 0000000..0387513 --- /dev/null +++ b/tools/tree-sitter/queries/elna/folds.scm @@ -0,0 +1,20 @@ +[ + (module_declaration) + (program_declaration) + (procedure_declaration) + (record_type) + (enum_type) + (block) + (if_statement) + (elsif_clause) + (else_clause) + (while_statement) + (while_elsif_clause) + (repeat_statement) + (for_statement) + (defer_statement) + (block_statement) + (case_statement) + (case_arm) + (comment) +] @fold diff --git a/tools/tree-sitter/queries/elna/highlights.scm b/tools/tree-sitter/queries/elna/highlights.scm new file mode 100644 index 0000000..b5e6d10 --- /dev/null +++ b/tools/tree-sitter/queries/elna/highlights.scm @@ -0,0 +1,201 @@ +; Keywords +[ + "program" + "module" + "type" + "var" + "threadvar" + "record" + "extern" + "defer" + "block" + "break" + "with" + "to" + "cast" + "begin" + "end" +] @keyword + +"proc" @keyword.function +"return" @keyword.return +"import" @keyword.import + +[ + "while" + "do" + "for" + "repeat" + "until" +] @keyword.repeat + +[ + "if" + "then" + "else" + "elsif" + "case" + "of" +] @keyword.conditional + +"const" @keyword.modifier + +[ + "or" + "xor" +] @keyword.operator + +; Comments +(comment) @comment @spell + +; Literals +(integer) @number +(float) @number.float +(boolean) @boolean +(nil) @constant.builtin + +(string) @string +(character) @character +(byte) @character +(escape_sequence) @string.escape + +; Traits and Attributes +(trait) @attribute +(attribute + "#{" @punctuation.special + name: (identifier) @attribute + "}" @punctuation.special) + +; Builtin Types +((identifier) @type.builtin + (#any-of? @type.builtin + "Int" "Word" + "Int8" "Int16" "Int32" "Int64" + "Word8" "Word16" "Word32" "Word64" + "Single" "Double" + "Char" "Pointer" "Bool")) + +; Declarations and Definitions +(type_declaration + name: (identifier_definition + name: (identifier) @type.definition)) + +(type_parameters + (identifier) @type.parameter) + +(type_arguments + (identifier) @type) + +(record_type + base: (identifier) @type) + +(record_constructor + type: (identifier) @type) + +(generic_type + name: (identifier) @type) + +(cast_expression + type: (identifier) @type) + +(traits_expression + arguments: (identifier) @type) + +(enum_type + member: (identifier) @constant) + +(procedure_declaration + name: (identifier_definition + name: (identifier) @function)) + +(identifier_definition + exported: "*" @punctuation.special) + +(field_declaration + names: (identifier_definition + name: (identifier) @variable.member)) + +(parameter_list + (field_declaration + names: (identifier_definition + name: (identifier) @variable.parameter))) + +(variable_declaration + names: (identifier_definition + name: (identifier) @variable)) + +(for_statement + variable: (identifier) @variable + counter: (identifier)? @variable) + +(block_statement + name: (identifier) @label) + +(break_statement + label: (identifier) @label) + +(import_path + (identifier) @module) + +; Calls and Member Access +(call_expression + function: (identifier) @function.call) + +(call_expression + function: (field_expression + field: (identifier) @function.method.call)) + +(field_expression + field: (identifier) @variable.member) + +(field_initializer + name: (identifier) @variable.member) + +; Fallback identifiers +(identifier) @variable + +; Operators +[ + ":=" + "=" + "<>" + "<" + ">" + "<=" + ">=" + "+" + "-" + "*" + "/" + "%" + "<<" + ">>" + "&" + "|" + "~" + "->" + "^" + "@" +] @operator + +; Delimiters and Punctuation +[ + ";" + "," + ":" + "." +] @punctuation.delimiter + +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket + +[ + "#[" + "#{" +] @punctuation.special diff --git a/tools/tree-sitter/queries/elna/indents.scm b/tools/tree-sitter/queries/elna/indents.scm new file mode 100644 index 0000000..0e807d0 --- /dev/null +++ b/tools/tree-sitter/queries/elna/indents.scm @@ -0,0 +1,22 @@ +[ + (type_section) + (var_section) + (threadvar_section) + (procedure_body) + (block) + (record_type) + (case_arm) +] @indent.begin + +[ + "end" + "until" + (return_clause) +] @indent.end + +[ + "begin" + (elsif_clause) + (else_clause) + (while_elsif_clause) +] @indent.branch diff --git a/tools/tree-sitter/queries/elna/locals.scm b/tools/tree-sitter/queries/elna/locals.scm new file mode 100644 index 0000000..1e9bb70 --- /dev/null +++ b/tools/tree-sitter/queries/elna/locals.scm @@ -0,0 +1,33 @@ +[ + (source_file) + (module_declaration) + (program_declaration) + (procedure_declaration) + (procedure_body) + (block) + (block_statement) + (if_statement) + (while_statement) + (for_statement) + (repeat_statement) + (case_statement) +] @local.scope + +(variable_declaration + names: (identifier_definition + name: (identifier) @local.definition)) + +(parameter_list + (field_declaration + names: (identifier_definition + name: (identifier) @local.definition))) + +(for_statement + variable: (identifier) @local.definition + counter: (identifier)? @local.definition) + +(procedure_declaration + name: (identifier_definition + name: (identifier) @local.definition)) + +(identifier) @local.reference diff --git a/tools/tree-sitter/test/corpus/aliased_type_constant.txt b/tools/tree-sitter/test/corpus/aliased_type_constant.txt new file mode 100644 index 0000000..589c756 --- /dev/null +++ b/tools/tree-sitter/test/corpus/aliased_type_constant.txt @@ -0,0 +1,50 @@ +================== +aliased_type_constant +================== + +module + +type + Handle = Int + +var + limit: const Int := 1 + +proc check() +begin + assert(limit = 1) +return + +end. + +--- + +(source_file + (module_declaration + (type_section + (type_declaration + (identifier_definition + (identifier)) + (identifier))) + (var_section + (variable_declaration + (identifier_definition + (identifier)) + (const_type + (identifier)) + (literal + (integer)))) + (procedure_declaration + (identifier_definition + (identifier)) + (parameter_list) + (procedure_body + (block + (call_expression + (identifier) + (argument_list + (binary_expression + (identifier) + (literal + (integer)))))) + (return_clause))))) diff --git a/tools/tree-sitter/test/corpus/assign_record_to_base.txt b/tools/tree-sitter/test/corpus/assign_record_to_base.txt new file mode 100644 index 0000000..6488889 --- /dev/null +++ b/tools/tree-sitter/test/corpus/assign_record_to_base.txt @@ -0,0 +1,61 @@ +================== +assign_record_to_base +================== + +program() +type + B = record + x: Int + end + R = record(B) + y: Int + end + +var + x: ^B := nil + y: ^R := nil + +begin + x := y +end. + +--- + +(source_file + (program_declaration + (type_section + (type_declaration + (identifier_definition + (identifier)) + (record_type + (field_declaration + (identifier_definition + (identifier)) + (identifier)))) + (type_declaration + (identifier_definition + (identifier)) + (record_type + (identifier) + (field_declaration + (identifier_definition + (identifier)) + (identifier))))) + (var_section + (variable_declaration + (identifier_definition + (identifier)) + (pointer_type + (identifier)) + (literal + (nil))) + (variable_declaration + (identifier_definition + (identifier)) + (pointer_type + (identifier)) + (literal + (nil)))) + (assignment_statement + (identifier) + (identifier)))) diff --git a/tools/tree-sitter/test/corpus/compile_time_array_length.txt b/tools/tree-sitter/test/corpus/compile_time_array_length.txt new file mode 100644 index 0000000..0e250f2 --- /dev/null +++ b/tools/tree-sitter/test/corpus/compile_time_array_length.txt @@ -0,0 +1,39 @@ +================== +compile_time_array_length +================== + +module + +var + source: const [3]Int := [1, 2, 3] + target: Word := source.length + +end. + +--- + +(source_file + (module_declaration + (var_section + (variable_declaration + (identifier_definition + (identifier)) + (const_type + (array_type + (literal + (integer)) + (identifier))) + (array_constructor + (literal + (integer)) + (literal + (integer)) + (literal + (integer)))) + (variable_declaration + (identifier_definition + (identifier)) + (identifier) + (field_expression + (identifier) + (identifier)))))) diff --git a/tools/tree-sitter/test/corpus/const_alias.txt b/tools/tree-sitter/test/corpus/const_alias.txt new file mode 100644 index 0000000..ae19588 --- /dev/null +++ b/tools/tree-sitter/test/corpus/const_alias.txt @@ -0,0 +1,45 @@ +================== +const_alias +================== + +module + +type + CI = const Int + CCI = const CI + +var + x: CCI := 8 + y: const CI := 9 + +end. + +--- + +(source_file + (module_declaration + (type_section + (type_declaration + (identifier_definition + (identifier)) + (const_type + (identifier))) + (type_declaration + (identifier_definition + (identifier)) + (const_type + (identifier)))) + (var_section + (variable_declaration + (identifier_definition + (identifier)) + (identifier) + (literal + (integer))) + (variable_declaration + (identifier_definition + (identifier)) + (const_type + (identifier)) + (literal + (integer)))))) diff --git a/tools/tree-sitter/test/corpus/const_element_array.txt b/tools/tree-sitter/test/corpus/const_element_array.txt new file mode 100644 index 0000000..e43c2f1 --- /dev/null +++ b/tools/tree-sitter/test/corpus/const_element_array.txt @@ -0,0 +1,47 @@ +================== +const_element_array +================== + +module + +type + CI = const Int + +var + a: [3]CI := [1, 2, 3] + b: [3]CI + +end. + +--- + +(source_file + (module_declaration + (type_section + (type_declaration + (identifier_definition + (identifier)) + (const_type + (identifier)))) + (var_section + (variable_declaration + (identifier_definition + (identifier)) + (array_type + (literal + (integer)) + (identifier)) + (array_constructor + (literal + (integer)) + (literal + (integer)) + (literal + (integer)))) + (variable_declaration + (identifier_definition + (identifier)) + (array_type + (literal + (integer)) + (identifier)))))) diff --git a/tools/tree-sitter/test/corpus/const_extern.txt b/tools/tree-sitter/test/corpus/const_extern.txt new file mode 100644 index 0000000..0fb71bc --- /dev/null +++ b/tools/tree-sitter/test/corpus/const_extern.txt @@ -0,0 +1,21 @@ +================== +const_extern +================== + +module + +var + errno_like: const Int := extern + +end. + +--- + +(source_file + (module_declaration + (var_section + (variable_declaration + (identifier_definition + (identifier)) + (const_type + (identifier)))))) diff --git a/tools/tree-sitter/test/corpus/const_negation.txt b/tools/tree-sitter/test/corpus/const_negation.txt new file mode 100644 index 0000000..89e801c --- /dev/null +++ b/tools/tree-sitter/test/corpus/const_negation.txt @@ -0,0 +1,49 @@ +================== +const_negation +================== + +program() +var + x: const Int := -5 + y: const Int := -x + +begin + assert(x = -5); + assert(y = 5); +end. + +--- + +(source_file + (program_declaration + (var_section + (variable_declaration + (identifier_definition + (identifier)) + (const_type + (identifier)) + (unary_expression + (literal + (integer)))) + (variable_declaration + (identifier_definition + (identifier)) + (const_type + (identifier)) + (unary_expression + (identifier)))) + (call_expression + (identifier) + (argument_list + (binary_expression + (identifier) + (unary_expression + (literal + (integer)))))) + (call_expression + (identifier) + (argument_list + (binary_expression + (identifier) + (literal + (integer))))))) diff --git a/tools/tree-sitter/test/corpus/const_var_chain.txt b/tools/tree-sitter/test/corpus/const_var_chain.txt new file mode 100644 index 0000000..fca40c9 --- /dev/null +++ b/tools/tree-sitter/test/corpus/const_var_chain.txt @@ -0,0 +1,37 @@ +================== +const_var_chain +================== + +program() +var + x: const Int := 42 + y: Int := x + +begin + assert(y = 42) +end. + +--- + +(source_file + (program_declaration + (var_section + (variable_declaration + (identifier_definition + (identifier)) + (const_type + (identifier)) + (literal + (integer))) + (variable_declaration + (identifier_definition + (identifier)) + (identifier) + (identifier))) + (call_expression + (identifier) + (argument_list + (binary_expression + (identifier) + (literal + (integer))))))) diff --git a/tools/tree-sitter/test/corpus/double_literals.txt b/tools/tree-sitter/test/corpus/double_literals.txt new file mode 100644 index 0000000..9dc7cc1 --- /dev/null +++ b/tools/tree-sitter/test/corpus/double_literals.txt @@ -0,0 +1,56 @@ +================== +double_literals +================== + +module + +proc f() +var + x: const Double := 3.14 + y: const Double := 1e10 + z: const Double := 4.567e8 + t: const Double := 2.5E-3 +return + +end. + +--- + +(source_file + (module_declaration + (procedure_declaration + (identifier_definition + (identifier)) + (parameter_list) + (procedure_body + (block + (var_section + (variable_declaration + (identifier_definition + (identifier)) + (const_type + (identifier)) + (literal + (float))) + (variable_declaration + (identifier_definition + (identifier)) + (const_type + (identifier)) + (literal + (float))) + (variable_declaration + (identifier_definition + (identifier)) + (const_type + (identifier)) + (literal + (float))) + (variable_declaration + (identifier_definition + (identifier)) + (const_type + (identifier)) + (literal + (float))))) + (return_clause))))) diff --git a/tools/tree-sitter/test/corpus/empty_proc.txt b/tools/tree-sitter/test/corpus/empty_proc.txt new file mode 100644 index 0000000..338c2fb --- /dev/null +++ b/tools/tree-sitter/test/corpus/empty_proc.txt @@ -0,0 +1,21 @@ +================== +empty_proc +================== + +module + +proc f() +return + +end. + +--- + +(source_file + (module_declaration + (procedure_declaration + (identifier_definition + (identifier)) + (parameter_list) + (procedure_body + (return_clause))))) diff --git a/tools/tree-sitter/test/corpus/empty_proc_type_expression.txt b/tools/tree-sitter/test/corpus/empty_proc_type_expression.txt new file mode 100644 index 0000000..3d259a4 --- /dev/null +++ b/tools/tree-sitter/test/corpus/empty_proc_type_expression.txt @@ -0,0 +1,21 @@ +================== +empty_proc_type_expression +================== + +module + +type + P = proc() + +end. + +--- + +(source_file + (module_declaration + (type_section + (type_declaration + (identifier_definition + (identifier)) + (procedure_type + (parameter_list)))))) diff --git a/tools/tree-sitter/test/corpus/empty_statements_in_a_row.txt b/tools/tree-sitter/test/corpus/empty_statements_in_a_row.txt new file mode 100644 index 0000000..98700ae --- /dev/null +++ b/tools/tree-sitter/test/corpus/empty_statements_in_a_row.txt @@ -0,0 +1,24 @@ +================== +empty_statements_in_a_row +================== + +module + +proc f() +begin + ; +return + +end. + +--- + +(source_file + (module_declaration + (procedure_declaration + (identifier_definition + (identifier)) + (parameter_list) + (procedure_body + (block) + (return_clause))))) diff --git a/tools/tree-sitter/test/corpus/generic_alias.txt b/tools/tree-sitter/test/corpus/generic_alias.txt new file mode 100644 index 0000000..54a8ea2 --- /dev/null +++ b/tools/tree-sitter/test/corpus/generic_alias.txt @@ -0,0 +1,132 @@ +================== +generic_alias +================== + +program() +type + File = record + fd: Int + end + + Node#[T] = record + next: ^Node#[T]; + value: ^T + end + + Ref#[T] = ^T + + Boxed#[V] = record + inner: ^Node#[V] + end + +var + chain: Node#[File] + aliased: Ref#[File] + raw: ^File + boxed: Boxed#[File] + +begin + chain.next := nil; + aliased := raw; + raw := aliased; + boxed.inner := @chain +end. + +--- + +(source_file + (program_declaration + (type_section + (type_declaration + (identifier_definition + (identifier)) + (record_type + (field_declaration + (identifier_definition + (identifier)) + (identifier)))) + (type_declaration + (identifier_definition + (identifier)) + (type_parameters + (identifier)) + (record_type + (field_declaration + (identifier_definition + (identifier)) + (pointer_type + (generic_type + (identifier) + (type_arguments + (identifier))))) + (field_declaration + (identifier_definition + (identifier)) + (pointer_type + (identifier))))) + (type_declaration + (identifier_definition + (identifier)) + (type_parameters + (identifier)) + (pointer_type + (identifier))) + (type_declaration + (identifier_definition + (identifier)) + (type_parameters + (identifier)) + (record_type + (field_declaration + (identifier_definition + (identifier)) + (pointer_type + (generic_type + (identifier) + (type_arguments + (identifier)))))))) + (var_section + (variable_declaration + (identifier_definition + (identifier)) + (generic_type + (identifier) + (type_arguments + (identifier)))) + (variable_declaration + (identifier_definition + (identifier)) + (generic_type + (identifier) + (type_arguments + (identifier)))) + (variable_declaration + (identifier_definition + (identifier)) + (pointer_type + (identifier))) + (variable_declaration + (identifier_definition + (identifier)) + (generic_type + (identifier) + (type_arguments + (identifier))))) + (assignment_statement + (field_expression + (identifier) + (identifier)) + (literal + (nil))) + (assignment_statement + (identifier) + (identifier)) + (assignment_statement + (identifier) + (identifier)) + (assignment_statement + (field_expression + (identifier) + (identifier)) + (unary_expression + (identifier))))) diff --git a/tools/tree-sitter/test/corpus/generic_arguments.txt b/tools/tree-sitter/test/corpus/generic_arguments.txt new file mode 100644 index 0000000..3f325de --- /dev/null +++ b/tools/tree-sitter/test/corpus/generic_arguments.txt @@ -0,0 +1,167 @@ +================== +generic_arguments +================== + +program() +type + File = record + fd: Int + end + + Pair#[K, V] = record + key: ^K; + value: ^V + end + +var + entry: Pair#[File, Word8] + +proc allocate#[T](size: Word) -> ^T +extern + +proc first#[K, V](entry_ptr: ^Pair#[K, V]) -> ^K +return entry_ptr^.key + +begin + entry.key := allocate#[File](#size(File)); + assert(#size(Pair#[File, Word8]) = #size(Pointer) * 2u); + assert(#offset(Pair#[File, Word8], value) = #size(Pointer)); + assert(first#[File, Word8](@entry) = entry.key) +end. + +--- + +(source_file + (program_declaration + (type_section + (type_declaration + (identifier_definition + (identifier)) + (record_type + (field_declaration + (identifier_definition + (identifier)) + (identifier)))) + (type_declaration + (identifier_definition + (identifier)) + (type_parameters + (identifier) + (identifier)) + (record_type + (field_declaration + (identifier_definition + (identifier)) + (pointer_type + (identifier))) + (field_declaration + (identifier_definition + (identifier)) + (pointer_type + (identifier)))))) + (var_section + (variable_declaration + (identifier_definition + (identifier)) + (generic_type + (identifier) + (type_arguments + (identifier) + (identifier))))) + (procedure_declaration + (identifier_definition + (identifier)) + (type_parameters + (identifier)) + (parameter_list + (field_declaration + (identifier_definition + (identifier)) + (identifier))) + (pointer_type + (identifier))) + (procedure_declaration + (identifier_definition + (identifier)) + (type_parameters + (identifier) + (identifier)) + (parameter_list + (field_declaration + (identifier_definition + (identifier)) + (pointer_type + (generic_type + (identifier) + (type_arguments + (identifier) + (identifier)))))) + (pointer_type + (identifier)) + (procedure_body + (return_clause + (field_expression + (dereference_expression + (identifier)) + (identifier))))) + (assignment_statement + (field_expression + (identifier) + (identifier)) + (call_expression + (generic_type + (identifier) + (type_arguments + (identifier))) + (argument_list + (traits_expression + (trait) + (identifier))))) + (call_expression + (identifier) + (argument_list + (binary_expression + (traits_expression + (trait) + (generic_type + (identifier) + (type_arguments + (identifier) + (identifier)))) + (binary_expression + (traits_expression + (trait) + (identifier)) + (literal + (integer)))))) + (call_expression + (identifier) + (argument_list + (binary_expression + (traits_expression + (trait) + (generic_type + (identifier) + (type_arguments + (identifier) + (identifier))) + (identifier)) + (traits_expression + (trait) + (identifier))))) + (call_expression + (identifier) + (argument_list + (binary_expression + (call_expression + (generic_type + (identifier) + (type_arguments + (identifier) + (identifier))) + (argument_list + (unary_expression + (identifier)))) + (field_expression + (identifier) + (identifier))))))) diff --git a/tools/tree-sitter/test/corpus/generic_base_chain.txt b/tools/tree-sitter/test/corpus/generic_base_chain.txt new file mode 100644 index 0000000..770b7db --- /dev/null +++ b/tools/tree-sitter/test/corpus/generic_base_chain.txt @@ -0,0 +1,144 @@ +================== +generic_base_chain +================== + +program() +type + File = record + fd: Int + end + + Map#[K, V] = record + key: ^K; + value: ^V + end + + Cache#[K, V] = record(Map#[Word8, V]) + newest: ^K + end + +var + store: Cache#[Int, File] + byte_key: ^Word8 + upcast: ^Map#[Word8, File] + +proc put#[K2, V2](target: ^Map#[K2, V2]; key: ^K2) +begin + target^.key := key +return + +begin + upcast := @store; + put(@store, byte_key) +end. + +--- + +(source_file + (program_declaration + (type_section + (type_declaration + (identifier_definition + (identifier)) + (record_type + (field_declaration + (identifier_definition + (identifier)) + (identifier)))) + (type_declaration + (identifier_definition + (identifier)) + (type_parameters + (identifier) + (identifier)) + (record_type + (field_declaration + (identifier_definition + (identifier)) + (pointer_type + (identifier))) + (field_declaration + (identifier_definition + (identifier)) + (pointer_type + (identifier))))) + (type_declaration + (identifier_definition + (identifier)) + (type_parameters + (identifier) + (identifier)) + (record_type + (generic_type + (identifier) + (type_arguments + (identifier) + (identifier))) + (field_declaration + (identifier_definition + (identifier)) + (pointer_type + (identifier)))))) + (var_section + (variable_declaration + (identifier_definition + (identifier)) + (generic_type + (identifier) + (type_arguments + (identifier) + (identifier)))) + (variable_declaration + (identifier_definition + (identifier)) + (pointer_type + (identifier))) + (variable_declaration + (identifier_definition + (identifier)) + (pointer_type + (generic_type + (identifier) + (type_arguments + (identifier) + (identifier)))))) + (procedure_declaration + (identifier_definition + (identifier)) + (type_parameters + (identifier) + (identifier)) + (parameter_list + (field_declaration + (identifier_definition + (identifier)) + (pointer_type + (generic_type + (identifier) + (type_arguments + (identifier) + (identifier))))) + (field_declaration + (identifier_definition + (identifier)) + (pointer_type + (identifier)))) + (procedure_body + (block + (assignment_statement + (field_expression + (dereference_expression + (identifier)) + (identifier)) + (identifier))) + (return_clause))) + (assignment_statement + (identifier) + (unary_expression + (identifier))) + (call_expression + (identifier) + (argument_list + (unary_expression + (identifier)) + (identifier))))) diff --git a/tools/tree-sitter/test/corpus/generic_const_inference.txt b/tools/tree-sitter/test/corpus/generic_const_inference.txt new file mode 100644 index 0000000..e4b5bf9 --- /dev/null +++ b/tools/tree-sitter/test/corpus/generic_const_inference.txt @@ -0,0 +1,204 @@ +================== +generic_const_inference +================== + +program() +type + ConstAlias = const ^Word8 + BasePtr = ^Word8 + NestedConst = const BasePtr + +var + slice: []const Word8 + aliased: ConstAlias := nil + nested: NestedConst := nil + direct_const: const ^Word8 := nil + +proc write#[T](fd: Int; buf: ^T; count: Int) -> Int +return 0 + +proc write_const#[T](fd: Int; buf: ^const T; count: Int) -> Int +return 0 + +begin + write(1, slice.ptr, cast(slice.length: Int)); + write(1, aliased, 0); + write(1, nested, 0); + write(1, direct_const, 0); + write_const(1, slice.ptr, cast(slice.length: Int)); + write_const(1, aliased, 0); + write_const(1, nested, 0); + write_const(1, direct_const, 0) +end. + +--- + +(source_file + (program_declaration + (type_section + (type_declaration + (identifier_definition + (identifier)) + (const_type + (pointer_type + (identifier)))) + (type_declaration + (identifier_definition + (identifier)) + (pointer_type + (identifier))) + (type_declaration + (identifier_definition + (identifier)) + (const_type + (identifier)))) + (var_section + (variable_declaration + (identifier_definition + (identifier)) + (slice_type + (const_type + (identifier)))) + (variable_declaration + (identifier_definition + (identifier)) + (identifier) + (literal + (nil))) + (variable_declaration + (identifier_definition + (identifier)) + (identifier) + (literal + (nil))) + (variable_declaration + (identifier_definition + (identifier)) + (const_type + (pointer_type + (identifier))) + (literal + (nil)))) + (procedure_declaration + (identifier_definition + (identifier)) + (type_parameters + (identifier)) + (parameter_list + (field_declaration + (identifier_definition + (identifier)) + (identifier)) + (field_declaration + (identifier_definition + (identifier)) + (pointer_type + (identifier))) + (field_declaration + (identifier_definition + (identifier)) + (identifier))) + (identifier) + (procedure_body + (return_clause + (literal + (integer))))) + (procedure_declaration + (identifier_definition + (identifier)) + (type_parameters + (identifier)) + (parameter_list + (field_declaration + (identifier_definition + (identifier)) + (identifier)) + (field_declaration + (identifier_definition + (identifier)) + (pointer_type + (const_type + (identifier)))) + (field_declaration + (identifier_definition + (identifier)) + (identifier))) + (identifier) + (procedure_body + (return_clause + (literal + (integer))))) + (call_expression + (identifier) + (argument_list + (literal + (integer)) + (field_expression + (identifier) + (identifier)) + (cast_expression + (field_expression + (identifier) + (identifier)) + (identifier)))) + (call_expression + (identifier) + (argument_list + (literal + (integer)) + (identifier) + (literal + (integer)))) + (call_expression + (identifier) + (argument_list + (literal + (integer)) + (identifier) + (literal + (integer)))) + (call_expression + (identifier) + (argument_list + (literal + (integer)) + (identifier) + (literal + (integer)))) + (call_expression + (identifier) + (argument_list + (literal + (integer)) + (field_expression + (identifier) + (identifier)) + (cast_expression + (field_expression + (identifier) + (identifier)) + (identifier)))) + (call_expression + (identifier) + (argument_list + (literal + (integer)) + (identifier) + (literal + (integer)))) + (call_expression + (identifier) + (argument_list + (literal + (integer)) + (identifier) + (literal + (integer)))) + (call_expression + (identifier) + (argument_list + (literal + (integer)) + (identifier) + (literal + (integer)))))) diff --git a/tools/tree-sitter/test/corpus/generic_inference.txt b/tools/tree-sitter/test/corpus/generic_inference.txt new file mode 100644 index 0000000..ccac55c --- /dev/null +++ b/tools/tree-sitter/test/corpus/generic_inference.txt @@ -0,0 +1,157 @@ +================== +generic_inference +================== + +program() +type + File = record + fd: Int + end + + Cell#[T] = record + held: ^T + end + +var + files: Cell#[File] + bytes: Cell#[Word8] + f: File + b: Word8 + +proc store#[T](target: ^Cell#[T]; value: ^T) + target^.held := value +return + +proc relay#[T](target: ^Cell#[T]; value: ^T) + store(target, value) +return + +begin + store(@files, @f); + relay(@bytes, @b); + store(@files, nil) +end. + +--- + +(source_file + (program_declaration + (type_section + (type_declaration + (identifier_definition + (identifier)) + (record_type + (field_declaration + (identifier_definition + (identifier)) + (identifier)))) + (type_declaration + (identifier_definition + (identifier)) + (type_parameters + (identifier)) + (record_type + (field_declaration + (identifier_definition + (identifier)) + (pointer_type + (identifier)))))) + (var_section + (variable_declaration + (identifier_definition + (identifier)) + (generic_type + (identifier) + (type_arguments + (identifier)))) + (variable_declaration + (identifier_definition + (identifier)) + (generic_type + (identifier) + (type_arguments + (identifier)))) + (variable_declaration + (identifier_definition + (identifier)) + (identifier)) + (variable_declaration + (identifier_definition + (identifier)) + (identifier))) + (procedure_declaration + (identifier_definition + (identifier)) + (type_parameters + (identifier)) + (parameter_list + (field_declaration + (identifier_definition + (identifier)) + (pointer_type + (generic_type + (identifier) + (type_arguments + (identifier))))) + (field_declaration + (identifier_definition + (identifier)) + (pointer_type + (identifier)))) + (procedure_body + (block + (assignment_statement + (field_expression + (dereference_expression + (identifier)) + (identifier)) + (identifier))) + (return_clause))) + (procedure_declaration + (identifier_definition + (identifier)) + (type_parameters + (identifier)) + (parameter_list + (field_declaration + (identifier_definition + (identifier)) + (pointer_type + (generic_type + (identifier) + (type_arguments + (identifier))))) + (field_declaration + (identifier_definition + (identifier)) + (pointer_type + (identifier)))) + (procedure_body + (block + (call_expression + (identifier) + (argument_list + (identifier) + (identifier)))) + (return_clause))) + (call_expression + (identifier) + (argument_list + (unary_expression + (identifier)) + (unary_expression + (identifier)))) + (call_expression + (identifier) + (argument_list + (unary_expression + (identifier)) + (unary_expression + (identifier)))) + (call_expression + (identifier) + (argument_list + (unary_expression + (identifier)) + (literal + (nil)))))) diff --git a/tools/tree-sitter/test/corpus/generic_pointee.txt b/tools/tree-sitter/test/corpus/generic_pointee.txt new file mode 100644 index 0000000..55f5a1a --- /dev/null +++ b/tools/tree-sitter/test/corpus/generic_pointee.txt @@ -0,0 +1,71 @@ +================== +generic_pointee +================== + +program() + +type + File = record + fd: Int + end + +proc allocate#[T](size: Word) -> ^T +extern + +var + f: ^File + +begin + f := allocate#[File](#size(File)); + assert(f = nil) +end. + +--- + +(source_file + (program_declaration + (type_section + (type_declaration + (identifier_definition + (identifier)) + (record_type + (field_declaration + (identifier_definition + (identifier)) + (identifier))))) + (procedure_declaration + (identifier_definition + (identifier)) + (type_parameters + (identifier)) + (parameter_list + (field_declaration + (identifier_definition + (identifier)) + (identifier))) + (pointer_type + (identifier))) + (var_section + (variable_declaration + (identifier_definition + (identifier)) + (pointer_type + (identifier)))) + (assignment_statement + (identifier) + (call_expression + (generic_type + (identifier) + (type_arguments + (identifier))) + (argument_list + (traits_expression + (trait) + (identifier))))) + (call_expression + (identifier) + (argument_list + (binary_expression + (identifier) + (literal + (nil))))))) diff --git a/tools/tree-sitter/test/corpus/noreturn_procedure.txt b/tools/tree-sitter/test/corpus/noreturn_procedure.txt new file mode 100644 index 0000000..8f8466b --- /dev/null +++ b/tools/tree-sitter/test/corpus/noreturn_procedure.txt @@ -0,0 +1,23 @@ +================== +noreturn_procedure +================== + +module + +proc exit() #{noreturn} +return + +end. + +--- + +(source_file + (module_declaration + (procedure_declaration + (identifier_definition + (identifier)) + (parameter_list) + (attribute + (identifier)) + (procedure_body + (return_clause))))) diff --git a/tools/tree-sitter/test/corpus/opaque_type.txt b/tools/tree-sitter/test/corpus/opaque_type.txt new file mode 100644 index 0000000..7182bb9 --- /dev/null +++ b/tools/tree-sitter/test/corpus/opaque_type.txt @@ -0,0 +1,65 @@ +================== +opaque_type +================== + +program() +type + Handle = extern + Alias = Handle + +var + handle: ^Handle := nil + alias: ^Alias + +proc take(h: ^Handle) -> ^Handle +return h + +begin + alias := take(handle) +end. + +--- + +(source_file + (program_declaration + (type_section + (type_declaration + (identifier_definition + (identifier))) + (type_declaration + (identifier_definition + (identifier)) + (identifier))) + (var_section + (variable_declaration + (identifier_definition + (identifier)) + (pointer_type + (identifier)) + (literal + (nil))) + (variable_declaration + (identifier_definition + (identifier)) + (pointer_type + (identifier)))) + (procedure_declaration + (identifier_definition + (identifier)) + (parameter_list + (field_declaration + (identifier_definition + (identifier)) + (pointer_type + (identifier)))) + (pointer_type + (identifier)) + (procedure_body + (return_clause + (identifier)))) + (assignment_statement + (identifier) + (call_expression + (identifier) + (argument_list + (identifier)))))) diff --git a/tools/tree-sitter/test/corpus/pointer_cast.txt b/tools/tree-sitter/test/corpus/pointer_cast.txt new file mode 100644 index 0000000..63a28ab --- /dev/null +++ b/tools/tree-sitter/test/corpus/pointer_cast.txt @@ -0,0 +1,38 @@ +================== +pointer_cast +================== + +program() +var + c: ^Char := nil + p: Pointer := nil + +begin + p := c; + c := p +end. + +--- + +(source_file + (program_declaration + (var_section + (variable_declaration + (identifier_definition + (identifier)) + (pointer_type + (identifier)) + (literal + (nil))) + (variable_declaration + (identifier_definition + (identifier)) + (identifier) + (literal + (nil)))) + (assignment_statement + (identifier) + (identifier)) + (assignment_statement + (identifier) + (identifier)))) diff --git a/tools/tree-sitter/test/corpus/pointer_const_conversion.txt b/tools/tree-sitter/test/corpus/pointer_const_conversion.txt new file mode 100644 index 0000000..f134f00 --- /dev/null +++ b/tools/tree-sitter/test/corpus/pointer_const_conversion.txt @@ -0,0 +1,32 @@ +================== +pointer_const_conversion +================== + +program() +var + x: Int + p: ^const Int + +begin + p := @x +end. + +--- + +(source_file + (program_declaration + (var_section + (variable_declaration + (identifier_definition + (identifier)) + (identifier)) + (variable_declaration + (identifier_definition + (identifier)) + (pointer_type + (const_type + (identifier))))) + (assignment_statement + (identifier) + (unary_expression + (identifier))))) diff --git a/tools/tree-sitter/test/corpus/pointer_subtraction.txt b/tools/tree-sitter/test/corpus/pointer_subtraction.txt new file mode 100644 index 0000000..3e28de8 --- /dev/null +++ b/tools/tree-sitter/test/corpus/pointer_subtraction.txt @@ -0,0 +1,32 @@ +================== +pointer_subtraction +================== + +module + +proc test(a, b: ^Char) -> Int +return a - b + +end. + +--- + +(source_file + (module_declaration + (procedure_declaration + (identifier_definition + (identifier)) + (parameter_list + (field_declaration + (identifier_definition + (identifier)) + (identifier_definition + (identifier)) + (pointer_type + (identifier)))) + (identifier) + (procedure_body + (return_clause + (binary_expression + (identifier) + (identifier))))))) diff --git a/tools/tree-sitter/test/corpus/procedure_forward_reference.txt b/tools/tree-sitter/test/corpus/procedure_forward_reference.txt new file mode 100644 index 0000000..2b8627f --- /dev/null +++ b/tools/tree-sitter/test/corpus/procedure_forward_reference.txt @@ -0,0 +1,40 @@ +================== +procedure_forward_reference +================== + +module + +proc first() -> Int +return second() + 1 + +proc second() -> Int +return 41 + +end. + +--- + +(source_file + (module_declaration + (procedure_declaration + (identifier_definition + (identifier)) + (parameter_list) + (identifier) + (procedure_body + (return_clause + (binary_expression + (call_expression + (identifier) + (argument_list)) + (literal + (integer)))))) + (procedure_declaration + (identifier_definition + (identifier)) + (parameter_list) + (identifier) + (procedure_body + (return_clause + (literal + (integer))))))) diff --git a/tools/tree-sitter/test/corpus/record_const_base.txt b/tools/tree-sitter/test/corpus/record_const_base.txt new file mode 100644 index 0000000..e6f7cc6 --- /dev/null +++ b/tools/tree-sitter/test/corpus/record_const_base.txt @@ -0,0 +1,76 @@ +================== +record_const_base +================== + +module + +type + B = record + x: Int + end + CB = const B + D = record(CB) + y: Int + end + +proc f() +var + d: D +begin + d.x := 1; + d.y := 2 +return + +end. + +--- + +(source_file + (module_declaration + (type_section + (type_declaration + (identifier_definition + (identifier)) + (record_type + (field_declaration + (identifier_definition + (identifier)) + (identifier)))) + (type_declaration + (identifier_definition + (identifier)) + (const_type + (identifier))) + (type_declaration + (identifier_definition + (identifier)) + (record_type + (identifier) + (field_declaration + (identifier_definition + (identifier)) + (identifier))))) + (procedure_declaration + (identifier_definition + (identifier)) + (parameter_list) + (procedure_body + (block + (var_section + (variable_declaration + (identifier_definition + (identifier)) + (identifier))) + (assignment_statement + (field_expression + (identifier) + (identifier)) + (literal + (integer))) + (assignment_statement + (field_expression + (identifier) + (identifier)) + (literal + (integer)))) + (return_clause))))) diff --git a/tools/tree-sitter/test/corpus/self-referencing-record.txt b/tools/tree-sitter/test/corpus/self-referencing-record.txt new file mode 100644 index 0000000..02948f3 --- /dev/null +++ b/tools/tree-sitter/test/corpus/self-referencing-record.txt @@ -0,0 +1,27 @@ +================== +self-referencing-record +================== + +module + +type + R = record + field: ^R + end + +end. + +--- + +(source_file + (module_declaration + (type_section + (type_declaration + (identifier_definition + (identifier)) + (record_type + (field_declaration + (identifier_definition + (identifier)) + (pointer_type + (identifier)))))))) diff --git a/tools/tree-sitter/test/corpus/semicolon_parameter_separator.txt b/tools/tree-sitter/test/corpus/semicolon_parameter_separator.txt new file mode 100644 index 0000000..f9c1f14 --- /dev/null +++ b/tools/tree-sitter/test/corpus/semicolon_parameter_separator.txt @@ -0,0 +1,29 @@ +================== +semicolon_parameter_separator +================== + +module + +proc f(a: Int; b: Word) +return + +end. + +--- + +(source_file + (module_declaration + (procedure_declaration + (identifier_definition + (identifier)) + (parameter_list + (field_declaration + (identifier_definition + (identifier)) + (identifier)) + (field_declaration + (identifier_definition + (identifier)) + (identifier))) + (procedure_body + (return_clause))))) diff --git a/tools/tree-sitter/test/corpus/single_literals.txt b/tools/tree-sitter/test/corpus/single_literals.txt new file mode 100644 index 0000000..0c7faab --- /dev/null +++ b/tools/tree-sitter/test/corpus/single_literals.txt @@ -0,0 +1,56 @@ +================== +single_literals +================== + +module + +proc f() +var + x: const Single := 3.14f + y: const Single := 1e10f + z: const Single := 4.567e8f + t: const Single := 2.5E-3f +return + +end. + +--- + +(source_file + (module_declaration + (procedure_declaration + (identifier_definition + (identifier)) + (parameter_list) + (procedure_body + (block + (var_section + (variable_declaration + (identifier_definition + (identifier)) + (const_type + (identifier)) + (literal + (float))) + (variable_declaration + (identifier_definition + (identifier)) + (const_type + (identifier)) + (literal + (float))) + (variable_declaration + (identifier_definition + (identifier)) + (const_type + (identifier)) + (literal + (float))) + (variable_declaration + (identifier_definition + (identifier)) + (const_type + (identifier)) + (literal + (float))))) + (return_clause))))) diff --git a/tools/tree-sitter/test/corpus/slice_index.txt b/tools/tree-sitter/test/corpus/slice_index.txt new file mode 100644 index 0000000..5480038 --- /dev/null +++ b/tools/tree-sitter/test/corpus/slice_index.txt @@ -0,0 +1,58 @@ +================== +slice_index +================== + +module + +proc f() +var + a: []Int + x: Int + p: ^Int +begin + x := a[1]; + a := p[1u to 10u] +return + +end. + +--- + +(source_file + (module_declaration + (procedure_declaration + (identifier_definition + (identifier)) + (parameter_list) + (procedure_body + (block + (var_section + (variable_declaration + (identifier_definition + (identifier)) + (slice_type + (identifier))) + (variable_declaration + (identifier_definition + (identifier)) + (identifier)) + (variable_declaration + (identifier_definition + (identifier)) + (pointer_type + (identifier)))) + (assignment_statement + (identifier) + (index_expression + (identifier) + (literal + (integer)))) + (assignment_statement + (identifier) + (slice_expression + (identifier) + (literal + (integer)) + (literal + (integer))))) + (return_clause))))) diff --git a/tools/tree-sitter/test/corpus/take_const_address.txt b/tools/tree-sitter/test/corpus/take_const_address.txt new file mode 100644 index 0000000..d84e20f --- /dev/null +++ b/tools/tree-sitter/test/corpus/take_const_address.txt @@ -0,0 +1,35 @@ +================== +take_const_address +================== + +program() +var + x: ^const Int + y: const Int := 1 + +begin + x := @y +end. + +--- + +(source_file + (program_declaration + (var_section + (variable_declaration + (identifier_definition + (identifier)) + (pointer_type + (const_type + (identifier)))) + (variable_declaration + (identifier_definition + (identifier)) + (const_type + (identifier)) + (literal + (integer)))) + (assignment_statement + (identifier) + (unary_expression + (identifier))))) diff --git a/tools/tree-sitter/test/corpus/trailing_text.txt b/tools/tree-sitter/test/corpus/trailing_text.txt new file mode 100644 index 0000000..bb39c86 --- /dev/null +++ b/tools/tree-sitter/test/corpus/trailing_text.txt @@ -0,0 +1,16 @@ +================== +trailing_text +================== + +module + +end. + +Everything after the module terminator is ignored and is never scanned, so it +does not have to be Elna: proc 1 2 3 "unterminated + +--- + +(source_file + (module_declaration) + (trailing_content)) diff --git a/tools/tree-sitter/test/corpus/traits_size.txt b/tools/tree-sitter/test/corpus/traits_size.txt new file mode 100644 index 0000000..f566e0c --- /dev/null +++ b/tools/tree-sitter/test/corpus/traits_size.txt @@ -0,0 +1,93 @@ +================== +traits_size +================== + +program() +var + i: Int := 1 + s: Int := cast(#size(Int): Int) + a: [10]Int + as: Int := cast(#size([10]Int): Int) + p: Int := cast(#size(Pointer): Int) + +begin + assert(s > 0); + assert(as = 10 * cast(#size(Int): Int)); + assert(p > 0) +end. + +--- + +(source_file + (program_declaration + (var_section + (variable_declaration + (identifier_definition + (identifier)) + (identifier) + (literal + (integer))) + (variable_declaration + (identifier_definition + (identifier)) + (identifier) + (cast_expression + (traits_expression + (trait) + (identifier)) + (identifier))) + (variable_declaration + (identifier_definition + (identifier)) + (array_type + (literal + (integer)) + (identifier))) + (variable_declaration + (identifier_definition + (identifier)) + (identifier) + (cast_expression + (traits_expression + (trait) + (array_type + (literal + (integer)) + (identifier))) + (identifier))) + (variable_declaration + (identifier_definition + (identifier)) + (identifier) + (cast_expression + (traits_expression + (trait) + (identifier)) + (identifier)))) + (call_expression + (identifier) + (argument_list + (binary_expression + (identifier) + (literal + (integer))))) + (call_expression + (identifier) + (argument_list + (binary_expression + (identifier) + (binary_expression + (literal + (integer)) + (cast_expression + (traits_expression + (trait) + (identifier)) + (identifier)))))) + (call_expression + (identifier) + (argument_list + (binary_expression + (identifier) + (literal + (integer))))))) diff --git a/tools/tree-sitter/tree-sitter.json b/tools/tree-sitter/tree-sitter.json new file mode 100644 index 0000000..cfbe469 --- /dev/null +++ b/tools/tree-sitter/tree-sitter.json @@ -0,0 +1,18 @@ +{ + "grammars": [ + { + "name": "elna", + "camelcase": "Elna", + "scope": "source.elna", + "file-types": ["elna"], + "highlights": ["queries/elna/highlights.scm"], + "folds": ["queries/elna/folds.scm"], + "locals": ["queries/elna/locals.scm"], + "indents": ["queries/elna/indents.scm"] + } + ], + "metadata": { + "version": "0.1.0", + "license": "MPL-2.0" + } +} |
