Implement public keyword for functions
This commit is contained in:
parent
f00302c8af
commit
e80809b3f9
|
@ -7,10 +7,13 @@ edition = "2021"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["lua", "shulkerbox"]
|
default = ["lua", "shulkerbox"]
|
||||||
|
serde = ["dep:serde", "shulkerbox?/serde"]
|
||||||
shulkerbox = ["dep:shulkerbox"]
|
shulkerbox = ["dep:shulkerbox"]
|
||||||
serde = ["dep:serde"]
|
|
||||||
lua = ["dep:mlua"]
|
lua = ["dep:mlua"]
|
||||||
|
|
||||||
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||||
|
path-absolutize = { version = "3.1.1", features = ["use_unix_paths_on_wasm"] }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chksum-md5 = "0.0.0"
|
chksum-md5 = "0.0.0"
|
||||||
colored = "2.1.0"
|
colored = "2.1.0"
|
||||||
|
|
|
@ -4,7 +4,12 @@
|
||||||
|
|
||||||
### Program
|
### Program
|
||||||
```ebnf
|
```ebnf
|
||||||
Program: Declaration*;
|
Program: Namespace Declaration*;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Namespace
|
||||||
|
```ebnf
|
||||||
|
Namespace: 'namespace' StringLiteral;
|
||||||
```
|
```
|
||||||
|
|
||||||
### Declaration
|
### Declaration
|
||||||
|
@ -15,7 +20,7 @@ Declaration: FunctionDeclaration;
|
||||||
### FunctionDeclaration
|
### FunctionDeclaration
|
||||||
```ebnf
|
```ebnf
|
||||||
Function:
|
Function:
|
||||||
Annotation* 'fn' Identifier '(' ParameterList? ')' Block
|
Annotation* 'pub'? 'fn' Identifier '(' ParameterList? ')' Block
|
||||||
;
|
;
|
||||||
ParameterList:
|
ParameterList:
|
||||||
Identifier (',' Identifier)* ','?
|
Identifier (',' Identifier)* ','?
|
||||||
|
|
|
@ -19,6 +19,7 @@ use super::{error::UnterminatedDelimitedComment, Error};
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
pub enum KeywordKind {
|
pub enum KeywordKind {
|
||||||
Function,
|
Function,
|
||||||
|
Pub,
|
||||||
If,
|
If,
|
||||||
Else,
|
Else,
|
||||||
Align,
|
Align,
|
||||||
|
@ -76,6 +77,7 @@ impl KeywordKind {
|
||||||
pub fn as_str(self) -> &'static str {
|
pub fn as_str(self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Self::Function => "fn",
|
Self::Function => "fn",
|
||||||
|
Self::Pub => "pub",
|
||||||
Self::If => "if",
|
Self::If => "if",
|
||||||
Self::Else => "else",
|
Self::Else => "else",
|
||||||
Self::Align => "align",
|
Self::Align => "align",
|
||||||
|
|
|
@ -97,7 +97,7 @@ impl SourceElement for Annotation {
|
||||||
///
|
///
|
||||||
/// ``` ebnf
|
/// ``` ebnf
|
||||||
/// Function:
|
/// Function:
|
||||||
/// Annotation* 'fn' Identifier '(' ParameterList? ')' Block
|
/// Annotation* 'pub'? 'fn' Identifier '(' ParameterList? ')' Block
|
||||||
/// ;
|
/// ;
|
||||||
///
|
///
|
||||||
/// ParameterList:
|
/// ParameterList:
|
||||||
|
@ -107,6 +107,8 @@ impl SourceElement for Annotation {
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Getters)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Getters)]
|
||||||
pub struct Function {
|
pub struct Function {
|
||||||
|
#[get = "pub"]
|
||||||
|
public_keyword: Option<Keyword>,
|
||||||
#[get = "pub"]
|
#[get = "pub"]
|
||||||
annotations: Vec<Annotation>,
|
annotations: Vec<Annotation>,
|
||||||
#[get = "pub"]
|
#[get = "pub"]
|
||||||
|
@ -130,6 +132,7 @@ impl Function {
|
||||||
pub fn dissolve(
|
pub fn dissolve(
|
||||||
self,
|
self,
|
||||||
) -> (
|
) -> (
|
||||||
|
Option<Keyword>,
|
||||||
Vec<Annotation>,
|
Vec<Annotation>,
|
||||||
Keyword,
|
Keyword,
|
||||||
Identifier,
|
Identifier,
|
||||||
|
@ -139,6 +142,7 @@ impl Function {
|
||||||
Block,
|
Block,
|
||||||
) {
|
) {
|
||||||
(
|
(
|
||||||
|
self.public_keyword,
|
||||||
self.annotations,
|
self.annotations,
|
||||||
self.function_keyword,
|
self.function_keyword,
|
||||||
self.identifier,
|
self.identifier,
|
||||||
|
@ -148,11 +152,21 @@ impl Function {
|
||||||
self.block,
|
self.block,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if the function is public.
|
||||||
|
#[must_use]
|
||||||
|
pub fn is_public(&self) -> bool {
|
||||||
|
self.public_keyword.is_some()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SourceElement for Function {
|
impl SourceElement for Function {
|
||||||
fn span(&self) -> Span {
|
fn span(&self) -> Span {
|
||||||
self.function_keyword.span.join(&self.block.span()).unwrap()
|
self.public_keyword
|
||||||
|
.as_ref()
|
||||||
|
.map_or_else(|| self.function_keyword.span(), SourceElement::span)
|
||||||
|
.join(&self.block.span())
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,6 +245,7 @@ impl<'a> Parser<'a> {
|
||||||
let block = self.parse_block(handler)?;
|
let block = self.parse_block(handler)?;
|
||||||
|
|
||||||
Some(Declaration::Function(Function {
|
Some(Declaration::Function(Function {
|
||||||
|
public_keyword: None,
|
||||||
annotations: Vec::new(),
|
annotations: Vec::new(),
|
||||||
function_keyword,
|
function_keyword,
|
||||||
identifier,
|
identifier,
|
||||||
|
@ -241,6 +256,55 @@ impl<'a> Parser<'a> {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reading::Atomic(Token::Keyword(pub_keyword))
|
||||||
|
if pub_keyword.keyword == KeywordKind::Pub =>
|
||||||
|
{
|
||||||
|
// eat the public keyword
|
||||||
|
self.forward();
|
||||||
|
|
||||||
|
// parse the function keyword
|
||||||
|
let function_keyword_reading = self.next_significant_token();
|
||||||
|
|
||||||
|
match function_keyword_reading {
|
||||||
|
Reading::Atomic(Token::Keyword(function_keyword))
|
||||||
|
if function_keyword.keyword == KeywordKind::Function =>
|
||||||
|
{
|
||||||
|
// eat the function keyword
|
||||||
|
self.forward();
|
||||||
|
|
||||||
|
// parse the identifier
|
||||||
|
let identifier = self.parse_identifier(handler)?;
|
||||||
|
let delimited_tree = self.parse_enclosed_list(
|
||||||
|
Delimiter::Parenthesis,
|
||||||
|
',',
|
||||||
|
|parser: &mut Parser<'_>| parser.parse_identifier(handler),
|
||||||
|
handler,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// parse the block
|
||||||
|
let block = self.parse_block(handler)?;
|
||||||
|
|
||||||
|
Some(Declaration::Function(Function {
|
||||||
|
public_keyword: Some(pub_keyword),
|
||||||
|
annotations: Vec::new(),
|
||||||
|
function_keyword,
|
||||||
|
identifier,
|
||||||
|
open_paren: delimited_tree.open,
|
||||||
|
parameters: delimited_tree.list,
|
||||||
|
close_paren: delimited_tree.close,
|
||||||
|
block,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
unexpected => {
|
||||||
|
handler.receive(Error::UnexpectedSyntax(UnexpectedSyntax {
|
||||||
|
expected: SyntaxKind::Keyword(KeywordKind::Function),
|
||||||
|
found: unexpected.into_token(),
|
||||||
|
}));
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// parse annotations
|
// parse annotations
|
||||||
Reading::Atomic(Token::Punctuation(punctuation)) if punctuation.punctuation == '#' => {
|
Reading::Atomic(Token::Punctuation(punctuation)) if punctuation.punctuation == '#' => {
|
||||||
// parse the annotation
|
// parse the annotation
|
||||||
|
|
Loading…
Reference in New Issue