summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsbrandt <sbrandt@17b73243-c579-4c4c-a9d2-2d5706c11dac>2014-01-15 21:55:04 +0000
committersbrandt <sbrandt@17b73243-c579-4c4c-a9d2-2d5706c11dac>2014-01-15 21:55:04 +0000
commit321185b08dc338e8aaa489b1b909069274b4dc4c (patch)
tree8df8e11ca0be23550ebd68556e1df0a35acb8dd3
parent1f4618cad94f362422c552338c6fe83998a5d329 (diff)
Fix ticket 1401
git-svn-id: http://svn.cactuscode.org/flesh/trunk@5066 17b73243-c579-4c4c-a9d2-2d5706c11dac
-rw-r--r--src/piraha/Call.cc1516
-rw-r--r--src/piraha/Matcher.cc27
-rw-r--r--src/piraha/Piraha.hpp4
-rw-r--r--src/piraha/Seq.cc2
4 files changed, 796 insertions, 753 deletions
diff --git a/src/piraha/Call.cc b/src/piraha/Call.cc
index fd2ff1ca..30547c0d 100644
--- a/src/piraha/Call.cc
+++ b/src/piraha/Call.cc
@@ -25,9 +25,9 @@ extern "C" int CCTK_ParameterFilename(int len, char *filename);
static smart_ptr<Grammar> par_file_grammar = new Grammar();
static std::string mklower(std::string& in) {
- std::string s = in;
- std::transform(s.begin(), s.end(), s.begin(), ::tolower);
- return s;
+ std::string s = in;
+ std::transform(s.begin(), s.end(), s.begin(), ::tolower);
+ return s;
}
enum ValueType { PIR_STRING,PIR_INT,PIR_REAL,PIR_BOOL,PIR_VOID };
@@ -43,26 +43,26 @@ std::string get_parfile() {
}
int n = strlen(value);
if(n > 4 && strcmp(value+n-4,".par")==0) {
- value[n-4] = '\0';
+ value[n-4] = '\0';
}
std::string s = value;
return s;
}
std::ostream& operator<<(std::ostream& o,const ValueType& vt) {
- if(vt == PIR_STRING)
- o << "STRING";
- else if(vt == PIR_INT)
- o << "INT";
- else if(vt == PIR_REAL)
- o << "REAL";
- else if(vt == PIR_BOOL)
- o << "BOOL";
- else if(vt == PIR_VOID)
- o << "VOID";
- else
- o << "UNDEF";
- return o;
+ if(vt == PIR_STRING)
+ o << "STRING";
+ else if(vt == PIR_INT)
+ o << "INT";
+ else if(vt == PIR_REAL)
+ o << "REAL";
+ else if(vt == PIR_BOOL)
+ o << "BOOL";
+ else if(vt == PIR_VOID)
+ o << "VOID";
+ else
+ o << "UNDEF";
+ return o;
}
std::string current_thorn;
@@ -73,140 +73,140 @@ std::string current_thorn;
* that identifies which field is currently valid.
*/
struct Value {
- /** This field holds the parse tree element associated with this Value. */
- smart_ptr<Group> hold;
- double ddata;
- int idata;
- std::string sdata;
- ValueType type;
- Value(smart_ptr<Group> g) : hold(g), ddata(0), idata(0), sdata(), type(PIR_VOID) {}
- ~Value() {}
- /**
- * Create a string representation of the Value.
- */
- std::string copy() {
- assert(type != PIR_VOID);
- if(type == PIR_STRING) {
- return sdata;
- } else if(type == PIR_BOOL) {
- std::string s = idata ? "yes" : "no";
- return s;
- } else {
- std::ostringstream o;
- if(type == PIR_REAL) {
- o << std::setprecision(15) << ddata;
- } else {
- o << idata;
- }
- return o.str();
- }
- }
- /**
- * Check to see if something is a bool and throw an error
- * if it's not.
- */
- void checkBool() {
- if(type != PIR_BOOL) {
- std::ostringstream msg;
- msg << "Does not evaluate to a boolean: " << hold->substring();
- std::string par = get_parfile();
- CCTK_Error(hold->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
- }
- }
- /**
- * Compares with another Value, and throws a CCTK_Error
- * if the comparison doesn't make sense.
- */
- bool equals(smart_ptr<Value> v) {
- if(type == PIR_BOOL && v->type == PIR_BOOL) {
- return idata == v->idata;
- } else if(type == PIR_INT && v->type == PIR_INT) {
- return idata == v->idata;
- } else if(type == PIR_INT && v->type == PIR_REAL) {
- return idata == v->ddata;
- } else if(type == PIR_REAL && v->type == PIR_INT) {
- return ddata == v->idata;
- } else if(type == PIR_REAL && v->type == PIR_REAL) {
- return ddata == v->ddata;
- } else if(type == PIR_STRING && v->type == PIR_STRING) {
- return sdata == v->sdata;
- }
- std::ostringstream msg;
- msg << "Cannot compare " << type << " and " << v->type << std::endl;
- std::string par = get_parfile();
- CCTK_Error(hold->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
- }
- /**
- * Return a double value, whether the underlying
- * quantity is integer or real.
- */
- double doubleValue() {
- if(type == PIR_REAL)
- return ddata;
- else if(type == PIR_INT)
- return idata;
- std::ostringstream msg;
- msg << "Cannot convert " << type << " to double." << std::endl;
- std::string par = get_parfile();
- CCTK_Error(hold->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
- return 0;
- }
- bool intOrDouble() {
- return type == PIR_INT || type == PIR_REAL;
- }
- /**
- * This function converts a double to a real, but
- * only if this can be done without loss of precision.
- */
- void integerize() {
- if(type == PIR_REAL) {
- idata = ddata;
- if(idata == ddata) {
- type = PIR_INT;
- }
- }
- }
- void booleanize(smart_ptr<Group> gr) {
- if(type == PIR_STRING) {
- std::string s = mklower(sdata);
- if(s == "yes" || s == "true") {
- idata = 1;
- type = PIR_BOOL;
- } else if(s == "no" || s == "false") {
- idata = 0;
- type = PIR_BOOL;
- }
- } else if(type == PIR_INT) {
- /// Steven R. Brandt would like to remove this
- /// particular auto-conversion
- if(idata == 1 || idata == 0) {
- type = PIR_BOOL;
- std::ostringstream msg;
- msg << "Boolean variable is set with integer: " << gr->substring() << std::endl;
- std::string par = get_parfile();
- CCTK_Warn(1,gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
- }
- }
- }
+ /** This field holds the parse tree element associated with this Value. */
+ smart_ptr<Group> hold;
+ double ddata;
+ int idata;
+ std::string sdata;
+ ValueType type;
+ Value(smart_ptr<Group> g) : hold(g), ddata(0), idata(0), sdata(), type(PIR_VOID) { smart_ptr<Group> foo(g); }
+ ~Value() {}
+ /**
+ * Create a string representation of the Value.
+ */
+ std::string copy() {
+ assert(type != PIR_VOID);
+ if(type == PIR_STRING) {
+ return sdata;
+ } else if(type == PIR_BOOL) {
+ std::string s = idata ? "yes" : "no";
+ return s;
+ } else {
+ std::ostringstream o;
+ if(type == PIR_REAL) {
+ o << std::setprecision(15) << ddata;
+ } else {
+ o << idata;
+ }
+ return o.str();
+ }
+ }
+ /**
+ * Check to see if something is a bool and throw an error
+ * if it's not.
+ */
+ void checkBool() {
+ if(type != PIR_BOOL) {
+ std::ostringstream msg;
+ msg << "Does not evaluate to a boolean: " << hold->substring();
+ std::string par = get_parfile();
+ CCTK_Error(hold->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
+ }
+ }
+ /**
+ * Compares with another Value, and throws a CCTK_Error
+ * if the comparison doesn't make sense.
+ */
+ bool equals(smart_ptr<Value> v) {
+ if(type == PIR_BOOL && v->type == PIR_BOOL) {
+ return idata == v->idata;
+ } else if(type == PIR_INT && v->type == PIR_INT) {
+ return idata == v->idata;
+ } else if(type == PIR_INT && v->type == PIR_REAL) {
+ return idata == v->ddata;
+ } else if(type == PIR_REAL && v->type == PIR_INT) {
+ return ddata == v->idata;
+ } else if(type == PIR_REAL && v->type == PIR_REAL) {
+ return ddata == v->ddata;
+ } else if(type == PIR_STRING && v->type == PIR_STRING) {
+ return sdata == v->sdata;
+ }
+ std::ostringstream msg;
+ msg << "Cannot compare " << type << " and " << v->type << std::endl;
+ std::string par = get_parfile();
+ CCTK_Error(hold->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
+ }
+ /**
+ * Return a double value, whether the underlying
+ * quantity is integer or real.
+ */
+ double doubleValue() {
+ if(type == PIR_REAL)
+ return ddata;
+ else if(type == PIR_INT)
+ return idata;
+ std::ostringstream msg;
+ msg << "Cannot convert " << type << " to double." << std::endl;
+ std::string par = get_parfile();
+ CCTK_Error(hold->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
+ return 0;
+ }
+ bool intOrDouble() {
+ return type == PIR_INT || type == PIR_REAL;
+ }
+ /**
+ * This function converts a double to a real, but
+ * only if this can be done without loss of precision.
+ */
+ void integerize() {
+ if(type == PIR_REAL) {
+ idata = ddata;
+ if(idata == ddata) {
+ type = PIR_INT;
+ }
+ }
+ }
+ void booleanize(smart_ptr<Group> gr) {
+ if(type == PIR_STRING) {
+ std::string s = mklower(sdata);
+ if(s == "yes" || s == "true") {
+ idata = 1;
+ type = PIR_BOOL;
+ } else if(s == "no" || s == "false") {
+ idata = 0;
+ type = PIR_BOOL;
+ }
+ } else if(type == PIR_INT) {
+ /// Steven R. Brandt would like to remove this
+ /// particular auto-conversion
+ if(idata == 1 || idata == 0) {
+ type = PIR_BOOL;
+ std::ostringstream msg;
+ msg << "Boolean variable is set with integer: " << gr->substring() << std::endl;
+ std::string par = get_parfile();
+ CCTK_Warn(1,gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
+ }
+ }
+ }
};
std::ostream& operator<<(std::ostream& o,const smart_ptr<Value>& val) {
- if(!val.valid()) {
- return o << "NULL";
- }
- o << "(" << val->type << ")";
- if(val->type == PIR_REAL) {
- o << val->ddata;
- } else if(val->type == PIR_INT) {
- o << val->idata;
- } else if(val->type == PIR_BOOL) {
- o << (val->idata ? "true" : "false");
- } else if(val->type == PIR_STRING) {
- o << "\"" << val->sdata << "\"";
- } else {
- o << val->hold->substring();
- }
- return o;
+ if(!val.valid()) {
+ return o << "NULL";
+ }
+ o << "(" << val->type << ")";
+ if(val->type == PIR_REAL) {
+ o << val->ddata;
+ } else if(val->type == PIR_INT) {
+ o << val->idata;
+ } else if(val->type == PIR_BOOL) {
+ o << (val->idata ? "true" : "false");
+ } else if(val->type == PIR_STRING) {
+ o << "\"" << val->sdata << "\"";
+ } else {
+ o << val->hold->substring();
+ }
+ return o;
}
typedef std::map<std::string,std::map<std::string,smart_ptr<Value> > >::iterator th_iter;
@@ -217,17 +217,17 @@ smart_ptr<Value> eval_expr(std::string inp);
// If the value was already defined in this parameter file, look
// it up in the map. Otherwise, get it from Cactus.
smart_ptr<Value> find_val(smart_ptr<Group> gr,std::string thorn,std::string name) {
- smart_ptr<Value> ret = new Value(gr);
+ smart_ptr<Value> ret = new Value(gr);
int type;
const void *result;
result = CCTK_ParameterGet(name.c_str(),thorn.c_str(),&type);
if(result == NULL) {
- std::ostringstream msg;
- msg << "Undefined or inaccessible variable: " << thorn << "::" << name << std::endl;
- std::string par = get_parfile();
- CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
+ std::ostringstream msg;
+ msg << "Undefined or inaccessible variable: " << thorn << "::" << name << std::endl;
+ std::string par = get_parfile();
+ CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
}
-
+
switch(type) {
case PARAMETER_REAL:
ret->type = PIR_REAL;
@@ -251,62 +251,62 @@ smart_ptr<Value> find_val(smart_ptr<Group> gr,std::string thorn,std::string name
}
break;
default:
- std::ostringstream msg;
- msg << "Unexpected type result from ParameterGet=" << type << std::endl;
- std::string par = get_parfile();
- CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
+ std::ostringstream msg;
+ msg << "Unexpected type result from ParameterGet=" << type << std::endl;
+ std::string par = get_parfile();
+ CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
}
//std::cout << "Piraha: GET: " << thorn << "::" << name << "=" << ret << std::endl;
- return ret;
+ return ret;
}
smart_ptr<Value> lookup_var(smart_ptr<Group> gr) {
- smart_ptr<Value> ret;
- if(gr->group(0)->getPatternName() == "env") {
- const char *env = getenv(gr->group(0)->group(0)->substring().c_str());
- if(env != NULL) {
- ret = new Value(gr);
- ret->type = PIR_STRING;
- ret->sdata = env;
- }
- } else if(gr->group(0)->substring() == "parfile") {
- ret = new Value(gr);
- ret->type = PIR_STRING;
- ret->sdata = get_parfile();
- } else if(gr->group(0)->substring() == "pi") {
- ret = new Value(gr);
- ret->type = PIR_REAL;
- ret->ddata = 4.0*atan2(1.0,1.0);
- }
- if(!ret.valid()) {
- std::ostringstream msg;
- msg << "Unknown variable: " << gr->substring() << std::endl;
- std::string par = get_parfile();
- CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
- }
- return ret;
+ smart_ptr<Value> ret;
+ if(gr->group(0)->getPatternName() == "env") {
+ const char *env = getenv(gr->group(0)->group(0)->substring().c_str());
+ if(env != NULL) {
+ ret = new Value(gr);
+ ret->type = PIR_STRING;
+ ret->sdata = env;
+ }
+ } else if(gr->group(0)->substring() == "parfile") {
+ ret = new Value(gr);
+ ret->type = PIR_STRING;
+ ret->sdata = get_parfile();
+ } else if(gr->group(0)->substring() == "pi") {
+ ret = new Value(gr);
+ ret->type = PIR_REAL;
+ ret->ddata = 4.0*atan2(1.0,1.0);
+ }
+ if(!ret.valid()) {
+ std::ostringstream msg;
+ msg << "Unknown variable: " << gr->substring() << std::endl;
+ std::string par = get_parfile();
+ CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
+ }
+ return ret;
}
std::string string_reparser(std::string s) {
- smart_ptr<Matcher> m = new Matcher(par_file_grammar,"stringparser",s.c_str(),s.length());
- if(m->matches()) {
- std::string out = "";
- for(int i=0;i < m->groupCount(); i++) {
- std::string pn = m->group(i)->getPatternName();
- if(pn == "any" || pn == "name") {
- out += m->group(i)->substring();
- } else if(pn == "stringcomment") {
- ;
- } else {
- smart_ptr<Value> val = lookup_var(m->group(i));
- out += val->copy();
- }
- }
- return out;
- } else {
- return s;
- }
+ smart_ptr<Matcher> m = new Matcher(par_file_grammar,"stringparser",s.c_str(),s.length());
+ if(m->matches()) {
+ std::string out = "";
+ for(int i=0;i < m->groupCount(); i++) {
+ std::string pn = m->group(i)->getPatternName();
+ if(pn == "any" || pn == "name") {
+ out += m->group(i)->substring();
+ } else if(pn == "stringcomment") {
+ ;
+ } else {
+ smart_ptr<Value> val = lookup_var(m->group(i));
+ out += val->copy();
+ }
+ }
+ return out;
+ } else {
+ return s;
+ }
}
/**
@@ -316,12 +316,12 @@ std::string string_reparser(std::string s) {
* used recursively.
**/
smart_ptr<Value> meval(smart_ptr<Group> gr) {
- assert(gr.valid());
- std::string pn = gr->getPatternName();
- smart_ptr<Value> ret = new Value(gr);
- if(pn == "num") {
- std::string s = gr->substring();
- s = mklower(s);
+ assert(gr.valid());
+ std::string pn = gr->getPatternName();
+ smart_ptr<Value> ret = new Value(gr);
+ if(pn == "num") {
+ std::string s = gr->substring();
+ s = mklower(s);
std::replace(s.begin(),s.end(),'d','e');
std::istringstream iss(s);
if(iss >> ret->ddata) {
@@ -337,571 +337,595 @@ smart_ptr<Value> meval(smart_ptr<Group> gr) {
std::string par = get_parfile();
CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
}
- } else if(pn == "paren" || pn == "parindex") {
- return meval(gr->group(0));
- } else if(pn == "func") {
- std::string fn = gr->group(0)->substring();
- fn = mklower(fn);
- smart_ptr<Value> val = meval(gr->group(1));
- if(val->type == PIR_REAL || val->type == PIR_INT) {
- if(fn == "trunc") {
- val->ddata = trunc(val->doubleValue());
- val->type = PIR_REAL;
- return val;
- } else if(fn == "floor") {
- val->ddata = floor(val->doubleValue());
- val->type = PIR_REAL;
- return val;
- } else if(fn == "ceil") {
- val->ddata = ceil(val->doubleValue());
- val->type = PIR_REAL;
- return val;
- } else if(fn == "sqrt") {
- val->ddata = sqrt(val->doubleValue());
- val->type = PIR_REAL;
- return val;
- } else if(fn == "atan") {
- val->ddata = atan(val->doubleValue());
- val->type = PIR_REAL;
- return val;
- } else if(fn == "sin") {
- val->ddata = sin(val->doubleValue());
- val->type = PIR_REAL;
- return val;
- } else if(fn == "cos") {
- val->ddata = cos(val->doubleValue());
- val->type = PIR_REAL;
- return val;
- } else if(fn == "tan") {
- val->ddata = tan(val->doubleValue());
- val->type = PIR_REAL;
- return val;
- } else if(fn == "exp") {
- val->ddata = exp(val->doubleValue());
- val->type = PIR_REAL;
- return val;
- } else if(fn == "log") {
- val->ddata = log(val->doubleValue());
- val->type = PIR_REAL;
- return val;
- } else if(fn == "abs") {
- val->ddata = fabs(val->doubleValue());
- val->type = PIR_REAL;
- return val;
- } else if(fn == "acos") {
- val->ddata = acos(val->doubleValue());
- val->type = PIR_REAL;
- return val;
- } else if(fn == "asin") {
- val->ddata = asin(val->doubleValue());
- val->type = PIR_REAL;
- return val;
- } else if(fn == "bool") {
- if(val->type == PIR_REAL) {
- val->idata = val->ddata;
- }
- val->type = PIR_BOOL;
- return val;
- } else if(fn == "int") {
- if(val->type == PIR_REAL) {
- val->idata = val->ddata;
- val->type = PIR_INT;
- }
- return val;
- } else if(fn == "real") {
- if(val->type == PIR_INT) {
- val->ddata = val->idata;
- val->type = PIR_REAL;
- }
- return val;
- }
- } else if(val->type == PIR_BOOL) {
- if(fn == "int") {
- val->type = PIR_INT;
- return val;
- } else if(fn == "real") {
- val->type = PIR_REAL;
- val->ddata = val->idata;
- return val;
- }
- }
- std::ostringstream msg;
- msg << "Unknown func: " << fn << "(" << val->type << ")" << std::endl;
- std::string par = get_parfile();
- CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
- } else if(pn == "name"||pn == "dname") {
- std::string s = gr->substring();
- s = mklower(s);
- if(s == "nan") {
- ret->ddata = NAN;
- ret->type = PIR_REAL;
- } else if(s == "inf") {
- ret->ddata = INFINITY;
- ret->type = PIR_REAL;
- } else if(s == "no" || s == "false") {
- ret->type = PIR_BOOL;
- ret->idata = 0;
- } else if(s == "yes" || s == "true") {
- ret->type = PIR_BOOL;
- ret->idata = 1;
- } else {
- ret->type = PIR_STRING;
- ret->sdata = gr->substring();
- }
- return ret;
- } else if(pn == "par") {
- std::string thorn = gr->group(0)->substring();
- std::string name = gr->group(1)->substring();
- if(gr->groupCount() == 3) {
- std::ostringstream vn;
- smart_ptr<Value> index = meval(gr->group(2));
- if(index->type == PIR_INT) {
- std::stringstream o;
- o << name << "[" << index->idata << "]";
- o << std::flush;
- std::string keyi = o.str();
- ret = find_val(gr,thorn,keyi);
- return ret;
- }
- } else {
- ret = find_val(gr,thorn,name);
- return ret;
- }
- std::ostringstream msg;
- msg << "Unknown par: " << thorn << "::" << name << std::endl;
- std::string par = get_parfile();
- CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
- } else if(pn == "var") {
- ret = lookup_var(gr);
- } else if(pn == "value") {
- if(gr->groupCount()==2) {
- std::string unop = gr->group(0)->substring();
- ret = meval(gr->group(1));
- if(unop == "-") {
- if(ret->type == PIR_INT) {
- ret->idata = -ret->idata;
- } else if(ret->type == PIR_REAL) {
- ret->ddata = -ret->ddata;
- } else {
- std::ostringstream msg;
- msg << "Unknown operation: " << unop << ret->type << std::endl;
- std::string par = get_parfile();
- CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
- }
- } else if(unop == "!") {
- if(ret->type == PIR_BOOL) {
- ret->idata = !ret->idata;
- } else {
- std::ostringstream msg;
- msg << "Unknown operation: " << unop << ret->type << std::endl;
- std::string par = get_parfile();
- CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
- }
- } else {
- std::ostringstream msg;
- msg << "Unknown operation: " << unop << ret->type << std::endl;
- std::string par = get_parfile();
- CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
- }
- } else {
- return meval(gr->group(0));
- }
- } else if(pn == "quot") {
- ret->type = PIR_STRING;
- ret->sdata = string_reparser(gr->group(0)->substring());
- } else if(pn == "inquot") {
- ret->type = PIR_STRING;
- ret->sdata = gr->substring();
- } else if(pn == "expr") {
- if(gr->groupCount()==1)
- return meval(gr->group(0));
- smart_ptr<Value> v1 = meval(gr->group(0));
- smart_ptr<Value> v2 = meval(gr->group(1));
- v1->checkBool();
- v2->checkBool();
- ret->type = PIR_BOOL;
- ret->idata = v1->idata || v2->idata;
- } else if(pn == "powexpr") {
- if(gr->groupCount()==1)
- return meval(gr->group(0));
- smart_ptr<Value> v1 = meval(gr->group(0));
- smart_ptr<Value> v2 = meval(gr->group(1));
- ret->type = PIR_REAL;
- ret->ddata = pow(v1->doubleValue(),v2->doubleValue());
- } else if(pn == "andexpr") {
- if(gr->groupCount()==1)
- return meval(gr->group(0));
- smart_ptr<Value> v1 = meval(gr->group(0));
- smart_ptr<Value> v2 = meval(gr->group(1));
- v1->checkBool();
- v2->checkBool();
- ret->type = PIR_BOOL;
- ret->idata = v1->idata && v2->idata;
- } else if(pn == "eqexpr") {
- if(gr->groupCount()==1)
- return meval(gr->group(0));
- smart_ptr<Value> v1 = meval(gr->group(0));
- std::string eqop = gr->group(1)->substring();
- smart_ptr<Value> v2 = meval(gr->group(2));
- ret->type = PIR_BOOL;
- if(eqop == "==") {
- ret->idata = v1->equals(v2);
- } else if(eqop == "!=") {
- ret->idata = !v1->equals(v2);
- } else {
- std::ostringstream msg;
- msg << "Unknown equality operator: " << eqop << std::endl;
- std::string par = get_parfile();
- CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
- }
- } else if(pn == "compexpr") {
- if(gr->groupCount()==1)
- return meval(gr->group(0));
- smart_ptr<Value> v1 = meval(gr->group(0));
- if(gr->groupCount()>0) {
- std::string compop = gr->group(1)->substring();
- smart_ptr<Value> v2 = meval(gr->group(2));
- double d1 = v1->doubleValue();
- double d2 = v2->doubleValue();
- ret->type = PIR_BOOL;
- if(compop == "<") {
- ret->idata = (d1 < d2);
- return ret;
- } else if(compop == ">") {
- ret->idata = (d1 > d2);
- return ret;
- } else if(compop == "<=") {
- ret->idata = (d1 <= d2);
- return ret;
- } else if(compop == ">=") {
- ret->idata = (d1 >= d2);
- return ret;
- }
- std::ostringstream msg;
- msg << "Unknown comparison operator: " << compop << std::endl;
- std::string par = get_parfile();
- CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
- }
- } else if(pn == "aexpr") {
- if(gr->groupCount()==1)
- return meval(gr->group(0));
- smart_ptr<Value> v1 = meval(gr->group(0));
- for(int i=1;i+1<gr->groupCount();i+=2) {
- std::string addop = gr->group(i)->substring();
- smart_ptr<Value> v2 = meval(gr->group(i+1));
- assert(v2.valid());
- if(v1->type == PIR_INT && v2->type == PIR_INT) {
- ret->type = PIR_INT;
- if(addop == "+") {
- ret->idata = v1->idata + v2->idata;
- } else if(addop == "-") {
- ret->idata = v1->idata - v2->idata;
- } else {
- std::ostringstream msg;
- msg << "Unknown add operator: " << addop << std::endl;
- std::string par = get_parfile();
- CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
- }
- } else if(v1->type == PIR_STRING && v2->type == PIR_STRING) {
- ret->type = PIR_STRING;
- if(addop == "+") {
- ret->sdata = v1->sdata + v2->sdata;
- } else {
- std::ostringstream msg;
+ } else if(pn == "paren" || pn == "parindex") {
+ return meval(gr->group(0));
+ } else if(pn == "func") {
+ std::string fn = gr->group(0)->substring();
+ fn = mklower(fn);
+ smart_ptr<Value> val = meval(gr->group(1));
+ if(val->type == PIR_REAL || val->type == PIR_INT) {
+ if(fn == "trunc") {
+ val->ddata = trunc(val->doubleValue());
+ val->type = PIR_REAL;
+ return val;
+ } else if(fn == "floor") {
+ val->ddata = floor(val->doubleValue());
+ val->type = PIR_REAL;
+ return val;
+ } else if(fn == "ceil") {
+ val->ddata = ceil(val->doubleValue());
+ val->type = PIR_REAL;
+ return val;
+ } else if(fn == "sqrt") {
+ val->ddata = sqrt(val->doubleValue());
+ val->type = PIR_REAL;
+ return val;
+ } else if(fn == "atan") {
+ val->ddata = atan(val->doubleValue());
+ val->type = PIR_REAL;
+ return val;
+ } else if(fn == "sin") {
+ val->ddata = sin(val->doubleValue());
+ val->type = PIR_REAL;
+ return val;
+ } else if(fn == "cos") {
+ val->ddata = cos(val->doubleValue());
+ val->type = PIR_REAL;
+ return val;
+ } else if(fn == "tan") {
+ val->ddata = tan(val->doubleValue());
+ val->type = PIR_REAL;
+ return val;
+ } else if(fn == "exp") {
+ val->ddata = exp(val->doubleValue());
+ val->type = PIR_REAL;
+ return val;
+ } else if(fn == "log") {
+ val->ddata = log(val->doubleValue());
+ val->type = PIR_REAL;
+ return val;
+ } else if(fn == "abs") {
+ val->ddata = fabs(val->doubleValue());
+ val->type = PIR_REAL;
+ return val;
+ } else if(fn == "acos") {
+ val->ddata = acos(val->doubleValue());
+ val->type = PIR_REAL;
+ return val;
+ } else if(fn == "asin") {
+ val->ddata = asin(val->doubleValue());
+ val->type = PIR_REAL;
+ return val;
+ } else if(fn == "bool") {
+ if(val->type == PIR_REAL) {
+ val->idata = val->ddata;
+ }
+ val->type = PIR_BOOL;
+ return val;
+ } else if(fn == "int") {
+ if(val->type == PIR_REAL) {
+ val->idata = val->ddata;
+ val->type = PIR_INT;
+ }
+ return val;
+ } else if(fn == "real") {
+ if(val->type == PIR_INT) {
+ val->ddata = val->idata;
+ val->type = PIR_REAL;
+ }
+ return val;
+ }
+ } else if(val->type == PIR_BOOL) {
+ if(fn == "int") {
+ val->type = PIR_INT;
+ return val;
+ } else if(fn == "real") {
+ val->type = PIR_REAL;
+ val->ddata = val->idata;
+ return val;
+ }
+ }
+ std::ostringstream msg;
+ msg << "Unknown func: " << fn << "(" << val->type << ")" << std::endl;
+ std::string par = get_parfile();
+ CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
+ } else if(pn == "name"||pn == "dname") {
+ std::string s = gr->substring();
+ s = mklower(s);
+ if(s == "nan") {
+ ret->ddata = NAN;
+ ret->type = PIR_REAL;
+ } else if(s == "inf") {
+ ret->ddata = INFINITY;
+ ret->type = PIR_REAL;
+ } else if(s == "no" || s == "false") {
+ ret->type = PIR_BOOL;
+ ret->idata = 0;
+ } else if(s == "yes" || s == "true") {
+ ret->type = PIR_BOOL;
+ ret->idata = 1;
+ } else {
+ ret->type = PIR_STRING;
+ ret->sdata = gr->substring();
+ }
+ return ret;
+ } else if(pn == "par") {
+ std::string thorn = gr->group(0)->substring();
+ std::string name = gr->group(1)->substring();
+ if(gr->groupCount() == 3) {
+ std::ostringstream vn;
+ smart_ptr<Value> index = meval(gr->group(2));
+ if(index->type == PIR_INT) {
+ std::stringstream o;
+ o << name << "[" << index->idata << "]";
+ o << std::flush;
+ std::string keyi = o.str();
+ ret = find_val(gr,thorn,keyi);
+ return ret;
+ }
+ } else {
+ ret = find_val(gr,thorn,name);
+ return ret;
+ }
+ std::ostringstream msg;
+ msg << "Unknown par: " << thorn << "::" << name << std::endl;
+ std::string par = get_parfile();
+ CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
+ } else if(pn == "var") {
+ ret = lookup_var(gr);
+ } else if(pn == "value") {
+ if(gr->groupCount()==2) {
+ std::string unop = gr->group(0)->substring();
+ ret = meval(gr->group(1));
+ if(unop == "-") {
+ if(ret->type == PIR_INT) {
+ ret->idata = -ret->idata;
+ } else if(ret->type == PIR_REAL) {
+ ret->ddata = -ret->ddata;
+ } else {
+ std::ostringstream msg;
+ msg << "Unknown operation: " << unop << ret->type << std::endl;
+ std::string par = get_parfile();
+ CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
+ }
+ } else if(unop == "!") {
+ if(ret->type == PIR_BOOL) {
+ ret->idata = !ret->idata;
+ } else {
+ std::ostringstream msg;
+ msg << "Unknown operation: " << unop << ret->type << std::endl;
+ std::string par = get_parfile();
+ CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
+ }
+ } else {
+ std::ostringstream msg;
+ msg << "Unknown operation: " << unop << ret->type << std::endl;
+ std::string par = get_parfile();
+ CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
+ }
+ } else {
+ return meval(gr->group(0));
+ }
+ } else if(pn == "quot") {
+ ret->type = PIR_STRING;
+ ret->sdata = string_reparser(gr->group(0)->substring());
+ } else if(pn == "inquot") {
+ ret->type = PIR_STRING;
+ ret->sdata = gr->substring();
+ } else if(pn == "expr") {
+ if(gr->groupCount()==1)
+ return meval(gr->group(0));
+ smart_ptr<Value> v1 = meval(gr->group(0));
+ smart_ptr<Value> v2 = meval(gr->group(1));
+ v1->checkBool();
+ v2->checkBool();
+ ret->type = PIR_BOOL;
+ ret->idata = v1->idata || v2->idata;
+ } else if(pn == "powexpr") {
+ if(gr->groupCount()==1)
+ return meval(gr->group(0));
+ smart_ptr<Value> v1 = meval(gr->group(0));
+ smart_ptr<Value> v2 = meval(gr->group(1));
+ ret->type = PIR_REAL;
+ ret->ddata = pow(v1->doubleValue(),v2->doubleValue());
+ } else if(pn == "andexpr") {
+ if(gr->groupCount()==1)
+ return meval(gr->group(0));
+ smart_ptr<Value> v1 = meval(gr->group(0));
+ smart_ptr<Value> v2 = meval(gr->group(1));
+ v1->checkBool();
+ v2->checkBool();
+ ret->type = PIR_BOOL;
+ ret->idata = v1->idata && v2->idata;
+ } else if(pn == "eqexpr") {
+ if(gr->groupCount()==1)
+ return meval(gr->group(0));
+ smart_ptr<Value> v1 = meval(gr->group(0));
+ std::string eqop = gr->group(1)->substring();
+ smart_ptr<Value> v2 = meval(gr->group(2));
+ ret->type = PIR_BOOL;
+ if(eqop == "==") {
+ ret->idata = v1->equals(v2);
+ } else if(eqop == "!=") {
+ ret->idata = !v1->equals(v2);
+ } else {
+ std::ostringstream msg;
+ msg << "Unknown equality operator: " << eqop << std::endl;
+ std::string par = get_parfile();
+ CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
+ }
+ } else if(pn == "compexpr") {
+ if(gr->groupCount()==1)
+ return meval(gr->group(0));
+ smart_ptr<Value> v1 = meval(gr->group(0));
+ if(gr->groupCount()>0) {
+ std::string compop = gr->group(1)->substring();
+ smart_ptr<Value> v2 = meval(gr->group(2));
+ double d1 = v1->doubleValue();
+ double d2 = v2->doubleValue();
+ ret->type = PIR_BOOL;
+ if(compop == "<") {
+ ret->idata = (d1 < d2);
+ return ret;
+ } else if(compop == ">") {
+ ret->idata = (d1 > d2);
+ return ret;
+ } else if(compop == "<=") {
+ ret->idata = (d1 <= d2);
+ return ret;
+ } else if(compop == ">=") {
+ ret->idata = (d1 >= d2);
+ return ret;
+ }
+ std::ostringstream msg;
+ msg << "Unknown comparison operator: " << compop << std::endl;
+ std::string par = get_parfile();
+ CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
+ }
+ } else if(pn == "aexpr") {
+ if(gr->groupCount()==1)
+ return meval(gr->group(0));
+ smart_ptr<Value> v1 = meval(gr->group(0));
+ for(int i=1;i+1<gr->groupCount();i+=2) {
+ std::string addop = gr->group(i)->substring();
+ smart_ptr<Value> v2 = meval(gr->group(i+1));
+ assert(v2.valid());
+ if(v1->type == PIR_INT && v2->type == PIR_INT) {
+ ret->type = PIR_INT;
+ if(addop == "+") {
+ ret->idata = v1->idata + v2->idata;
+ } else if(addop == "-") {
+ ret->idata = v1->idata - v2->idata;
+ } else {
+ std::ostringstream msg;
+ msg << "Unknown add operator: " << addop << std::endl;
+ std::string par = get_parfile();
+ CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
+ }
+ } else if(v1->type == PIR_STRING && v2->type == PIR_STRING) {
+ ret->type = PIR_STRING;
+ if(addop == "+") {
+ ret->sdata = v1->sdata + v2->sdata;
+ } else {
+ std::ostringstream msg;
ret->sdata = v1->sdata + addop + v2->sdata;
- msg << "Unknown add operator: " << addop << std::endl;
+ msg << "Unknown add operator: " << addop << std::endl;
msg << "Interpreting as literal string with value '" << ret->sdata << "'" << std::endl;
- std::string par = get_parfile();
- CCTK_Warn(1,gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
- }
- } else if(v1->intOrDouble() && v2->intOrDouble()) {
- ret->type = PIR_REAL;
- if(addop == "+") {
- ret->ddata = v1->doubleValue()+v2->doubleValue();
- } else if(addop == "-") {
- ret->ddata = v1->doubleValue()-v2->doubleValue();
- } else {
- std::ostringstream msg;
- msg << "Unknown add operator: " << addop << std::endl;
- std::string par = get_parfile();
- CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
- }
- } else {
- std::ostringstream msg;
- msg << "Unknown operation: " << v1->type;
- msg << " " << addop << v2->type << std::endl;
- std::string par = get_parfile();
- CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
- }
- v1 = ret;
- }
- } else if(pn == "mexpr") {
- if(gr->groupCount()==1)
- return meval(gr->group(0));
- smart_ptr<Value> v1 = meval(gr->group(0));
- for(int i=1;i+1<gr->groupCount();i+=2) {
- std::string mulop = gr->group(i)->substring();
- smart_ptr<Value> v2 = meval(gr->group(i+1));
- if(v1->type == PIR_INT && v2->type == PIR_INT) {
- ret->type = PIR_INT;
- if(mulop == "*") {
- ret->idata = v1->idata * v2->idata;
- } else if(mulop == "/") {
- ret->idata = v1->idata / v2->idata;
- } else if(mulop == "%") {
- ret->idata = v1->idata % v2->idata;
- } else {
- std::ostringstream msg;
- msg << "Unknown mul operator: " << v1->type << mulop << v2->type << std::endl;
- std::string par = get_parfile();
- CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
- }
- } else if(v1->type == PIR_STRING && v2->type == PIR_INT) {
- ret->type = PIR_STRING;
- if(mulop == "*") {
- ret->sdata = "";
- for(int i=0;i<v2->idata;i++)
- ret->sdata += v1->sdata;
- } else {
- std::ostringstream msg;
- msg << "Unknown mul operator: " << v1->type << mulop << v2->type << std::endl;
- std::string par = get_parfile();
- CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
- }
- } else if(v1->intOrDouble() && v2->intOrDouble()) {
- ret->type = PIR_REAL;
- if(mulop == "*") {
- ret->ddata = v1->doubleValue()*v2->doubleValue();
- } else if(mulop == "/") {
- ret->ddata = v1->doubleValue()/v2->doubleValue();
- } else {
- std::ostringstream msg;
- msg << "Unknown mul operator: " << v1->type << mulop << v2->type << std::endl;
- std::string par = get_parfile();
- CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
- }
- } else if(v1->type == PIR_STRING && v2->type == PIR_STRING) {
- std::ostringstream msg;
+ std::string par = get_parfile();
+ CCTK_Warn(1,gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
+ }
+ } else if(v1->intOrDouble() && v2->intOrDouble()) {
+ ret->type = PIR_REAL;
+ if(addop == "+") {
+ ret->ddata = v1->doubleValue()+v2->doubleValue();
+ } else if(addop == "-") {
+ ret->ddata = v1->doubleValue()-v2->doubleValue();
+ } else {
+ std::ostringstream msg;
+ msg << "Unknown add operator: " << addop << std::endl;
+ std::string par = get_parfile();
+ CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
+ }
+ } else {
+ std::ostringstream msg;
+ msg << "Unknown operation: " << v1->type;
+ msg << " " << addop << v2->type << std::endl;
+ std::string par = get_parfile();
+ CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
+ }
+ v1 = ret;
+ }
+ } else if(pn == "mexpr") {
+ if(gr->groupCount()==1)
+ return meval(gr->group(0));
+ smart_ptr<Value> v1 = meval(gr->group(0));
+ for(int i=1;i+1<gr->groupCount();i+=2) {
+ std::string mulop = gr->group(i)->substring();
+ smart_ptr<Value> v2 = meval(gr->group(i+1));
+ if(v1->type == PIR_INT && v2->type == PIR_INT) {
+ ret->type = PIR_INT;
+ if(mulop == "*") {
+ ret->idata = v1->idata * v2->idata;
+ } else if(mulop == "/") {
+ ret->idata = v1->idata / v2->idata;
+ } else if(mulop == "%") {
+ ret->idata = v1->idata % v2->idata;
+ } else {
+ std::ostringstream msg;
+ msg << "Unknown mul operator: " << v1->type << mulop << v2->type << std::endl;
+ std::string par = get_parfile();
+ CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
+ }
+ } else if(v1->type == PIR_STRING && v2->type == PIR_INT) {
+ ret->type = PIR_STRING;
+ if(mulop == "*") {
+ ret->sdata = "";
+ for(int i=0;i<v2->idata;i++)
+ ret->sdata += v1->sdata;
+ } else {
+ std::ostringstream msg;
+ msg << "Unknown mul operator: " << v1->type << mulop << v2->type << std::endl;
+ std::string par = get_parfile();
+ CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
+ }
+ } else if(v1->intOrDouble() && v2->intOrDouble()) {
+ ret->type = PIR_REAL;
+ if(mulop == "*") {
+ ret->ddata = v1->doubleValue()*v2->doubleValue();
+ } else if(mulop == "/") {
+ ret->ddata = v1->doubleValue()/v2->doubleValue();
+ } else {
+ std::ostringstream msg;
+ msg << "Unknown mul operator: " << v1->type << mulop << v2->type << std::endl;
+ std::string par = get_parfile();
+ CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
+ }
+ } else if(v1->type == PIR_STRING && v2->type == PIR_STRING) {
+ std::ostringstream msg;
ret->type = PIR_STRING;
ret->sdata = v1->sdata + mulop + v2->sdata;
- msg << "Unknown operation: " << v1->type << " " << mulop << v2->type << std::endl;
+ msg << "Unknown operation: " << v1->type << " " << mulop << v2->type << std::endl;
msg << "Interpreting as literal string with value '" << ret->sdata << "'" << std::endl;
- std::string par = get_parfile();
- CCTK_Warn(1,gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
- } else {
- std::ostringstream msg;
- msg << "Unknown operation: " << v1->type << " " << mulop << v2->type << std::endl;
- std::string par = get_parfile();
- CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
- }
- v1 = ret;
- }
- } else {
- std::ostringstream msg;
- std::string par = get_parfile();
- msg << "Pattern not handled[" << gr->getPatternName() << "]=" << gr->substring() <<
- " at " << gr->line() << " in " << par << std::endl;
- CCTK_Error(__LINE__,__FILE__,"piraha",msg.str().c_str());
- }
- return ret;
+ std::string par = get_parfile();
+ CCTK_Warn(1,gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
+ } else {
+ std::ostringstream msg;
+ msg << "Unknown operation: " << v1->type << " " << mulop << v2->type << std::endl;
+ std::string par = get_parfile();
+ CCTK_Error(gr->line(),par.c_str(),current_thorn.c_str(),msg.str().c_str());
+ }
+ v1 = ret;
+ }
+ } else {
+ std::ostringstream msg;
+ std::string par = get_parfile();
+ msg << "Pattern not handled[" << gr->getPatternName() << "]=" << gr->substring() <<
+ " at " << gr->line() << " in " << par << std::endl;
+ CCTK_Error(__LINE__,__FILE__,"piraha",msg.str().c_str());
+ }
+ return ret;
}
smart_ptr<Value> eval_expr(std::string input) {
- smart_ptr<Matcher> m = new Matcher(par_file_grammar,"eval",input.c_str());
- smart_ptr<Value> ret;
- if(m->matches()) {
- ret = meval(m->group(0));
- }
- return ret;
+ smart_ptr<Matcher> m = new Matcher(par_file_grammar,"eval",input.c_str());
+ smart_ptr<Value> ret;
+ if(m->matches()) {
+ ret = meval(m->group(0));
+ }
+ return ret;
}
void check_types(const char *thorn,int line,smart_ptr<Value> svm,int t) {
ValueType v = svm->type;
- bool ok = false;
- if(v == PIR_STRING && (t == PARAMETER_STRING || t == PARAMETER_KEYWORD))
- ok = true;
- else if(v == PIR_INT && t == PARAMETER_INT)
- ok = true;
- else if(v == PIR_BOOL && t == PARAMETER_BOOLEAN)
- ok = true;
- else if((v == PIR_INT || v == PIR_REAL) && t == PARAMETER_REAL)
- ok = true;
- if(!ok) {
- std::string par = get_parfile();
- std::ostringstream msg;
+ bool ok = false;
+ if(v == PIR_STRING && (t == PARAMETER_STRING || t == PARAMETER_KEYWORD))
+ ok = true;
+ else if(v == PIR_INT && t == PARAMETER_INT)
+ ok = true;
+ else if(v == PIR_BOOL && t == PARAMETER_BOOLEAN)
+ ok = true;
+ else if((v == PIR_INT || v == PIR_REAL) && t == PARAMETER_REAL)
+ ok = true;
+ if(!ok) {
+ std::string par = get_parfile();
+ std::ostringstream msg;
msg << "Invalid assignment: Attempting to set a variable of type ";
- switch(t) {
- case PARAMETER_BOOLEAN:
- msg << "BOOL";
- break;
- case PARAMETER_INT:
- msg << "INT";
- break;
- case PARAMETER_KEYWORD:
- msg << "KEYWORD";
- break;
- case PARAMETER_STRING:
- msg << "STRING";
- break;
- case PARAMETER_REAL:
- msg << "REAL";
- break;
- default:
- msg << "type(" << t << ")";
- break;
- }
+ switch(t) {
+ case PARAMETER_BOOLEAN:
+ msg << "BOOL";
+ break;
+ case PARAMETER_INT:
+ msg << "INT";
+ break;
+ case PARAMETER_KEYWORD:
+ msg << "KEYWORD";
+ break;
+ case PARAMETER_STRING:
+ msg << "STRING";
+ break;
+ case PARAMETER_REAL:
+ msg << "REAL";
+ break;
+ default:
+ msg << "type(" << t << ")";
+ break;
+ }
msg << " with " << svm << std::endl;
- CCTK_Error(line,par.c_str(),thorn,msg.str().c_str());
- }
+ CCTK_Error(line,par.c_str(),thorn,msg.str().c_str());
+ }
}
extern "C" int cctk_PirahaParser(const char *buffer,unsigned long buffersize,int (*set_function)(const char *, const char *, int)) {
- const char *par_file_src =
- "skipper = ([ \\t\\r\\n]|\\#.*)*\n"
- "# comment\n"
- "skipeol = ([ \\t\\r]|\\#.*)*($|\\n)\n"
- "any = [^]\n"
- "stringcomment = #.*\n"
- "stringparser = ^({stringcomment}|{var}|{name}|{any})*$\n"
-
- "# Note that / occurs in some par files. It is my\n"
- "# feeling that this should require quote marks.\n"
-
- "name = [a-zA-Z][a-zA-Z0-9_]*\n"
- "dname = [0-9][a-zA-Z_]{2,}\n"
- "inquot = ({var}|\\\\.|[^\\\\\"])*\n"
- "fname = \\.?/[-\\./0-9a-zA-Z_]+\n"
- "quot = \"{inquot}\"|{fname}\n"
- "num = ([0-9]+(\\.[0-9]*|)|\\.[0-9]+)([edDE][+-]?[0-9]+|)\n"
- "env = ENV\\{{name}\\}\n"
- "var = \\$({env}|{name}|\\{{name}\\})\n"
-
- "powexpr = {value}( \\*\\* {value})?\n"
- "mulop = [*/%]\n"
- "mexpr = {powexpr}( {mulop} {powexpr})*\n"
- "addop = [+-]\n"
- "aexpr = {mexpr}( {addop} {mexpr})*\n"
- "compop = [<>]=?\n"
- "compexpr = {aexpr}( {compop} {aexpr})?\n"
- "eqop = [!=]=\n"
- "eqexpr = {compexpr}( {eqop} {eqexpr})?\n"
- "andexpr = {eqexpr}( && {eqexpr})?\n"
- "expr = {andexpr}( \\|\\| {andexpr})?\n"
- "eval = {expr}\n"
-
- "paren = \\( {expr} \\)\n"
- "par = {name} :: {name}( {parindex})?\n"
- "func = {name} \\( {expr} \\)\n"
- "array = \\[ {expr}( , {expr})* \\]\n"
-
- "value = {unop}?({par}|{func}|{paren}|{dname}|{num}|{quot}|{name}|{var})\n"
- "unop = [-!]\n"
-
- "int = [0-9]+\n"
- "index = \\[ {int} \\]\n"
- "parindex = \\[ {expr} \\]\n"
- "active = (?i:ActiveThorns)\n"
- "set = ({active} = ({quot}|{name})|{par}( {index}|) = ({array}|\\+?{expr})){-skipeol}\n"
- "desc = !DESC {quot}\n"
- "file = ^( ({desc}|{set}|{active}) )*$";
+ const char *par_file_src =
+ "skipper = ([ \\t\\r\\n]|\\#.*)*\n"
+ "# comment\n"
+ "skipeol = ([ \\t\\r]|\\#.*)*($|\\n)\n"
+ "any = [^]\n"
+ "stringcomment = #.*\n"
+ "stringparser = ^({stringcomment}|{var}|{name}|{any})*$\n"
+
+ "# Note that / occurs in some par files. It is my\n"
+ "# feeling that this should require quote marks.\n"
+
+ "name = [a-zA-Z][a-zA-Z0-9_]*\n"
+ "dname = [0-9][a-zA-Z_]{2,}\n"
+ "inquot = ({var}|\\\\.|[^\\\\\"])*\n"
+ "fname = \\.?/[-\\./0-9a-zA-Z_]+\n"
+ "quot = \"{inquot}\"|{fname}\n"
+ "num = ([0-9]+(\\.[0-9]*|)|\\.[0-9]+)([edDE][+-]?[0-9]+|)\n"
+ "env = ENV\\{{name}\\}\n"
+ "var = \\$({env}|{name}|\\{{name}\\})\n"
+
+ "powexpr = {value}( \\*\\* {value})?\n"
+ "mulop = [*/%]\n"
+ "mexpr = {powexpr}( {mulop} {powexpr})*\n"
+ "addop = [+-]\n"
+ "aexpr = {mexpr}( {addop} {mexpr})*\n"
+ "compop = [<>]=?\n"
+ "compexpr = {aexpr}( {compop} {aexpr})?\n"
+ "eqop = [!=]=\n"
+ "eqexpr = {compexpr}( {eqop} {eqexpr})?\n"
+ "andexpr = {eqexpr}( && {eqexpr})?\n"
+ "expr = {andexpr}( \\|\\| {andexpr})?\n"
+ "eval = {expr}\n"
+
+ "paren = \\( {expr} \\)\n"
+ "par = {name} :: {name}( {parindex})?\n"
+ "func = {name} \\( {expr} \\)\n"
+ "array = \\[ {expr}( , {expr})* \\]\n"
+
+ "value = {unop}?({par}|{func}|{paren}|{dname}|{num}|{quot}|{name}|{var})\n"
+ "unop = [-!]\n"
+
+ "int = [0-9]+\n"
+ "index = \\[ {int} \\]\n"
+ "parindex = \\[ {expr} \\]\n"
+ "active = (?i:ActiveThorns)\n"
+ "set = ({active} = ({quot}|{name})|{par}( {index}|) = ({array}|\\+?{expr})){-skipeol}\n"
+ "desc = !DESC {quot}\n"
+ "file = ^( ({desc}|{set}|{active}) )*$";
//std::ofstream peg("/tmp/par.peg");
//peg << par_file_src;
//peg.close();
- compileFile(par_file_grammar,par_file_src,strlen(par_file_src));
+ compileFile(par_file_grammar,par_file_src,strlen(par_file_src));
- std::string active;
+ std::string active;
smart_ptr<Matcher> m2 = new Matcher(par_file_grammar,"file",buffer,buffersize);
if(m2->matches()) {
- int line = -1;
- for(int i=0;i<m2->groupCount();i++) {
- smart_ptr<Group> gr = m2->group(i);
- if(gr->group(0)->getPatternName() == "active") {
- smart_ptr<Value> smv = meval(gr->group(1));
- std::string val = smv->copy();
- active += val;
- active += ' ';
- line = gr->line();
- }
- }
- set_function("ActiveThorns",active.c_str(),line);
- for(int i=0;i<m2->groupCount();i++) {
- smart_ptr<Group> gr = m2->group(i);
- if(gr->getPatternName() != "set")
- continue;
- smart_ptr<Group> par = gr->group("par");
- if(par.valid()) {
- // add value->quot->inquot
- std::string key;
- std::string thorn = par->group("name",0)->substring();
- std::string name = par->group("name",1)->substring();
- key += thorn;
- key += "::";
- key += name;
- const cParamData *data = CCTK_ParameterData(name.c_str(),thorn.c_str());
-
- smart_ptr<Group> index = par->group("parindex");
- if(index.valid()) {
- key += '[';
- smart_ptr<Value> vv = meval(index);
- if(vv->type != PIR_INT) {
- std::ostringstream msg;
- std::string par = get_parfile();
- msg << "bad index " << vv << std::endl;
- CCTK_Error(index->line(),par.c_str(),thorn.c_str(),msg.str().c_str());
- }
- std::string vvstr = vv->copy();
- key += vvstr;
- key += ']';
- }
-
- std::string val;
- smart_ptr<Group> aexpr = gr->group("expr");
- if(aexpr.valid()) {
- current_thorn = thorn;
- smart_ptr<Value> smv = meval(aexpr);
- val = smv->copy();
- assert(smv.valid());
- smv->integerize();
- if(data != NULL) {
- if(data->type == PARAMETER_REAL)
- smv->integerize();
- if(data->type == PARAMETER_BOOLEAN)
- smv->booleanize(gr);
- check_types(thorn.c_str(),aexpr->line(),smv,data->type);
- }
- set_function(
- strdup(key.c_str()),
- strdup(val.c_str()),
- gr->group(0)->line());
- } else {
- smart_ptr<Group> arr = gr->group("array");
- for(int i=0;i<arr->groupCount();i++) {
- aexpr = arr->group(i);
- std::ostringstream keyi;
- keyi << key << '[' << i << ']';
- smart_ptr<Value> smv = meval(aexpr);
- val = smv->copy();
- if(data != NULL) {
- if(data->type == PARAMETER_REAL)
- smv->integerize();
- if(data->type == PARAMETER_BOOLEAN)
- smv->booleanize(gr);
- check_types(thorn.c_str(),aexpr->line(),smv,data->type);
- }
- set_function(
- strdup(keyi.str().c_str()),
- strdup(val.c_str()),
- aexpr->line());
- }
- }
- }
- }
+ int line = -1;
+ for(int i=0;i<m2->groupCount();i++) {
+ smart_ptr<Group> gr = m2->group(i);
+ if(gr->group(0)->getPatternName() == "active") {
+ smart_ptr<Value> smv = meval(gr->group(1));
+ std::string val = smv->copy();
+ active += val;
+ active += ' ';
+ line = gr->line();
+ }
+ }
+ set_function("ActiveThorns",active.c_str(),line);
+ for(int i=0;i<m2->groupCount();i++) {
+ smart_ptr<Group> gr = m2->group(i);
+ if(gr->getPatternName() != "set")
+ continue;
+ smart_ptr<Group> par = gr->group("par");
+ if(par.valid()) {
+ // add value->quot->inquot
+ std::string key;
+ std::string thorn = par->group("name",0)->substring();
+ std::string name = par->group("name",1)->substring();
+ key += thorn;
+ key += "::";
+ key += name;
+ const cParamData *data = CCTK_ParameterData(name.c_str(),thorn.c_str());
+
+ smart_ptr<Group> index = par->group("parindex");
+ if(index.valid()) {
+ key += '[';
+ smart_ptr<Value> vv = meval(index);
+ if(vv->type != PIR_INT) {
+ std::ostringstream msg;
+ std::string par = get_parfile();
+ msg << "bad index " << vv << std::endl;
+ CCTK_Error(index->line(),par.c_str(),thorn.c_str(),msg.str().c_str());
+ }
+ std::string vvstr = vv->copy();
+ key += vvstr;
+ key += ']';
+ }
+
+ std::string val;
+ smart_ptr<Group> aexpr = gr->group("expr");
+ if(aexpr.valid()) {
+ current_thorn = thorn;
+ smart_ptr<Value> smv = meval(aexpr);
+ val = smv->copy();
+ assert(smv.valid());
+ smv->integerize();
+ if(data != NULL) {
+ if(data->type == PARAMETER_REAL)
+ smv->integerize();
+ if(data->type == PARAMETER_BOOLEAN)
+ smv->booleanize(gr);
+ check_types(thorn.c_str(),aexpr->line(),smv,data->type);
+ }
+ set_function(
+ strdup(key.c_str()),
+ strdup(val.c_str()),
+ gr->group(0)->line());
+ } else {
+ smart_ptr<Group> arr = gr->group("array");
+ for(int i=0;i<arr->groupCount();i++) {
+ aexpr = arr->group(i);
+ std::ostringstream keyi;
+ keyi << key << '[' << i << ']';
+ smart_ptr<Value> smv = meval(aexpr);
+ val = smv->copy();
+ if(data != NULL) {
+ if(data->type == PARAMETER_REAL)
+ smv->integerize();
+ if(data->type == PARAMETER_BOOLEAN)
+ smv->booleanize(gr);
+ check_types(thorn.c_str(),aexpr->line(),smv,data->type);
+ }
+ set_function(
+ strdup(keyi.str().c_str()),
+ strdup(val.c_str()),
+ aexpr->line());
+ }
+ }
+ }
+ }
} else {
- // TODO: Fix this
- std::cout << "ERROR IN PARAMETER FILE:" << std::endl;
- m2->showError();
+ std::ostringstream msg;
+ msg << "ERROR IN PARAMETER FILE:";
+ if(m2->inrule_max == "file::set::par" && m2->foundChar() =='=') {
+ msg << std::endl;
+ msg << "Invalid assignment." << std::endl;
+ msg << "Valid assignments are: " << std::endl;
+ msg << "ActiveThorns = \"...\"" << std::endl;
+ msg << "Arrangement::Thorn = ..." << std::endl;
+ // Construct the parse tree for the partial match
+ if(m2->matchesTo(m2->max_pos)) {
+ // find the last element in the parse tree
+ smart_ptr<Group> gr = m2->group(m2->groupCount()-1);
+ while(true) {
+ int n = gr->groupCount();
+ if(n > 0)
+ gr = gr->group(n-1);
+ else
+ break;
+ }
+ msg << "You wrote: " << gr->substring() << " = ..." << std::endl;
+ }
+ } else {
+ m2->showError(msg);
+ }
+ std::string par = get_parfile();
+ par += ".par";
+ CCTK_Warn(0,m2->line(),par.c_str(),"cactus",msg.str().c_str());
return 1;
}
return 0;
diff --git a/src/piraha/Matcher.cc b/src/piraha/Matcher.cc
index 9a37a06b..fd1b2355 100644
--- a/src/piraha/Matcher.cc
+++ b/src/piraha/Matcher.cc
@@ -6,13 +6,21 @@ using namespace cctki_piraha;
Matcher::Matcher(smart_ptr<Grammar> g_,const char *pat_,const char *input_,int input_size_) :
Group(pat_,input_),
input(input_), g(g_), input_size(input_size_),
- pos(0), max_pos(-1), pat(pat_), expected(), err_pos(-1) {
+ pos(0), max_pos(-1), match_to(-2), pat(pat_), expected(), err_pos(-1) {
inrule = pat_;
if(input_size < 0)
input_size=strlen(input);
}
bool Matcher::matches() {
+ // -2 is used just to make sure
+ // we can't actually get to that
+ // position, even in an error
+ // condition.
+ return matchesTo(-2);
+}
+
+bool Matcher::matchesTo(int match_to_) {
smart_ptr<Pattern> p = g->patterns.get(pat);
if(!p.valid()) {
std::cout << "Grammar does not contain \"" << pat << "\"" << std::endl;
@@ -21,6 +29,7 @@ bool Matcher::matches() {
assert(p.valid());
pos = 0;
max_pos = -1;
+ match_to = match_to_;
err_pos = -1;
children.clear();
bool b = p->match(this);
@@ -45,6 +54,10 @@ void Matcher::fail(char lo,char hi) {
}
void Matcher::showError() {
+ showError(std::cout);
+}
+
+void Matcher::showError(std::ostream& out) {
int line = 1;
int error_pos = -1;
const int num_previous_lines = 4;
@@ -56,7 +69,7 @@ void Matcher::showError() {
if(i == max_pos) {
error_pos = i;
int column = i - start_of_previous_line[0]+1;
- std::cout << "In rule '" << inrule_max
+ out << "In rule '" << inrule_max
<< "' Line=" << line << ", Column=" << column << std::endl;
while(input[i] == '\n'||input[i] == '\r') {
line++;
@@ -79,15 +92,15 @@ void Matcher::showError() {
}
bool eol = false;
for(int i=start_of_previous_line[0];i<input_size;i++) {
- std::cout << input[i];
+ out << input[i];
if(i > error_pos && input[i] == '\n') {
eol = true;
break;
}
}
- if(!eol) std::cout << std::endl;
+ if(!eol) out << std::endl;
for(int i=start_of_line;i<=error_pos;i++)
- std::cout << ' ';
- std::cout << "^" << std::endl;
- std::cout << "Expected one of the following characters: " << expected << std::endl;
+ out << ' ';
+ out << "^" << std::endl;
+ out << "Expected one of the following characters: " << expected << std::endl;
}
diff --git a/src/piraha/Piraha.hpp b/src/piraha/Piraha.hpp
index bd2d70a5..2e7dff90 100644
--- a/src/piraha/Piraha.hpp
+++ b/src/piraha/Piraha.hpp
@@ -355,15 +355,19 @@ public:
int input_size;
int pos;
int max_pos;
+ int match_to;
const char *pat;
bool matches();
+ bool matchesTo(int mt);
Bracket expected;
+ void showError(std::ostream& out);
void showError();
std::string inrule;
std::string inrule_max;
int err_pos;
void fail(Bracket *ex);
void fail(char lo,char hi);
+ char foundChar() { return input[max_pos+1]; }
};
extern smart_ptr<Grammar> pegGrammar;
diff --git a/src/piraha/Seq.cc b/src/piraha/Seq.cc
index 80be5ace..cd65a71d 100644
--- a/src/piraha/Seq.cc
+++ b/src/piraha/Seq.cc
@@ -24,6 +24,8 @@ bool Seq::match(Matcher *m) {
for(pattern_iter p = patterns.begin();p != patterns.end();++p) {
if(!(*p)->match(m))
return false;
+ if(m->max_pos == m->match_to)
+ return true;
}
return true;
}