Compare commits

...

18 commits

Author SHA1 Message Date
Bruno BELANYI 2b2a75af43 Release 0.1.0
All checks were successful
continuous-integration/drone/push Build is passing
With the extensions now integrated, and most queries being in a state
fit to start testing them, this is good enough for a first release.
2022-06-04 22:06:06 +02:00
Bruno BELANYI 5862966ddf Add README 2022-06-04 22:04:10 +02:00
Bruno BELANYI d6f624ebda Add method text objects 2022-06-04 22:02:34 +02:00
Bruno BELANYI a522aab9cd Add class text objects 2022-06-04 22:00:08 +02:00
Bruno BELANYI 7d0ab1f40c Add object-oriented indents 2022-06-04 21:54:44 +02:00
Bruno BELANYI 2e08482c67 Add object-oriented folds 2022-06-04 21:52:39 +02:00
Bruno BELANYI c9efe870ab Add class tags 2022-06-04 21:50:45 +02:00
Bruno BELANYI 746c8d27b8 Add method tags 2022-06-04 21:45:54 +02:00
Bruno BELANYI b1c2da4cb4 Add 'self' built-in variable high-lighting 2022-06-04 21:45:54 +02:00
Bruno BELANYI acb5765591 Make 'method' keyword more specific 2022-06-04 21:45:54 +02:00
Bruno BELANYI 065ad5f760 Make 'new' constructor keyword 2022-06-04 21:45:54 +02:00
Bruno BELANYI 9c51cbc93f Add 'Object' built-in type 2022-06-04 21:45:54 +02:00
Bruno BELANYI 425890a6fc Add methods high-lighting 2022-06-04 21:45:54 +02:00
Bruno BELANYI 555e10c736 Add object-oriented keywords high-lighting 2022-06-04 21:45:54 +02:00
Bruno BELANYI 60804f0ff0 Add object-oriented constructs
Another EPITA extension, although this is mentionned in the book.
2022-06-04 21:45:47 +02:00
Bruno BELANYI 21172e21e7 Fix assignment priority
The assignment operator is lower priority than any other binary
operator.

Otherwise the following:

```tiger
a := b | c
```

Would be parsed as:

```tiger
(a := b) | c
```

Instead of the expected:

```tiger
a := (b | c)
```
2022-06-04 21:45:40 +02:00
Bruno BELANYI 869b0bf79a Add meta-variable keywords high-lighting 2022-06-04 21:45:40 +02:00
Bruno BELANYI 572dab6f4b Add meta-variables
This is an EPITA extension of the language, used mostly by internal
compiler machinery.
2022-06-04 21:45:33 +02:00
20 changed files with 10101 additions and 4458 deletions

View file

@ -1,7 +1,7 @@
[package]
name = "tree-sitter-tiger"
description = "Tiger grammar for the tree-sitter parsing library"
version = "0.0.1"
version = "0.1.0"
keywords = ["incremental", "parsing", "tiger"]
categories = ["parsing", "text-editors"]
repository = "https://gitea.belanyi.fr/ambroisie/tree-sitter-tiger"

11
README.md Normal file
View file

