667 lines
14 KiB
C++
667 lines
14 KiB
C++
/*
|
|
----
|
|
This file is part of SECONDO.
|
|
|
|
Copyright (C) 2008, University in Hagen,
|
|
Faculty of Mathematics and Computer Science,
|
|
Database Systems for New Applications.
|
|
|
|
SECONDO is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
SECONDO is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with SECONDO; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
----
|
|
|
|
|
|
*/
|
|
|
|
#include "NestedList.h"
|
|
#include "QueryProcessor.h"
|
|
extern NestedList* nl;
|
|
|
|
|
|
/*
|
|
4.1.0 [->] R
|
|
|
|
*/
|
|
template<class R>
|
|
ListExpr TypeMap0(ListExpr args){
|
|
std::string err ="no arguments expected";
|
|
if(!nl->IsEmpty(args)){
|
|
ErrorReporter::ReportError(err);
|
|
return nl->TypeError();
|
|
}
|
|
return nl->SymbolAtom(R::BasicType());
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
4.1.1 A [->] R
|
|
|
|
This type mapping can be used for non-overloaded
|
|
Operators.
|
|
|
|
*/
|
|
template<class A, class R>
|
|
ListExpr TypeMap1(ListExpr args){
|
|
std::string err = A::BasicType()+ " expected";
|
|
if(nl->ListLength(args)!=1){
|
|
ErrorReporter::ReportError(err);
|
|
return nl->TypeError();
|
|
}
|
|
if(!A::checkType(nl->First(args))){
|
|
ErrorReporter::ReportError(err);
|
|
return nl->TypeError();
|
|
}
|
|
return nl->SymbolAtom(R::BasicType());
|
|
}
|
|
|
|
/*
|
|
4.1.2 A1 [x] A2 [->] R
|
|
|
|
|
|
*/
|
|
template<class A1, class A2, class R>
|
|
ListExpr TypeMap2(ListExpr args){
|
|
std::string err = A1::BasicType()+ " x " + A2::BasicType() + " expected";
|
|
if(nl->ListLength(args)!=2){
|
|
ErrorReporter::ReportError(err);
|
|
return nl->TypeError();
|
|
}
|
|
if(!A1::checkType(nl->First(args)) ||
|
|
!A2::checkType(nl->Second(args))){
|
|
ErrorReporter::ReportError(err);
|
|
return nl->TypeError();
|
|
}
|
|
return nl->SymbolAtom(R::BasicType());
|
|
}
|
|
|
|
/*
|
|
4.1.2 A1 [x] A2 [x] A3 [->] R
|
|
|
|
|
|
*/
|
|
template<class A1, class A2, class A3, class R>
|
|
ListExpr TypeMap3(ListExpr args){
|
|
std::string err = A1::BasicType()+ " x " + A2::BasicType() + "x" +
|
|
A3::BasicType() + " expected";
|
|
if(nl->ListLength(args)!=3){
|
|
ErrorReporter::ReportError(err);
|
|
return nl->TypeError();
|
|
}
|
|
if(!A1::checkType(nl->First(args)) ||
|
|
!A2::checkType(nl->Second(args)) ||
|
|
!A3::checkType(nl->Third(args))){
|
|
ErrorReporter::ReportError(err);
|
|
return nl->TypeError();
|
|
}
|
|
return nl->SymbolAtom(R::BasicType());
|
|
}
|
|
|
|
/*
|
|
4.1.2 A1 [x] A2 [x] A3 [->] R
|
|
|
|
|
|
*/
|
|
template<class A1, class A2, class A3, class A4, class R>
|
|
ListExpr TypeMap4(ListExpr args){
|
|
std::string err = A1::BasicType()+ " x " + A2::BasicType() + " x "+
|
|
A3::BasicType() + "x" + A4::BasicType() + " expected";
|
|
if(nl->ListLength(args)!=3){
|
|
ErrorReporter::ReportError(err);
|
|
return nl->TypeError();
|
|
}
|
|
if(!A1::checkType(nl->First(args)) ||
|
|
!A2::checkType(nl->Second(args)) ||
|
|
!A3::checkType(nl->Third(args)) ||
|
|
!A4::checkType(nl->Fourth(args))){
|
|
ErrorReporter::ReportError(err);
|
|
return nl->TypeError();
|
|
}
|
|
return nl->SymbolAtom(R::BasicType());
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
4.1.3 More complex TypeMapping
|
|
|
|
~simpleTMHelper~
|
|
|
|
This class provides some functions for easy creating
|
|
simple type mappings as templates.
|
|
|
|
*/
|
|
|
|
class simpleTMHelper{
|
|
public:
|
|
|
|
/*
|
|
~constructor~
|
|
|
|
*/
|
|
simpleTMHelper():resultType(""),args(0){}
|
|
|
|
/*
|
|
~constructor~
|
|
|
|
This constructor sets the resulttype.
|
|
|
|
*/
|
|
simpleTMHelper(const std::string resultType):args(0){
|
|
this->resultType = resultType;
|
|
}
|
|
|
|
/*
|
|
~operator<<~
|
|
|
|
Using this operator, we can create the arguments for this type mapping.
|
|
For example, to create a simpleTMHelper for a type mapping of the form
|
|
a [x] b [->] r, just use the following code:
|
|
|
|
----
|
|
|
|
simpleTMHelper("r") << "a" << "b";
|
|
|
|
----
|
|
|
|
|
|
*/
|
|
simpleTMHelper& operator<<(const std::string& arg){
|
|
args.push_back(arg);
|
|
return *this;
|
|
}
|
|
|
|
/*
|
|
~Assignment operator~
|
|
|
|
*/
|
|
simpleTMHelper& operator=(const simpleTMHelper& src){
|
|
resultType = src.resultType;
|
|
args = src.args;
|
|
return *this;
|
|
}
|
|
|
|
/*
|
|
~Copy constructor~
|
|
|
|
*/
|
|
simpleTMHelper(const simpleTMHelper& src){
|
|
resultType = src.resultType;
|
|
args = src.args;
|
|
}
|
|
/*
|
|
~Destructor~
|
|
|
|
*/
|
|
~simpleTMHelper(){
|
|
|
|
}
|
|
|
|
/*
|
|
~check~
|
|
|
|
This function checks, whether the argumentlist matchs this
|
|
simple type mapping.
|
|
|
|
*/
|
|
bool check(ListExpr args) const{
|
|
if(nl->ListLength(args)!= static_cast<int>(this->args.size())){
|
|
return false;
|
|
}
|
|
int pos = 0;
|
|
while(!nl->IsEmpty(args)){
|
|
if(!nl->IsEqual(nl->First(args),this->args[pos])){
|
|
return false;
|
|
}
|
|
args = nl->Rest(args);
|
|
pos++;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
~argString~
|
|
|
|
Returns the argumentlist formatted as a x b x ...
|
|
|
|
*/
|
|
std::string argString() const{
|
|
if(args.size()==0){
|
|
return "()";
|
|
} else {
|
|
std::stringstream ss;
|
|
for(unsigned int i=0;i<args.size();i++){
|
|
if(i>0) {
|
|
ss << " x ";
|
|
}
|
|
ss << args[i];
|
|
}
|
|
return ss.str();
|
|
}
|
|
}
|
|
/*
|
|
~getResultType~
|
|
|
|
Returns the result type for this value mapping.
|
|
|
|
*/
|
|
std::string getResultType()const{
|
|
return resultType;
|
|
}
|
|
|
|
private:
|
|
std::string resultType;
|
|
std::vector<std::string> args;
|
|
};
|
|
|
|
|
|
/*
|
|
1.1 class tm0
|
|
|
|
This class provides a simple type mapping for operators
|
|
of the format [->] r.
|
|
|
|
*/
|
|
template<class R>
|
|
class tm0 : public simpleTMHelper{
|
|
public:
|
|
tm0():simpleTMHelper(R::BasicType()){
|
|
}
|
|
};
|
|
|
|
/*
|
|
1.2 class tm1
|
|
|
|
Type mapping template for unary operators.
|
|
|
|
*/
|
|
template<class A,class R>
|
|
class tm1 : public simpleTMHelper{
|
|
public:
|
|
tm1():simpleTMHelper(R::BasicType()){
|
|
*this << A::BasicType();
|
|
}
|
|
};
|
|
|
|
/*
|
|
1.3 class tm2
|
|
|
|
Type mapping template for binary operators.
|
|
|
|
*/
|
|
template<class A1, class A2,class R>
|
|
class tm2 : public simpleTMHelper{
|
|
public:
|
|
tm2():simpleTMHelper(R::BasicType()){
|
|
*this << A1::BasicType();
|
|
*this << A2::BasicType();
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
1.3 class tm3
|
|
|
|
Type mapping template for terner operators.
|
|
|
|
*/
|
|
template<class A1, class A2, class A3, class R>
|
|
class tm3 : public simpleTMHelper{
|
|
public:
|
|
tm3():simpleTMHelper(R::BasicType()){
|
|
*this << A1::BasicType();
|
|
*this << A2::BasicType();
|
|
*this << A3::BasicType();
|
|
}
|
|
};
|
|
|
|
/*
|
|
1.3 class tm4
|
|
|
|
Type mapping template for 4 arguments.
|
|
|
|
*/
|
|
template<class A1, class A2, class A3, class A4, class R>
|
|
class tm4 : public simpleTMHelper{
|
|
public:
|
|
tm4():simpleTMHelper(R::BasicType()){
|
|
*this << A1::BasicType();
|
|
*this << A2::BasicType();
|
|
*this << A3::BasicType();
|
|
*this << A4::BasicType();
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
1.3 class tm5
|
|
|
|
Type mapping template for terner operators.
|
|
|
|
*/
|
|
template<class A1, class A2, class A3, class A4, class A5, class R>
|
|
class tm5 : public simpleTMHelper{
|
|
public:
|
|
tm5():simpleTMHelper(R::BasicType()){
|
|
*this << A1::BasicType();
|
|
*this << A2::BasicType();
|
|
*this << A3::BasicType();
|
|
*this << A4::BasicType();
|
|
*this << A5::BasicType();
|
|
}
|
|
};
|
|
|
|
/*
|
|
1.3 class tm11
|
|
|
|
Type mapping template for 9 operators.
|
|
|
|
*/
|
|
template<class A1, class A2, class A3, class A4, class A5,
|
|
class A6, class A7, class A8, class R>
|
|
class tm9 : public simpleTMHelper{
|
|
public:
|
|
tm9():simpleTMHelper(R::BasicType()){
|
|
*this << A1::BasicType();
|
|
*this << A2::BasicType();
|
|
*this << A3::BasicType();
|
|
*this << A4::BasicType();
|
|
*this << A5::BasicType();
|
|
*this << A6::BasicType();
|
|
*this << A7::BasicType();
|
|
*this << A8::BasicType();
|
|
}
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
Enter here classes for further type mappings.
|
|
|
|
*/
|
|
|
|
|
|
/*
|
|
1.5 Complex Type Mapping
|
|
|
|
This class is a collection of type mappings. It can be used for
|
|
simple overloaded operators.
|
|
|
|
*/
|
|
|
|
class complexTM{
|
|
public:
|
|
/*
|
|
~constructor~
|
|
|
|
*/
|
|
complexTM():mappings(0){}
|
|
|
|
/*
|
|
~add~
|
|
|
|
This function adds a simple type mapping.
|
|
|
|
*/
|
|
void add(simpleTMHelper tm){
|
|
mappings.push_back(tm);
|
|
}
|
|
|
|
/*
|
|
~functor~
|
|
|
|
This functor realized the type mapping.
|
|
|
|
*/
|
|
ListExpr operator()(const ListExpr args) const{
|
|
std::stringstream err;
|
|
err << "allowed = " << endl << getSignatures();
|
|
for(unsigned int i=0;i<mappings.size();i++){
|
|
if(mappings[i].check(args)){
|
|
return nl->SymbolAtom(mappings[i].getResultType());
|
|
}
|
|
}
|
|
ErrorReporter::ReportError(err.str());
|
|
return nl->TypeError();
|
|
}
|
|
|
|
/*
|
|
~select~
|
|
|
|
Provides functionality for the slection function.
|
|
|
|
*/
|
|
|
|
int select(const ListExpr args) const{
|
|
for(unsigned int i=0;i<mappings.size();i++){
|
|
if(mappings[i].check(args)){
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
~getSignatures~
|
|
|
|
Returns the allowed signatures line by line.
|
|
|
|
*/
|
|
std::string getSignatures()const {
|
|
std::stringstream sigs;
|
|
for(unsigned int i=0;i<mappings.size();i++){
|
|
sigs << mappings[i].argString()
|
|
<< " -> " << mappings[i].getResultType()
|
|
<< endl;
|
|
}
|
|
return sigs.str();
|
|
}
|
|
|
|
|
|
/*
|
|
~getSpecification~
|
|
|
|
Returns the specification string.
|
|
|
|
*/
|
|
const std::string getSpecification(const std::string syntax,
|
|
const std::string meaning,
|
|
const std::string example ){
|
|
return
|
|
std::string("((\"Signature\" \"Syntax\" \"Meaning\" \"Example\" )")
|
|
+ "( <text>" + getSignatures() + "</text--->"
|
|
+ " <text>" + syntax + "</text--->"
|
|
+ " <text>" + meaning + "</text--->"
|
|
+ " <text>" + example + "</text--->))";
|
|
}
|
|
/*
|
|
~getVMCount~
|
|
|
|
Returns the number of stored value mappings.
|
|
|
|
*/
|
|
int getVMCount()const{
|
|
return mappings.size();
|
|
}
|
|
|
|
private:
|
|
std::vector<simpleTMHelper> mappings;
|
|
|
|
};
|
|
|
|
|
|
/*
|
|
~Generic Value Mapping Function~
|
|
|
|
This function realized value mappings in the form
|
|
A1 [x] A2 [->] R
|
|
where Fun is the function applied to a1 and a2.
|
|
|
|
*/
|
|
template<class A1, class A2, class R, class Fun>
|
|
int GenVM2(Word* args, Word& result, int message,
|
|
Word& local, Supplier s){
|
|
result = ::qp->ResultStorage(s);
|
|
A1* a1 = static_cast<A1*>(args[0].addr);
|
|
A2* a2 = static_cast<A2*>(args[1].addr);
|
|
R* res = static_cast<R*>(result.addr);
|
|
if(!a1->IsDefined() || !a2->IsDefined()){
|
|
res->SetDefined(false);
|
|
} else {
|
|
Fun fun;
|
|
fun(a1,a2,res);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
~Generic Value Mapping Function~
|
|
|
|
This function realized value mappings in the form
|
|
A1 [x] A2 [x] A3 [->] R
|
|
where Fun is the function applied to a1,a2, and a3.
|
|
|
|
*/
|
|
template<class A1, class A2, class A3, class R, class Fun>
|
|
int GenVM3(Word* args, Word& result, int message,
|
|
Word& local, Supplier s){
|
|
result = ::qp->ResultStorage(s);
|
|
A1* a1 = static_cast<A1*>(args[0].addr);
|
|
A2* a2 = static_cast<A2*>(args[1].addr);
|
|
A3* a3 = static_cast<A3*>(args[2].addr);
|
|
R* res = static_cast<R*>(result.addr);
|
|
if(!a1->IsDefined() || !a2->IsDefined() || !a3->IsDefined()){
|
|
res->SetDefined(false);
|
|
} else {
|
|
Fun fun;
|
|
fun(a1,a2,a3,res);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
~Generic Value Mapping Function~
|
|
|
|
This function realized value mappings in the form
|
|
A1 [x] A2 [x] A3 [x] A4 [->] R
|
|
where Fun is the function applied to a1,a2,a3, and a4.
|
|
|
|
*/
|
|
template<class A1, class A2, class A3,class A4, class R, class Fun>
|
|
int GenVM4(Word* args, Word& result, int message,
|
|
Word& local, Supplier s){
|
|
result = ::qp->ResultStorage(s);
|
|
A1* a1 = static_cast<A1*>(args[0].addr);
|
|
A2* a2 = static_cast<A2*>(args[1].addr);
|
|
A3* a3 = static_cast<A3*>(args[2].addr);
|
|
A4* a4 = static_cast<A4*>(args[3].addr);
|
|
R* res = static_cast<R*>(result.addr);
|
|
if(!a1->IsDefined() || !a2->IsDefined() || !a3->IsDefined()||
|
|
!a4->IsDefined()){
|
|
res->SetDefined(false);
|
|
} else {
|
|
Fun fun;
|
|
fun(a1,a2,a3,a4,res);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
~Generic Value Mapping Function~
|
|
|
|
This function realized value mappings in the form
|
|
A1 [x] A2 [x] A3 [x] A4 [x] A5 [->] R
|
|
where Fun is the function applied to a1,a2,a3,a4 and a5.
|
|
|
|
*/
|
|
template<class A1, class A2, class A3,class A4, class A5,
|
|
class R, class Fun>
|
|
int GenVM5(Word* args, Word& result, int message,
|
|
Word& local, Supplier s){
|
|
result = ::qp->ResultStorage(s);
|
|
A1* a1 = static_cast<A1*>(args[0].addr);
|
|
A2* a2 = static_cast<A2*>(args[1].addr);
|
|
A3* a3 = static_cast<A3*>(args[2].addr);
|
|
A4* a4 = static_cast<A4*>(args[3].addr);
|
|
A5* a5 = static_cast<A5*>(args[4].addr);
|
|
R* res = static_cast<R*>(result.addr);
|
|
if(!a1->IsDefined() || !a2->IsDefined() || !a3->IsDefined()||
|
|
!a4->IsDefined() || !a5->IsDefined()){
|
|
res->SetDefined(false);
|
|
} else {
|
|
Fun fun;
|
|
fun(a1,a2,a3,a4,a5,res);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
~Generic Value Mapping Function~
|
|
|
|
This function realized value mappings in the form
|
|
A1 [x] A2 [x] A3 [x] A4 [x] A5 [x] A6 [x] A7 [x] A8 [->] R
|
|
where Fun is the function applied to a1,a2,a3,a4,a5,a6,a7, and a8.
|
|
|
|
*/
|
|
template<class A1, class A2, class A3,
|
|
class A4, class A5, class A6,
|
|
class A7, class A8, class R,
|
|
class Fun>
|
|
int GenVM9(Word* args, Word& result, int message,
|
|
Word& local, Supplier s){
|
|
result = ::qp->ResultStorage(s);
|
|
A1* a1 = static_cast<A1*>(args[0].addr);
|
|
A2* a2 = static_cast<A2*>(args[1].addr);
|
|
A3* a3 = static_cast<A3*>(args[2].addr);
|
|
A4* a4 = static_cast<A4*>(args[3].addr);
|
|
A5* a5 = static_cast<A5*>(args[4].addr);
|
|
A6* a6 = static_cast<A6*>(args[5].addr);
|
|
A7* a7 = static_cast<A7*>(args[6].addr);
|
|
A8* a8 = static_cast<A8*>(args[7].addr);
|
|
R* res = static_cast<R*>(result.addr);
|
|
if(!a1->IsDefined() || !a2->IsDefined() || !a3->IsDefined()||
|
|
!a4->IsDefined() || !a5->IsDefined() || !a6->IsDefined()||
|
|
!a7->IsDefined() || !a8->IsDefined() ){
|
|
res->SetDefined(false);
|
|
} else {
|
|
Fun fun;
|
|
fun(a1,a2,a3,a4,a5,a6,a7,a8,res);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
~Generic Value Mapping~
|
|
|
|
This value mapping realized functions with signatur
|
|
A [->] R
|
|
|
|
*/
|
|
template<class A, class R, class Fun>
|
|
int GenVM1(Word* args, Word& result, int message,
|
|
Word& local, Supplier s){
|
|
result = ::qp->ResultStorage(s);
|
|
A* a = static_cast<A*>(args[0].addr);
|
|
R* res = static_cast<R*>(result.addr);
|
|
if(!a->IsDefined()){
|
|
res->SetDefined(false);
|
|
} else {
|
|
Fun fun;
|
|
fun(a,res);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|