pub fn termify_expr(&self, ast: &ast::Expr) -> Result<Spanned<Term<'a>>> {
        let term = match ast.data {
            // Literals with optional unit.
            ast::LitExpr(ref lit, unit) => {
                let lit = self.termify_literal(Spanned::new(lit, ast.span))?;
                let unit = match unit {
                    Some(unit_name) => Some(self.termify_name(unit_name.map_into())?),
                    None => None,
                };
                if let Some(unit) = unit {
                    let unit = self.ensure_resolved(unit)?;
                    let unit = match unit.value {
                        Term::Ident(Spanned {
                            value: Def::Unit(u),
                            span,
                        }) => Spanned::new(EitherUnit::Old(u), span),
                        Term::Ident2(Spanned {
                            value: Def2::Unit(u),
                            span,
                        }) => Spanned::new(EitherUnit::New(u), span),
                        _ => {
                            self.emit(
                                DiagBuilder2::error(format!(
                                    "`{}` is not a valid physical unit",
                                    unit.span.extract()
                                ))
                                .span(unit.span),
                            );
                            debugln!("It is a {:#?}", unit.value);
                            return Err(());
                        }
                    };
                    let lit = match lit.value {
                        Term::IntLit(v) => v,
                        _ => {
                            self.emit(
                                DiagBuilder2::error(format!(
                                    "`{}` is not a valid value for a physical literal",
                                    lit.span.extract()
                                ))
                                .span(lit.span),
                            );
                            debugln!("It is a {:#?}", lit.value);
                            return Err(());
                        }
                    };
                    Term::PhysLit(lit, unit)
                } else {
                    lit.value
                }
            }
            ast::NameExpr(ref name) => return self.termify_compound_name(name),
            // ast::ResolExpr(ref paren_elems, ref name) => {
            //  let name = self.termify_compound_name(name)?;
            // }
            ast::UnaryExpr(op, ref arg) => {
                Term::Unary(UnaryOp::from(op, self.ctx)?, self.termify_expr(arg)?.into())
            }
            ast::BinaryExpr(op, ref lhs, ref rhs) => {
                if let ast::BinaryOp::Dir(d) = op.value {
                    Term::Range(
                        Spanned::new(d, op.span),
                        self.termify_expr(lhs)?.into(),
                        self.termify_expr(rhs)?.into(),
                    )
                } else {
                    Term::Binary(
                        BinaryOp::from(op, self.ctx)?,
                        self.termify_expr(lhs)?.into(),
                        self.termify_expr(rhs)?.into(),
                    )
                }
            }
            ast::NullExpr => Term::Null,
            ast::OpenExpr => Term::Open,
            ast::OthersExpr => Term::Others,
            ast::DefaultExpr => Term::Default,
            ast::ParenExpr(ref elems) => self.termify_paren_elems(elems)?.value,
            ast::QualExpr(ref name, ref arg) => Term::Qual(
                self.termify_compound_name(name)?.into(),
                self.termify_paren_elems(arg)?.into(),
            ),
            ast::NewExpr(ref expr) => Term::New(self.termify_expr(expr)?.into()),
            ref wrong => {
                self.emit(
                    DiagBuilder2::bug(format!(
                        "termification of expression `{}` not implemented",
                        ast.span.extract()
                    ))
                    .span(ast.span)
                    .add_note(format!("{:?}", wrong)),
                );
                return Err(());
            }
        };
        Ok(self.fold(Spanned::new(term, ast.span)))
    }
/// Map an AST expression to a term.
Map an AST expression to a term.
Map an AST expression to a term .
pub fn termify_expr(&self, ast: &ast::Expr) -> Result<Spanned<Term<'a>>> {
        let term = match ast.data {
            // Literals with optional unit.
            ast::LitExpr(ref lit, unit) => {
                let lit = self.termify_literal(Spanned::new(lit, ast.span))?;
                let unit = match unit {
                    Some(unit_name) => Some(self.termify_name(unit_name.map_into())?),
                    None => None,
                };
                if let Some(unit) = unit {
                    let unit = self.ensure_resolved(unit)?;
                    let unit = match unit.value {
                        Term::Ident(Spanned {
                            value: Def::Unit(u),
                            span,
                        }) => Spanned::new(EitherUnit::Old(u), span),
                        Term::Ident2(Spanned {
                            value: Def2::Unit(u),
                            span,
                        }) => Spanned::new(EitherUnit::New(u), span),
                        _ => {
                            self.emit(
                                DiagBuilder2::error(format!(
                                    "`{}` is not a valid physical unit",
                                    unit.span.extract()
                                ))
                                .span(unit.span),
                            );
                            debugln!("It is a {:#?}", unit.value);
                            return Err(());
                        }
                    };
                    let lit = match lit.value {
                        Term::IntLit(v) => v,
                        _ => {
                            self.emit(
                                DiagBuilder2::error(format!(
                                    "`{}` is not a valid value for a physical literal",
                                    lit.span.extract()
                                ))
                                .span(lit.span),
                            );
                            debugln!("It is a {:#?}", lit.value);
                            return Err(());
                        }
                    };
                    Term::PhysLit(lit, unit)
                } else {
                    lit.value
                }
            }
            ast::NameExpr(ref name) => return self.termify_compound_name(name),
            // ast::ResolExpr(ref paren_elems, ref name) => {
            //  let name = self.termify_compound_name(name)?;
            // }
            ast::UnaryExpr(op, ref arg) => {
                Term::Unary(UnaryOp::from(op, self.ctx)?, self.termify_expr(arg)?.into())
            }
            ast::BinaryExpr(op, ref lhs, ref rhs) => {
                if let ast::BinaryOp::Dir(d) = op.value {
                    Term::Range(
                        Spanned::new(d, op.span),
                        self.termify_expr(lhs)?.into(),
                        self.termify_expr(rhs)?.into(),
                    )
                } else {
                    Term::Binary(
                        BinaryOp::from(op, self.ctx)?,
                        self.termify_expr(lhs)?.into(),
                        self.termify_expr(rhs)?.into(),
                    )
                }
            }
            ast::NullExpr => Term::Null,
            ast::OpenExpr => Term::Open,
            ast::OthersExpr => Term::Others,
            ast::DefaultExpr => Term::Default,
            ast::ParenExpr(ref elems) => self.termify_paren_elems(elems)?.value,
            ast::QualExpr(ref name, ref arg) => Term::Qual(
                self.termify_compound_name(name)?.into(),
                self.termify_paren_elems(arg)?.into(),
            ),
            ast::NewExpr(ref expr) => Term::New(self.termify_expr(expr)?.into()),
            ref wrong => {
                self.emit(
                    DiagBuilder2::bug(format!(
                        "termification of expression `{}` not implemented",
                        ast.span.extract()
                    ))
                    .span(ast.span)
                    .add_note(format!("{:?}", wrong)),
                );
                return Err(());
            }
        };
        Ok(self.fold(Spanned::new(term, ast.span)))
    }
