Add object-oriented constructs

Another EPITA extension, although this is mentionned in the book.
This commit is contained in:
Bruno BELANYI 2022-06-04 21:10:23 +02:00
parent 21172e21e7
commit 60804f0ff0
5 changed files with 6390 additions and 3620 deletions

View file

@ -25,6 +25,8 @@ module.exports = grammar({
$._type_identifier,
$._field_identifier,
$._function_declaration_common,
$._class_declaration_common,
$._class_field,
],
conflicts: ($) => [
@ -75,6 +77,9 @@ module.exports = grammar({
$.break_expression,
$.let_expression,
$.new_expression,
$.method_call,
$.meta_cast,
$.meta_expression,
),
@ -263,6 +268,7 @@ module.exports = grammar({
_declaration_chunk: ($) => prec.left(
choice(
repeat1($.type_declaration),
repeat1($.class_declaration),
repeat1(choice($.function_declaration, $.primitive_declaration)),
$.variable_declaration,
$.import_declaration,
@ -280,6 +286,7 @@ module.exports = grammar({
$.type_alias,
$.record_type,
$.array_type,
$.class_type,
),
type_alias: ($) => $._type_identifier,
@ -349,6 +356,61 @@ 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(

View file

@ -90,6 +90,14 @@
"type": "SYMBOL",
"name": "let_expression"
},
{
"type": "SYMBOL",
"name": "new_expression"
},
{
"type": "SYMBOL",
"name": "method_call"
},
{
"type": "SYMBOL",
"name": "meta_cast"
@ -1110,6 +1118,13 @@
"name": "type_declaration"
}
},
{
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "class_declaration"
}
},
{
"type": "REPEAT1",
"content": {
@ -1180,6 +1195,10 @@
{
"type": "SYMBOL",
"name": "array_type"
},
{
"type": "SYMBOL",
"name": "class_type"
}
]
},
@ -1544,6 +1563,227 @@
}
]
},
"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": [
@ -1712,7 +1952,9 @@
"inline": [
"_type_identifier",
"_field_identifier",
"_function_declaration_common"
"_function_declaration_common",
"_class_declaration_common",
"_class_field"
],
"supertypes": []
}

View file

@ -63,6 +63,14 @@
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
@ -153,6 +161,14 @@
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
@ -305,6 +321,14 @@
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
@ -423,6 +447,14 @@
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
@ -529,6 +561,14 @@
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
@ -629,6 +669,14 @@
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
@ -661,6 +709,234 @@
}
}
},
{
"type": "class_declaration",
"named": true,
"fields": {
"fields": {
"multiple": true,
"required": false,
"types": [
{
"type": "field_declaration",
"named": true
},
{
"type": "method_declaration",
"named": true
}
]
},
"name": {
"multiple": false,
"required": true,
"types": [
{
"type": "identifier",
"named": true
}
]
}
},
"children": {
"multiple": false,
"required": false,
"types": [
{
"type": "extends_qualifier",
"named": true
}
]
}
},
{
"type": "class_type",
"named": true,
"fields": {
"fields": {
"multiple": true,
"required": false,
"types": [
{
"type": "field_declaration",
"named": true
},
{
"type": "method_declaration",
"named": true
}
]
}
},
"children": {
"multiple": false,
"required": false,
"types": [
{
"type": "extends_qualifier",
"named": true
}
]
}
},
{
"type": "extends_qualifier",
"named": true,
"fields": {
"super": {
"multiple": false,
"required": true,
"types": [
{
"type": "meta_type_identifier",
"named": true
},
{
"type": "type_identifier",
"named": true
}
]
}
}
},
{
"type": "field_declaration",
"named": true,
"fields": {
"name": {
"multiple": false,
"required": true,
"types": [
{
"type": "identifier",
"named": true
}
]
},
"type": {
"multiple": false,
"required": false,
"types": [
{
"type": "meta_type_identifier",
"named": true
},
{
"type": "type_identifier",
"named": true
}
]
},
"value": {
"multiple": false,
"required": true,
"types": [
{
"type": "array_expression",
"named": true
},
{
"type": "array_value",
"named": true
},
{
"type": "assignment_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
},
{
"type": "break_expression",
"named": true
},
{
"type": "for_expression",
"named": true
},
{
"type": "function_call",
"named": true
},
{
"type": "identifier",
"named": true
},
{
"type": "if_expression",
"named": true
},
{
"type": "integer_literal",
"named": true
},
{
"type": "let_expression",
"named": true
},
{
"type": "meta_cast",
"named": true
},
{
"type": "meta_expression",
"named": true
},
{
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
},
{
"type": "record_expression",
"named": true
},
{
"type": "record_value",
"named": true
},
{
"type": "sequence_expression",
"named": true
},
{
"type": "string_literal",
"named": true
},
{
"type": "unary_expression",
"named": true
},
{
"type": "while_expression",
"named": true
}
]
}
},
"children": {
"multiple": false,
"required": true,
"types": [
{
"type": "operator",
"named": true
}
]
}
},
{
"type": "for_expression",
"named": true,
@ -725,6 +1001,14 @@
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
@ -815,6 +1099,14 @@
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
@ -915,6 +1207,14 @@
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
@ -1025,6 +1325,14 @@
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
@ -1131,6 +1439,14 @@
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
@ -1261,6 +1577,14 @@
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
@ -1351,6 +1675,14 @@
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
@ -1441,6 +1773,14 @@
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
@ -1557,6 +1897,14 @@
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
@ -1591,6 +1939,10 @@
"multiple": true,
"required": false,
"types": [
{
"type": "class_declaration",
"named": true
},
{
"type": "function_declaration",
"named": true
@ -1683,6 +2035,14 @@
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
@ -1721,6 +2081,10 @@
"type": "array_type",
"named": true
},
{
"type": "class_type",
"named": true
},
{
"type": "record_type",
"named": true
@ -1796,6 +2160,304 @@
]
}
},
{
"type": "method_call",
"named": true,
"fields": {
"arguments": {
"multiple": true,
"required": false,
"types": [
{
"type": ",",
"named": false
},
{
"type": "array_expression",
"named": true
},
{
"type": "array_value",
"named": true
},
{
"type": "assignment_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
},
{
"type": "break_expression",
"named": true
},
{
"type": "for_expression",
"named": true
},
{
"type": "function_call",
"named": true
},
{
"type": "identifier",
"named": true
},
{
"type": "if_expression",
"named": true
},
{
"type": "integer_literal",
"named": true
},
{
"type": "let_expression",
"named": true
},
{
"type": "meta_cast",
"named": true
},
{
"type": "meta_expression",
"named": true
},
{
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
},
{
"type": "record_expression",
"named": true
},
{
"type": "record_value",
"named": true
},
{
"type": "sequence_expression",
"named": true
},
{
"type": "string_literal",
"named": true
},
{
"type": "unary_expression",
"named": true
},
{
"type": "while_expression",
"named": true
}
]
},
"method": {
"multiple": false,
"required": true,
"types": [
{
"type": "identifier",
"named": true
}
]
},
"object": {
"multiple": false,
"required": true,
"types": [
{
"type": "array_value",
"named": true
},
{
"type": "identifier",
"named": true
},
{
"type": "meta_lvalue",
"named": true
},
{
"type": "record_value",
"named": true
}
]
}
}
},
{
"type": "method_declaration",
"named": true,
"fields": {
"body": {
"multiple": false,
"required": true,
"types": [
{
"type": "array_expression",
"named": true
},
{
"type": "array_value",
"named": true
},
{
"type": "assignment_expression",
"named": true
},
{
"type": "binary_expression",
"named": true
},
{
"type": "break_expression",
"named": true
},
{
"type": "for_expression",
"named": true
},
{
"type": "function_call",
"named": true
},
{
"type": "identifier",
"named": true
},
{
"type": "if_expression",
"named": true
},
{
"type": "integer_literal",
"named": true
},
{
"type": "let_expression",
"named": true
},
{
"type": "meta_cast",
"named": true
},
{
"type": "meta_expression",
"named": true
},
{
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
},
{
"type": "record_expression",
"named": true
},
{
"type": "record_value",
"named": true
},
{
"type": "sequence_expression",
"named": true
},
{
"type": "string_literal",
"named": true
},
{
"type": "unary_expression",
"named": true
},
{
"type": "while_expression",
"named": true
}
]
},
"name": {
"multiple": false,
"required": true,
"types": [
{
"type": "identifier",
"named": true
}
]
},
"parameters": {
"multiple": false,
"required": true,
"types": [
{
"type": "parameters",
"named": true
}
]
},
"return_type": {
"multiple": false,
"required": false,
"types": [
{
"type": "meta_type_identifier",
"named": true
},
{
"type": "type_identifier",
"named": true
}
]
}
}
},
{
"type": "new_expression",
"named": true,
"fields": {
"class": {
"multiple": false,
"required": true,
"types": [
{
"type": "meta_type_identifier",
"named": true
},
{
"type": "type_identifier",
"named": true
}
]
}
}
},
{
"type": "parameters",
"named": true,
@ -1940,6 +2602,14 @@
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
@ -2118,6 +2788,14 @@
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
@ -2177,6 +2855,10 @@
"type": "break_expression",
"named": true
},
{
"type": "class_declaration",
"named": true
},
{
"type": "for_expression",
"named": true
@ -2225,6 +2907,14 @@
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
@ -2324,6 +3014,10 @@
"type": "array_type",
"named": true
},
{
"type": "class_type",
"named": true
},
{
"type": "record_type",
"named": true
@ -2400,6 +3094,14 @@
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
@ -2530,6 +3232,14 @@
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
@ -2636,6 +3346,14 @@
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
@ -2726,6 +3444,14 @@
"type": "meta_lvalue",
"named": true
},
{
"type": "method_call",
"named": true
},
{
"type": "new_expression",
"named": true
},
{
"type": "nil_literal",
"named": true
@ -2826,6 +3552,10 @@
"type": "break_expression",
"named": true
},
{
"type": "class",
"named": false
},
{
"type": "comment",
"named": true
@ -2846,6 +3576,10 @@
"type": "escape_sequence",
"named": true
},
{
"type": "extends",
"named": false
},
{
"type": "field_identifier",
"named": true
@ -2882,6 +3616,14 @@
"type": "let",
"named": false
},
{
"type": "method",
"named": false
},
{
"type": "new",
"named": false
},
{
"type": "nil_literal",
"named": true

File diff suppressed because it is too large Load diff

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))))