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/Set the user function during runtime
112 const UserFunctionDescriptor
* GetUserFunction(IdAtom idAtom
);
113 void SetUserFunction(IdAtom idAtom
, const UserFunctionDescriptor
*);
115 // Create/destoys variable scope
116 void PushVariableScope();
117 void PopVariableScope();
119 VariableScope
& GetCurrentScope();
121 // Various commonly returned values. Functions should
122 // return these to avoid allocating new values unnecessarily.
123 const List
* TrueList();
124 const List
* FalseList();
125 const List
* NilList();
126 const List
* BoolList(bool trueOrFalse
);
128 // Set a context document for the compuation
129 void SetDocument(Document
* pDoc
);
131 // Get the context document for the computation. If once doesn't exist,
132 // fabric creates a special default one to use.
133 Document
& GetDocument();
135 // Built in to Fabric are ASSERT and ASSERTFALSE, and they are used
136 // by the test suite. When Fabric encounters an ASSERT but an assert
137 // handler is not set, then the entire contained expression is skipped.
138 FailedAssertHandler
* GetFailedAssertHandler();
139 void SetFailedAssertHandler(FailedAssertHandler
* pHandler
);
141 void SetEarlyReturnList(const List
* pList
);
143 class SyntaxException
: public std::runtime_error
146 SyntaxException(const char* message
)
147 : std::runtime_error(message
)
151 void SetSelected(bool flag
);
154 void AddToDestructionQueue(Destructable
* d
);
156 AllocOnlyMemoryPool
<0xFFFF> indefMa
; // Memory only needed for the current formula execution
157 AllocOnlyMemoryPool
<0xFFFF> transMa
; // Memory needed across all formula executions
158 MA
* ma
; // pointer to indefMa, for convenience
162 const List
* Execute(const RuntimeNode
* pRoot
);
163 RuntimeNode
* BuildTree(antlr::RefAST pAST
);
165 // this in NewRuntimeNode.cpp
166 RuntimeNode
* NewRuntimeNode(int type
, const char* pNodeText
);
168 fmap
<const TextElement
, IdAtom
, TextElementILess
> m_idAtoms
;
171 VariableScope
* m_pCurrentVarScope
;
173 AtomUserFunctionMap
* m_pUserFunctions
;
175 RuntimeNode
* m_pRootNode
;
177 char* m_pCompileError
;
179 const List
* m_pTrueList
;
180 const List
* m_pFalseList
;
181 const List
* m_pNilList
;
183 const List
* m_pEarlyReturnList
;
186 Document
* m_pDefaultDoc
;
188 fvector
<const List
*> m_columnLists
;
190 fvector
<Destructable
*> m_destructables
;
194 FailedAssertHandler
* m_pFailedAssertHandler
;
199 // UserFunctionDescriptor - Describes a user function.
201 class UserFunctionDescriptor
204 fvector
<IdAtom
> m_argIds
; // the IdAtoms of the argument variable names
205 const RuntimeNode
* pRuntimeNode
; // the actual function itself
207 UserFunctionDescriptor(MA
* ma
)
214 // VariableScope - Contains the variables, input args
215 // and return value for the current scope.
220 fmap
<const IdAtom
, const List
*> map
;
222 VariableScope
* pPrev
;
223 VariableScope
* pNext
;
225 const List
* pReturnList
;
227 fvector
<const List
*> inputArgs
;
230 VariableScope(MA
* ma
)
231 : map(ma
), pPrev(NULL
), pNext(NULL
), pReturnList(NULL
), inputArgs(ma
)
238 // FailedAssertHandler - Interface class so callers can dealing with failed
239 // asserts. Used only during testing.
241 class FailedAssertHandler
244 virtual void HandleFailedAssert() = 0;
251 virtual void Destruct() = 0;
256 template<class T
> int cmp(const T
& a
, const T
& b
)
269 //*******************************************
270 // Inline functions below:
271 //*******************************************