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