Merge branch 'gh/maint-clean' into ht/-include
[shapes.git] / source / astvar.h
blob5a74b341e16a29ad654f773a9fc80c4548fe97bb
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 Henrik Tidefelt
19 #pragma once
21 #include "Shapes_Kernel_decls.h"
23 #include "ast.h"
25 namespace Shapes
27 namespace Ast
30 class SourceLocationMark : public Node
32 public:
33 SourceLocationMark( const Ast::SourceLocation & loc );
34 virtual ~SourceLocationMark( );
36 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
40 class CodeBracket : public Expression
42 public:
43 typedef std::map< const char *, size_t, charPtrLess > MapType;
44 private:
45 std::list< Ast::Node * > * nodes_;
46 Ast::CodeBracket * extends_;
47 public:
48 MapType * argumentOrder_;
49 MapType * dynamicMap_;
50 MapType * stateOrder_;
51 public:
52 CodeBracket( const Ast::SourceLocation & loc, std::list< Ast::Node * > * nodes, Ast::CodeBracket * extends = 0 );
53 virtual ~CodeBracket( );
55 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
56 virtual void eval( Kernel::EvalState * evalState ) const;
58 Kernel::Environment * newEnvironment( Kernel::Environment * parent, const char * debugName = "Bracket" ) const;
59 void eval( Kernel::EvalState * evalState, Kernel::Environment * extendsEnv ) const;
61 void evalAt( const RefCountPtr< const Kernel::CodeBracketContInfo > & info, const std::list< Ast::Node * >::const_iterator & i, Kernel::EvalState * evalState ) const;
63 void setDynamicMap( MapType * dynamicMap );
68 namespace Kernel
70 class CodeBracketContInfo
72 public:
73 const Ast::CodeBracket * bracketExpr_;
74 Kernel::PassedEnv env_;
75 Kernel::PassedDyn dyn_;
76 Kernel::ContRef cont_;
78 CodeBracketContInfo( const Ast::CodeBracket * bracketExpr, const Kernel::EvalState & evalState );
79 ~CodeBracketContInfo( );
81 void gcMark( Kernel::GCMarkedSet & marked );
84 class CodeBracketContinuation : public Kernel::Continuation
86 RefCountPtr< const Kernel::CodeBracketContInfo > info_;
87 std::list< Ast::Node * >::const_iterator pos_;
88 public:
89 CodeBracketContinuation( const Ast::SourceLocation & _traceLoc, const RefCountPtr< const Kernel::CodeBracketContInfo > & _info, const std::list< Ast::Node * >::const_iterator & _pos );
90 virtual ~CodeBracketContinuation( );
91 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const;
92 virtual Kernel::ContRef up( ) const;
93 virtual RefCountPtr< const char > description( ) const;
94 virtual void gcMark( Kernel::GCMarkedSet & marked );
98 class DynamicBindingContinuation : public Kernel::Continuation
100 Kernel::PassedEnv env_;
101 Kernel::Environment::LexicalKey key_;
102 const Ast::DynamicBindingExpression * bindingExpr_;
103 Kernel::ContRef cont_;
104 public:
105 DynamicBindingContinuation( const Ast::SourceLocation & traceLoc, const Kernel::PassedEnv & env, const Kernel::Environment::LexicalKey & key, const Ast::DynamicBindingExpression * bindingExpr, const Kernel::ContRef & cont );
106 virtual ~DynamicBindingContinuation( );
107 virtual void takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const;
108 virtual Kernel::ContRef up( ) const;
109 virtual RefCountPtr< const char > description( ) const;
110 virtual void gcMark( Kernel::GCMarkedSet & marked );
113 class WithDynamicContinuation : public Kernel::Continuation
115 Ast::Expression * expr_;
116 Kernel::PassedEnv env_;
117 Kernel::PassedDyn dyn_;
118 Kernel::ContRef cont_;
119 public:
120 WithDynamicContinuation( const Ast::SourceLocation & traceLoc, Ast::Expression * expr, const Kernel::EvalState & evalState );
121 virtual ~WithDynamicContinuation( );
122 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const;
123 virtual Kernel::ContRef up( ) const;
124 virtual RefCountPtr< const char > description( ) const;
125 virtual void gcMark( Kernel::GCMarkedSet & marked );
128 class DynamicVariableDeclContinuation : public Kernel::Continuation
130 const Ast::DynamicVariableDecl * declExpr_;
131 Kernel::PassedEnv env_;
132 Kernel::PassedDyn dyn_;
133 Kernel::ContRef cont_;
134 public:
135 DynamicVariableDeclContinuation( const Ast::SourceLocation & traceLoc, const Ast::DynamicVariableDecl * declExpr, Kernel::EvalState & evalState );
136 virtual ~DynamicVariableDeclContinuation( );
137 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const;
138 virtual Kernel::ContRef up( ) const;
139 virtual RefCountPtr< const char > description( ) const;
140 virtual void gcMark( Kernel::GCMarkedSet & marked );
143 class AssertStructureContinuation : public Kernel::Continuation
145 Kernel::ContRef cont_;
146 public:
147 AssertStructureContinuation( const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc );
148 ~AssertStructureContinuation( );
149 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const;
150 virtual Kernel::ContRef up( ) const;
151 virtual RefCountPtr< const char > description( ) const;
152 virtual void gcMark( Kernel::GCMarkedSet & marked );
155 } // End of namespace Kernel.
157 namespace Ast
159 class LexiographicVariable : public Expression
161 const char * id_;
162 mutable Kernel::Environment::LexicalKey ** idKey_;
163 size_t scope_level_;
164 public:
165 LexiographicVariable( const Ast::SourceLocation & loc, const char * id, Kernel::Environment::LexicalKey ** idKey );
166 virtual ~LexiographicVariable( );
167 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
168 virtual void eval( Kernel::EvalState * evalState ) const;
170 /* The following function may be called after the expression has been analyzed, to find out what kind of binding that
171 * the variable refers to. Kernel bindings can be fetched without evaluation before the program starts. Prelude and user
172 * top-level bindings need only be evaluated once. Other bindings are harder to analyze, and should be evaluated
173 * each time.
174 * Note that the "level" here refers to the level of the binding, and not the variable expression referring to the binding.
176 * 0 means kernel bindings, 1 means prelude bindings, 2 means user top-level, and 3 or higher means a non-global binding.
178 size_t scope_level( ) const { return scope_level_; }
179 const char * id( ) const { return id_; }
182 class EvalOutsideExpr : public Expression
184 Ast::Expression * expr_;
185 public:
186 EvalOutsideExpr( const Ast::SourceLocation & loc, Ast::Expression * expr );
187 virtual ~EvalOutsideExpr( );
188 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
189 virtual void eval( Kernel::EvalState * evalState ) const;
192 class DefineVariable : public BindNode
194 Ast::Expression * expr_;
195 mutable size_t ** idPos_;
196 public:
197 DefineVariable( const Ast::SourceLocation & idLoc, const char * id, Ast::Expression * expr, size_t ** idPos );
198 virtual ~DefineVariable( );
199 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
200 virtual void evalHelper( Kernel::EvalState * evalState ) const;
203 class LexicalVariableLocationExpr : public Expression
205 public:
206 typedef enum { INDEX, DEPTH } Kind;
207 private:
208 const char * id_;
209 Kind kind_;
210 RefCountPtr< const Lang::Value > value_;
211 public:
212 LexicalVariableLocationExpr( const Ast::SourceLocation & idLoc, const char * id, Kind kind );
213 virtual ~LexicalVariableLocationExpr( );
214 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
215 virtual void eval( Kernel::EvalState * evalState ) const;
218 class LexicalVariableNameExpr : public Expression
220 RefCountPtr< const Lang::Value > value_;
221 public:
222 LexicalVariableNameExpr( const Ast::SourceLocation & loc );
223 virtual ~LexicalVariableNameExpr( );
224 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
225 virtual void eval( Kernel::EvalState * evalState ) const;
228 class StructSplitReference : public Expression
230 Ast::SourceLocation structLoc_;
231 size_t ** structPos_;
232 const char * fieldId_;
233 size_t fieldPos_;
234 Ast::Expression * defaultExpr_;
235 public:
236 StructSplitReference( Ast::SourceLocation fieldLoc, const char * fieldId, Ast::Expression * defaultExpr );
237 StructSplitReference( Ast::SourceLocation fieldLoc, size_t fieldPos, Ast::Expression * defaultExpr );
238 virtual ~StructSplitReference( );
239 void setStruct( Ast::SourceLocation structLoc, size_t ** structPos );
240 bool isOrdered( ) const { return fieldId_ == 0; }
241 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
242 virtual void eval( Kernel::EvalState * evalState ) const;
245 class StructSplitSink : public Expression
247 Ast::SourceLocation structLoc_;
248 size_t ** structPos_;
249 size_t consumedArguments_;
250 public:
251 StructSplitSink( );
252 virtual ~StructSplitSink( );
253 void setStruct( Ast::SourceLocation structLoc, size_t ** structPos, size_t consumedArguments );
254 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
255 virtual void eval( Kernel::EvalState * evalState ) const;
258 class AssertNoSinkNeeded : public Assertion
260 size_t orderedCount_;
261 Ast::SourceLocation structLoc_;
262 size_t ** structPos_;
263 public:
264 AssertNoSinkNeeded( const Ast::SourceLocation & loc, size_t orderedCount, Ast::SourceLocation structLoc, size_t ** structPos );
265 virtual ~AssertNoSinkNeeded( );
266 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
267 virtual void eval( Kernel::EvalState * evalState ) const;
270 class SplitDefineVariables
272 static size_t splitVarCount;
273 static PtrOwner_back_Access< std::list< const char * > > mem;
274 const char * splitVarId_;
275 public:
276 std::list< std::pair< Ast::DefineVariable *, Ast::StructSplitReference * > > exprs_;
277 Ast::DefineVariable * sinkDefine_;
278 Ast::StructSplitSink * sinkExpr_;
279 bool seenNamed_;
280 bool seenDefault_;
281 SplitDefineVariables( );
282 const char * newSplitVarId( ) const;
285 class StateReference : public Node
287 protected:
288 Node * someParent_; // The inherited parent_ does not make sense for reused nodes. Use this instead.
289 Ast::AnalysisEnvironment * someAnalysisEnv_; // The inherited analysisEnv_ does not make sense for reused nodes. Use this instead.
290 public:
291 StateReference( const Ast::SourceLocation & loc );
292 virtual ~StateReference( );
293 virtual Kernel::StateHandle getHandle( Kernel::PassedEnv env, Kernel::PassedDyn dyn ) const = 0;
296 class LexiographicState : public StateReference
298 const char * id_;
299 mutable Kernel::Environment::LexicalKey ** idKey_;
300 public:
301 LexiographicState( const Ast::SourceLocation & loc, const char * id, Kernel::Environment::LexicalKey ** idKey );
302 virtual ~LexiographicState( );
303 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
304 Kernel::StateHandle getHandle( Kernel::PassedEnv env, Kernel::PassedDyn dyn ) const;
307 class DynamicState : public Ast::StateReference
309 const char * id_;
310 mutable Kernel::Environment::LexicalKey ** idKey_;
311 public:
312 DynamicState( const Ast::SourceLocation & loc, const char * id );
313 virtual ~DynamicState( );
314 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
315 Kernel::StateHandle getHandle( Kernel::PassedEnv env, Kernel::PassedDyn dyn ) const;
318 class IntroduceState : public BindNode
320 Ast::Expression * expr_;
321 mutable size_t ** idPos_;
322 Ast::StateID stateID_;
323 public:
324 IntroduceState( const Ast::SourceLocation & idLoc, const char * id, Ast::Expression * expr, size_t ** idPos );
325 virtual ~IntroduceState( );
326 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
327 virtual void evalHelper( Kernel::EvalState * evalState ) const;
328 Ast::StateID getStateID( ) const { return stateID_; } /* Make sure analyze_impl has been called first! */
331 class Insertion : public Expression
333 Ast::StateReference * stateRef_;
334 Ast::Expression * expr_;
335 public:
336 Insertion( Ast::StateReference * stateRef, Ast::Expression * expr );
337 virtual ~Insertion( );
338 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
339 virtual void eval( Kernel::EvalState * evalState ) const;
342 class InsertionMutatorCall : public Expression
344 Ast::Expression * expr_;
345 public:
346 InsertionMutatorCall( const Ast::SourceLocation & loc, Ast::Expression * expr );
347 ~InsertionMutatorCall( );
348 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
349 virtual void eval( Kernel::EvalState * evalState ) const;
350 Ast::Expression * getExpr( ) { return expr_; }
353 class Freeze : public Expression
355 const char * id_;
356 mutable size_t ** idPos_;
357 public:
358 Freeze( const Ast::SourceLocation & idLoc, const char * id, size_t ** idPos );
359 virtual ~Freeze( );
360 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
361 virtual void eval( Kernel::EvalState * evalState ) const;
364 class Peek : public Expression
366 Ast::StateReference * stateRef_;
367 public:
368 Peek( const Ast::SourceLocation & idLoc, Ast::StateReference * stateRef );
369 virtual ~Peek( );
370 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
371 virtual void eval( Kernel::EvalState * evalState ) const;
374 class EvalSymbolFunction : public Lang::Function
376 Ast::SourceLocation loc_;
377 Ast::Expression * expr_;
378 Ast::AnalysisEnvironment * analysisEnv_;
379 public:
380 EvalSymbolFunction( const Ast::SourceLocation & loc, Ast::Expression * expr );
381 virtual ~EvalSymbolFunction( );
382 void push_exprs( Ast::ArgListExprs * args ) const;
383 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
384 virtual void call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const;
385 virtual void gcMark( Kernel::GCMarkedSet & marked ){ };
386 virtual bool isTransforming( ) const { return false; }
389 class MemberReferenceFunction : public Lang::Function
391 Ast::SourceLocation loc_;
392 Ast::Expression * variable_;
393 const char * fieldID_;
394 public:
395 MemberReferenceFunction( const Ast::SourceLocation & loc, Ast::Expression * variable, const char * fieldID );
396 virtual ~MemberReferenceFunction( );
397 void push_exprs( Ast::ArgListExprs * args ) const;
398 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
399 virtual void call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const;
400 virtual void gcMark( Kernel::GCMarkedSet & marked ){ };
401 virtual bool isTransforming( ) const { return false; }
404 class MutatorReference : public Ast::Expression
406 Ast::SourceLocation mutatorLoc_;
407 Ast::StateReference * state_;
408 const char * mutatorID_;
409 public:
410 MutatorReference( const Ast::SourceLocation & mutatorLoc, Ast::StateReference * state, const char * mutatorID );
411 virtual ~MutatorReference( );
412 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
413 virtual void eval( Kernel::EvalState * evalState ) const;
416 class SpecialLength : public Expression
418 double val_;
419 int sort_;
420 public:
421 SpecialLength( const Ast::SourceLocation & loc, double val, int sort );
422 virtual ~SpecialLength( );
423 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
424 virtual void eval( Kernel::EvalState * evalState ) const;
427 class DynamicVariable : public Ast::Expression
429 const char * id_;
430 mutable Kernel::Environment::LexicalKey ** idKey_;
431 public:
432 DynamicVariable( const Ast::SourceLocation & loc, const char * id );
433 virtual ~DynamicVariable( );
434 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
435 virtual void eval( Kernel::EvalState * evalState ) const;
438 class DynamicBindingExpression : public Ast::Expression
440 Ast::SourceLocation idLoc_;
441 const char * id_;
442 Ast::Expression * expr_;
443 mutable Kernel::Environment::LexicalKey ** idKey_;
444 public:
445 DynamicBindingExpression( const Ast::SourceLocation & idLoc, const char * id, Ast::Expression * expr, Kernel::Environment::LexicalKey ** idKey );
446 virtual ~DynamicBindingExpression( );
447 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
448 virtual void eval( Kernel::EvalState * evalState ) const;
449 const Ast::SourceLocation & idLoc( ) const { return idLoc_; }
450 const Ast::SourceLocation & exprLoc( ) const { return expr_->loc( ); }
451 const char * id( ) const { return id_; }
454 class DynamicStateBindingExpression : public Ast::Expression
456 Ast::SourceLocation dstLoc_;
457 const char * dstId_;
458 mutable Kernel::Environment::LexicalKey ** dstIdKey_;
459 Ast::StateReference * src_;
460 public:
461 DynamicStateBindingExpression( const Ast::SourceLocation & loc, const Ast::SourceLocation & dstLoc, const char * dstId, Ast::StateReference * src );
462 virtual ~DynamicStateBindingExpression( );
463 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
464 virtual void eval( Kernel::EvalState * evalState ) const;
467 class WithDynamicExpr : public Ast::Expression
469 Ast::Expression * bindings_;
470 Ast::Expression * expr_;
471 public:
472 WithDynamicExpr( const Ast::SourceLocation & loc, Ast::Expression * bindings, Ast::Expression * expr );
473 virtual ~WithDynamicExpr( );
474 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
475 virtual void eval( Kernel::EvalState * evalState ) const;
478 class DynamicVariableDecl : public BindNode
480 mutable size_t ** idPos_;
481 Ast::Expression * impl_;
482 public:
483 DynamicVariableDecl( const Ast::SourceLocation & loc, const Ast::SourceLocation & idLoc, const char * id, Ast::Expression * filterExpr, Ast::Expression * defaultExpr );
484 virtual ~DynamicVariableDecl( );
485 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
486 virtual void evalHelper( Kernel::EvalState * evalState ) const;
489 class DynamicVariableDeclFunction : public Lang::Function
491 const char * id_;
492 Ast::Expression * filterExpr_;
493 Ast::Expression * defaultExpr_;
494 size_t ** idPos_;
495 public:
496 DynamicVariableDeclFunction( const char * id, Ast::Expression * filterExpr, Ast::Expression * defaultExpr, size_t ** idPos );
497 virtual ~DynamicVariableDeclFunction( );
498 void push_exprs( Ast::ArgListExprs * args ) const;
499 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
500 virtual void call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const;
501 virtual void gcMark( Kernel::GCMarkedSet & marked ){ };
502 virtual bool isTransforming( ) const { return false; }
505 class DynamicStateDecl : public BindNode
507 const char * defaultStateID_;
508 mutable size_t ** idPos_;
509 Ast::StateReference * defaultState_;
510 public:
511 DynamicStateDecl( const Ast::SourceLocation & loc, const Ast::SourceLocation & idLoc, const char * id, Ast::StateReference * defaultState, size_t ** idPos );
512 virtual ~DynamicStateDecl( );
513 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
514 virtual void evalHelper( Kernel::EvalState * evalState ) const;
517 class DynamicExpression : public Ast::Expression
519 Ast::Expression * expr_;
520 public:
521 DynamicExpression( const Ast::SourceLocation & loc, Ast::Expression * expr );
522 virtual ~DynamicExpression( );
523 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
524 virtual void eval( Kernel::EvalState * evalState ) const;
527 class LexiographicType : public Expression
529 const char * id_;
530 mutable Kernel::Environment::LexicalKey ** idKey_;
531 public:
532 LexiographicType( const Ast::SourceLocation & loc, const char * id, Kernel::Environment::LexicalKey ** idKey );
533 virtual ~LexiographicType( );
534 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
535 virtual void eval( Kernel::EvalState * evalState ) const;