Commit 8b7d2ba4 authored by Victor Yacovlev's avatar Victor Yacovlev

Fixed loading cached modules

parent 49742c5f
......@@ -1512,6 +1512,9 @@ void SyntaxAnalizer::parseImport(int str)
return;
}
name = binFile.absoluteFilePath();
moduleToImport = loadKodFile(name, st.data[1]->error);
if (!moduleToImport)
return;
}
else {
QString localError = lexer_->testName(st.data[1]->data);
......@@ -1543,6 +1546,78 @@ void SyntaxAnalizer::parseImport(int str)
}
}
AST::ModulePtr SyntaxAnalizer::loadKodFile(const QString &name, QString &error)
{
QString canonicalName = name;
if (canonicalName.startsWith(QDir::currentPath())) {
canonicalName.remove(0, QDir::currentPath().length());
if (canonicalName.startsWith("/"))
canonicalName.remove(0,1);
}
QFileInfo kodFile(name);
QString kodFilePath = QDir::toNativeSeparators(kodFile.absoluteFilePath());
char programName[1024];
strcpy(programName, kodFilePath.toLocal8Bit().constData());
std::ifstream programFile(programName, std::ios::in|std::ios::binary);
Bytecode::Data programData;
if (!programFile.is_open()) {
error = _("Can't open module file");
}
else {
try {
Bytecode::bytecodeFromDataStream(programFile, programData);
}
catch (...) {
error = _("Module file is damaged");
}
}
programFile.close();
AST::ModulePtr result;
if (error.length()==0) {
AST::Module * module = new AST::Module;
module->header.type = AST::ModTypeCached;
module->header.name = canonicalName;
for (size_t e=0; e<programData.d.size(); e++) {
const Bytecode::TableElem & elem = programData.d.at(e);
if (elem.type==Bytecode::EL_FUNCTION || elem.type==Bytecode::EL_MAIN) {
const QString algName = QString::fromStdWString(elem.name);
if (algName.length()>0 && !algName.startsWith("_")) {
AST::Algorithm * alg = new AST::Algorithm;
alg->header.name = algName;
alg->header.implType = AST::AlgorhitmExternal;
alg->header.external.moduleName = canonicalName;
alg->header.external.id = elem.id;
const QString signature = QString::fromStdWString(elem.signature);
QStringList algSig = signature.split(":");
alg->header.returnType = typeFromSignature(algSig[0]);
if (algSig.size()>1) {
QStringList argSignatures = algSig[1].split(",");
for (int argNo=0; argNo<argSignatures.size(); argNo++) {
if (argSignatures[argNo].length()==0)
break;
AST::Variable * var = new AST::Variable;
QStringList sigPair = argSignatures[argNo].split(" ");
if (sigPair[0]=="in")
var->accessType = AST::AccessArgumentIn;
else if (sigPair[0]=="out")
var->accessType = AST::AccessArgumentOut;
else if (sigPair[0]=="inout")
var->accessType = AST::AccessArgumentInOut;
var->baseType = typeFromSignature(sigPair[1]);
var->dimension = sigPair[1].count("[]");
alg->header.arguments.push_back(AST::VariablePtr(var));
}
}
module->header.algorhitms.push_back(AST::AlgorithmPtr(alg));
}
}
}
result = AST::ModulePtr(module);
ast_->modules.push_back(result);
}
return result;
}
void SyntaxAnalizer::parseModuleHeader(int str)
{
if (statements_[str].hasError())
......
......@@ -81,6 +81,7 @@ private /*methods*/:
void parseEndLoop(int str);
void parseIfCase(int str);
void parseLoopBegin(int str);
AST::ModulePtr loadKodFile(const QString & fileName, QString &localError);
const TextStatement & findSourceStatementByLexem(const Lexem* lexem) const;
......
......@@ -701,7 +701,7 @@ void KumirVM::reset()
c.moduleId = pTestingProgram->module;
c.name = pTestingProgram->name;
}
c.IP = 0;
c.IP = -1;
if (c.program) {
// Push startup context to stack (if non empty)
......@@ -1887,7 +1887,8 @@ void KumirVM::do_specialcall(uint16_t alg)
margin.push_back('=');
margin += svalue;
}
debugHandler_->appendTextToMargin(lineNo, margin);
if (contextsStack_.top().moduleContextNo == 0)
debugHandler_->appendTextToMargin(lineNo, margin);
}
}
if (alg==0x01) {
......@@ -2151,8 +2152,9 @@ void KumirVM::do_setarr(uint8_t s, uint16_t id)
}
}
const String notice = name+Kumir::Core::fromAscii("[")+boundsText+Kumir::Core::fromAscii("]");
if (debugHandler_ && currentContext().runMode==CRM_OneStep) {
debugHandler_->appendTextToMargin(lineNo, notice);
if (debugHandler_ && currentContext().runMode==CRM_OneStep) {
if (contextsStack_.top().moduleContextNo == 0)
debugHandler_->appendTextToMargin(lineNo, notice);
if (VariableScope(s)==Bytecode::LOCAL) {
debugHandler_->debuggerUpdateLocalTableBounds(name, bounds);
}
......@@ -2187,6 +2189,7 @@ void KumirVM::do_updarr(uint8_t s, uint16_t id)
const int lineNo = contextsStack_.top().lineNo;
if (lineNo!=-1 &&
!blindMode_ &&
contextsStack_.top().moduleContextNo == 0 &&
contextsStack_.top().type != EL_BELOWMAIN
)
{
......@@ -2201,7 +2204,8 @@ void KumirVM::do_updarr(uint8_t s, uint16_t id)
}
const String notice = name+Kumir::Core::fromAscii("[")+boundsText+Kumir::Core::fromAscii("]");
if (debugHandler_)
debugHandler_->appendTextToMargin(lineNo, notice);
if (contextsStack_.top().moduleContextNo == 0)
debugHandler_->appendTextToMargin(lineNo, notice);
}
}
nextIP();
......@@ -2231,6 +2235,7 @@ void KumirVM::do_store(uint8_t s, uint16_t id)
if (lineNo!=-1 &&
!blindMode_ &&
contextsStack_.top().type != EL_BELOWMAIN &&
contextsStack_.top().moduleContextNo == 0 &&
value.dimension()==0
)
{
......@@ -2271,7 +2276,8 @@ void KumirVM::do_store(uint8_t s, uint16_t id)
}
if (debugHandler_ && svalue.length()>0) {
const String message = name+Char('=')+svalue;
debugHandler_->appendTextToMargin(lineNo, message);
if (contextsStack_.top().moduleContextNo == 0)
debugHandler_->appendTextToMargin(lineNo, message);
}
if (debugHandler_ && currentContext().runMode==CRM_OneStep) {
if (VariableScope(s)==Bytecode::LOCAL)
......@@ -2382,7 +2388,8 @@ void KumirVM::do_storearr(uint8_t s, uint16_t id)
notice.push_back(Char('='));
notice += svalue;
if (debugHandler_) {
debugHandler_->appendTextToMargin(lineNo, notice);
if (contextsStack_.top().moduleContextNo == 0)
debugHandler_->appendTextToMargin(lineNo, notice);
}
if (debugHandler_ && currentContext().runMode==CRM_OneStep) {
if (VariableScope(s)==Bytecode::LOCAL)
......@@ -2484,7 +2491,8 @@ void KumirVM::do_setref(uint8_t s, uint16_t id)
// name.push_back('&');
// name += qn;
if (debugHandler_) {
debugHandler_->appendTextToMargin(lineNo, name);
if (contextsStack_.top().moduleContextNo == 0)
debugHandler_->appendTextToMargin(lineNo, name);
}
if (debugHandler_ && currentContext().runMode==CRM_OneStep) {
if (VariableScope(s)==Bytecode::LOCAL) {
......@@ -2599,7 +2607,8 @@ void KumirVM::do_showreg(uint8_t regNo) {
? register0_
: currentContext().registers[regNo];
if (debugHandler_)
debugHandler_->appendTextToMargin(lineNo, val.toString());
if (contextsStack_.top().moduleContextNo == 0)
debugHandler_->appendTextToMargin(lineNo, val.toString());
}
}
nextIP();
......@@ -2638,7 +2647,7 @@ void KumirVM::do_ret()
&& lastContext_.runMode == CRM_OneStep
)
{
if (contextsStack_.size()>0 && contextsStack_.top().moduleContextNo==0) {
if (contextsStack_.size()>0) {
contextsStack_.top().runMode = CRM_OneStep;
if (debugHandler_ && !blindMode_
&& contextsStack_.top().type==EL_MAIN)
......@@ -2679,7 +2688,7 @@ void KumirVM::do_line(const Bytecode::Instruction & instr)
if (extractColumnPositionsFromLineInstruction(instr, from, to)) {
currentContext().columnStart = from;
currentContext().columnEnd = to;
if (!blindMode_ && contextsStack_.top().runMode==CRM_OneStep) {
if (!blindMode_ && contextsStack_.top().runMode==CRM_OneStep && contextsStack_.top().moduleContextNo==0) {
if (debugHandler_)
debugHandler_->noticeOnLineChanged(currentContext().lineNo, from, to);
}
......
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