@ -0,0 +1,11 @@
# tree-sitter-tiger
Tiger grammar for [tree-sitter](https://github.com/tree-sitter/tree-sitter).
It includes extensions to the language that are specific to the EPITA dialect of
Tiger: meta-variables, and Object Oriented syntax.
## References
- [EPITA's Tiger assignment website](https://assignments.lrde.epita.fr/)
- [Official website for A. W. Appel's book](https://www.cs.princeton.edu/~appel/modern/)

View file

@ -7,12 +7,12 @@ function sepBy(sep, rule) {
}
const PREC = {
assign: 6,
multiplicative: 5,
additive: 4,
comparative: 3,
and: 2,
or: 1,
multiplicative: 6,
additive: 5,
comparative: 4,
and: 3,
or: 2,
assign: 1,
};
module.exports = grammar({
@ -25,10 +25,13 @@ module.exports = grammar({
$._type_identifier,
$._field_identifier,
$._function_declaration_common,
$._class_declaration_common,
$._class_field,
],
conflicts: ($) => [
[$._lvalue, $.array_expression],
[$._lvalue, $.record_expression],
[$._lvalue, $._type_identifier],
],
@ -73,6 +76,12 @@ module.exports = grammar({
$.for_expression,
$.break_expression,
$.let_expression,
$.new_expression,
$.method_call,
$.meta_cast,
$.meta_expression,
),
nil_literal: (_) => "nil",
@ -88,7 +97,10 @@ module.exports = grammar({
// NOTE: includes reserved identifiers
identifier: (_) => /[_a-zA-Z0-9]+/,
_type_identifier: ($) => alias($.identifier, $.type_identifier),
_type_identifier: ($) => choice(
alias($.identifier, $.type_identifier),
$.meta_type_identifier,
),
_field_identifier: ($) => alias($.identifier, $.field_identifier),
@ -112,6 +124,7 @@ module.exports = grammar({
$.identifier,
$.record_value,
$.array_value,
$.meta_lvalue,
),
record_value: ($) => seq(
@ -245,11 +258,17 @@ module.exports = grammar({
// Declarations {{{
_declaration_chunks: ($) => repeat1($._declaration_chunk),
_declaration_chunks: ($) => repeat1(
choice(
$.meta_chunks,
$._declaration_chunk,
),
),
_declaration_chunk: ($) => prec.left(
choice(
repeat1($.type_declaration),
repeat1($.class_declaration),
repeat1(choice($.function_declaration, $.primitive_declaration)),
$.variable_declaration,
$.import_declaration,
@ -267,6 +286,7 @@ module.exports = grammar({
$.type_alias,
$.record_type,
$.array_type,
$.class_type,
),
type_alias: ($) => $._type_identifier,
@ -335,6 +355,102 @@ module.exports = grammar({
),
// }}}
// Object Oriented {{{
new_expression: ($) => seq(
"new",
field("class", $._type_identifier),
),
method_call: ($) => seq(
field("object", $._lvalue),
".",
field("method", $.identifier),
"(",
field("arguments", sepBy(",", $._expr)),
")",
),
class_declaration: ($) => seq(
"class",
field("name", $.identifier),
$._class_declaration_common,
),
class_type: ($) => seq(
"class",
$._class_declaration_common,
),
_class_declaration_common: ($) => seq(
optional($.extends_qualifier),
"{",
field("fields", repeat($._class_field)),
"}",
),
extends_qualifier: ($) => seq(
"extends",
field("super", $._type_identifier),
),
_class_field: ($) => choice(
$._field_declaration,
$.method_declaration,
),
_field_declaration: ($) => alias($.variable_declaration, $.field_declaration),
method_declaration: ($) => seq(
"method",
$._function_declaration_common,
"=",
field("body", $._expr),
),
// }}}
// Meta-variables {{{
meta_chunks: ($) => seq(
"_chunks",
"(",
field("index", $.integer_literal),
")",
),
meta_cast: ($) => seq(
"_cast",
"(",
field("expression", $._expr),
",",
field("type", $._type),
")",
),
meta_expression: ($) => seq(
"_exp",
"(",
field("index", $.integer_literal),
")",
),
meta_lvalue: ($) => seq(
"_lvalue",
"(",
field("index", $.integer_literal),
")",
),
meta_type_identifier: ($) => seq(
"_namety",
"(",
$.integer_literal,
")",
),
// }}}
}
});

View file

@ -1,6 +1,6 @@
{
"name": "tree-sitter-tiger",
"version": "0.0.1",
"version": "0.1.0",
"description": "tiger grammar for tree-sitter",
"main": "bindings/node",
"keywords": [

View file

@ -8,6 +8,10 @@
(let_expression)
(function_declaration)
(primitive_declaration)
(class_declaration)
(class_type)
(method_declaration)
] @fold
[

View file

@ -5,7 +5,11 @@
(#is-not? local))
((type_identifier) @type.builtin
(#match? @type.builtin "^(int|string)$")
(#match? @type.builtin "^(int|string|Object)$")
(#is-not? local))
((identifier) @variable.builtin
(#match? @variable.builtin "^self$")
(#is-not? local))
; }}}
@ -22,6 +26,14 @@
"while"
] @keyword.repeat
[
"new"
] @keyword.constructor
[
"method"
] @keyword.method
[
"array"
(break_expression)
@ -41,6 +53,17 @@
"type"
"var"
"while"
"class"
"extends"
"method"
"new"
"_cast"
"_chunks"
"_exp"
"_lvalue"
"_namety"
] @keyword
; }}}
@ -64,7 +87,7 @@
] @punctuation.bracket
; }}}
; Functions {{{
; Functions and methods {{{
(function_call
function: (identifier) @function)
(function_declaration
@ -72,6 +95,11 @@
(primitive_declaration
name: (identifier) @function)
(method_call
method: (identifier) @method)
(method_declaration
name: (identifier) @method)
(parameters
name: (identifier) @variable.parameter)
; }}}

View file

@ -10,6 +10,13 @@
body: (_) @indent)
; }}}
; Class {{{
(class_declaration
fields: (_)* @indent)
(class_type
fields: (_)* @indent)
; }}}
; Misc{{{
(comment) @ignore
(string_literal) @ignore

View file

@ -8,4 +8,25 @@
function: (identifier) @name) @reference.call
; }}}
; Class {{{
(class_declaration
name: (identifier) @name) @definition.class
(type_declaration
name: (identifier) @name
(class_type)) @definition.class
(new_expression
class: (type_identifier) @name) @reference.class
(extends_qualifier
super: (type_identifier) @name) @reference.class
; }}}
; Methods {{{
(method_declaration
name: (identifier) @name) @definition.method
(method_call
method: (identifier) @name) @reference.call
; }}}
; vim: sw=2 foldmethod=marker

View file

@ -1,12 +1,19 @@
; Functions {{{
; Functions and methods {{{
(function_declaration
parameters: ((_) @parameter.inner)* @parameter.outer
body: (_) @function.inner) @function.outer
(primitive_declaration
parameters: ((_) @parameter.inner)* @parameter.outer) @function.outer
(method_declaration
parameters: ((_) @parameter.inner)* @parameter.outer
body: (_) @function.inner) @function.outer
(function_call
arguments: ((_) @call.inner)*) @call.outer
(method_call
arguments: ((_) @call.inner)*) @call.outer
; }}}
; Control flow {{{
@ -21,6 +28,13 @@
body: (_) @loop.inner) @loop.outer
; }}}
; Class {{{
(class_declaration
fields: (_)* @class.inner) @class.outer
(class_type
fields: (_)* @class.inner) @class.outer
; }}}
; Misc {{{
(comment) @comment.outer
; }}}

View file

@ -89,6 +89,22 @@
{
"type": "SYMBOL",
"name": "let_expression"
},
{
"type": "SYMBOL",
"name": "new_expression"
},
{
"type": "SYMBOL",
"name": "method_call"
},
{
"type": "SYMBOL",
"name": "meta_cast"
},
{
"type": "SYMBOL",
"name": "meta_expression"
}
]
},
@ -134,13 +150,22 @@
"value": "[_a-zA-Z0-9]+"
},
"_type_identifier": {
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "identifier"
},
"named": true,
"value": "type_identifier"
"type": "CHOICE",
"members": [
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "identifier"
},
"named": true,
"value": "type_identifier"
},
{
"type": "SYMBOL",
"name": "meta_type_identifier"
}
]
},
"_field_identifier": {
"type": "ALIAS",
@ -245,6 +270,10 @@
{
"type": "SYMBOL",
"name": "array_value"
},
{
"type": "SYMBOL",
"name": "meta_lvalue"
}
]
},
@ -391,7 +420,7 @@
"members": [
{
"type": "PREC_LEFT",
"value": 5,
"value": 6,
"content": {
"type": "SEQ",
"members": [
@ -438,7 +467,7 @@
},
{
"type": "PREC_LEFT",
"value": 4,
"value": 5,
"content": {
"type": "SEQ",
"members": [
@ -485,7 +514,7 @@
},
{
"type": "PREC_LEFT",
"value": 3,
"value": 4,
"content": {
"type": "SEQ",
"members": [
@ -548,7 +577,7 @@
},
{
"type": "PREC_LEFT",
"value": 2,
"value": 3,
"content": {
"type": "SEQ",
"members": [
@ -586,7 +615,7 @@
},
{
"type": "PREC_LEFT",
"value": 1,
"value": 2,
"content": {
"type": "SEQ",
"members": [
@ -809,7 +838,7 @@
},
"assignment_expression": {
"type": "PREC_RIGHT",
"value": 6,
"value": 1,
"content": {
"type": "SEQ",
"members": [
@ -1063,8 +1092,17 @@
"_declaration_chunks": {
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "_declaration_chunk"
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "meta_chunks"
},
{
"type": "SYMBOL",
"name": "_declaration_chunk"
}
]
}
},
"_declaration_chunk": {
@ -1080,6 +1118,13 @@
"name": "type_declaration"
}
},
{
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "class_declaration"
}
},
{
"type": "REPEAT1",
"content": {
@ -1150,6 +1195,10 @@
{
"type": "SYMBOL",
"name": "array_type"
},
{
"type": "SYMBOL",
"name": "class_type"
}
]
},
@ -1513,6 +1562,360 @@
}
}
]
},
"new_expression": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "new"
},
{
"type": "FIELD",
"name": "class",
"content": {
"type": "SYMBOL",
"name": "_type_identifier"
}
}
]
},
"method_call": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "object",
"content": {
"type": "SYMBOL",
"name": "_lvalue"
}
},
{
"type": "STRING",
"value": "."
},
{
"type": "FIELD",
"name": "method",
"content": {
"type": "SYMBOL",
"name": "identifier"
}
},
{
"type": "STRING",
"value": "("
},
{
"type": "FIELD",
"name": "arguments",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_expr"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_expr"
}
]
}
}
]
},
{
"type": "BLANK"
}
]
}
},
{
"type": "STRING",
"value": ")"
}
]
},
"class_declaration": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "class"
},
{
"type": "FIELD",
"name": "name",
"content": {
"type": "SYMBOL",
"name": "identifier"
}
},
{
"type": "SYMBOL",
"name": "_class_declaration_common"
}
]
},
"class_type": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "class"
},
{
"type": "SYMBOL",
"name": "_class_declaration_common"
}
]
},
"_class_declaration_common": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "extends_qualifier"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "{"
},
{
"type": "FIELD",
"name": "fields",
"content": {
"type": "REPEAT",
"content": {
"type": "SYMBOL",
"name": "_class_field"
}
}
},
{
"type": "STRING",
"value": "}"
}
]
},
"extends_qualifier": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "extends"
},
{
"type": "FIELD",
"name": "super",
"content": {
"type": "SYMBOL",
"name": "_type_identifier"
}
}
]
},
"_class_field": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_field_declaration"
},
{
"type": "SYMBOL",
"name": "method_declaration"
}
]
},
"_field_declaration": {
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "variable_declaration"
},
"named": true,
"value": "field_declaration"
},
"method_declaration": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "method"
},
{
"type": "SYMBOL",
"name": "_function_declaration_common"
},
{
"type": "STRING",
"value": "="
},
{
"type": "FIELD",
"name": "body",
"content": {
"type": "SYMBOL",
"name": "_expr"
}
}
]
},
"meta_chunks": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "_chunks"
},
{
"type": "STRING",
"value": "("
},
{
"type": "FIELD",
"name": "index",
"content": {
"type": "SYMBOL",
"name": "integer_literal"
}
},
{
"type": "STRING",
"value": ")"
}
]
},
"meta_cast": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "_cast"
},
{
"type": "STRING",
"value": "("
},
{
"type": "FIELD",
"name": "expression",
"content": {
"type": "SYMBOL",
"name": "_expr"
}
},
{
"type": "STRING",
"value": ","
},
{
"type": "FIELD",
"name": "type",
"content": {
"type": "SYMBOL",
"name": "_type"
}
},
{
"type": "STRING",
"value": ")"
}
]
},
"meta_expression": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "_exp"
},
{
"type": "STRING",
"value": "("
},
{
"type": "FIELD",
"name": "index",
"content": {
"type": "SYMBOL",
"name": "integer_literal"
}
},
{
"type": "STRING",
"value": ")"
}
]
},
"meta_lvalue": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "_lvalue"
},
{
"type": "STRING",
"value": "("
},
{
"type": "FIELD",
"name": "index",
"content": {
"type": "SYMBOL",
"name": "integer_literal"
}
},
{
"type": "STRING",
"value": ")"
}
]
},
"meta_type_identifier": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "_namety"
},
{
"type": "STRING",
"value": "("
},
{
"type": "SYMBOL",
"name": "integer_literal"
},
{
"type": "STRING",
"value": ")"
}
]
}
},
"extras": [
@ -1530,6 +1933,10 @@
"_lvalue",
"array_expression"
],
[
"_lvalue",
"record_expression"
],
[
"_lvalue",
"_type_identifier"
@ -1545,7 +1952,9 @@
"inline": [
"_type_identifier",
"_field_identifier",
"_function_declaration_common"
"_function_declaration_common",
"_class_declaration_common",
"_class_field"
],
"supertypes": []
}

