This repository has been archived on 2024-03-20. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
ContactBook/CExpr/Cexpr.h
2024-03-20 09:28:18 -05:00

246 lines
8 KiB
C++

/*
* File: cexpr.h
* Purpose: Prolog-like file I/O
* Author: Julian Smart
* Created: 1997
* Updated:
* Copyright: (c) 1997, Julian Smart
*/
/* sccsid[] = "%W% %G%" */
#ifndef __CEXPRH__
#define __CEXPRH__
#include <stdio.h>
#include <iostream.h>
#include "wx_list.h"
#include "wx_hash.h"
#include "expr.h"
// Error types
#define CEXPR_ERROR_GENERAL 1
#define CEXPR_ERROR_SYNTAX 2
// Error handler function definition. If app returns TRUE,
// carry on processing.
typedef BOOL (*CExprErrorHandler) (int errorType, char *msg);
extern CExprErrorHandler currentCExprErrorHandler;
extern "C" FILE *yyin;
//#ifndef __WATCOMC__
extern "C"
//#endif
int yyparse(void);
typedef enum {
CExprNull,
CExprInteger,
CExprReal,
CExprWord,
CExprString,
CExprList
} CExprType;
class CExprDatabase;
class ClipsTemplate;
class ClipsTemplateSlot;
class CExpr
{
public:
CObject *client_data;
CExprType type;
union {
long integer;
char *word;
char *string;
float real;
CExpr *first; // If is a list expr, points to the first node
} value;
CExpr *next; // If this is a node in a list, points to the next node
CExpr *last; // If is a list expr, points to the last node
CExpr(CExprType the_type, char *word_or_string, BOOL allocate);
CExpr(const CString& functor); // Assume this is a new clause - pass functor
CExpr(CExprType the_type, const CString& word_or_string = "");
CExpr(long the_integer);
CExpr(float the_real);
CExpr(wxList *the_list);
~CExpr(void);
inline CExprType Type(void) { return type; }
inline long IntegerValue(void)
{
if (type == CExprInteger)
return value.integer;
else if (type == CExprReal)
return (long)value.real;
else return 0;
}
inline float RealValue(void) {
if (type == CExprReal)
return value.real;
else if (type == CExprInteger)
return (float)value.integer;
else return (float)0.0;
}
inline CString WordValue(void) {
if (type == CExprWord)
return value.word;
else if (type == CExprString)
return CString(value.string);
else return CString("");
}
inline CString StringValue(void) {
if (type == CExprString)
return CString(value.string);
else if (type == CExprWord)
return CString(value.word);
else return CString("");
}
// Get nth arg of clause (starting from 1)
CExpr *Arg(CExprType type, int arg);
// Return nth argument of a list expression (starting from zero)
CExpr *Nth(int arg);
// Returns the number of elements in a list expression
int Number(void);
CExpr *Copy(void);
CExpr *GetAttributeValueNode(const CString& word); // Use only for a clause or list
CExpr *AttributeValue(const CString& word); // Use only for a clause
CString Functor(void); // Only for a clause
BOOL IsFunctor(const CString& s); // Only for a clause
void WriteClause(ostream& stream); // Write this expression as a top-level clause
void WriteExpr(ostream& stream); // Write as any other subexpression
void WriteLispExpr(ostream& stream);
void WriteClipsClause(ostream& stream, BOOL filtering = FALSE,
CExprDatabase *database = NULL);
void WriteClipsSlot(ostream& stream, ClipsTemplate *temp);
void WriteClipsList(ostream& stream);
// Append an expression to a list
void Append(CExpr *expr);
// Insert at beginning of list
void Insert(CExpr *expr);
// Get first expr in list
inline CExpr *GetFirst(void) { return ((type == CExprList) ? value.first : NULL); }
// Get next expr if this is a node in a list
inline CExpr *GetNext(void) { return next; }
// Get last expr in list
inline CExpr *GetLast(void) { return ((type == CExprList) ? last : NULL); }
// This should really be called SetAttributeValue since any existing
// attribute-value is deleted first.
void AddAttributeValue(const CString& attribute, long value);
void AddAttributeValue(const CString& attribute, float value);
void AddAttributeValueWord(const CString& attribute, const CString& value);
void AddAttributeValueString(const CString& attribute, const CString& value);
void AddAttributeValue(const CString& attribute, wxList *value);
void AddAttributeValue(const CString& attribute, CExpr *value);
void AddAttributeValueStringList(const CString& attribute, wxList *string_list);
void DeleteAttributeValue(const CString& attribute);
BOOL GetAttributeValue(const CString& att, int& var);
BOOL GetAttributeValue(const CString& att, long& var);
BOOL GetAttributeValue(const CString& att, float& var);
BOOL GetAttributeValue(const CString& att, CString& var); // Word OR string -> string
BOOL GetAttributeValue(const CString& att, CExpr **var);
// Add string items to list if the list attribute exists
BOOL GetAttributeValueStringList(const CString& att, wxList *var);
// Associate other data with this expression, e.g. when reading in a
// number of linked items - store C++ object pointer with the expression
// so we can index into the CExpr database and fish out the pointer.
inline void SetClientData(CObject *data) { client_data = data; }
inline CObject *GetClientData(void) { return client_data; }
};
class CExprDatabase: public wxList
{
DECLARE_DYNAMIC(CExprDatabase)
private:
wxNode *position; // Where we are in a search
wxHashTable *hash_table;
CString attribute_to_hash;
public:
int noErrors;
CExprDatabase(CExprErrorHandler handler = 0);
// Use hashing on both the functor, and the attribute of
// specified type (CExprString or CExprInteger) and name.
// So to find node 45
// (i.e. match the clause node(id=45, ...))
// it usually requires 1 look-up: the keys for functor and attribute
// are added together.
// Obviously if the attribute was missing in a clause, it would
// fail to be found by this method, but could be retrieved by a
// linear search using BeginFind and FindClauseByFunctor,
// or just searching through the list as per usual.
CExprDatabase(CExprType type, const CString& attribute, int size = 500,
CExprErrorHandler handler = 0);
~CExprDatabase(void);
int GetItemCount(void); // get count of possible items
void BeginFind(void); // Initialise a search
CExpr *FindClause(long id); // Find a term based on an integer id attribute
// e.g. node(id=23, type=rectangle, ....).
// Find on basis of attribute/value pairs, e.g. type=rectangle
// This doesn't use hashing; it's a linear search.
CExpr *FindClause(const CString& word, const CString& value);
CExpr *FindClause(const CString& word, long value);
CExpr *FindClause(const CString& word, float value);
CExpr *FindClauseByFunctor(const CString& functor);
CExpr *HashFind(const CString& functor, const CString& value);
CExpr *HashFind(const CString& functor, long value);
void Append(CExpr *expr); // Does cleverer things if hashing is on
void ClearDatabase(void);
inline int GetErrorCount() { return noErrors; }
BOOL Read(const CString& filename);
BOOL ReadFromString(const CString& buffer);
BOOL Write(const CString& fileName);
BOOL Write(ostream& stream);
void WriteLisp(ostream& stream);
};
// Function call-style interface - some more convenience wrappers/unwrappers
// Make a call
CExpr *CExprMakeCall(const CString& functor ...);
#define CExprMakeInteger(x) (new CExpr((long)x))
#define CExprMakeReal(x) (new CExpr((float)x))
#define CExprMakeString(x) (new CExpr(CExprString, x))
#define CExprMakeWord(x) (new CExpr(CExprWord, x))
#define CExprMake(x) (new CExpr(x))
// Checks functor
BOOL CExprIsFunctor(CExpr *expr, const CString& functor);
// Temporary variable for communicating between read.cc and YACC/LEX
extern CExprDatabase *theCExprDatabase;
// YACC/LEX can leave memory lying around...
extern "C" CExprCleanUp();
#endif