3 Copyright (C) 2006 Damien Katz
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27 #define ASSERT _ASSERT
41 #include "Exceptions.h"
42 #include "MemoryPool.h"
43 #include "antlr/CommonAST.hpp"
44 #include "FabricSTL.h"
49 //forward declarations
54 class FailedAssertHandler
;
55 class UserFunctionDescriptor
;
59 class TextElementILess
62 bool operator () (const TextElement
& left
, const TextElement
& right
) const;
65 typedef size_t IdAtom
;
66 typedef fmap
<const IdAtom
, const UserFunctionDescriptor
*> AtomUserFunctionMap
;
73 // This is the main interface class.
74 // It compiles and executes formulas, and keeps all the formula specific state
78 static void ProcessInit();
83 // Compiles a formula and sets up the runtime machinery to execute the formula
84 void Compile(const char* pInputFormula
, FormulaType formulaType
= kSimple
);
86 // Executes the formula and returns the result of computation
87 const List
* Execute();
90 bool SelectCompute(Document
& doc
);
91 const fvector
<const List
*>& GetColumns();
92 void AppendColumnList(const List
* pList
);
93 const char* CompileError();
95 fvector
<TextElement
> GetColumnNames();
99 // Converts a string to a number that is unique to that string.
100 // For each subsequent request using the same string (case insensitive)
101 // results in the same atom
102 IdAtom
GetIdAtom(const TextElement
& ident
);
104 // Set/Get variable values. The IdAtom versions are faster if you have
105 // the IdAtom already computed, otherwise just use the text versions.
106 const List
* GetVariableValue(const TextElement
& varId
);
107 void SetVariableValue(const TextElement
& varId
, const List
* pList
);
108 const List
* GetVariableValue(IdAtom varIdAtom
);
109 void SetVariableValue(IdAtom varIdAtom
, const List
* pList
);
111 // Get a value but first looking in the Variables, then in the document fields
112 const List
* GetValue(const TextElement
& varId
, IdAtom varIdAtom
);
114 // Get/Set the user function during runtime
115 const UserFunctionDescriptor
* GetUserFunction(IdAtom idAtom
);
116 void SetUserFunction(IdAtom idAtom
, const UserFunctionDescriptor
*);
118 // Create/destoys variable scope
119 void PushVariableScope();
120 void PopVariableScope();
122 VariableScope
& GetCurrentScope();
124 // Various commonly returned values. Functions should
125 // return these to avoid allocating new values unnecessarily.
126 const List
* TrueList();
127 const List
* FalseList();
128 const List
* NilList();
129 const List
* BoolList(bool trueOrFalse
);
131 // Set a context document for the compuation
132 void SetDocument(Document
* pDoc
);
134 // Get the context document for the computation. If once doesn't exist,
135 // fabric creates a special default one to use.
136 Document
& GetDocument();
138 // Built in to Fabric are ASSERT and ASSERTFALSE, and they are used
139 // by the test suite. When Fabric encounters an ASSERT but an assert
140 // handler is not set, then the entire contained expression is skipped.
141 FailedAssertHandler
* GetFailedAssertHandler();
142 void SetFailedAssertHandler(FailedAssertHandler
* pHandler
);
144 void SetEarlyReturnList(const List
* pList
);
146 class SyntaxException
: public std::runtime_error
149 SyntaxException(const char* message
)
150 : std::runtime_error(message
)
154 void SetSelected(bool flag
);
157 void AddToDestructionQueue(Destructable
* d
);
159 AllocOnlyMemoryPool
<0xFFFF> indefMa
; // Memory only needed for the current formula execution
160 AllocOnlyMemoryPool
<0xFFFF> transMa
; // Memory needed across all formula executions
161 MA
* ma
; // pointer to indefMa, for convenience
165 const List
* Execute(const RuntimeNode
* pRoot
);
166 RuntimeNode
* BuildTree(antlr::RefAST pAST
);
168 // this in NewRuntimeNode.cpp
169 RuntimeNode
* NewRuntimeNode(int type
, const char* pNodeText
);
171 fmap
<const TextElement
, IdAtom
, TextElementILess
> m_idAtoms
;
174 VariableScope
* m_pCurrentVarScope
;
176 AtomUserFunctionMap
* m_pUserFunctions
;
178 RuntimeNode
* m_pRootNode
;
180 char* m_pCompileError
;
182 const List
* m_pTrueList
;
183 const List
* m_pFalseList
;
184 const List
* m_pNilList
;
186 const List
* m_pEarlyReturnList
;
189 Document
* m_pDefaultDoc
;
191 fvector
<const List
*> m_columnLists
;
193 fvector
<Destructable
*> m_destructables
;
197 FailedAssertHandler
* m_pFailedAssertHandler
;
202 // UserFunctionDescriptor - Describes a user function.
204 class UserFunctionDescriptor
207 fvector
<IdAtom
> m_argIds
; // the IdAtoms of the argument variable names
208 const RuntimeNode
* pRuntimeNode
; // the actual function itself
210 UserFunctionDescriptor(MA
* ma
)
217 // VariableScope - Contains the variables, input args
218 // and return value for the current scope.
223 fmap
<const IdAtom
, const List
*> map
;
225 VariableScope
* pPrev
;
226 VariableScope
* pNext
;
228 const List
* pReturnList
;
230 fvector
<const List
*> inputArgs
;
233 VariableScope(MA
* ma
)
234 : map(ma
), pPrev(NULL
), pNext(NULL
), pReturnList(NULL
), inputArgs(ma
)
241 // FailedAssertHandler - Interface class so callers can dealing with failed
242 // asserts. Used only during testing.
244 class FailedAssertHandler
247 virtual void HandleFailedAssert() = 0;
254 virtual void Destruct() = 0;
259 template<class T
> int cmp(const T
& a
, const T
& b
)
272 //*******************************************
273 // Inline functions below:
274 //*******************************************