File diff suppressed because it is too large Load diff

12346
src/parser.c

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,65 @@
================================================================================
Meta chunks
================================================================================
_chunks(42)
--------------------------------------------------------------------------------
(source_file
(meta_chunks
index: (integer_literal)))
================================================================================
Cast
================================================================================
_cast(42, string)
--------------------------------------------------------------------------------
(source_file
(meta_cast
expression: (integer_literal)
type: (type_alias
(type_identifier))))
================================================================================
Meta expression
================================================================================
_exp(42)
--------------------------------------------------------------------------------
(source_file
(meta_expression
index: (integer_literal)))
================================================================================
Meta lvalue
================================================================================
_lvalue(42)
--------------------------------------------------------------------------------
(source_file
(meta_lvalue
index: (integer_literal)))
================================================================================
Meta type identifier
================================================================================
var a : _namety(42) := "I'm So Meta Even This Acronym"
--------------------------------------------------------------------------------
(source_file
(variable_declaration
name: (identifier)
type: (meta_type_identifier
(integer_literal))
(operator)
value: (string_literal)))

View file

@ -0,0 +1,132 @@
================================================================================
New expression
================================================================================
new Object
--------------------------------------------------------------------------------
(source_file
(new_expression
class: (type_identifier)))
================================================================================
Method call
================================================================================
object.method(12, "27")
--------------------------------------------------------------------------------
(source_file
(method_call
object: (identifier)
method: (identifier)
arguments: (integer_literal)
arguments: (string_literal)))
================================================================================
Class declaration
================================================================================
class A { }
--------------------------------------------------------------------------------
(source_file
(class_declaration
name: (identifier)))
================================================================================
Class type
================================================================================
type A = class { }
--------------------------------------------------------------------------------
(source_file
(type_declaration
(identifier)
(class_type)))
================================================================================
Class declaration extends
================================================================================
class A extends Object { }
--------------------------------------------------------------------------------
(source_file
(class_declaration
name: (identifier)
(extends_qualifier
super: (type_identifier))))
================================================================================
Class type
================================================================================
type A = class extends Object { }
--------------------------------------------------------------------------------
(source_file
(type_declaration
name: (identifier)
value: (class_type
(extends_qualifier
super: (type_identifier)))))
================================================================================
Class field
================================================================================
class A {
var a : int := 12
var b := 27
}
--------------------------------------------------------------------------------
(source_file
(class_declaration
name: (identifier)
fields: (field_declaration
name: (identifier)
type: (type_identifier)
(operator)
value: (integer_literal))
fields: (field_declaration
name: (identifier)
(operator)
value: (integer_literal))))
================================================================================
Class method
================================================================================
class A {
method m(a: int, b: string) : int = a
method n() = ()
}
--------------------------------------------------------------------------------
(source_file
(class_declaration
name: (identifier)
fields: (method_declaration
name: (identifier)
parameters: (parameters
name: (identifier)
type: (type_identifier)
name: (identifier)
type: (type_identifier))
return_type: (type_identifier)
body: (identifier))
fields: (method_declaration
name: (identifier)
parameters: (parameters)
body: (sequence_expression))))

