pr47 0.1.4-CHARLIE

A semi-experimental programming language. Still working in progress.
Documentation
#![allow(unused_variables)]
#![allow(dead_code)]

//! # Concrete syntax tree of declarations
//!
//! Declaration syntax:
//! ```text
//! declaration ::= maybe-attributed-declaration
//!               | import-declaration
//!               | export-declaration
//!
//! maybe-attributed-declaration ::= maybe-attribute attr-able-declaration
//!
//! maybe-attribute ::= attribute
//!                   | NIL
//!
//! attr-able-declaration ::= const-declaration
//!                         | func-declaration
//!                         | var-declaration
//!
//! import-declaration ::= 'import' identifier ';'
//!
//! open-import-declaration ::= 'open' 'import' identifier 'using' '(' use-item-list ')';
//!
//! export-declaration ::= 'export' '(' non-empty-identifier-list ')' ';'
//!
//! use-item-list ::= use-item use-item-list-tail
//!                  | use-item
//!
//! use-item-list-tail ::= ',' use-item use-item-list-tail
//!                      | NIL
//!
//! use-item ::= '*'
//!            | identifier
//!            | identifier 'as' ID
//!
//! non-empty-identifier-list ::= non-empty-identifier-list ',' identifier
//!                             | identifier
//! ```

use smallvec::SmallVec;

use crate::diag::location::{SourceLoc, SourceRange};
use crate::syntax::attr::Attribute;
use crate::syntax::expr::ConcreteExpr;
use crate::syntax::id::Identifier;
use crate::syntax::stmt::ConcreteCompoundStmt;
use crate::syntax::ty::ConcreteType;

#[cfg_attr(test, derive(Debug))]
pub enum ConcreteDecl<'a> {
    ConstDecl(ConcreteObjectDecl<'a>),
    ExportDecl(ConcreteExportDecl<'a>),
    FuncDecl(ConcreteFuncDecl<'a>),
    ImportDecl(ConcreteImportDecl<'a>),
    OpenImportDecl(ConcreteOpenImportDecl<'a>),
    VarDecl(ConcreteObjectDecl<'a>)
}

#[cfg_attr(test, derive(Debug))]
pub struct ConcreteObjectDecl<'a> {
    pub attr: Option<Attribute<'a>>,

    pub name: Identifier<'a>,
    pub obj_type: Option<ConcreteType<'a>>,
    pub init_expr: ConcreteExpr<'a>,

    pub kwd_range: SourceRange,
    pub eq_range: SourceRange
}

#[cfg_attr(test, derive(Debug))]
pub struct FunctionParam<'a> {
    pub attr: Option<Attribute<'a>>,

    pub param_name: Identifier<'a>,
    pub param_type: Option<ConcreteType<'a>>
}

#[cfg_attr(test, derive(Debug))]
pub struct FuncDeclExceptionSpec<'a> {
    pub exc_list: SmallVec<[ConcreteType<'a>; 4]>,
    pub throws_range: SourceRange,
    pub lparen_loc: SourceLoc,
    pub rparen_loc: SourceLoc
}

#[cfg_attr(test, derive(Debug))]
pub struct ConcreteFuncDecl<'a> {
    pub attr: Option<Attribute<'a>>,

    pub func_name: Identifier<'a>,
    pub func_param_list: Vec<FunctionParam<'a>>,
    pub func_return_types: Vec<ConcreteType<'a>>,
    pub exception_spec: Option<FuncDeclExceptionSpec<'a>>,
    pub func_body: Option<ConcreteCompoundStmt<'a>>,

    pub func_kwd_range: SourceRange,
    pub param_open_paren_loc: SourceLoc,
    pub param_close_paren_loc: SourceLoc
}

#[cfg_attr(test, derive(Debug))]
pub struct ConcreteImportDecl<'a> {
    pub import_path: Identifier<'a>,
    pub import_kwd_range: SourceRange,

    pub is_syntax_action: bool
}

#[cfg_attr(test, derive(Debug))]
pub enum OpenImportUsingItem<'a> {
    UsingAny { aster_loc: SourceLoc },
    UsingIdent {
        ident: Identifier<'a>,
        as_ident: Option<Identifier<'a>>,
        is_syntax_action: bool
    }
}

#[cfg_attr(test, derive(Debug))]
pub struct ConcreteOpenImportDecl<'a> {
    pub import_path: Identifier<'a>,
    pub use_item_list: Vec<OpenImportUsingItem<'a>>,

    pub open_kwd_range: SourceRange,
    pub import_kwd_range: SourceRange,
    pub using_kwd_range: SourceRange,
    pub using_list_left_paren_loc: SourceLoc,
    pub using_list_right_paren_loc: SourceLoc
}

#[cfg_attr(test, derive(Debug))]
pub struct ConcreteExportDecl<'a> {
    pub exported_idents: Vec<Identifier<'a>>,
    pub export_kwd_range: SourceRange,
    pub left_paren_loc: SourceLoc,
    pub right_paren_loc: SourceLoc
}