Commit 8141ddac authored by Victor Yacovlev's avatar Victor Yacovlev

Implemented external kumir module reusing

parent b50359f6
......@@ -18,6 +18,7 @@
"No module name";"Нет имени исполнителя";"";"";"";"";
"Array dimension mismatch";"Несоответствие размерностей таблиц";"";"";"";"";
"No pairing 'begin module'";"Нет парной “исп”";"";"";"";"";
"No such module";"Нет такого исполнителя";"";"";"";"";
"No 'end' after 'then'";"Нет “все” после “то”";"";"";"";"";
"The name is used by global variable";"Имя занято глобальной величиной";"";"";"";"";
"Algorith out of module";"";"";"";"";"";
......@@ -26,7 +27,7 @@
"Nothing between '(' and ')'";"Пусто между “(“ и “)”";"";"";"";"";
"No operands";"Только операция";"";"";"";"";
"File handle is not integer";"Ключ – не целое число";"";"";"";"";
"No colon after condition";"В конце нет “:”";"";"";"";"";
"Wrong E-real number";"Ошибка в E-записи числа";"";"";"";"";
"Can't not %1";"Нельзя не %1";"";"";"";"";
"No pairing ']'";"Нет парной “]”";"";"";"";"";
"Can't integer:=charect";"Нельзя “цел := сим”";"";"";"";"";
......@@ -37,6 +38,7 @@
"Can't boolean:=integer";"Нельзя “лог := цел”";"";"";"";"";
"Algorhitms can't return array";"Нельзя вернуть таблицу";"";"";"";"";
"'to' earler then 'from'";"“до” раньше чем “от”";"";"";"";"";
"Error compiling this module";"Ошибка сборки этого исполнителя";"";"";"";"";
"Extra operator";"Лишний оператор";"";"";"";"";
"Can't input value of type %1";"";"";"";"";"";
"File already specified";"";"";"";"";"";
......@@ -55,7 +57,7 @@
"Function in array bound";"Алгоритм в границе";"";"";"";"";
"Indeces was specified before";"Повторное указание индексов";"";"";"";"";
"From-value not specified";"Нет значения после “от”";"";"";"";"";
"No variables declared after '%1'";"Пусто после “%1”";"";"";"";"";
"Right array bound is not integer";"Правая граница таблицы не целая";"";"";"";"";
"Too many 'not'";"Много “не”";"";"";"";"";
"No pairing ')'";"Нет парной “)”";"";"";"";"";
"Table constant element of variant type";"";"";"";"";"";
......@@ -74,7 +76,7 @@
"Variable name is empty";"Где имя величины?";"";"";"";"";
"Assignment to in- argument";"Нельзя присвоить аргументу";"";"";"";"";
"No coma before type";"Нет запятой перед объявлением";"";"";"";"";
"Right array bound is not integer";"Правая граница таблицы не целая";"";"";"";"";
"No variables declared after '%1'";"Пусто после “%1”";"";"";"";"";
"No arguments";"Нет аргументов";"";"";"";"";
"Extra 'fi'";"Что - “все”?";"";"";"";"";
"Type not declared before";"Не указан тип";"";"";"";"";
......@@ -88,14 +90,15 @@
"Not enought indeces";"Не все индексы";"";"";"";"";
"Begin in algorhitm body";"“нач” внутри алгоритма";"";"";"";"";
"'=' instead of ':='";"“=” вместо “:=”";"";"";"";"";
"Must be Kumir program file name";"Нет имени файла исполнителя";"";"";"";"";
"Not integer to-value";"Величина не целая";"";"";"";"";
"Input format must be a string";"";"";"";"";"";
"Must be a file name or empty string";"Должно быть имя файла или пустая строка";"";"";"";"";
"Can't %1:=%2";"";"";"";"";"";
"Can't %1:=%2";"Нельзя “%1 := %2”";"";"";"";"";
"No 'begin' after header";"После “алг” нет “нач”";"";"";"";"";
"This algorhitm is broken";"Алгоритм с ошибкой";"";"";"";"";
"Name contains keyword";"Ключевое слово в имени";"";"";"";"";
"No such module";"Нет такого исполнителя";"";"";"";"";
"No operand before non-unary operator";"";"";"";"";"";
"Can't run kumir2-bc to compile this module";"Не могу запустить компилятор для сборки этого испонителя";"";"";"";"";
"Extra 'switch'";"Нет ”все” после “выбор”";"";"";"";"";
"Error contains unpaired quote";"Непарная кавычка";"";"";"";"";
"Constant type mismatch";"Несоответствие типа константы";"";"";"";"";
......@@ -109,7 +112,7 @@
"Garbage at the end of statement";"Мусор в конце выражения";"";"";"";"";
"No 'then' after 'if'";"Где “то” после условия?";"";"";"";"";
"Assignment to complex expression";"Нельзя присвоить выражению";"";"";"";"";
"'end' instead of 'endloop'";"“кон” вместо “кц”";"";"";"";"";
"Can't output value of type %1";"";"";"";"";"";
"Can't real:=string";"Нельзя “вещ := лит”";"";"";"";"";
"Wrong hex constant";"Плохая 16-ричная константа";"";"";"";"";
"':=' or '=' ?";"“:=” или “=” ?";"";"";"";"";
......@@ -140,6 +143,7 @@
"'%1' in algorithm";"“%1” внутри алгоритма";"";"";"";"";
"Can't pass in-argument as in/out-argument";"Нельзя арг передать в рез или аргрез";"";"";"";"";
"Garbage between if..then";"Мусор между “если”..”то”";"";"";"";"";
"No such file";"Нет такого исполнителя рядом с программой";"";"";"";"";
"No loop 'to' value";"Нет “до” после “от”";"";"";"";"";
"Extra format";"";"";"";"";"";
"Can't charect:=string";"Нельзя “сим := лит”";"";"";"";"";
......@@ -165,6 +169,7 @@
"Can't charect:=real";"Нельзя “сим := вещ”";"";"";"";"";
"No right array bound";"Нет правой границы таблицы";"";"";"";"";
"Extra 'then'";"“то” не на месте";"";"";"";"";
"kumir2-bc crashed while compiling this module";"Компилятор сломался при попытки сборки этого испонителя";"";"";"";"";
"No right value of assignment";"Нет правой части присваивания";"";"";"";"";
"Garbage after 'if' statement";"Мусор после “если”";"";"";"";"";
"Extra algorithm arguments";"Лишние аргументы";"";"";"";"";
......@@ -176,7 +181,7 @@
"Unpaired '['";"Не парная “[“";"";"";"";"";
"Can't pass this expression as in/out-argumeny";"Не величина в аргрез-параметре";"";"";"";"";
"Must be a scalar constant";"";"";"";"";"";
"Wrong E-real number";"Ошибка в E-записи числа";"";"";"";"";
"No colon after condition";"В конце нет “:”";"";"";"";"";
"Extra 'end'";"Лишний “кон”";"";"";"";"";
"Algorhitm header in algorhitm body";"Вложенное описание алгоритма";"";"";"";"";
"Not a simple index";"Индекс – не число";"";"";"";"";
......@@ -192,7 +197,7 @@
"No then before else";"Нет “то” перед “иначе”";"";"";"";"";
"Assignment of array";"Нельзя присваивать таблицы";"";"";"";"";
"Extra 'not'";"Лишнее “не”";"";"";"";"";
"Can't output value of type %1";"";"";"";"";"";
"'end' instead of 'endloop'";"“кон” вместо “кц”";"";"";"";"";
"Keyword in name";"Ключевое слово в имени";"";"";"";"";
"Can't input an array";"";"";"";"";"";
"No 'case' after 'switch'";"Нет “при:” после “выбор”";"";"";"";"";
......@@ -234,6 +239,7 @@
"Format already declared";"";"";"";"";"";
"Variable not found";"Величина не описана";"";"";"";"";
"'alg' instead of 'arg'";"“алг” вместо “арг”";"";"";"";"";
"Can't open module file";"Не могу открыть файл исполнителя";"";"";"";"";
"Algorhitm not implemented";"Алгоритм не реализован";"";"";"";"";
"Can't string:=boolean";"Нельзя “лит := лог”";"";"";"";"";
"No 'from' before 'to'";"Нет “от”.. перед “до”";"";"";"";"";
......@@ -242,7 +248,7 @@
"No coma before %1";"Нет запятой перед %1";"";"";"";"";
"Misplaced import";"“использовать” не в начале";"";"";"";"";
"No loop variable";"Не указана величина цикла";"";"";"";"";
"No operand before non-unary operator";"";"";"";"";"";
"Name contains keyword";"Ключевое слово в имени";"";"";"";"";
"Constant value not typed";"Не введено значение константы";"";"";"";"";
"Here must be \"input\" or \"output\"";"";"";"";"";"";
"Hidden part must contain only algorithm";"Скрытый текст может содержать только алгоритмы";"";"";"";"";
......@@ -279,5 +285,5 @@
"Left array bound is empty";"Нет левой границы таблицы";"";"";"";"";
"Expression not assigned to anything";"Выражение ничему не присвоено";"";"";"";"";
"Many quotes in constant";"Много кавычек в одной константе";"";"";"";"";
"Module file is damaged";"Файл исполнителя поврежден";"";"";"";"";
"Extra close brace";"";"";"";"";"";
"Can't %1:=%2";"Нельзя “%1 := %2”";"";"";"";"";
......@@ -373,7 +373,7 @@ void KumirProgram::prepareKumirRunner(Shared::GeneratorInterface::DebugLevel deb
qDebug() << "Error generating execuable: " << res.first;
}
else {
plugin_bytecodeRun->loadProgram(bufArray, Shared::FormatBinary);
plugin_bytecodeRun->loadProgram("", bufArray, Shared::FormatBinary);
}
}
const QString exeFileName = s_sourceFileName.mid(0, s_sourceFileName.length()-4)+".kum";
......
......@@ -2,13 +2,15 @@
#include "lexer.h"
#include <limits>
#include <deque>
#include <iostream>
#include <fstream>
#include "dataformats/ast_variable.h"
#include "dataformats/ast_type.h"
#include "errormessages/errormessages.h"
#include "extensionsystem/pluginmanager.h"
#include "interfaces/actorinterface.h"
#include "vm/vm_bytecode.hpp"
#define BADNAME_KEYWORD TN_BAD_NAME_3
#define BADNAME_OPERATOR TN_BAD_NAME_1
......@@ -195,6 +197,38 @@ Lexem * SyntaxAnalizerPrivate::findLexemByType(const QList<Lexem*> lxs, LexemTyp
return 0;
}
AST::Type typeFromSignature(QString s) {
AST::Type result;
if (s.startsWith("void"))
result.kind = AST::TypeNone;
else if (s.startsWith("int"))
result.kind = AST::TypeInteger;
else if (s.startsWith("real"))
result.kind = AST::TypeReal;
else if (s.startsWith("bool"))
result.kind = AST::TypeBoolean;
else if (s.startsWith("char"))
result.kind = AST::TypeCharect;
else if (s.startsWith("string"))
result.kind = AST::TypeString;
else if (s.startsWith("record ")) {
result.kind = AST::TypeUser;
s.remove(0, 7);
int br = s.indexOf("{");
result.name = s.left(br);
s.remove(0, br+1);
int lbr = s.lastIndexOf("}");
s = s.left(lbr);
QStringList fields = s.split(";");
for (int i=0; i<fields.size(); i++) {
AST::Type fieldType = typeFromSignature(fields[i]);
AST::Field field(fields[i], fieldType);
result.userTypeFields.append(field);
}
}
return result;
}
void SyntaxAnalizer::buildTables(bool allowOperatorsDeclaration)
{
// if (d->algorhitm)
......@@ -242,7 +276,76 @@ void SyntaxAnalizer::buildTables(bool allowOperatorsDeclaration)
break;
}
// TODO Find and load unresolved imports!
// Find and load unresolved imports
for (int i=0; i<d->unresolvedImports.size(); i++) {
const QString name = d->unresolvedImports.toList()[i];
QString error;
if (name.endsWith(".kod")) {
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());
const char * programName = kodFilePath.toLocal8Bit().constData();
std::ifstream programFile(programName);
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");
}
}
if (error.length()==0) {
AST::Module * module = new AST::Module;
module->header.type = AST::ModTypeCached;
module->header.name = canonicalName;
module->header.enabled = true;
d->ast->modules.push_back(module);
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::Algorhitm * alg = new AST::Algorhitm;
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++) {
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(var);
}
}
module->header.algorhitms.push_back(alg);
}
}
}
}
}
}
// Set errors for imports that could not be resolved
for (int i=0; i<d->unresolvedImports.size(); i++) {
......@@ -449,15 +552,70 @@ void SyntaxAnalizerPrivate::parseImport(int str)
st.data[1]->error = _("No module name");
return;
}
QString localError = lexer->testName(st.data[1]->data);
if (localError.size()>0) {
st.data[1]->error = localError;
return;
QString name;
if (st.data[1]->type==LxConstLiteral) {
name = st.data[1]->data.trimmed();
if (name.isEmpty()) {
st.data[1]->error = _("Must be Kumir program file name");
return;
}
if (!name.endsWith(".kum") && !name.endsWith(".kod")) {
name += ".kum";
}
QString kumName, binName;
QFileInfo binFile, kumFile;
if (name.endsWith(".kum")) {
kumName = name;
name = binName = name.left(name.length()-4)+".kod";
binFile = QFileInfo (QDir::current().absoluteFilePath(binName));
kumFile = QFileInfo (QDir::current().absoluteFilePath(kumName));
QString kumir2bc = QDir(QCoreApplication::applicationDirPath()).absoluteFilePath("kumir2-bc");
#ifdef Q_OS_WIN32
kumir2bc += ".exe";
#endif
if (kumFile.exists()) {
if (!binFile.exists() || binFile.lastModified()<kumFile.lastModified()) {
// Run kumir2-bc to create (or update) binary module
int status = QProcess::execute(kumir2bc, QStringList()
<< "--debuglevel=2" << kumFile.absoluteFilePath());
if (status==-2) {
st.data[1]->error = _("Can't run kumir2-bc to compile this module");
return;
}
else if (status==-1) {
st.data[1]->error = _("kumir2-bc crashed while compiling this module");
return;
}
binFile = QFileInfo (QDir::current().absoluteFilePath(binName));
if (!binFile.exists()) {
st.data[1]->error = _("Error compiling this module");
return;
}
}
}
}
else {
binName = name;
binFile = QFileInfo (QDir::current().absoluteFilePath(binName));
}
if (!kumFile.exists() && !binFile.exists()) {
st.data[1]->error = _("No such file");
return;
}
name = binFile.absoluteFilePath();
}
else {
QString localError = lexer->testName(st.data[1]->data);
if (localError.size()>0) {
st.data[1]->error = localError;
return;
}
name = st.data[1]->data.simplified();
st.data[1]->type = LxNameModule;
}
AST::Module * mod = st.mod;
Q_CHECK_PTR(mod);
st.data[1]->type = LxNameModule;
mod->header.uses.insert(st.data[1]->data.simplified());
mod->header.uses.insert(name);
}
void SyntaxAnalizerPrivate::parseModuleHeader(int str)
......
......@@ -239,6 +239,8 @@ void Generator::generateExternTable()
}
}
}
if (mod->header.type==AST::ModTypeCached)
moduleFileName = mod->header.name;
e.moduleName = mod->header.name.toStdWString();
e.name = alg->header.name.toStdWString();
e.signature = signature.toStdWString();
......@@ -565,6 +567,38 @@ void Generator::addInputArgumentsMainAlgorhitm(int moduleId, int algorhitmId, co
}
QString typeSignature(const AST::Type & tp) {
QString signature;
if (tp.kind==AST::TypeNone) {
signature += "void";
}
else if (tp.kind==AST::TypeInteger) {
signature += "int";
}
else if (tp.kind==AST::TypeReal) {
signature += "real";
}
else if (tp.kind==AST::TypeBoolean) {
signature += "bool";
}
else if (tp.kind==AST::TypeCharect) {
signature += "char";
}
else if (tp.kind==AST::TypeString) {
signature += "string";
}
else if (tp.kind==AST::TypeUser) {
signature += "record "+tp.name+" {";
for (int i=0; i<tp.userTypeFields.size(); i++) {
signature += typeSignature(tp.userTypeFields.at(i).second);
if (i<tp.userTypeFields.size()-1)
signature += ";";
}
signature += "}";
}
return signature;
}
void Generator::addFunction(int id, int moduleId, Bytecode::ElemType type, const AST::Algorhitm *alg)
{
QString headerError = "";
......@@ -588,6 +622,25 @@ void Generator::addFunction(int id, int moduleId, Bytecode::ElemType type, const
}
}
QString signature;
signature = typeSignature(alg->header.returnType)+":";
for (int i=0; i<alg->header.arguments.size(); i++) {
const AST::Variable * var = alg->header.arguments[i];
if (var->accessType==AST::AccessArgumentIn)
signature += "in ";
else if (var->accessType==AST::AccessArgumentOut)
signature += "out ";
else if (var->accessType==AST::AccessArgumentInOut)
signature += "inout ";
signature += typeSignature(var->baseType);
for (int j=0; j<var->dimension; j++) {
signature += "[]";
}
if (i<alg->header.arguments.size()-1)
signature += ",";
}
for (int i=0; i<alg->impl.locals.size(); i++) {
const AST::Variable * var = alg->impl.locals[i];
......@@ -607,6 +660,7 @@ void Generator::addFunction(int id, int moduleId, Bytecode::ElemType type, const
func.module = moduleId;
func.algId = func.id = id;
func.name = alg->header.name.toStdWString();
func.signature = signature.toStdWString();
QList<Bytecode::Instruction> argHandle;
Bytecode::Instruction l;
......@@ -852,7 +906,7 @@ void Generator::findFunction(const AST::Algorhitm *alg, quint8 &module, quint16
for (quint8 i=0; i<m_ast->modules.size(); i++) {
const AST::Module * mod = m_ast->modules[i];
QList<AST::Algorhitm*> table;
if (mod->header.type==AST::ModTypeExternal)
if (mod->header.type==AST::ModTypeExternal || mod->header.type==AST::ModTypeCached)
table = mod->header.algorhitms + mod->header.operators;
else
table = mod->impl.algorhitms + mod->header.operators;
......@@ -860,7 +914,8 @@ void Generator::findFunction(const AST::Algorhitm *alg, quint8 &module, quint16
if (alg==table[j]) {
module = i;
id = j;
if (mod->header.type==AST::ModTypeExternal && (mod->builtInID & 0xF0) == 0) {
if (mod->header.type==AST::ModTypeCached ||
mod->header.type==AST::ModTypeExternal && (mod->builtInID & 0xF0) == 0) {
QPair<quint8,quint16> ext(module, id);
if (!l_externs.contains(ext))
l_externs << ext;
......
......@@ -58,17 +58,17 @@ int Plugin::currentLineNo() const
return d->effectiveLineNo();
}
bool Plugin::loadProgram(const QByteArray & source, Shared::ProgramFormat format)
bool Plugin::loadProgram(const QString & filename, const QByteArray & source, Shared::ProgramFormat format)
{
if (format==Shared::FormatBinary) {
std::list<char> buffer;
for (int i=0; i<source.size(); i++)
buffer.push_back(source[i]);
d->loadProgramFromBinaryBuffer(buffer);
d->loadProgramFromBinaryBuffer(buffer, filename.toStdWString());
}
else {
const std::string str(source.constData());
d->loadProgramFromTextBuffer(str);
d->loadProgramFromTextBuffer(str, filename.toStdWString());
}
d->programLoaded = true;
return true;
......@@ -268,7 +268,7 @@ QString Plugin::initialize(const QStringList &)
QFile f(fileName);
if (f.open(QIODevice::ReadOnly)) {
const QByteArray data = f.readAll();
loadProgram(data, fileName.endsWith(".ks")? Shared::FormatText : Shared::FormatBinary);
loadProgram(fileName, data, fileName.endsWith(".ks")? Shared::FormatText : Shared::FormatBinary);
}
}
}
......
......@@ -20,7 +20,7 @@ public:
bool canStepOut() const;
bool loadProgram(const QByteArray & source, Shared::ProgramFormat format);
bool loadProgram(const QString & fileName, const QByteArray & source, Shared::ProgramFormat format);
bool hasMoreInstructions() const;
QString error() const;
QVariantList remainingValues() const;
......
......@@ -874,10 +874,10 @@ int Run::effectiveLineNo() const
return vm->effectiveLineNo();
}
void Run::loadProgramFromBinaryBuffer(std::list<char> &stream)
void Run::loadProgramFromBinaryBuffer(std::list<char> &stream, const String & filename)
{
String error;
if (!vm->loadProgramFromBinaryBuffer(stream, error)) {
if (!vm->loadProgramFromBinaryBuffer(stream, true, filename, error)) {
std::string msg;
#if defined(WIN32) || defined(_WIN32)
msg = Kumir::Coder::encode(Kumir::CP866, error);
......@@ -888,10 +888,10 @@ void Run::loadProgramFromBinaryBuffer(std::list<char> &stream)
}
}
void Run::loadProgramFromTextBuffer(const std::string &stream)
void Run::loadProgramFromTextBuffer(const std::string &stream, const String & filename)
{
String error;
if (!vm->loadProgramFromTextBuffer(stream, error)) {
if (!vm->loadProgramFromTextBuffer(stream, true, filename, error)) {
std::string msg;
#if defined(WIN32) || defined(_WIN32)
msg = Kumir::Coder::encode(Kumir::CP866, error);
......
......@@ -27,8 +27,8 @@ public:
// VM Access methods
int effectiveLineNo() const;
void loadProgramFromBinaryBuffer(std::list<char> & stream);
void loadProgramFromTextBuffer(const std::string & stream);
void loadProgramFromBinaryBuffer(std::list<char> & stream, const String & filename);
void loadProgramFromTextBuffer(const std::string & stream, const String & filename);
QString error() const;
QVariantList remainingValues() const;
void setEntryPointToMain();
......
......@@ -34,7 +34,7 @@ enum AlgorhitmType {
/** Algorhitm implementation type */
enum AlgorhitmImplementationType {
/** Kumir-compiler algorhitm */
/** Kumir-compiled algorhitm */
AlgorhitmCompiled,
/** External or builtin algorhitm */
......
......@@ -14,7 +14,7 @@ enum ProgramFormat {
class RunInterface {
public:
enum StopReason { SR_Done, SR_UserInteraction, SR_InputRequest, SR_Error, SR_UserTerminated };
virtual bool loadProgram(const QByteArray & source, ProgramFormat format) = 0;
virtual bool loadProgram(const QString &fileName, const QByteArray & source, ProgramFormat format) = 0;
virtual QDateTime loadedProgramVersion() const = 0;
virtual bool canStepOut() const = 0;
......
......@@ -1363,20 +1363,15 @@ public:
}
#else
inline static bool exist(const String & fileName) {
char * path;
# ifdef NO_UNICODE
path = const_cast<char*>(fileName.c_str());
const char * path = const_cast<char*>(fileName.c_str());
# else
path = reinterpret_cast<char*>( calloc(fileName.length()*2+1, sizeof(char)) );
size_t pl = wcstombs(path, fileName.c_str(), fileName.length()*2+1);
path[pl] = '\0';
std::string localName = Kumir::Coder::encode(Kumir::UTF8, fileName);
const char * path = localName.c_str();
# endif
struct stat st;
int res = stat(path, &st);
bool result = res==0;
# ifndef NO_UNICODE
free(path);
# endif
return result;
}
......
......@@ -14,12 +14,42 @@ enum ContextRunMode {
CRM_OneStep
};
// Two strings
typedef std::pair<String,String> TwoStrings;
struct ExternReference {
int moduleContext;
uint32_t funcKey;
String moduleName;
};
typedef std::map<uint32_t, ExternReference> ExternsMap;
// module_id|alg_id -> instructions
typedef std::map<uint32_t, Bytecode::TableElem> FunctionMap;
// module_id|global_id
typedef std::pair<uint8_t,uint16_t> GlobalsIndex;
// module_id|global_id -> global variable
typedef std::map<GlobalsIndex, Variable > GlobalsMap;
// constant_id -> constant value
typedef std::map<uint16_t,Variable> ConstantsMap;
typedef std::vector<Variable> VariantArray;