Commit 7124ba9b authored by Aleix Pol Gonzalez's avatar Aleix Pol Gonzalez 🐧

Added multilining in the kalgebra's console version.

Fixed a little bug (thanks valgrind!)
Added boolean values to the Cn definition in order to give better support to piecewise.

svn path=/trunk/KDE/kdeedu/kalgebra/; revision=704713
parent 98b034b2
......@@ -99,7 +99,7 @@ Object* Analitza::eval(const Object* branch, bool resolve)
cond=simp(cond);
if(cond->type()==Object::value) {
Cn* cval=static_cast<Cn*>(cond);
if(condition(*cval)) {
if(cval->isTrue()) {
ret=eval(p->m_params[0], resolve);
}
}
......@@ -547,7 +547,7 @@ Cn Analitza::operate(const Container* c)
bool isPiece = p->containerType()==Container::piece;
if(isPiece) {
Cn ret=calc(p->m_params[1]);
if(condition(ret)) { // FIXME: could improve that
if(ret.isTrue()) {
r=p->m_params[0];
}
} else {
......@@ -860,8 +860,9 @@ void Analitza::reduce(enum Operator::OperatorType op, Cn *ret, Cn oper, bool una
m_err << i18n("The operator <em>%1</em> has not been implemented", op);
break;
}
//
ret->setValue(a);
ret->setBoolean(boolean);
}
QStringList Analitza::bvarList() const //FIXME: if
......@@ -934,7 +935,7 @@ Object* Analitza::simp(Object* root)
p->m_params[1]=simp(p->m_params[1]);
if(p->m_params[1]->type()==Object::value) {
Cn* cond=static_cast<Cn*>(p->m_params[1]);
if(condition(*cond)) {
if(cond->isTrue()) {
delete p->m_params[1];
p->m_params.removeAt(1);
p->setContainerType(Container::otherwise);
......@@ -1462,7 +1463,6 @@ Expression Analitza::derivative()
exp.m_tree = derivative(vars.first(), m_exp.m_tree);
exp.m_tree = simp(exp.m_tree);
// objectWalker(exp.m_tree);
}
return exp;
}
......@@ -1477,7 +1477,3 @@ void Analitza::insertVariable(const QString & name, const Object * value)
m_vars->modify(name, value);
}
bool Analitza::condition(const Cn & v)
{
return v.value()!=0.;
}
......@@ -116,7 +116,6 @@ class ANALITZA_EXPORT Analitza
Cn sum(const Container& c);
Cn product(const Container& c);
Cn func(const Container& c);
static bool condition(const Cn& v);
Object* simp(Object* root);
void simpScalar(Container* c);
......
......@@ -305,14 +305,14 @@ enum Container::ContainerType Container::toContainerType(const QString& tag)
return ret;
}
QStringList Container::bvarList() const //NOTE: Should return Ci's instead of Strings?
QStringList Container::bvarList() const //NOTE: Should we return Ci's instead of Strings?
{
QStringList bvars;
QList<Object*>::const_iterator it;
for(it=m_params.begin(); it!=m_params.end(); ++it) {
Container* c = (Container*) (*it);
if(c->containerType() == Container::bvar)
if(c->isContainer() && c->containerType() == Container::bvar)
bvars.append(((Ci*)c->m_params[0])->name());
}
......
......@@ -76,7 +76,7 @@ public:
void setContainerType(enum ContainerType c) { m_cont_type = c; }
/** Returns the type of the container. */
enum ContainerType containerType() const { return m_cont_type; }
enum ContainerType containerType() const { Q_ASSERT(m_type==Object::container && m_cont_type!=none); return m_cont_type; }
/** Returns whether @p c is equal or not. */
bool operator==(const Container& c) const;
......
......@@ -22,8 +22,6 @@
#include <KLocale>
using namespace std;
//TODO:piece { x=3 ? x-3, x=4 ? x², x}
#if 0
QString opr2str(int in);
void printPilaOpr(QStack<int> opr);
......@@ -96,7 +94,7 @@ const actEnum parseTbl[tMaxOp][tMaxOp] = {
{ S, S, S, S, S, S, S, S, S, S, S, S, S, E, S, E3, S, E3, A }, //$
};
Exp::Exp(QString exp) : str(exp)
Exp::Exp(QString exp) : str(exp), completelyRead(0)
{}
Exp::~Exp(){}
......@@ -227,6 +225,11 @@ int Exp::getTok()
t=getToken(str, ignored, antnum);
if(t.tipus==tLcb)
completelyRead++;
else if(t.tipus==tRcb)
completelyRead--;
if(t.tipus==tMaxOp)
err << i18n("Unknown token");
......
......@@ -82,6 +82,8 @@ public:
QStringList error();
QString mathML();
bool isCompletelyRead() const { return completelyRead==0; }
static TOKEN getToken(QString &a, int &l, tokEnum prev);
private:
QString mml;
......@@ -102,6 +104,7 @@ private:
int getTok();
int shift();
int reduce();
int completelyRead;
};
#endif
......@@ -18,14 +18,17 @@
#include "value.h"
#include "operator.h"
#include "variables.h"
#include <KLocale>
Cn::Cn(Object const *o)
: Object(Object::value), m_value(0.)/*, m_boolean(false)*/
: Object(Object::value), m_value(0.), m_boolean(false)
{
if(o->type()==Operator::value){
Cn *v = (Cn*) o;
m_value = v->value();
// m_boolean = v->isBoolean();
m_boolean = v->isBoolean();
setCorrect(v->isCorrect());
} else {
setCorrect(false);
......@@ -34,17 +37,35 @@ Cn::Cn(Object const *o)
QString Cn::toString() const
{
return QString("%1").arg(m_value, 0, 'g', 12);;
if(isBoolean()) {
if(isTrue())
return "true";
else
return "false";
} else
return QString("%1").arg(m_value, 0, 'g', 12);
}
QString Cn::toMathML() const
{
return QString("<cn>%1</cn>").arg(m_value, 0, 'g', 12);
if(isBoolean()) {
if(isTrue())
return "<cn type='constant'>true</cn>";
else
return "<cn type='constant'>false</cn>";
} else
return QString("<cn>%1</cn>").arg(m_value, 0, 'g', 12);
}
QString Cn::toHtml() const
{
return QString("<span class='num'>%1</span>").arg(m_value, 0, 'g', 12);;
if(isBoolean()) {
if(isTrue())
return i18nc("html representation of a number", "<span class='const'>true</span>");
else
return i18nc("html representation of a number", "<span class='const'>false</span>");
} else
return i18nc("html representation of a number", "<span class='num'>%1</span>", m_value);
}
/*enum Cn::ValueFormat Cn::whatValueFormat(const QDomElement& val)
......@@ -79,39 +100,35 @@ QString Cn::toHtml() const
void Cn::setValue(const QDomElement& val)
{
double ret=0.0;
// this->m_vformat=whatValueFormat(val);
bool wrong;
QString tag = val.tagName();
m_boolean=false;
if(tag == "cn"){ // a is a number
if(val.attribute("type", "integer") == "real") {
ret= val.text().trimmed().toDouble(&wrong); //TODO: Base on double not implemented
m_value= val.text().trimmed().toDouble(&wrong); //TODO: Base on double not implemented
} else if(val.attribute("type", "integer") == "integer"){
int base = val.attribute("base", "10").toInt(NULL, 10);
ret= val.text().trimmed().toInt(&wrong, base);
m_value= val.text().trimmed().toInt(&wrong, base);
}
#if 0
else if(val.attribute("type") == "e-notation") { /*TODO: Not implemented */ }
else if(val.attribute("type") == "rational") { /*TODO: Not implemented */ }
else if(val.attribute("type") == "complex-cartesian") { /*TODO: Not implemented */ }
else if(val.attribute("type") == "complex-polar") { /*TODO: Not implemented */ }
#endif
else if(val.attribute("type") == "constant"){
if(val.text() == "&pi;") { ret = toNum(vars.value("pi")); }
else if (val.text() == "&ee;" || val.text() == "&ExponentialE;"){ ret = exp(1.); }
else if (val.text() == "&true;") { ret = toNum(vars.value("true")); }
else if (val.text() == "&false;") { ret = toNum(vars.value("false")); }
else if (val.text() == "&gamma;") { ret = 0.5772156649; }
if(val.text() == "&pi;") { m_value = Variables::pi().m_value; }
else if (val.text() == "&ee;" || val.text() == "&ExponentialE;"){ m_value = Variables::e().m_value; }
else if (val.text() == "&true;") { m_value=1.; m_boolean=true; }
else if (val.text() == "&false;") { m_value=0.; m_boolean=true; }
else if (val.text() == "&gamma;") { m_value = 0.5772156649; }
#if 0
else if (val.text() == "&ImagniaryI;") ; //TODO: Not implemented
else if (val.text() == "&infin;") ; //TODO: Not implemented }
else if (val.text() == "&NaN;") ; //TODO: Not implemented }*/
}
#endif
}/* else if(tag=="true") ret = toNum(vars.value("true"));
else if(tag=="false") ret = toNum(vars.value("false"));
else if(tag=="pi") ret = toNum(vars.value("pi"));
else if(tag=="exponentiale") ret = std::exp(1.);
else if(tag=="eulergamma") ret = 0.5772156649;*/
m_value = ret;
}
}
}
......@@ -34,10 +34,13 @@ class ANALITZA_EXPORT Cn : public Object
public:
// enum ValueFormat { none, nan, real, integer, boolean };
/** Copy constructor. Creates a Cn from another one. */
Cn(const Cn& v) : Object(v), m_value(v.value())/*, m_boolean(v.isBoolean())*/ {}
Cn(const Cn& v) : Object(v), m_value(v.value()), m_boolean(v.m_boolean) {}//, m_boolean(v.m_boolean) {}
/** Constructor. Creates a value with values @p v. */
Cn(const double &b=0.) : Object(Object::value), m_value(b)/*, m_boolean(false)*/ {}
Cn(const double &b=0.) : Object(Object::value), m_value(b), m_boolean(false) {}
/** Constructor. Creates a boolean value with value @p v. */
Cn(const bool b) : Object(Object::value), m_value(b?1.:0.), m_boolean(true) {}
/** Constructor. Creates a value from @p o. If @p o is not a Cn, a not correct Cn will be returned. */
Cn(Object const * o);
......@@ -62,14 +65,22 @@ class ANALITZA_EXPORT Cn : public Object
/**
* Returns the value as an int.
*/
int intValue() const { return static_cast<int>(m_value); }
int intValue() const { return static_cast<int>(std::floor(m_value)); }
#if 0
/**
* Returns whether it is a boolean value or not.
*/
bool isBoolean() const { return m_boolean; }
#endif
/**
* Sets whether this value is boolean or not.
*/
void setBoolean(bool val) { m_boolean=val; }
/**
* @return If it is a boolean value, returns if it is true or not, otherwise retuns false.
*/
bool isTrue() const { return m_boolean && m_value!=0.; }
// static double toNum(const QString& num, const QString& type, int base);
// static enum ValueFormat whatValueFormat(const QDomElement&);
......@@ -127,17 +138,17 @@ class ANALITZA_EXPORT Cn : public Object
/**
* Returns a string representation of the value.
*/
QString toString() const;
virtual QString toString() const;
/**
* Returns a MathML representation of the value.
*/
QString toMathML() const;
virtual QString toMathML() const;
/**
* Returns a html representation of the value.
*/
QString toHtml() const;
virtual QString toHtml() const;
/*/** Sets whether it is a correct Cn.
void setCorrect(bool b) {m_correct = b; }*/
......@@ -146,7 +157,7 @@ class ANALITZA_EXPORT Cn : public Object
bool isCorrect() const { return m_correct;}
private:
double m_value;
// bool m_boolean;
bool m_boolean;
// enum ValueFormat m_vformat;
};
......
......@@ -20,14 +20,17 @@
#include "container.h"
#include "expression.h"
Cn Variables::pi() { return Cn(3.1415926535897932384626433); }
Cn Variables::e() { return Cn(2.718281828); }
Cn Variables::euler() { return Cn(0.5772156649); }
Variables::Variables() : QHash<QString, Object*>()
{
insert("true", new Cn(1.));
insert("false", new Cn(0.));
insert("pi", new Cn(3.1415926535897932384626433));
insert("e", new Cn(2.718281828));
insert("euler", new Cn(0.5772156649));
// modify("perimeter", Expression("r->2*pi*r", false));
insert("true", new Cn(true));
insert("false", new Cn(false));
insert("pi", new Cn(pi()));
insert("e", new Cn(e()));
insert("euler", new Cn(euler()));
}
Variables::Variables(const Variables& v) : QHash<QString, Object*>(v)
......
......@@ -78,6 +78,9 @@ public:
*/
bool destroy(const QString& name);
static Cn pi();
static Cn e();
static Cn euler();
};
#endif
......@@ -28,11 +28,9 @@ using namespace std;
Analitza a;
void evaluate(char* expr)
void evaluate(const Expression& e)
{
Expression e(expr, false), ans;
qDebug() << e.toString();
Expression ans;
a.setExpression(e);
if(e.isCorrect())
ans=a.evaluate();
......@@ -40,10 +38,7 @@ void evaluate(char* expr)
if(a.isCorrect()) {
qDebug() << qPrintable(ans.toString());
a.insertVariable("ans", ans);
add_history(expr);
} else {
free(expr);
QStringList errors = a.errors();
qDebug() << "Error:";
foreach(QString err, errors)
......@@ -51,11 +46,9 @@ void evaluate(char* expr)
}
}
void calculate(char* expr)
void calculate(const Expression& e)
{
Expression e(expr, false);
Cn ans;
qDebug() << e.toString();
a.setExpression(e);
if(e.isCorrect())
......@@ -64,10 +57,7 @@ void calculate(char* expr)
if(a.isCorrect()) {
qDebug() << qPrintable(ans.toString());
a.insertVariable("ans", ans);
add_history(expr);
} else {
free(expr);
QStringList errors = a.errors();
qDebug() << "Error:";
foreach(QString err, errors)
......@@ -75,23 +65,43 @@ void calculate(char* expr)
}
}
const char* prompt=">>> ";
const char* insidePrompt="... ";
int main(int argc, char *argv[])
{
bool done=false;
bool inside=false;
using_history();
QString entry;
while(!done) {
char * expr=readline(">>> ");
char * expr;
if(inside)
expr=readline(insidePrompt);
else
expr=readline(prompt);
if(!expr)
done=true;
else {
#if 0
Exp ex(expr);
ex.parse();
qDebug() << ex.mathML() << ex.error();
#endif
else if(*expr==0) {
inside=false;
entry.clear();
} else {
add_history(expr);
entry+=QString(expr);
evaluate(expr);
Exp ex(entry);
ex.parse();
if(ex.isCompletelyRead()) {
Expression e(ex.mathML(), true);
qDebug() << entry << e.toString();
evaluate(e);
inside =false;
entry.clear();
} else {
inside =true;
}
}
}
......
......@@ -29,7 +29,7 @@
#include "variables.h"
#include "expression.h"
ConsoleHtml::ConsoleHtml(QWidget *parent) : KHTMLPart(parent), m_mode(Evaluation)
ConsoleHtml::ConsoleHtml(QWidget *parent) : KHTMLPart(parent), m_mode(Calculation)
{
setJScriptEnabled(false);
setJavaEnabled(false);
......@@ -48,6 +48,7 @@ ConsoleHtml::ConsoleHtml(QWidget *parent) : KHTMLPart(parent), m_mode(Evaluation
m_css +="\t.normal:hover { background-color: #f7f7f7; }\n";
m_css +="\t.sep { font-weight: bold; }\n";
m_css +="\t.num { color: #0000C4; }\n";
m_css +="\t.sep { font-weight: bold; color: #0000FF; }\n";
m_css +="\t.var { color: #640000; }\n";
m_css +="\t.func { color: #003600; }\n";
m_css +="\tli { padding-left: 12px; padding-bottom: 4px; list-style-position: inside; }";
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment