public Term listFunctor ( ) throws SourceCodeException { // Get the interned names of the nil and cons functors. int nilId = interner . internFunctorName ( "nil" , 0 ) ; int consId = interner . internFunctorName ( "cons" , 2 ) ; // A list always starts with a '['. Token leftDelim = consumeToken ( LSQPAREN ) ; // Check if the list contains any arguments and parse them if so. Term [ ] args = null ; Token nextToken = tokenSource . peek ( ) ; switch ( nextToken . kind ) { case LPAREN : case LSQPAREN : case INTEGER_LITERAL : case FLOATING_POINT_LITERAL : case STRING_LITERAL : case VAR : case FUNCTOR : case ATOM : args = arglist ( ) ; break ; default : } // Work out what the terminal element in the list is. It will be 'nil' unless an explicit cons '|' has // been used to specify a different terminal element. In the case where cons is used explciitly, the // list prior to the cons must not be empty. Term accumulator ; if ( tokenSource . peek ( ) . kind == CONS ) { if ( args == null ) { throw new SourceCodeException ( "Was expecting one of " + BEGIN_TERM_TOKENS + " but got " + tokenImage [ nextToken . kind ] + "." , null , null , null , new SourceCodePositionImpl ( nextToken . beginLine , nextToken . beginColumn , nextToken . endLine , nextToken . endColumn ) ) ; } consumeToken ( CONS ) ; accumulator = term ( ) ; } else { accumulator = new Nil ( nilId , null ) ; } // A list is always terminated with a ']'. Token rightDelim = consumeToken ( RSQPAREN ) ; // Walk down all of the lists arguments joining them together with cons/2 functors. if ( args != null ) // 'args' will contain one or more elements if not null. { for ( int i = args . length - 1 ; i >= 0 ; i -- ) { Term previousAccumulator = accumulator ; //accumulator = new Functor(consId.ordinal(), new Term[] { args[i], previousAccumulator }); accumulator = new Cons ( consId , new Term [ ] { args [ i ] , previousAccumulator } ) ; } } // Set the position that the list was parsed from, as being the region between the '[' and ']' brackets. SourceCodePosition position = new SourceCodePositionImpl ( leftDelim . beginLine , leftDelim . beginColumn , rightDelim . endLine , rightDelim . endColumn ) ; accumulator . setSourceCodePosition ( position ) ; // The cast must succeed because arglist must return at least one argument, therefore the cons generating // loop must have been run at least once. If arglist is not called at all because an empty list was // encountered, then the accumulator will contain the 'nil' constant which is a functor of arity zero. return ( Functor ) accumulator ; }
Parses a list expressed as a sequence of functors in first order logic . The empty list consists of the atom nil and a non - empty list consists of the functor cons with arguments the head of the list and the remainder of the list .