pub fn from_pattern_as_cells(list: CellRef) -> Result<PatternMatch, BindError> {
        // Set up to iterate through the list and generate the list of symbols
        let mut list_pos    = &*list;
        let mut symbols     = vec![];

        // Need some specific atoms for some parts of the parsing
        let angle_open      = get_id_for_atom_with_name("<");
        let angle_close     = get_id_for_atom_with_name(">");
        let curly_open      = get_id_for_atom_with_name("{");
        let curly_close     = get_id_for_atom_with_name("}");

        // Iterate through the list
        while let SafasCell::List(car, cdr) = list_pos {
            // Action depends on car
            match &**car {
                SafasCell::Atom(atom_id) => {
                    let atom_id = *atom_id;
                    if atom_id == angle_open {

                        // <foo> = bind statement to 'foo' - this is a bit annoying to parse
                        list_pos = cdr;

                        if let SafasCell::List(bind_atom, cdr) = list_pos {
                            if let SafasCell::Atom(bind_atom) = &**bind_atom {
                                symbols.push(MatchSymbol::StatementBinding(*bind_atom));
                                list_pos = &*cdr;
                            } else {
                                return Err(BindError::SyntaxExpectingAtom)
                            }
                        } else {
                            return Err(BindError::SyntaxExpectingAtom)
                        }

                        // Should be '>' (tedious to parse this out :-/)
                        if let SafasCell::List(close_bracket, cdr) = list_pos {
                            if let SafasCell::Atom(atom) = &**close_bracket {
                                if *atom != angle_close {
                                    return Err(BindError::SyntaxMissingBracket('>'));
                                }

                                // Continue after the '>'
                                list_pos = &*cdr;
                                continue;
                            } else {
                                return Err(BindError::SyntaxMissingBracket('>'));
                            }
                        } else {
                            return Err(BindError::SyntaxMissingBracket('>'));
                        }

                    } else if atom_id == curly_open {

                        // {foo} = bind whatever appears to 'foo' - same parsing mechanism as for <foo> except different brackets
                        list_pos = &*cdr;

                        if let SafasCell::List(bind_atom, cdr) = list_pos {
                            if let SafasCell::Atom(bind_atom) = &**bind_atom {
                                symbols.push(MatchSymbol::SymbolBinding(*bind_atom));
                                list_pos = cdr;
                            } else {
                                return Err(BindError::SyntaxExpectingAtom)
                            }
                        } else {
                            return Err(BindError::SyntaxExpectingAtom)
                        }

                        // Should be '}'
                        if let SafasCell::List(close_bracket, cdr) = list_pos {
                            if let SafasCell::Atom(atom) = &**close_bracket {
                                if *atom != curly_close {
                                    return Err(BindError::SyntaxMissingBracket('}'));
                                }

                                // Continue after the '}'
                                list_pos = &*cdr;
                                continue;
                            } else {
                                return Err(BindError::SyntaxMissingBracket('}'));
                            }
                        } else {
                            return Err(BindError::SyntaxMissingBracket('}'));
                        }

                    } else {
                        // Bind straight to the atom (<< and {{ are mapped to < and {)
                        let mut atom_name = name_for_atom_with_id(atom_id);
                        
                        // Strip extra '<' or '{'
                        let atom_id = if atom_name.chars().nth(0) == Some('<') {
                            atom_name.remove(0);
                            get_id_for_atom_with_name(&atom_name)
                        } else if atom_name.chars().nth(0) == Some('{') {
                            atom_name.remove(0);
                            get_id_for_atom_with_name(&atom_name)
                        } else {
                            atom_id
                        };

                        // Match a symbol directly
                        symbols.push(MatchSymbol::Atom(atom_id));
                    }
                }

                SafasCell::List(_, _) => { 
                    // Generate a pattern from the list and push it into the pattern we're building
                    let list_pattern = Self::from_pattern_as_cells(Arc::clone(car))?;
                    symbols.push(MatchSymbol::List(list_pattern.symbols));
                }

                SafasCell::Nil              => { symbols.push(MatchSymbol::Nil); }
                SafasCell::Boolean(val)     => { symbols.push(MatchSymbol::Boolean(*val)); }
                SafasCell::Number(number)   => { symbols.push(MatchSymbol::Number(number.clone())); }
                SafasCell::String(string)   => { symbols.push(MatchSymbol::String(string.clone())); }
                SafasCell::Char(chr)        => { symbols.push(MatchSymbol::Char(*chr)); }

                SafasCell::Any(_) | SafasCell::BTree(_, _) | SafasCell::Error(_) | SafasCell::BitCode(_) | SafasCell::Monad(_, _) | SafasCell::FrameMonad(_) | SafasCell::Syntax(_, _) | SafasCell::BoundSyntax(_) | SafasCell::FrameReference(_, _, _) => { return Err(BindError::NotValidInSyntax) }
            }

            // Move to the next cell
            list_pos = cdr;
        }

        Ok(Self::new(symbols))
    }
