Update procedures
[shapes.git] / source / astfun.cc
blob7947600158a49905214eefbf82f2003c1c56ebc7
1 /* This file is part of Shapes.
3 * Shapes is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * any later version.
8 * Shapes is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with Shapes. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright 2008, 2013, 2014 Henrik Tidefelt
19 #include "Shapes_Helpers_decls.h"
21 #include "astfun.h"
22 #include "astfun_impl.h"
23 #include "shapesexceptions.h"
24 #include "shapescore.h"
25 #include "consts.h"
26 #include "globals.h"
27 #include "continuations.h"
28 #include "astvar.h"
29 #include "astvalues.h"
30 #include "texlabelmanager.h"
32 #include <sstream>
34 using namespace Shapes;
35 using namespace std;
38 Kernel::Formals::Formals( )
39 : loc_( Ast::THE_UNKNOWN_LOCATION, bool( ) ),
40 seenDefault_( false ),
41 argumentIdentifiers_( new Ast::IdentifierTree( NULL, false ) ),
42 argumentOrder_( new std::map< const char *, size_t, charPtrLess > ),
43 sink_( NULL ),
44 stateIdentifiers_( new Ast::IdentifierTree( NULL, false ) ),
45 stateOrder_( new std::map< const char *, size_t, charPtrLess > )
46 { }
48 Kernel::Formals::Formals( size_t numberOfDummyDefaultExprs )
49 : loc_( Ast::THE_UNKNOWN_LOCATION, bool( ) ),
50 seenDefault_( false ),
51 argumentIdentifiers_( new Ast::IdentifierTree( NULL, false ) ),
52 argumentOrder_( new std::map< const char *, size_t, charPtrLess > ),
53 sink_( NULL ),
54 stateIdentifiers_( new Ast::IdentifierTree( NULL, false ) ),
55 stateOrder_( new std::map< const char *, size_t, charPtrLess > )
57 // Pushing null expressions is just a way of specifying how many non-sink arguments there are.
58 for( size_t i = 0; i < numberOfDummyDefaultExprs; ++i )
60 defaultExprs_.push_back( NULL );
64 Kernel::Formals::~Formals( )
66 delete argumentIdentifiers_;
67 delete argumentOrder_;
68 delete stateIdentifiers_;
69 delete stateOrder_;
70 if( sink_ != NULL )
72 delete sink_;
76 void
77 Kernel::Formals::setLoc( const Ast::SourceLocation & loc )
79 loc_ = loc;
82 bool
83 Kernel::Formals::appendArgumentFormal( const Ast::PlacedIdentifier & id )
85 size_t pos = argumentIdentifiers_->size( );
86 if( ! argumentIdentifiers_->insert( id, loc_ ) ) /* The source location given here is more or less a dummy, it should never be needed. */
87 return false;
88 argumentOrder_->insert( std::pair< const char *, size_t >( id.simpleId( ), pos ) );
89 return true;
92 bool
93 Kernel::Formals::appendStateFormal( const Ast::PlacedIdentifier & id )
95 size_t pos = stateIdentifiers_->size( );
96 if( ! stateIdentifiers_->insert( id, loc_ ) ) /* The source location given here is more or less a dummy, it should never be needed. */
97 return false;
98 stateOrder_->insert( std::pair< const char *, size_t >( id.simpleId( ), pos ) );
99 return true;
102 void
103 Kernel::Formals::push_exprs( Ast::ArgListExprs * args ) const
105 typedef typeof defaultExprs_ ListType;
106 for( ListType::const_iterator i = defaultExprs_.begin( ); i != defaultExprs_.end( ); ++i )
108 if( *i != 0 )
110 args->orderedExprs_->push_back( *i );
115 Kernel::EvaluatedFormals *
116 Kernel::Formals::newEvaluatedFormals( Kernel::Arguments & args ) const
118 size_t pos = 0;
119 return newEvaluatedFormals( args, & pos );
122 Kernel::EvaluatedFormals *
123 Kernel::Formals::newEvaluatedFormals( Kernel::Arguments & args, size_t * pos ) const
125 Kernel::EvaluatedFormals * res = new Kernel::EvaluatedFormals( const_cast< Kernel::Formals * >( this ) );
126 res->isSink_ = false; // The formals created here belong to user functions, which are exactly those which are not sinks.
128 res->defaults_.reserve( defaultExprs_.size( ) );
129 res->locations_.reserve( defaultExprs_.size( ) );
131 typedef typeof defaultExprs_ ListType;
132 for( ListType::const_iterator i = defaultExprs_.begin( ); i != defaultExprs_.end( ); ++i )
134 if( *i != 0 )
136 res->defaults_.push_back( args.getHandle( *pos ) );
137 res->locations_.push_back( args.getNode( *pos ) );
138 ++(*pos);
140 else
142 res->defaults_.push_back( Kernel::THE_SLOT_VARIABLE );
143 res->locations_.push_back( 0 ); // I really hope this is never dereferenced!
147 return res;
150 std::vector< bool > *
151 Kernel::Formals::newArgListForcePos( const Ast::ArgListExprs * argList ) const
153 /* Here, we use the knowledge that ordered arguments are evaluated backwards, and named arguments
154 * in the natural order (the lexiographic order of std::map).
157 std::vector< bool > * res = new std::vector< bool >;
158 res->resize( argList->orderedExprs_->size( ) );
159 res->reserve( argList->orderedExprs_->size( ) + argList->namedExprs_->size( ) );
161 if( ! argList->orderedExprs_->empty( ) )
163 typedef typeof forcePos_ SrcType;
164 SrcType::const_iterator src = forcePos_.begin( );
165 for( size_t arg = argList->orderedExprs_->size( ) - 1; ; --arg, ++src )
167 (*res)[ arg ] = *src;
168 if( arg == 0 )
170 break;
176 typedef typeof *argList->namedExprs_ MapType;
177 MapType::const_iterator end = argList->namedExprs_->end( );
178 for( MapType::const_iterator arg = argList->namedExprs_->begin( ); arg != end; ++arg )
180 res->push_back( forcePos_[ (*argumentOrder_)[ arg->first ] ] );
184 return res;
187 std::vector< bool > *
188 Kernel::Formals::newArgListForcePos( const Ast::ArgListExprs * argList, const Kernel::Arguments & curryArgs ) const
190 /* Compare with the non-curry version!
193 std::vector< bool > * res = new std::vector< bool >;
194 res->resize( argList->orderedExprs_->size( ) );
195 res->reserve( argList->orderedExprs_->size( ) + argList->namedExprs_->size( ) );
197 if( ! argList->orderedExprs_->empty( ) )
199 typedef typeof forcePos_ SrcType;
200 SrcType::const_iterator src = forcePos_.begin( );
201 size_t curryPos = 0;
202 while( curryPos < curryArgs.size( ) &&
203 ! curryArgs.isSlot( curryPos ) )
205 ++src;
206 ++curryPos;
208 for( size_t arg = argList->orderedExprs_->size( ) - 1; ; --arg )
210 (*res)[ arg ] = *src;
211 if( arg == 0 )
213 break;
215 ++src;
216 ++curryPos;
217 while( curryPos < curryArgs.size( ) &&
218 ! curryArgs.isSlot( curryPos ) )
220 ++src;
221 ++curryPos;
227 typedef typeof *argList->namedExprs_ MapType;
228 MapType::const_iterator end = argList->namedExprs_->end( );
229 for( MapType::const_iterator arg = argList->namedExprs_->begin( ); arg != end; ++arg )
231 res->push_back( forcePos_[ (*argumentOrder_)[ arg->first ] ] );
235 return res;
238 const Ast::SourceLocation &
239 Kernel::Formals::loc( ) const
241 return loc_;
246 Ast::ArgListExprs::ConstIterator::ConstIterator( std::list< Ast::Expression * >::const_reverse_iterator i1, std::map< const char *, Ast::Expression *, charPtrLess >::const_iterator i2, const size_t & index )
247 : i1_( i1 ), i2_( i2 ), index_( index )
250 Ast::ArgListExprs::ConstIterator::ConstIterator( const Ast::ArgListExprs::ConstIterator & orig )
251 : i1_( orig.i1_ ), i2_( orig.i2_ ), index_( orig.index_ )
254 Ast::ArgListExprs::ArgListExprs( bool exprOwner )
255 : exprOwner_( exprOwner ), firstOrderedStateOwner_( exprOwner ), orderedExprs_( new std::list< Ast::Expression * > ), namedExprs_( new std::map< const char *, Ast::Expression *, charPtrLess > ),
256 orderedStates_( new std::list< Ast::StateReference * > ), namedStates_( new std::map< const char *, Ast::StateReference *, charPtrLess > )
259 Ast::ArgListExprs::ArgListExprs( bool exprOwner, bool firstOrderedStateOwner )
260 : exprOwner_( exprOwner ), firstOrderedStateOwner_( firstOrderedStateOwner ), orderedExprs_( new std::list< Ast::Expression * > ), namedExprs_( new std::map< const char *, Ast::Expression *, charPtrLess > ),
261 orderedStates_( new std::list< Ast::StateReference * > ), namedStates_( new std::map< const char *, Ast::StateReference *, charPtrLess > )
265 Ast::ArgListExprs::ArgListExprs( std::list< Ast::Expression * > * orderedExprs, std::map< const char *, Ast::Expression *, charPtrLess > * namedExprs, std::list< Ast::StateReference * > * orderedStates, std::map< const char *, Ast::StateReference *, charPtrLess > * namedStates )
266 : exprOwner_( true ), firstOrderedStateOwner_( true ), orderedExprs_( orderedExprs ), namedExprs_( namedExprs ), orderedStates_( orderedStates ), namedStates_( namedStates )
269 Ast::ArgListExprs::~ArgListExprs( )
272 if( exprOwner_ )
274 typedef list< Ast::Expression * >::iterator I;
275 for( I i = orderedExprs_->begin( ); i != orderedExprs_->end( ); ++i )
277 delete *i;
280 delete orderedExprs_;
284 if( exprOwner_ )
286 typedef std::map< const char *, Ast::Expression *, charPtrLess >::const_iterator I;
287 for( I i = namedExprs_->begin( ); i != namedExprs_->end( ); ++i )
289 delete i->first;
290 delete i->second;
293 delete namedExprs_;
297 if( exprOwner_ )
299 typedef std::list< Ast::StateReference * >::iterator I;
300 I i = orderedStates_->begin( );
301 if( i != orderedStates_->end( ) ){
302 if( firstOrderedStateOwner_ ){
303 delete *i;
305 for( ++i; i != orderedStates_->end( ); ++i )
307 delete *i;
311 delete orderedStates_;
315 if( exprOwner_ )
317 typedef std::map< const char *, Ast::StateReference *, charPtrLess >::const_iterator I;
318 for( I i = namedStates_->begin( ); i != namedStates_->end( ); ++i )
320 delete i->first;
321 delete i->second;
324 delete namedStates_;
328 Ast::ArgListExprs::ArgListExprs( size_t numberOfOrderedDummyExprs )
329 : exprOwner_( true ), firstOrderedStateOwner_( true ), orderedExprs_( new std::list< Ast::Expression * > ), namedExprs_( new std::map< const char *, Ast::Expression *, charPtrLess > ), orderedStates_( new typeof *orderedStates_ ), namedStates_( new typeof *namedStates_ )
331 for( size_t i = 0; i < numberOfOrderedDummyExprs; ++i )
333 orderedExprs_->push_back( new Ast::DummyExpression );
337 void
338 Ast::ArgListExprs::evaluate( const RefCountPtr< const Kernel::CallContInfo > & info, const Ast::ArgListExprs::ConstIterator & pos, const RefCountPtr< const Lang::SingleList > & vals, Kernel::EvalState * evalState ) const
340 std::list< Ast::Expression * >::const_reverse_iterator i1end = orderedExprs_->rend( );
342 if( pos.i1_ == i1end &&
343 pos.i2_ == namedExprs_->end( ) )
345 evalState->cont_ = info->cont_;
346 info->cont_->takeValue( vals, evalState );
347 return;
350 if( pos.i1_ != i1end )
352 /* Note that it is necessary that the evaluation of expressions with free states is not delayed.
353 * If it would, it would be very strange for the calling function if a passed state would change
354 * value in response to the accessing of a formal parameter.
356 bool force = info->force( pos.index_ );
357 if( force || (*(pos.i1_))->immediate_ )
359 typedef typeof const_cast< Ast::ArgListExprs::ConstIterator & >( pos ).i1_ Iterator;
360 Iterator next = pos.i1_;
361 ++next;
362 evalState->expr_ = *(pos.i1_);
363 evalState->env_ = info->env_;
364 evalState->dyn_ = info->dyn_;
365 evalState->cont_ = Kernel::ContRef( new Kernel::CallCont_n( evalState->expr_->loc( ),
366 info,
367 Ast::ArgListExprs::ConstIterator( next, pos.i2_, pos.index_ + 1 ),
368 vals,
369 force ) );
370 return;
372 else
374 /* Delay evaluation of this argument by just putting a thunk in the list.
376 typedef typeof const_cast< Ast::ArgListExprs::ConstIterator & >( pos ).i1_ Iterator;
377 Iterator next = pos.i1_;
378 ++next;
379 evaluate( info,
380 Ast::ArgListExprs::ConstIterator( next, pos.i2_, pos.index_ + 1 ),
381 RefCountPtr< const Lang::SingleListPair >( new Lang::SingleListPair( Kernel::VariableHandle( new Kernel::Variable( new Kernel::Thunk( info->env_, info->dyn_, *pos.i1_ ) ) ),
382 vals ) ),
383 evalState );
384 return; /* It is not really important that the above compiles to a tail call. Hopefully, it does, but otherwise it is easy to see that the chain of recursive calls to this function
385 * will always completes without evaluation of expressions. */
388 else
390 bool force = info->force( pos.index_ );
391 if( force || pos.i2_->second->immediate_ )
393 typedef typeof const_cast< Ast::ArgListExprs::ConstIterator & >( pos ).i2_ Iterator;
394 Iterator next = pos.i2_;
395 ++next;
396 evalState->expr_ = pos.i2_->second;
397 evalState->env_ = info->env_;
398 evalState->dyn_ = info->dyn_;
399 evalState->cont_ = Kernel::ContRef( new Kernel::CallCont_n( evalState->expr_->loc( ),
400 info,
401 Ast::ArgListExprs::ConstIterator( pos.i1_, next, pos.index_ + 1 ),
402 vals,
403 force ) );
404 return;
406 else
408 /* Delay evaluation of this argument by just putting a thunk in the list.
410 typedef typeof const_cast< Ast::ArgListExprs::ConstIterator & >( pos ).i2_ Iterator;
411 Iterator next = pos.i2_;
412 ++next;
413 evaluate( info,
414 Ast::ArgListExprs::ConstIterator( pos.i1_, next, pos.index_ + 1 ),
415 RefCountPtr< const Lang::SingleListPair >( new Lang::SingleListPair( Kernel::VariableHandle( new Kernel::Variable( new Kernel::Thunk( info->env_, info->dyn_, pos.i2_->second ) ) ),
416 vals ) ),
417 evalState );
418 return; /* It is not really important that the above compiles to a tail call. Hopefully, it does, but otherwise it is easy to see that the chain of recursive calls to this function
419 * will always complete without evaluation of expressions. */
424 void
425 Ast::ArgListExprs::evaluate_Structure( const RefCountPtr< const Kernel::CallContInfo > & info, size_t pos, const RefCountPtr< const Lang::SingleList > & values, Kernel::EvalState * evalState ) const
427 const Lang::SingleListPair * valuesPtr = dynamic_cast< const Lang::SingleListPair * >( values.getPtr( ) );
428 if( valuesPtr == NULL ){
429 /* Finished, let the waiting CallCont_Structure_last do the rest. */
430 evalState->cont_ = info->cont_;
431 info->cont_->takeValue( Lang::THE_VOID, /* The continuation already has all values; Lang::THE_VOID is just a dummy. */
432 evalState );
433 return;
436 Kernel::VariableHandle first = valuesPtr->car_;
438 if( info->force( pos ) && first->isThunk( ) )
440 evalState->env_ = info->env_;
441 evalState->dyn_ = info->dyn_;
442 evalState->cont_ = Kernel::ContRef( new Kernel::CallCont_Structure_n
443 ( evalState->expr_->loc( ),
444 info,
445 pos - 1,
446 valuesPtr->cdr_ ) );
447 first->force( first, evalState );
448 return;
450 else
452 evaluate_Structure( info, pos - 1, valuesPtr->cdr_, evalState );
453 return;
457 void
458 Ast::ArgListExprs::bind( Kernel::Arguments * dst, RefCountPtr< const Lang::SingleList > vals, Kernel::PassedEnv env, Kernel::PassedDyn dyn ) const
460 typedef const Lang::SingleListPair ConsType;
462 /* Note that the arguments are bound in backwards-order, since that is how the values are accessed.
466 typedef std::map< const char *, Ast::Expression *, charPtrLess >::const_reverse_iterator I;
467 I i = namedExprs_->rbegin( );
468 I end = namedExprs_->rend( );
469 for( ; i != end; ++i )
471 RefCountPtr< ConsType > lst = vals.down_cast< ConsType >( );
472 if( lst == NullPtr< ConsType >( ) )
474 throw Exceptions::InternalError( strrefdup( "Out of argument values when binding application." ) );
476 dst->addNamedArgument( i->first, lst->car_, i->second );
477 vals = lst->cdr_;
482 typedef list< Ast::Expression * >::const_iterator I;
483 I i = orderedExprs_->begin( );
484 I end = orderedExprs_->end( );
485 for( ; i != end; ++i )
487 RefCountPtr< ConsType > lst = vals.down_cast< ConsType >( );
488 if( lst == NullPtr< ConsType >( ) )
490 throw Exceptions::InternalError( strrefdup( "Out of argument values when binding application." ) );
492 dst->addOrderedArgument( lst->car_, *i );
493 vals = lst->cdr_;
497 /* Here, it could/should be verified that vals is null. However, it only isn't in case of an internal error...
500 /* Next, we turn to the states. The states need no evaluation, as they are always passed by reference.
504 typedef std::map< const char *, Ast::StateReference *, charPtrLess >::const_iterator I;
505 I i = namedStates_->begin( );
506 I end = namedStates_->end( );
507 for( ; i != end; ++i )
509 dst->addNamedState( i->first, i->second->getHandle( env, dyn ) , i->second );
514 typedef list< Ast::StateReference * >::const_iterator I;
515 I i = orderedStates_->begin( );
516 I end = orderedStates_->end( );
517 for( ; i != end; ++i )
519 dst->addOrderedState( (*i)->getHandle( env, dyn ), *i );
526 Kernel::VariableHandle
527 Ast::ArgListExprs::findNamed( RefCountPtr< const Lang::SingleList > vals, const char * name ) const
529 /* This function is called when a Lang::Structure is asked for a field by name.
530 * This is reflected in the generated error in case the name is not found.
533 typedef const Lang::SingleListPair ConsType;
535 /* Note that the arguments are bound in backwards-order, since that is how the values are accessed.
538 typedef std::map< const char *, Ast::Expression *, charPtrLess >::const_reverse_iterator I;
539 I i = namedExprs_->rbegin( );
540 I end = namedExprs_->rend( );
541 for( ; i != end; ++i )
543 RefCountPtr< ConsType > lst = vals.down_cast< ConsType >( );
544 if( lst == NullPtr< ConsType >( ) )
546 throw Exceptions::InternalError( strrefdup( "Out of argument values when searching fields." ) );
548 if( strcmp( i->first, name ) == 0 )
550 return lst->car_;
552 vals = lst->cdr_;
555 throw Exceptions::NonExistentMember( strrefdup( "< user union >" ), name );
558 Kernel::VariableHandle
559 Ast::ArgListExprs::getOrdered( RefCountPtr< const Lang::SingleList > vals, size_t pos ) const
561 /* This function is called when a Lang::Structure is asked for a field by position.
562 * This is reflected in the generated error in case the position is not found.
565 typedef const Lang::SingleListPair ConsType;
567 /* Note that the arguments are bound in backwards-order, since that is how the values are accessed.
570 size_t i = 0;
571 while( true )
573 RefCountPtr< ConsType > lst = vals.down_cast< ConsType >( );
574 if( lst == NullPtr< ConsType >( ) )
576 break;
578 if( i == pos )
580 return lst->car_;
582 vals = lst->cdr_;
583 ++i;
586 throw Exceptions::NonExistentPosition( pos, i - 1 );
589 void
590 Ast::ArgListExprs::analyze( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst )
592 parent_ = parent;
594 RefCountPtr< Ast::StateIDSet > passedStates( new Ast::StateIDSet );
596 /* First traverse state arguments, so that we know which states that must not appear in the value arguments.
599 typedef typeof *orderedStates_ ListType;
600 for( ListType::iterator i = orderedStates_->begin( ); i != orderedStates_->end( ); ++i )
602 (*i)->analyze( parent_, env, passedStates.getPtr( ) );
606 typedef typeof *namedStates_ ListType;
607 for( ListType::iterator i = namedStates_->begin( ); i != namedStates_->end( ); ++i )
609 i->second->analyze( parent_, env, passedStates.getPtr( ) );
612 if( passedStates->size( ) < orderedStates_->size( ) + namedStates_->size( ) )
614 Ast::theAnalysisErrorsList.push_back( new Exceptions::RepeatedStateArgument( parent_->loc( ), passedStates ) );
617 /* Traverse children
620 typedef typeof *orderedExprs_ ListType;
621 for( ListType::iterator i = orderedExprs_->begin( ); i != orderedExprs_->end( ); ++i )
623 if( (*i)->immediate_ )
625 (*i)->analyze( parent_, env, freeStatesDst );
627 else
629 Ast::StateIDSet freeStates;
630 (*i)->analyze( parent_, env, & freeStates );
631 for( Ast::StateIDSet::const_iterator j = freeStates.begin( ); j != freeStates.end( ); ++j )
633 if( passedStates->find( *j ) != passedStates->end( ) )
635 Ast::theAnalysisErrorsList.push_back( new Exceptions::FreeStateIsAlsoPassed( (*i)->loc( ), *j ) );
637 freeStatesDst->insert( *j );
643 typedef typeof *namedExprs_ ListType;
644 for( ListType::iterator i = namedExprs_->begin( ); i != namedExprs_->end( ); ++i )
646 if( i->second->immediate_ )
648 i->second->analyze( parent_, env, freeStatesDst );
650 else
652 Ast::StateIDSet freeStates;
653 i->second->analyze( parent_, env, & freeStates );
654 for( Ast::StateIDSet::const_iterator j = freeStates.begin( ); j != freeStates.end( ); ++j )
656 if( passedStates->find( *j ) != passedStates->end( ) )
658 Ast::theAnalysisErrorsList.push_back( new Exceptions::FreeStateIsAlsoPassed( i->second->loc( ), *j ) );
660 freeStatesDst->insert( *j );
667 for( Ast::StateIDSet::const_iterator i = passedStates->begin( ); i != passedStates->end( ); ++i )
669 freeStatesDst->insert( *i );
674 Ast::ArgListExprs::ConstIterator
675 Ast::ArgListExprs::begin( ) const
677 return Ast::ArgListExprs::ConstIterator( orderedExprs_->rbegin( ), namedExprs_->begin( ), 0 );
681 Ast::FunctionFunction::FunctionFunction( const Ast::SourceLocation & loc, const Kernel::Formals * formals, Ast::Expression * body, const Ast::FunctionMode & functionMode )
682 : Lang::Function( new Kernel::EvaluatedFormals( Ast::FileID::build_internal( "< function construction >" ), false ) ), loc_( loc, bool( ) ), formals_( formals ), body_( body ), functionMode_( functionMode )
685 Ast::FunctionFunction::~FunctionFunction( )
687 delete formals_;
688 delete body_;
691 void
692 Ast::FunctionFunction::push_exprs( Ast::ArgListExprs * args ) const
694 formals_->push_exprs( args );
697 void
698 Ast::FunctionFunction::analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * parentEnv, Ast::StateIDSet * freeStatesDst )
700 Ast::AnalysisEnvironment * env( new Ast::AnalysisEnvironment( Ast::theAnalysisEnvironmentList, parentEnv, formals_->argumentIdentifiers_, formals_->stateIdentifiers_ ) );
701 env->activateFunctionBoundary( );
703 /* We know that the body does not access states outside the function's scope, so we can simply
704 * leave freeStatesDst without change.
706 Ast::StateIDSet freeStates;
707 body_->analyze( parent, env, & freeStates );
710 void
711 Ast::FunctionFunction::call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const
713 Kernel::ContRef cont = evalState->cont_;
714 cont->takeValue( Kernel::ValueRef( new Lang::UserFunction( formals_->newEvaluatedFormals( args ),
715 body_, evalState->env_, functionMode_ ) ),
716 evalState );
720 Kernel::CallCont_last::CallCont_last( const RefCountPtr< const Lang::Function > & fun, const Ast::ArgListExprs * argList, bool curry, Kernel::StateHandle mutatorSelf, const Kernel::PassedEnv & env, const Kernel::PassedDyn & dyn, const Kernel::ContRef & cont, const Ast::SourceLocation & callLoc )
721 : Kernel::Continuation( callLoc ), fun_( fun ), argList_( argList ), curry_( curry ), mutatorSelf_( mutatorSelf ), env_( env ), dyn_( dyn ), cont_( cont )
724 Kernel::CallCont_last::~CallCont_last( )
727 void
728 Kernel::CallCont_last::takeValue( const RefCountPtr< const Lang::Value > & valsUntyped, Kernel::EvalState * evalState, bool dummy ) const
730 typedef const Lang::SingleList ArgType;
731 RefCountPtr< ArgType > vals = Helpers::down_cast< ArgType >( valsUntyped, "< Internal error situation in CallCont_last >" );
733 Kernel::Arguments args = fun_->newCurriedArguments( );
734 argList_->bind( & args, vals, env_, dyn_ );
735 if( mutatorSelf_ != 0 )
737 args.setMutatorSelf( mutatorSelf_ );
740 if( curry_ )
742 evalState->cont_ = cont_;
743 cont_->takeValue( Kernel::ValueRef( new Lang::CuteFunction( fun_, args ) ), evalState );
745 else
747 evalState->env_ = env_; /* This matters only when the function being called is FunctionFunction! */
748 evalState->dyn_ = dyn_;
749 evalState->cont_ = cont_;
750 fun_->call( evalState, args, traceLoc_ );
754 Kernel::ContRef
755 Kernel::CallCont_last::up( ) const
757 return cont_;
760 RefCountPtr< const char >
761 Kernel::CallCont_last::description( ) const
763 return strrefdup( "function call's application" );
766 void
767 Kernel::CallCont_last::gcMark( Kernel::GCMarkedSet & marked )
769 const_cast< Lang::Function * >( fun_.getPtr( ) )->gcMark( marked );
770 dyn_->gcMark( marked );
771 cont_->gcMark( marked );
775 Kernel::CallCont_Structure_last::CallCont_Structure_last( const RefCountPtr< const Lang::Function > & fun, const Ast::ArgListExprs * argList, const RefCountPtr< const Lang::SingleList > & values, bool curry, const Kernel::PassedEnv & env, const Kernel::PassedDyn & dyn, const Kernel::ContRef & cont, const Ast::SourceLocation & callLoc )
776 : Kernel::Continuation( callLoc ), fun_( fun ), argList_( argList ), values_( values ), curry_( curry ), env_( env ), dyn_( dyn ), cont_( cont )
779 Kernel::CallCont_Structure_last::~CallCont_Structure_last( )
782 void
783 Kernel::CallCont_Structure_last::takeValue( const RefCountPtr< const Lang::Value > & valDummy, Kernel::EvalState * evalState, bool dummy ) const
785 Kernel::Arguments args = fun_->newCurriedArguments( );
786 argList_->bind( & args, values_, env_, dyn_ );
788 if( curry_ )
790 evalState->cont_ = cont_;
791 cont_->takeValue( Kernel::ValueRef( new Lang::CuteFunction( fun_, args ) ), evalState );
793 else
795 evalState->env_ = env_; /* This matters only when the function being called is FunctionFunction! */
796 evalState->dyn_ = dyn_;
797 evalState->cont_ = cont_;
798 fun_->call( evalState, args, traceLoc_ );
802 Kernel::ContRef
803 Kernel::CallCont_Structure_last::up( ) const
805 return cont_;
808 RefCountPtr< const char >
809 Kernel::CallCont_Structure_last::description( ) const
811 return strrefdup( "split structure application" );
814 void
815 Kernel::CallCont_Structure_last::gcMark( Kernel::GCMarkedSet & marked )
817 const_cast< Lang::Function * >( fun_.getPtr( ) )->gcMark( marked );
818 const_cast< Lang::SingleList * >( values_.getPtr( ) )->gcMark( marked );
819 dyn_->gcMark( marked );
820 cont_->gcMark( marked );
824 Kernel::CallContInfo::CallContInfo( const Ast::ArgListExprs * argList, const Kernel::EvalState & evalState, std::vector< bool > * forcePos )
825 : forcePos_( forcePos ), forceAll_( false ), argList_( argList ), env_( evalState.env_ ), dyn_( evalState.dyn_ ), cont_( evalState.cont_ )
828 Kernel::CallContInfo::CallContInfo( const Ast::ArgListExprs * argList, const Kernel::EvalState & evalState, bool forceAll )
829 : forcePos_( 0 ), forceAll_( forceAll ), argList_( argList ), env_( evalState.env_ ), dyn_( evalState.dyn_ ), cont_( evalState.cont_ )
832 Kernel::CallContInfo::~CallContInfo( )
834 if( forcePos_ != 0 )
836 delete forcePos_;
840 bool
841 Kernel::CallContInfo::force( const size_t & pos ) const
843 if( forcePos_ != 0 )
845 return (*forcePos_)[ pos ];
847 return forceAll_;
850 bool
851 Kernel::CallContInfo::isSelective( ) const
853 return forcePos_ != 0;
856 bool
857 Kernel::CallContInfo::forceNone( ) const
859 if( isSelective( ) )
860 return false;
861 return ! forceAll_;
864 bool
865 Kernel::CallContInfo::forceAll( ) const
867 if( isSelective( ) )
868 return false;
869 return forceAll_;
872 void
873 Kernel::CallContInfo::gcMark( Kernel::GCMarkedSet & marked )
875 env_->gcMark( marked );
876 dyn_->gcMark( marked );
877 cont_->gcMark( marked );
881 Kernel::CallCont_n::CallCont_n( const Ast::SourceLocation & traceLoc, const RefCountPtr< const Kernel::CallContInfo > & info, const Ast::ArgListExprs::ConstIterator & pos, RefCountPtr< const Lang::SingleList > vals, bool force )
882 : Kernel::Continuation( traceLoc ), info_( info ), pos_( pos ), vals_( vals ), force_( force )
885 Kernel::CallCont_n::~CallCont_n( )
888 void
889 Kernel::CallCont_n::takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const
891 /* Even if force_ is set, this continuation takes handles since handles is what goes into the argument list.
894 if( force_ && val->isThunk( ) )
896 val->force( val, evalState );
897 return;
899 if( val == Kernel::THE_SLOT_VARIABLE )
901 /* If we don't detect this, the error messages that will be printed later would be very confusing,
902 * saying that the argument is missing, when the problem is likely to be that some internal
903 * computation should result in THE_VOID_VARIABLE rather than THE_SLOT_VARIABLE.
905 throw Exceptions::InternalError( "An argument expression evaluated to THE_SLOT_VARIABLE." );
907 info_->argList_->evaluate( info_,
908 pos_,
909 RefCountPtr< const Lang::SingleListPair >( new Lang::SingleListPair( val, vals_ ) ),
910 evalState );
913 Kernel::ContRef
914 Kernel::CallCont_n::up( ) const
916 return info_->cont_;
919 RefCountPtr< const char >
920 Kernel::CallCont_n::description( ) const
922 return strrefdup( force_ ? "function call's forced argument" : "function call's immediate argument" );
925 void
926 Kernel::CallCont_n::gcMark( Kernel::GCMarkedSet & marked )
928 const_cast< Kernel::CallContInfo * >( info_.getPtr( ) )->gcMark( marked );
929 const_cast< Lang::SingleList * >( vals_.getPtr( ) )->gcMark( marked );
933 Kernel::CallCont_Structure_n::CallCont_Structure_n( const Ast::SourceLocation & traceLoc, const RefCountPtr< const Kernel::CallContInfo > & info, size_t pos, RefCountPtr< const Lang::SingleList > rest )
934 : Kernel::Continuation( traceLoc ), info_( info ), pos_( pos ), rest_( rest )
937 Kernel::CallCont_Structure_n::~CallCont_Structure_n( )
940 void
941 Kernel::CallCont_Structure_n::takeValue( const RefCountPtr< const Lang::Value > & forcedValue, Kernel::EvalState * evalState, bool dummy ) const
943 info_->argList_->evaluate_Structure( info_, pos_, rest_, evalState );
946 Kernel::ContRef
947 Kernel::CallCont_Structure_n::up( ) const
949 return info_->cont_;
952 RefCountPtr< const char >
953 Kernel::CallCont_Structure_n::description( ) const
955 return strrefdup( "split structure application forced argument" );
958 void
959 Kernel::CallCont_Structure_n::gcMark( Kernel::GCMarkedSet & marked )
961 const_cast< Kernel::CallContInfo * >( info_.getPtr( ) )->gcMark( marked );
962 const_cast< Lang::SingleList * >( rest_.getPtr( ) )->gcMark( marked );
966 Kernel::CallCont_1::CallCont_1( const Ast::SourceLocation & traceLoc, const Ast::ArgListExprs * argList, bool curry, Kernel::StateHandle mutatorSelf, const Kernel::EvalState & evalState, const Ast::SourceLocation & callLoc )
967 : Kernel::Continuation( traceLoc ), argList_( argList ), curry_( curry ), mutatorSelf_( mutatorSelf ), env_( evalState.env_ ), dyn_( evalState.dyn_ ), cont_( evalState.cont_ ), callLoc_( callLoc )
970 Kernel::CallCont_1::~CallCont_1( )
973 void
974 Kernel::CallCont_1::takeValue( const RefCountPtr< const Lang::Value > & funUntyped, Kernel::EvalState * evalState, bool dummy ) const
977 typedef const Lang::Function ArgType;
978 RefCountPtr< ArgType > fun = funUntyped.down_cast< const Lang::Function >( );
979 if( fun != NullPtr< ArgType >( ) )
981 evalState->env_ = env_;
982 evalState->dyn_ = dyn_;
983 evalState->cont_ = Kernel::ContRef( new Kernel::CallCont_last( fun, argList_, curry_, mutatorSelf_, env_, dyn_, cont_, callLoc_ ) );
984 argList_->evaluate( fun->newCallContInfo( argList_, *evalState ),
985 argList_->begin( ), Lang::THE_CONS_NULL,
986 evalState );
987 return;
991 typedef const Lang::Transform2D ArgType;
992 ArgType * transformVal = dynamic_cast< ArgType * >( funUntyped.getPtr( ) );
993 if( transformVal != 0 )
995 if( curry_ )
997 throw Exceptions::MiscellaneousRequirement( strrefdup( "Don't Curry transform applications. It's useless anyway!" ) );
999 if( argList_->orderedExprs_->size( ) != 1 )
1001 throw Exceptions::CoreArityMismatch( "<transform application>", 1, argList_->orderedExprs_->size( ) );
1003 if( ! argList_->namedExprs_->empty( ) )
1005 throw Exceptions::CoreNoNamedFormals( "<transform application>" );
1007 evalState->expr_ = argList_->orderedExprs_->front( );
1008 evalState->env_ = env_;
1009 evalState->dyn_ = dyn_;
1010 evalState->cont_ = Kernel::ContRef( new Kernel::Transform2DCont( *transformVal, cont_, callLoc_ ) );
1011 return;
1015 typedef const Lang::Transform3D ArgType;
1016 ArgType * transformVal = dynamic_cast< ArgType * >( funUntyped.getPtr( ) );
1017 if( transformVal != 0 )
1019 if( curry_ )
1021 throw Exceptions::MiscellaneousRequirement( strrefdup( "Don't Curry transform applications. It's useless anyway!" ) );
1023 if( argList_->orderedExprs_->size( ) != 1 )
1025 throw Exceptions::CoreArityMismatch( "<transform application>", 1, argList_->orderedExprs_->size( ) );
1027 if( ! argList_->namedExprs_->empty( ) )
1029 throw Exceptions::CoreNoNamedFormals( "<transform application>" );
1031 evalState->expr_ = argList_->orderedExprs_->front( );
1032 evalState->env_ = env_;
1033 evalState->dyn_ = dyn_;
1034 evalState->cont_ = Kernel::ContRef( new Kernel::Transform3DCont( *transformVal, cont_, callLoc_ ) );
1035 return;
1040 typedef const Lang::ElementaryPath2D ArgType;
1041 RefCountPtr< ArgType > path = NullPtr< ArgType >( );
1044 path = Helpers::elementaryPathCast2D( funUntyped, this );
1046 catch( const Exceptions::ContinuationTypeMismatch & ball )
1048 goto nextType1;
1051 if( curry_ )
1053 throw Exceptions::MiscellaneousRequirement( strrefdup( "Don't Curry path point selection. It's useless anyway!" ) );
1055 if( argList_->orderedExprs_->size( ) != 1 )
1057 throw Exceptions::CoreArityMismatch( "<path point selection>", 1, argList_->orderedExprs_->size( ) );
1059 if( ! argList_->namedExprs_->empty( ) )
1061 throw Exceptions::CoreNoNamedFormals( "<path point selection>" );
1064 evalState->expr_ = argList_->orderedExprs_->front( );
1065 evalState->env_ = env_;
1066 evalState->dyn_ = dyn_;
1067 evalState->cont_ = Kernel::ContRef( new Kernel::PathApplication2DCont( path,
1068 cont_,
1069 callLoc_ ) );
1070 return;
1072 nextType1:
1075 typedef const Lang::ElementaryPath3D ArgType;
1076 RefCountPtr< ArgType > path = NullPtr< ArgType >( );
1079 path = Helpers::elementaryPathCast3D( funUntyped, this );
1081 catch( const Exceptions::ContinuationTypeMismatch & ball )
1083 goto nextType2;
1086 if( curry_ )
1088 throw Exceptions::MiscellaneousRequirement( strrefdup( "Don't Curry path point selection. It's useless anyway!" ) );
1090 if( argList_->orderedExprs_->size( ) != 1 )
1092 throw Exceptions::CoreArityMismatch( "<path point selection>", 1, argList_->orderedExprs_->size( ) );
1094 if( ! argList_->namedExprs_->empty( ) )
1096 throw Exceptions::CoreNoNamedFormals( "<path point selection>" );
1099 evalState->expr_ = argList_->orderedExprs_->front( );
1100 evalState->env_ = env_;
1101 evalState->dyn_ = dyn_;
1102 evalState->cont_ = Kernel::ContRef( new Kernel::PathApplication3DCont( path,
1103 cont_,
1104 callLoc_ ) );
1105 return;
1107 nextType2:
1109 throw Exceptions::TypeMismatch( traceLoc_,
1110 funUntyped->getTypeName( ),
1111 Helpers::typeSetString( Lang::Function::staticTypeName( ),
1112 Lang::Transform2D::staticTypeName( ),
1113 Lang::Transform3D::staticTypeName( ),
1114 Lang::ElementaryPath2D::staticTypeName( ),
1115 Lang::ElementaryPath3D::staticTypeName( ) ) );
1118 Kernel::ContRef
1119 Kernel::CallCont_1::up( ) const
1121 return cont_;
1124 RefCountPtr< const char >
1125 Kernel::CallCont_1::description( ) const
1127 return strrefdup( "function call's function" );
1130 void
1131 Kernel::CallCont_1::gcMark( Kernel::GCMarkedSet & marked )
1133 dyn_->gcMark( marked );
1134 cont_->gcMark( marked );
1139 Ast::CallExpr::CallExpr( const Ast::SourceLocation & loc, Ast::Expression * funExpr, Ast::ArgListExprs * argList, bool curry )
1140 : Ast::Expression( loc ), curry_( curry ), constFun_( Kernel::THE_NO_FUNCTION ), mutatorSelf_( 0 ), funExpr_( funExpr ), argList_( argList )
1143 Ast::CallExpr::CallExpr( const Ast::SourceLocation & loc, const RefCountPtr< const Lang::Function > & constFun, Ast::ArgListExprs * argList, bool curry )
1144 : Ast::Expression( loc ), curry_( curry ), constFun_( constFun ), mutatorSelf_( 0 ), funExpr_( 0 ), argList_( argList )
1147 Ast::CallExpr::~CallExpr( )
1149 if( funExpr_ != 0 )
1151 delete funExpr_;
1153 if( mutatorSelf_ != 0 )
1155 delete mutatorSelf_;
1157 delete argList_;
1160 void
1161 Ast::CallExpr::setMutatorSelf( Ast::StateReference * mutatorSelf )
1163 mutatorSelf_ = mutatorSelf;
1166 void
1167 Ast::CallExpr::analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst )
1169 if( mutatorSelf_ != 0 )
1171 mutatorSelf_->analyze( this, env, freeStatesDst );
1173 if( funExpr_ != 0 )
1175 funExpr_->analyze( this, env, freeStatesDst );
1177 else
1179 const_cast< Lang::Function * >( constFun_.getPtr( ) )->analyze( this, env );
1181 argList_->analyze( this, env, freeStatesDst );
1183 if( funExpr_ != 0 )
1185 Ast::LexiographicVariable * var = dynamic_cast< Ast::LexiographicVariable * >( funExpr_ );
1186 if( var != 0 &&
1187 var->scope_level( ) == 0 )
1189 /* The callee is bound in the base environment. */
1190 if( strcmp( var->id( )->simpleId( ), Lang::TEX_SYNTAX_ID ) == 0 ) /* Assume there is only one namespace with a matching identifier to simplify the comparison. */
1192 /* Someone is calling TeX. If the argument is a string literal, it should be announced. */
1193 if( argList_->orderedExprs_ != 0 && ! argList_->orderedExprs_->empty( ) )
1195 /* If there are named arguments or more than one ordered argument, they are ignored; only the first ordered argument is checked. */
1196 Ast::Constant * carg = dynamic_cast< Ast::Constant * >( argList_->orderedExprs_->front( ) );
1197 if( carg != 0 )
1201 typedef const Lang::String ArgType;
1202 RefCountPtr< ArgType > strArg = carg->val( )->tryVal< ArgType >( );
1203 Kernel::theTeXLabelManager.announce( std::string( strArg->val_.getPtr( ) ), carg->loc( ) );
1205 catch( const NonLocalExit::NotThisType & ball )
1207 /* This is probably a type mismatch error, but we let the callee make the decision. */
1216 void
1217 Ast::CallExpr::eval( Kernel::EvalState * evalState ) const
1219 if( funExpr_ != 0 )
1221 evalState->expr_ = funExpr_;
1222 evalState->cont_ = Kernel::ContRef( new Kernel::CallCont_1( evalState->expr_->loc( ), argList_, curry_, mutatorSelf_ ? (mutatorSelf_->getHandle( evalState->env_, evalState->dyn_ )) : 0, *evalState, loc_ ) );
1224 else
1226 evalState->cont_ = Kernel::ContRef( new Kernel::CallCont_last( constFun_, argList_, curry_, mutatorSelf_ ? (mutatorSelf_->getHandle( evalState->env_, evalState->dyn_ )) : 0, evalState->env_, evalState->dyn_, evalState->cont_, loc_ ) );
1227 argList_->evaluate( constFun_->newCallContInfo( argList_, *evalState ),
1228 argList_->begin( ), Lang::THE_CONS_NULL,
1229 evalState );
1233 Kernel::UnionCont_last::UnionCont_last( const Ast::ArgListExprs * argList, const Kernel::ContRef & cont, const Ast::SourceLocation & callLoc )
1234 : Kernel::Continuation( callLoc ), argList_( argList ), cont_( cont )
1237 Kernel::UnionCont_last::~UnionCont_last( )
1240 void
1241 Kernel::UnionCont_last::takeValue( const RefCountPtr< const Lang::Value > & valsUntyped, Kernel::EvalState * evalState, bool dummy ) const
1243 typedef const Lang::SingleList ArgType;
1244 RefCountPtr< ArgType > vals = Helpers::down_cast< ArgType >( valsUntyped, "< Internal error situation in UnionCont_last >" );
1246 evalState->cont_ = cont_;
1247 cont_->takeValue( Kernel::ValueRef( new Lang::Structure( argList_, vals ) ),
1248 evalState );
1251 Kernel::ContRef
1252 Kernel::UnionCont_last::up( ) const
1254 return cont_;
1257 RefCountPtr< const char >
1258 Kernel::UnionCont_last::description( ) const
1260 return strrefdup( "union" );
1263 void
1264 Kernel::UnionCont_last::gcMark( Kernel::GCMarkedSet & marked )
1266 cont_->gcMark( marked );
1270 Ast::UnionExpr::UnionExpr( const Ast::SourceLocation & loc, Ast::ArgListExprs * argList )
1271 : Ast::Expression( loc ), argList_( argList )
1274 Ast::UnionExpr::~UnionExpr( )
1276 delete argList_;
1280 void
1281 Ast::UnionExpr::analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst )
1283 argList_->analyze( this, env, freeStatesDst );
1286 void
1287 Ast::UnionExpr::eval( Kernel::EvalState * evalState ) const
1289 evalState->cont_ = Kernel::ContRef( new Kernel::UnionCont_last( argList_, evalState->cont_, loc_ ) );
1291 argList_->evaluate( RefCountPtr< Kernel::CallContInfo >( new Kernel::CallContInfo( argList_, *evalState, false ) ),
1292 argList_->begin( ), Lang::THE_CONS_NULL,
1293 evalState );
1297 Kernel::SplitCont_1::SplitCont_1( const Ast::SourceLocation & traceLoc, Ast::Expression * argList, bool curry, const Kernel::EvalState & evalState, const Ast::SourceLocation & callLoc )
1298 : Kernel::Continuation( traceLoc ), argList_( argList ), curry_( curry ), env_( evalState.env_ ), dyn_( evalState.dyn_ ), cont_( evalState.cont_ ), callLoc_( callLoc )
1301 Kernel::SplitCont_1::~SplitCont_1( )
1304 void
1305 Kernel::SplitCont_1::takeValue( const RefCountPtr< const Lang::Value > & funUntyped, Kernel::EvalState * evalState, bool dummy ) const
1307 typedef const Lang::Function ArgType;
1308 RefCountPtr< ArgType > fun = Helpers::down_cast< ArgType >( funUntyped, "Split's function" );
1310 evalState->env_ = env_;
1311 evalState->dyn_ = dyn_;
1312 evalState->cont_ = Kernel::ContRef( new Kernel::SplitCont_2( fun, curry_, env_, dyn_, cont_, callLoc_ ) );
1313 evalState->expr_ = argList_;
1316 Kernel::ContRef
1317 Kernel::SplitCont_1::up( ) const
1319 return cont_;
1322 RefCountPtr< const char >
1323 Kernel::SplitCont_1::description() const
1325 return strrefdup( "split call's function" );
1328 void
1329 Kernel::SplitCont_1::gcMark( Kernel::GCMarkedSet & marked )
1331 dyn_->gcMark( marked );
1332 cont_->gcMark( marked );
1336 Kernel::SplitCont_2::SplitCont_2( const RefCountPtr< const Lang::Function > & fun, bool curry, const Kernel::PassedEnv & env, const Kernel::PassedDyn & dyn, const Kernel::ContRef & cont, const Ast::SourceLocation & callLoc )
1337 : Kernel::Continuation( callLoc ), fun_( fun ), curry_( curry ), env_( env ), dyn_( dyn ), cont_( cont )
1340 Kernel::SplitCont_2::~SplitCont_2( )
1343 void
1344 Kernel::SplitCont_2::takeValue( const RefCountPtr< const Lang::Value > & valsUntyped, Kernel::EvalState * evalState, bool dummy ) const
1346 /* This continuation shall mimic the behavior Kernel::CallCont_1.
1349 typedef const Lang::Structure ArgType;
1350 RefCountPtr< ArgType > structure = Helpers::down_cast< ArgType >( valsUntyped, "Split" );
1352 const Ast::ArgListExprs * argList = structure->argList_;
1354 evalState->env_ = env_;
1355 evalState->dyn_ = dyn_;
1356 evalState->cont_ = Kernel::ContRef( new Kernel::CallCont_Structure_last( fun_, argList, structure->values_, curry_, env_, dyn_, cont_, traceLoc_ ) );
1357 RefCountPtr< Kernel::CallContInfo > callContInfo = fun_->newCallContInfo( argList, *evalState );
1359 if( callContInfo->forceNone( ) ){
1361 /* Bypass forcing.
1363 Kernel::ContRef cont = evalState->cont_;
1364 cont->takeValue( structure->values_, evalState );
1366 }else{
1368 argList->evaluate_Structure( callContInfo,
1369 structure->valueCount( ) - 1, /* Reverse index of first element in structure->values_. */
1370 structure->values_,
1371 evalState );
1376 Kernel::ContRef
1377 Kernel::SplitCont_2::up( ) const
1379 return cont_;
1382 RefCountPtr< const char >
1383 Kernel::SplitCont_2::description( ) const
1385 return strrefdup( "Split/splice" );
1388 void
1389 Kernel::SplitCont_2::gcMark( Kernel::GCMarkedSet & marked )
1391 cont_->gcMark( marked );
1395 Ast::CallSplitExpr::CallSplitExpr( const Ast::SourceLocation & loc, Ast::Expression * funExpr, Ast::Expression * argList, bool curry )
1396 : Ast::Expression( loc ), curry_( curry ), funExpr_( funExpr ), argList_( argList )
1399 Ast::CallSplitExpr::~CallSplitExpr( )
1401 delete funExpr_;
1402 delete argList_;
1406 void
1407 Ast::CallSplitExpr::analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst )
1409 funExpr_->analyze( this, env, freeStatesDst );
1410 argList_->analyze( this, env, freeStatesDst );
1413 void
1414 Ast::CallSplitExpr::eval( Kernel::EvalState * evalState ) const
1416 evalState->expr_ = funExpr_;
1417 evalState->cont_ = Kernel::ContRef( new Kernel::SplitCont_1( evalState->expr_->loc( ), argList_, curry_, *evalState, loc_ ) );
1421 Ast::DummyExpression::DummyExpression( )
1422 : Ast::Expression( Ast::THE_UNKNOWN_LOCATION )
1425 Ast::DummyExpression::DummyExpression( const Ast::SourceLocation & loc )
1426 : Ast::Expression( loc )
1429 Ast::DummyExpression::~DummyExpression( )
1432 void
1433 Ast::DummyExpression::analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst )
1435 /* Nothing to do! */
1438 void
1439 Ast::DummyExpression::eval( Kernel::EvalState * evalState ) const
1441 throw Exceptions::InternalError( strrefdup( "A DummyExpression must never be evaluated." ) );