Skip to content
This repository has been archived by the owner on Jul 29, 2024. It is now read-only.

Fix defining predeclared items #89

Merged
merged 5 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion src/ast/declarations/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use derive_more::From;
use crate::{
ast::{Annotation, Expression, Statement, TypeReference},
syntax::{
error::ParseError, Context, Identifier, Keyword, Lexer, OperatorKind, Parse, Ranged, StartsHere, StringWithOffset, Token
error::ParseError, Context, Identifier, Keyword, Lexer, OperatorKind, Parse, Ranged,
StartsHere, StringWithOffset, Token,
},
};

Expand Down Expand Up @@ -163,6 +164,19 @@ pub struct FunctionDeclaration {
pub annotations: Vec<Annotation>,
}

impl Ranged for FunctionDeclaration {
fn start(&self) -> usize {
self.keyword.start()
}

fn end(&self) -> usize {
self.body
.last()
// FIXME: respect return_type, name_parts, generic_parameters
.map_or_else(|| self.keyword.end(), |s| s.end())
}
}

impl StartsHere for FunctionDeclaration {
/// Check that function declaration may start at current lexer position
fn starts_here(context: &mut Context<impl Lexer>) -> bool {
Expand Down
16 changes: 15 additions & 1 deletion src/ast/declarations/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
mod function;
use std::ops::Range;

pub use function::*;

mod types;
Expand All @@ -15,7 +17,7 @@ use ast_derive::AST;

use crate::syntax::{
error::{MissingDeclaration, ParseError},
Context, Lexer, Parse, StartsHere, Token,
Context, Lexer, Parse, Ranged, StartsHere, Token,
};

use derive_more::From;
Expand All @@ -29,6 +31,18 @@ pub enum Declaration {
Trait(TraitDeclaration),
}

impl Ranged for Declaration {
fn range(&self) -> Range<usize> {
use Declaration::*;
match self {
Variable(s) => s.range(),
Type(s) => s.range(),
Function(s) => s.range(),
Trait(s) => s.range(),
}
}
}

impl StartsHere for Declaration {
/// Check literal may start at current lexer position
fn starts_here(context: &mut Context<impl Lexer>) -> bool {
Expand Down
20 changes: 18 additions & 2 deletions src/ast/declarations/trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ extern crate ast_derive;
use ast_derive::AST;

use crate::syntax::{
error::ParseError, Context, Identifier, Keyword, Lexer, Parse, StartsHere, Token
error::ParseError, Context, Identifier, Keyword, Lexer, Parse, Ranged, StartsHere, Token,
};

use super::FunctionDeclaration;
Expand All @@ -18,6 +18,18 @@ pub struct TraitDeclaration {
pub functions: Vec<FunctionDeclaration>,
}

impl Ranged for TraitDeclaration {
fn start(&self) -> usize {
self.keyword.start()
}

fn end(&self) -> usize {
self.functions
.last()
.map_or_else(|| self.name.end(), |s| s.end())
}
}

impl StartsHere for TraitDeclaration {
/// Check that type declaration may start at current lexer position
fn starts_here(context: &mut Context<impl Lexer>) -> bool {
Expand All @@ -38,6 +50,10 @@ impl Parse for TraitDeclaration {

let functions = context.parse_block(FunctionDeclaration::parse)?;

Ok(TraitDeclaration { keyword, name, functions })
Ok(TraitDeclaration {
keyword,
name,
functions,
})
}
}
25 changes: 24 additions & 1 deletion src/ast/declarations/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use ast_derive::AST;
use crate::{
ast::{Annotation, TypeReference},
syntax::{
error::ParseError, Context, Identifier, Keyword, Lexer, Parse, StartsHere, Token
error::ParseError, Context, Identifier, Keyword, Lexer, Parse, Ranged, StartsHere, Token,
},
};

Expand All @@ -17,6 +17,16 @@ pub struct Member {
pub ty: TypeReference,
}

impl Ranged for Member {
fn start(&self) -> usize {
self.name.start()
}

fn end(&self) -> usize {
self.ty.end()
}
}

/// Parse single or multiple members, if they are separated by comma
pub fn parse_members(context: &mut Context<impl Lexer>) -> Result<Vec<Member>, ParseError> {
let names = context.parse_comma_separated(|context| context.consume_id());
Expand Down Expand Up @@ -77,6 +87,19 @@ pub struct TypeDeclaration {
pub members: Vec<Member>,
}

impl Ranged for TypeDeclaration {
fn start(&self) -> usize {
self.keyword.start()
}

fn end(&self) -> usize {
self.members
.last()
// FIXME: respect generic parameters
.map_or_else(|| self.name.end(), |s| s.end())
}
}

impl StartsHere for TypeDeclaration {
/// Check that type declaration may start at current lexer position
fn starts_here(context: &mut Context<impl Lexer>) -> bool {
Expand Down
12 changes: 11 additions & 1 deletion src/ast/declarations/variable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use ast_derive::AST;
use crate::ast::{Expression, TypeReference};
use crate::mutability::{Mutability, Mutable};
use crate::syntax::error::{MissingVariableName, ParseError};
use crate::syntax::{Context, Identifier, Keyword, Lexer, Parse, StartsHere, Token};
use crate::syntax::{Context, Identifier, Keyword, Lexer, Parse, Ranged, StartsHere, Token};

/// Declaration of the variable
#[derive(Debug, PartialEq, Eq, AST, Clone)]
Expand All @@ -22,6 +22,16 @@ pub struct VariableDeclaration {
pub mutability: Mutability,
}

impl Ranged for VariableDeclaration {
fn start(&self) -> usize {
self.keyword.start()
}

fn end(&self) -> usize {
self.initializer.end()
}
}

impl Mutable for VariableDeclaration {
fn is_mutable(&self) -> bool {
self.mutability.is_mutable()
Expand Down
12 changes: 11 additions & 1 deletion src/ast/statements/assignment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use ast_derive::AST;

use crate::ast::Expression;
use crate::syntax::{error::ParseError, Lexer, Parse, Token};
use crate::syntax::{Context, StartsHere};
use crate::syntax::{Context, Ranged, StartsHere};

/// AST for assignment
#[derive(Debug, PartialEq, Eq, AST, Clone)]
Expand All @@ -14,6 +14,16 @@ pub struct Assignment {
pub value: Expression,
}

impl Ranged for Assignment {
fn start(&self) -> usize {
self.target.start()
}

fn end(&self) -> usize {
self.value.end()
}
}

impl StartsHere for Assignment {
/// Check that assignment may start at current lexer position
fn starts_here(context: &mut Context<impl Lexer>) -> bool {
Expand Down
53 changes: 50 additions & 3 deletions src/ast/statements/if.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use ast_derive::AST;

use crate::ast::Expression;
use crate::syntax::{error::ParseError, Lexer, Parse, Token};
use crate::syntax::{Context, Keyword, StartsHere};
use crate::syntax::{Context, Keyword, Ranged, StartsHere};

use super::Statement;

Expand All @@ -19,6 +19,18 @@ pub struct ElseIf {
pub body: Vec<Statement>,
}

impl Ranged for ElseIf {
fn start(&self) -> usize {
self.else_keyword.start()
}

fn end(&self) -> usize {
self.body
.last()
.map_or_else(|| self.condition.end(), |s| s.end())
}
}

/// AST for else block
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Else {
Expand All @@ -28,6 +40,18 @@ pub struct Else {
pub body: Vec<Statement>,
}

impl Ranged for Else {
fn start(&self) -> usize {
self.keyword.start()
}

fn end(&self) -> usize {
self.body
.last()
.map_or_else(|| self.keyword.end(), |s| s.end())
}
}

/// AST for if-statement
#[derive(Debug, PartialEq, Eq, AST, Clone)]
pub struct If {
Expand All @@ -43,6 +67,24 @@ pub struct If {
pub else_block: Option<Else>,
}

impl Ranged for If {
fn start(&self) -> usize {
self.keyword.start()
}

fn end(&self) -> usize {
if let Some(else_block) = &self.else_block {
else_block.end()
} else if let Some(else_if) = self.else_ifs.last() {
else_if.end()
} else {
self.body
.last()
.map_or_else(|| self.condition.end(), |s| s.end())
}
}
}

impl StartsHere for If {
/// Check that assignment may start at current lexer position
fn starts_here(context: &mut Context<impl Lexer>) -> bool {
Expand Down Expand Up @@ -71,12 +113,17 @@ impl Parse for If {

context.lexer.consume(Token::Colon)?;
let body = context.parse_block(Statement::parse)?;
else_ifs.push(ElseIf { else_keyword, if_keyword, condition, body });
else_ifs.push(ElseIf {
else_keyword,
if_keyword,
condition,
body,
});
} else {
context.lexer.consume(Token::Colon)?;
else_block = Some(Else {
keyword: else_keyword,
body: context.parse_block(Statement::parse)?
body: context.parse_block(Statement::parse)?,
});
break;
}
Expand Down
14 changes: 13 additions & 1 deletion src/ast/statements/loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use ast_derive::AST;

use crate::ast::Statement;
use crate::syntax::{error::ParseError, Lexer, Parse, Token};
use crate::syntax::{Context, Keyword, StartsHere};
use crate::syntax::{Context, Keyword, Ranged, StartsHere};

/// AST for infinite loop
#[derive(Debug, PartialEq, Eq, AST, Clone)]
Expand All @@ -14,6 +14,18 @@ pub struct Loop {
pub body: Vec<Statement>,
}

impl Ranged for Loop {
fn start(&self) -> usize {
self.keyword.start()
}

fn end(&self) -> usize {
self.body
.last()
.map_or_else(|| self.keyword.end(), |s| s.end())
}
}

impl StartsHere for Loop {
/// Check that loop starts at current lexer position
fn starts_here(context: &mut Context<impl Lexer>) -> bool {
Expand Down
20 changes: 19 additions & 1 deletion src/ast/statements/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
mod assignment;
use std::ops::Range;

pub use assignment::*;

mod ret;
Expand All @@ -22,7 +24,7 @@ use ast_derive::AST;
use crate::ast::{Declaration, Expression};
use crate::syntax::error::MissingStatement;
use crate::syntax::{error::ParseError, Lexer, Parse, Token};
use crate::syntax::{Context, StartsHere};
use crate::syntax::{Context, Ranged, StartsHere};

use derive_more::From;

Expand All @@ -41,6 +43,22 @@ pub enum Statement {
Use(Use),
}

impl Ranged for Statement {
fn range(&self) -> Range<usize> {
use Statement::*;
match self {
Declaration(s) => s.range(),
Expression(s) => s.range(),
Assignment(s) => s.range(),
Return(s) => s.range(),
If(s) => s.range(),
Loop(s) => s.range(),
While(s) => s.range(),
Use(s) => s.range(),
}
}
}

impl StartsHere for Statement {
/// Check that statement may start at current lexer position
fn starts_here(context: &mut Context<impl Lexer>) -> bool {
Expand Down
Loading
Loading