///
/// Creates a pattern matcher from a list of SafasCells
///
Creates a pattern matcher from a list of SafasCells
Creates a pattern matcher from a list of SafasCells
pub fn from_pattern_as_cells(list: CellRef) -> Result<PatternMatch, BindError> {
        // Set up to iterate through the list and generate the list of symbols
        let mut list_pos    = &*list;
        let mut symbols     = vec![];
        // Need some specific atoms for some parts of the parsing
        let angle_open      = get_id_for_atom_with_name("<");
        let angle_close     = get_id_for_atom_with_name(">");
        let curly_open      = get_id_for_atom_with_name("{");
        let curly_close     = get_id_for_atom_with_name("}");
        // Iterate through the list
        while let SafasCell::List(car, cdr) = list_pos {
            // Action depends on car
            match &**car {
                SafasCell::Atom(atom_id) => {
                    let atom_id = *atom_id;
                    if atom_id == angle_open {
                        // <foo> = bind statement to 'foo' - this is a bit annoying to parse
                        list_pos = cdr;
                        if let SafasCell::List(bind_atom, cdr) = list_pos {
                            if let SafasCell::Atom(bind_atom) = &**bind_atom {
                                symbols.push(MatchSymbol::StatementBinding(*bind_atom));
                                list_pos = &*cdr;
                            } else {
                                return Err(BindError::SyntaxExpectingAtom)
                            }
                        } else {
                            return Err(BindError::SyntaxExpectingAtom)
                        }
                        // Should be '>' (tedious to parse this out :-/)
                        if let SafasCell::List(close_bracket, cdr) = list_pos {
                            if let SafasCell::Atom(atom) = &**close_bracket {
                                if *atom != angle_close {
                                    return Err(BindError::SyntaxMissingBracket('>'));
                                }
                                // Continue after the '>'
                                list_pos = &*cdr;
                                continue;
                            } else {
                                return Err(BindError::SyntaxMissingBracket('>'));
                            }
                        } else {
                            return Err(BindError::SyntaxMissingBracket('>'));
                        }
                    } else if atom_id == curly_open {
                        // {foo} = bind whatever appears to 'foo' - same parsing mechanism as for <foo> except different brackets
                        list_pos = &*cdr;
                        if let SafasCell::List(bind_atom, cdr) = list_pos {
                            if let SafasCell::Atom(bind_atom) = &**bind_atom {
                                symbols.push(MatchSymbol::SymbolBinding(*bind_atom));
                                list_pos = cdr;
                            } else {
                                return Err(BindError::SyntaxExpectingAtom)
                            }
                        } else {
                            return Err(BindError::SyntaxExpectingAtom)
                        }
                        // Should be '}'
                        if let SafasCell::List(close_bracket, cdr) = list_pos {
                            if let SafasCell::Atom(atom) = &**close_bracket {
                                if *atom != curly_close {
                                    return Err(BindError::SyntaxMissingBracket('}'));
                                }
                                // Continue after the '}'
                                list_pos = &*cdr;
                                continue;
                            } else {
                                return Err(BindError::SyntaxMissingBracket('}'));
                            }
                        } else {
                            return Err(BindError::SyntaxMissingBracket('}'));
                        }
                    } else {
                        // Bind straight to the atom (<< and {{ are mapped to < and {)
                        let mut atom_name = name_for_atom_with_id(atom_id);
                        // Strip extra '<' or '{'
                        let atom_id = if atom_name.chars().nth(0) == Some('<') {
                            atom_name.remove(0);
                            get_id_for_atom_with_name(&atom_name)
                        } else if atom_name.chars().nth(0) == Some('{') {
                            atom_name.remove(0);
                            get_id_for_atom_with_name(&atom_name)
                        } else {
                            atom_id
                        };
                        // Match a symbol directly
                        symbols.push(MatchSymbol::Atom(atom_id));
                    }
                }
                SafasCell::List(_, _) => { 
                    // Generate a pattern from the list and push it into the pattern we're building
                    let list_pattern = Self::from_pattern_as_cells(Arc::clone(car))?;
                    symbols.push(MatchSymbol::List(list_pattern.symbols));
                }
                SafasCell::Nil              => { symbols.push(MatchSymbol::Nil); }
                SafasCell::Boolean(val)     => { symbols.push(MatchSymbol::Boolean(*val)); }
                SafasCell::Number(number)   => { symbols.push(MatchSymbol::Number(number.clone())); }
                SafasCell::String(string)   => { symbols.push(MatchSymbol::String(string.clone())); }
                SafasCell::Char(chr)        => { symbols.push(MatchSymbol::Char(*chr)); }
                SafasCell::Any(_) | SafasCell::BTree(_, _) | SafasCell::Error(_) | SafasCell::BitCode(_) | SafasCell::Monad(_, _) | SafasCell::FrameMonad(_) | SafasCell::Syntax(_, _) | SafasCell::BoundSyntax(_) | SafasCell::FrameReference(_, _, _) => { return Err(BindError::NotValidInSyntax) }
            }
            // Move to the next cell
            list_pos = cdr;
        }
        Ok(Self::new(symbols))
    }