View file

@ -0,0 +1,16 @@
================================================================================
Assignment precedence
================================================================================
a := b | c
--------------------------------------------------------------------------------
(source_file
(assignment_expression
(identifier)
(operator)
(binary_expression
(identifier)
(operator)
(identifier))))

View file

@ -13,10 +13,19 @@ let
var c : int := "This is an \"int\""
/* ^ type.builtin (not sure why it isn't 'type')*/
var d : Object := nil
/* ^ type.builtin */
type Object = int
var self := "self"
in
let
var c : int := "This is an int"
/* ^ type.builtin (not sure why it isn't 'type')*/
var d : Object := "This is an object"
/* ^ type.builtin (not sure why it isn't 'type')*/
in
end;
@ -26,6 +35,9 @@ in
print("shadowing is fun");
/* <- function.builtin */
self;
/* <- variable */
b := print
/* ^ variable */
end

View file

@ -0,0 +1,13 @@
let
_chunks(42)
/* <- keyword */
in
_lvalue(12) : _namety(42) := _cast("I'm So Meta Even This Acronym", string);
/* <- keyword */
/* ^ keyword */
/* ^ keyword */
_exp(42)
/* <- keyword */
end

View file

@ -0,0 +1,28 @@
let
class A extends Object {}
/* <- keyword */
/* ^ keyword */
/* ^ type.builtin */
type B = class extends A {
/* ^ keyword */
/* ^ keyword */
/* ^ type */
var a := 12
method meth() : int = self.a
/* <- keyword.method */
/* ^ method */
/* ^ variable.builtin */
}
var object := new B
/* ^ keyword.constructor */
in
object.a := 27;
/* ^ property */
object.meth()
/* ^ method */
end

9
test/tags/classes.tig Normal file
View file

@ -0,0 +1,9 @@
class A {}
/* ^ definition.class */
type B = class extends A {}
/* ^ definition.class */
/* ^ reference.class */
var object := new B
/* ^ reference.class */

11
test/tags/methods.tig Normal file
View file

@ -0,0 +1,11 @@
let
class A {
method meth() = ()
/* ^ definition.method */
}
object := new A
in
object.meth()
/* ^ reference.call */
end