1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
use crate::{Context, PipelineArguments};
use crate::check::ast::ASTTy;
use crate::generate::ast::node::Core;
use crate::generate::convert::convert_node;
use crate::generate::convert::state::{Imports, State};
use crate::generate::result::GenResult;
mod convert;
pub mod ast;
pub mod name;
pub mod result;
#[derive(Default)]
pub struct GenArguments {
pub annotate: bool,
}
impl From<&PipelineArguments> for GenArguments {
fn from(pipeline_args: &PipelineArguments) -> Self {
GenArguments { annotate: pipeline_args.annotate }
}
}
/// Consumes the given [AST](mamba::parser::ast::AST) and produces
/// a [Core](mamba::generate.ast::construct::Core) node.
///
/// Note that the given [AST](mamba::parser::ast::AST) must be
/// correctly formed. Therefore, malformed
/// [AST](mamba::parser::ast::AST)'s should be caught by either
/// the parser or the type checker.
///
/// # Examples
///
/// ```
/// # use mamba::check::ast::ASTTy;
/// # use mamba::parse::ast::Node;
/// # use mamba::parse::ast::AST;
/// # use mamba::generate::ast::node::Core;
/// # use mamba::common::position::{CaretPos, Position};
/// # use mamba::generate::gen;
/// let node = Node::ReturnEmpty;
/// let ast = AST::new(Position::new(CaretPos::new(1, 1), CaretPos::new(1, 5)), node);
/// let ast_ty = ASTTy::from(&ast);
/// let core_result = gen(&ast_ty).unwrap();
///
/// assert_eq!(core_result, Core::Return { expr: Box::from(Core::None) });
/// ```
///
/// # Failures
///
/// Fails if converting a construct which has not been implemented yet.
///
/// ```rust
/// # use mamba::check::ast::ASTTy;
/// # use mamba::parse::ast::Node;
/// # use mamba::parse::ast::AST;
/// # use mamba::generate::ast::node::Core;
/// # use mamba::common::position::{CaretPos, Position};
/// # use mamba::generate::gen;
/// let cond_node = Node::Int { lit: String::from("56") };
/// let cond_pos = AST::new(Position::new(CaretPos::new(0, 0), CaretPos::new(0, 5)), cond_node);
/// let node = Node::Condition { cond: Box::from(cond_pos), el: None };
/// let ast = AST::new(Position::new(CaretPos::new(0, 0), CaretPos::new(0, 5)), node);
/// let ast_ty = ASTTy::from(&ast);
/// let core_result = gen(&ast_ty);
///
/// assert!(core_result.is_err());
/// ```
///
/// # Panics
///
/// A malformed [AST](crate::parser::ast::AST) causes this stage
/// to panic.
pub fn gen_arguments(ast_ty: &ASTTy, gen_args: &GenArguments, ctx: &Context) -> GenResult {
let state = State::from(gen_args);
let import = &mut Imports::new();
match convert_node(ast_ty, import, &state, ctx)? {
Core::Block { statements } => {
Ok(Core::Block { statements: import.imports().into_iter().chain(statements).collect() })
}
other if !import.is_empty() => {
Ok(Core::Block { statements: import.imports().into_iter().chain(vec![other]).collect() })
}
other => Ok(other)
}
}
pub fn gen(ast_ty: &ASTTy) -> GenResult {
gen_arguments(ast_ty, &GenArguments::default(), &Context::default())
}