pub fn from_pattern_as_cells ( list : CellRef ) -> Result < PatternMatch , BindError > { // Set up to iterate through the list and generate the list of symbols let mut list_pos = & * list ; let mut symbols = vec ! [ ] ; // Need some specific atoms for some parts of the parsing let angle_open = get_id_for_atom_with_name ( " " ) ; let angle_close = get_id_for_atom_with_name ( " " ) ; let curly_open = get_id_for_atom_with_name ( " " ) ; let curly_close = get_id_for_atom_with_name ( " " ) ; // Iterate through the list while let SafasCell :: List ( car , cdr ) = list_pos { // Action depends on car match & * * car { SafasCell :: Atom ( atom_id ) => { let atom_id = * atom_id ; if atom_id == angle_open { // <foo> = bind statement to 'foo' - this is a bit annoying to parse list_pos = cdr ; if let SafasCell :: List ( bind_atom , cdr ) = list_pos { if let SafasCell :: Atom ( bind_atom ) = & * * bind_atom { symbols . push ( MatchSymbol :: StatementBinding ( * bind_atom ) ) ; list_pos = & * cdr ; } else { return Err ( BindError :: SyntaxExpectingAtom ) } } else { return Err ( BindError :: SyntaxExpectingAtom ) } // Should be '>' (tedious to parse this out :-/) if let SafasCell :: List ( close_bracket , cdr ) = list_pos { if let SafasCell :: Atom ( atom ) = & * * close_bracket { if * atom != angle_close { return Err ( BindError :: SyntaxMissingBracket ( '>' ) ) ; } // Continue after the '>' list_pos = & * cdr ; continue ; } else { return Err ( BindError :: SyntaxMissingBracket ( '>' ) ) ; } } else { return Err ( BindError :: SyntaxMissingBracket ( '>' ) ) ; } } else if atom_id == curly_open { // {foo} = bind whatever appears to 'foo' - same parsing mechanism as for <foo> except different brackets list_pos = & * cdr ; if let SafasCell :: List ( bind_atom , cdr ) = list_pos { if let SafasCell :: Atom ( bind_atom ) = & * * bind_atom { symbols . push ( MatchSymbol :: SymbolBinding ( * bind_atom ) ) ; list_pos = cdr ; } else { return Err ( BindError :: SyntaxExpectingAtom ) } } else { return Err ( BindError :: SyntaxExpectingAtom ) } // Should be '}' if let SafasCell :: List ( close_bracket , cdr ) = list_pos { if let SafasCell :: Atom ( atom ) = & * * close_bracket { if * atom != curly_close { return Err ( BindError :: SyntaxMissingBracket ( '}' ) ) ; } // Continue after the '}' list_pos = & * cdr ; continue ; } else { return Err ( BindError :: SyntaxMissingBracket ( '}' ) ) ; } } else { return Err ( BindError :: SyntaxMissingBracket ( '}' ) ) ; } } else { // Bind straight to the atom (<< and {{ are mapped to < and {) let mut atom_name = name_for_atom_with_id ( atom_id ) ; // Strip extra '<' or '{' let atom_id = if atom_name . chars ( ) . nth ( 0 ) == Some ( '<' ) { atom_name . remove ( 0 ) ; get_id_for_atom_with_name ( & atom_name ) } else if atom_name . chars ( ) . nth ( 0 ) == Some ( '{' ) { atom_name . remove ( 0 ) ; get_id_for_atom_with_name ( & atom_name ) } else { atom_id } ; // Match a symbol directly symbols . push ( MatchSymbol :: Atom ( atom_id ) ) ; } } SafasCell :: List ( _ , _ ) => { // Generate a pattern from the list and push it into the pattern we're building let list_pattern = Self :: from_pattern_as_cells ( Arc :: clone ( car ) ) ? ; symbols . push ( MatchSymbol :: List ( list_pattern . symbols ) ) ; } SafasCell :: Nil => { symbols . push ( MatchSymbol :: Nil ) ; } SafasCell :: Boolean ( val ) => { symbols . push ( MatchSymbol :: Boolean ( * val ) ) ; } SafasCell :: Number ( number ) => { symbols . push ( MatchSymbol :: Number ( number . clone ( ) ) ) ; } SafasCell :: String ( string ) => { symbols . push ( MatchSymbol :: String ( string . clone ( ) ) ) ; } SafasCell :: Char ( chr ) => { symbols . push ( MatchSymbol :: Char ( * chr ) ) ; } SafasCell :: Any ( _ ) | SafasCell :: BTree ( _ , _ ) | SafasCell :: Error ( _ ) | SafasCell :: BitCode ( _ ) | SafasCell :: Monad ( _ , _ ) | SafasCell :: FrameMonad ( _ ) | SafasCell :: Syntax ( _ , _ ) | SafasCell :: BoundSyntax ( _ ) | SafasCell :: FrameReference ( _ , _ , _ ) => { return Err ( BindError :: NotValidInSyntax ) } } // Move to the next cell list_pos = cdr ; } Ok ( Self :: new ( symbols ) ) }
Creates a pattern matcher from a list of SafasCells
Creates a pattern matcher from a list of SafasCells
list
CellRef
list
CellRef