Commit 4f138888 authored by Victor Yacovlev's avatar Victor Yacovlev

Implemented garbage runtime errors

parent f5b2bce9
......@@ -1133,6 +1133,15 @@ void PDAutomataPrivate::setCurrentError(const QString &value)
}
}
void PDAutomataPrivate::setCurrentErrorRaisePosition(Lexem::ErrorRaisePosition pos)
{
for (int i=0; i<source[currentPosition]->data.size(); i++) {
if (source[currentPosition]->data[i]->type!=LxTypeComment) {
source[currentPosition]->data[i]->errorRaisePosition = pos;
}
}
}
void PDAutomataPrivate::setOutOfAlgError()
{
QString value;
......@@ -1465,6 +1474,8 @@ void PDAutomataPrivate::processCorrectCase()
{
setCurrentIndentRank(-1, +1);
currentContext.pop();
if (currentContext.size()==0 || currentContext.top()->size()==0)
return;
Q_ASSERT(currentContext.size()>0);
Q_ASSERT(currentContext.top()->last()->type==AST::StSwitchCaseElse);
AST::ConditionSpec cond;
......@@ -1726,8 +1737,18 @@ void PDAutomataPrivate::setGarbageAlgError()
QList<LexemType>() << LxPriImport << LxPriAlgHeader << LxPriModule << LxPriEndModule;
if (OutgoingOperationalBrackets.contains(source[currentPosition]->type))
setCurrentError(_("'%1' in algorithm", source[currentPosition]->data.first()->data));
else
else {
setCurrentError(_("Garbage between alg..begin"));
setCurrentErrorRaisePosition(Lexem::Header);
if (currentAlgorhitm) {
int lineNo = -1;
if (source[currentPosition]->data.size()>0) {
lineNo = source[currentPosition]->data[0]->lineNo;
}
currentAlgorhitm->impl.headerRuntimeError = _("Garbage between alg..begin");
currentAlgorhitm->impl.headerRuntimeErrorLine = lineNo;
}
}
appendSimpleLine();
}
......@@ -1745,6 +1766,18 @@ void PDAutomataPrivate::setGarbageIfThenError()
}
const QString error = hasThen? _("Garbage between if..then")
: _("No 'then' after 'if'");
if (currentContext.size()>0
&& currentContext.top()->size()>0
&& currentContext.top()->at(0)->type==AST::StIfThenElse
)
{
currentContext.top()->at(0)->headerError = error;
int lineNo = -1;
if (source[currentPosition]->data.size()>0) {
lineNo = source[currentPosition]->data[0]->lineNo;
}
currentContext.top()->at(0)->headerErrorLine = lineNo;
}
setCurrentError(error);
// appendSimpleLine();
processCorrectThen();
......
......@@ -79,6 +79,7 @@ public:
public slots:
void addDummyAlgHeader();
void setCurrentError(const QString & value);
void setCurrentErrorRaisePosition(Lexem::ErrorRaisePosition pos);
void setOutOfAlgError();
void setModuleBeginError(const QString & value);
void setCurrentIndentRank(int start, int end);
......
......@@ -1081,7 +1081,7 @@ void SyntaxAnalizerPrivate::parseIfCase(int str)
delete expr;
}
else {
if (st.conditionalIndex < st.statement->conditionals.size()) {
if (st.statement && st.conditionalIndex < st.statement->conditionals.size()) {
st.statement->conditionals[st.conditionalIndex].condition = expr;
}
else {
......@@ -3575,13 +3575,13 @@ AST::Expression * SyntaxAnalizerPrivate::parseExpression(
const SubexpressionElement & el = subexpression.at(i);
if (el.o && (el.o->type==LxOperEqual || el.o->type==LxOperNotEqual) ) {
bool isBooleanComparision =
i>0 && subexpression[i-1].e && subexpression[i-1].e->baseType.kind == AST::TypeBoolean
(i>0 && subexpression[i-1].e && subexpression[i-1].e->baseType.kind == AST::TypeBoolean)
// ||
// i>0 && hasBoolOpBefore(subexpression, i)
||
i<subexpression.size()-1 && subexpression[i+1].e && subexpression[i+1].e->baseType.kind == AST::TypeBoolean
(i<subexpression.size()-1 && subexpression[i+1].e && subexpression[i+1].e->baseType.kind == AST::TypeBoolean)
||
i<subexpression.size()-1 && subexpression[i+1].o && subexpression[i+1].o->type==LxSecNot;
(i<subexpression.size()-1 && subexpression[i+1].o && subexpression[i+1].o->type==LxSecNot);
if (isBooleanComparision) {
if (el.o->type == LxOperEqual)
el.o->type = LxOperBoolEqual;
......
......@@ -679,6 +679,19 @@ void Generator::addFunction(int id, int moduleId, Bytecode::ElemType type, const
argHandle << err;
}
if (alg->impl.headerRuntimeError.size()>0) {
Bytecode::Instruction l;
l.type = Bytecode::LINE;
l.arg = alg->impl.headerRuntimeErrorLine;
argHandle << l;
l.type = Bytecode::ERRORR;
l.scope = Bytecode::CONSTT;
l.arg = constantValue(Bytecode::VT_string, 0,
ErrorMessages::message("KumirAnalizer", QLocale::Russian, alg->impl.headerRuntimeError)
);
argHandle << l;
}
if (alg->impl.endLexems.size()>0 && e_debugLevel==GeneratorInterface::LinesAndVariables) {
Bytecode::Instruction clearmarg;
......@@ -1396,6 +1409,20 @@ void Generator::IFTHENELSE(int modId, int algId, int level, const AST::Statement
showreg.registerr = 0;
result << showreg;
if (st->headerError.size()>0) {
Bytecode::Instruction garbage;
garbage.type = Bytecode::LINE;
garbage.arg = st->headerErrorLine;
result << garbage;
garbage.type = Bytecode::ERRORR;
garbage.scope = Bytecode::CONSTT;
garbage.arg = constantValue(Bytecode::VT_string, 0,
ErrorMessages::message("KumirAnalizer", QLocale::Russian, st->headerError)
);
result << garbage;
}
jzIP = result.size();
Bytecode::Instruction jz;
jz.type = Bytecode::JZ;
......
......@@ -102,6 +102,9 @@ struct AlgorhitmImplementation {
/** End lexems */
QList<struct Lexem*> endLexems;
QString headerRuntimeError;
int headerRuntimeErrorLine;
};
/** Algorhitm representation */
......
......@@ -130,6 +130,8 @@ struct ABSTRACTSYNTAXTREE_EXPORT Statement {
/** Compile-time error */
QString error;
QString headerError;
int headerErrorLine;
QString beginBlockError;
QString endBlockError;
......
......@@ -8,9 +8,12 @@ namespace AST {
struct Lexem {
enum ErrorStage { NoError, Lexer, PDAutomata, Tables, Semantics } errorStage;
enum ErrorRaisePosition { AsIs, Header, Begin, End } errorRaisePosition;
inline Lexem() {
type = Shared::LxTypeEmpty;
lineNo = -1; linePos = 0; length = 0; errorStage = NoError;
lineNo = -1; linePos = 0; length = 0;
errorStage = NoError;
errorRaisePosition = AsIs;
}
Shared::LexemType type;
QString data;
......
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