pub fn termify_expr ( & self , ast : & ast :: Expr ) -> Result < Spanned < Term < ' a > > > { let term = match ast . data { // Literals with optional unit. ast :: LitExpr ( ref lit , unit ) => { let lit = self . termify_literal ( Spanned :: new ( lit , ast . span ) ) ? ; let unit = match unit { Some ( unit_name ) => Some ( self . termify_name ( unit_name . map_into ( ) ) ? ) , None => None , } ; if let Some ( unit ) = unit { let unit = self . ensure_resolved ( unit ) ? ; let unit = match unit . value { Term :: Ident ( Spanned { value : Def :: Unit ( u ) , span , } ) => Spanned :: new ( EitherUnit :: Old ( u ) , span ) , Term :: Ident2 ( Spanned { value : Def2 :: Unit ( u ) , span , } ) => Spanned :: new ( EitherUnit :: New ( u ) , span ) , _ => { self . emit ( DiagBuilder2 :: error ( format ! ( " " unit span extract ( ) ) ) . span ( unit . span ) , ) ; debugln ! ( " " unit value ) ; return Err ( ( ) ) ; } } ; let lit = match lit . value { Term :: IntLit ( v ) => v , _ => { self . emit ( DiagBuilder2 :: error ( format ! ( " " lit span extract ( ) ) ) . span ( lit . span ) , ) ; debugln ! ( " " lit value ) ; return Err ( ( ) ) ; } } ; Term :: PhysLit ( lit , unit ) } else { lit . value } } ast :: NameExpr ( ref name ) => return self . termify_compound_name ( name ) , // ast::ResolExpr(ref paren_elems, ref name) => { //  let name = self.termify_compound_name(name)?; // } ast :: UnaryExpr ( op , ref arg ) => { Term :: Unary ( UnaryOp :: from ( op , self . ctx ) ? , self . termify_expr ( arg ) ? . into ( ) ) } ast :: BinaryExpr ( op , ref lhs , ref rhs ) => { if let ast :: BinaryOp :: Dir ( d ) = op . value { Term :: Range ( Spanned :: new ( d , op . span ) , self . termify_expr ( lhs ) ? . into ( ) , self . termify_expr ( rhs ) ? . into ( ) , ) } else { Term :: Binary ( BinaryOp :: from ( op , self . ctx ) ? , self . termify_expr ( lhs ) ? . into ( ) , self . termify_expr ( rhs ) ? . into ( ) , ) } } ast :: NullExpr => Term :: Null , ast :: OpenExpr => Term :: Open , ast :: OthersExpr => Term :: Others , ast :: DefaultExpr => Term :: Default , ast :: ParenExpr ( ref elems ) => self . termify_paren_elems ( elems ) ? . value , ast :: QualExpr ( ref name , ref arg ) => Term :: Qual ( self . termify_compound_name ( name ) ? . into ( ) , self . termify_paren_elems ( arg ) ? . into ( ) , ) , ast :: NewExpr ( ref expr ) => Term :: New ( self . termify_expr ( expr ) ? . into ( ) ) , ref wrong => { self . emit ( DiagBuilder2 :: bug ( format ! ( " " ast span extract ( ) ) ) . span ( ast . span ) . add_note ( format ! ( " " wrong ) ) , ) ; return Err ( ( ) ) ; } } ; Ok ( self . fold ( Spanned :: new ( term , ast . span ) ) ) }
Map an AST expression to a term.
Map an AST expression to a term .
&self
ast
&ast::Expr
&self
ast
&ast::Expr