Re[2]: Синхронизация C++ исходника с Java и Python
От: R.O. Prokopiev Россия http://127.0.0.1/
Дата: 13.10.15 13:48
Оценка:
Здравствуйте, Кодт, Вы писали:

ROP>>Как бы сделать так чтобы модифицировать файл только на одном языке, а остальные генерились?..

К>Может, тогда в качестве исходного языка выбрать Cython?

Погонял немного. Cython предназначен прежде всего для компиляции питонового кода в натив (и последующего импорта из питона), C — это побочный продукт. Можно делать строгую compile-time типизацию при помощи cdef и пр.,
но совместимость с питоном при этом теряется. Как из cython исходника получить чисто питоновский так и не нашел.
Код без cdef компилится в лапшу, аналогичную llvm+clang. С использованием cdef код получается веселее, но питоновые хелперы всё равно генерятся, похоже они неотключаемые.

enji подсказал похоже самое практичное решение — использовать сишный макропроцессор.
Re[4]: Синхронизация C++ исходника с Java и Python
От: Evgeny.Panasyuk Россия  
Дата: 13.10.15 17:10
Оценка:
Здравствуйте, enji, Вы писали:

ROP>>Но в рабочий код такие трюки тащить нельзя.

E>Ява-плюсы проблем практически не вызывают, если писать на подмножестве обоих языков. Питон-плюсы — немного препроцессора понадобится, плюс соглашение об отступах
E>
E>FUNC(void, myFunc, (int, a)(float b)) {
E>  DECL(int) c = a + b;
E>  IF (a > b) {
E>    c = c - 2;
E>  }
E>  g(a, c);
E>}
E>

E>Все это обрабатывается стандартным сишным препроцессором, плюс {} для питона убираются. Не так и страшно, на самом деле.

В библиотеке TaskGraph (1, 2) видел интересный приём на эту тему:
int main( int argc, char *argv[] ) {
  TG_IntResIntArg T;
  int n = atoi( argv[1] );
  taskgraph( TG_IntResIntArg, T, tuple1(a) ) {
    tVar(int, i);
    tVar(int, j);
    tFor(i, 0, n-1) {
      tFor(j, 0, n-1) {
        tPrintf("Iteration i=%d, j=%d\n", i, j);
      }
    }
    tReturn(a + n);
  }
  InterchangeSettings inter;
  inter.firstLoop = LoopIdentifier ( 1 );
  inter.secondLoop = LoopIdentifier ( 1, 1 );
  T.applyOptimisation ( "interchange", &inter );
  T.compile( tg::GCC, true );
  printf( "T(%d) = %d\n", n, T(n) );
}

Макросы в середине функции (tVar, tFor и т.п.) описывают код вычислительного ядра. Это описание в конце концов переводится во время выполнения в код стороннего языка. (помимо этого там ещё производятся оптимизации циклов, через обработку полученного AST)

Основная фишка в том, то что эти макросы могут отличать начало/конец scope. То есть примирительно к задаче ТС можно автоматом расставлять отступы в Python, а для C++/Java расставлять скобки.
Вот дистиллированный пример:
#include <iostream>
#include <ostream>
#include <sstream>
#include <string>
 
using namespace std;
 
int level = 0;
void print_indent()
{
    cout << string(level*4,' ');
}
 
class Integer
{
    string name;
public:
    Integer()
    {
        static int counter = 0;
        stringstream ss;
        ss << "var" << (++counter);
        name = ss.str();
        print_indent();
        cout << "int " << name << "=0;" << endl;
    }
    Integer &operator++()
    {
        print_indent();
        cout << "++" << name << ";" << endl;
        return *this;
    }
    Integer &operator=(const Integer &rhs)
    {
        print_indent();
        cout << name << "=" << rhs.name << ";" << endl;
        return *this;
    }
};
class Block
{
    bool done;
public:
    Block()
        : done(false)
    {
        print_indent();
        cout << "{" << endl;
        ++level;
    }
    bool next()
    {
        return !done;
    }
    void after()
    {
        --level;
        print_indent();
        cout << "}" << endl;
        done = true;
    }
};
 
#define BLOCK for(Block b##__LINE__;b##__LINE__.next();b##__LINE__.after())
 
int main()
{
    BLOCK {
        Integer a,b;
        a=b;
        ++a;
        Integer c;
        BLOCK
            a=b=c;
        ++b;
        BLOCK {
            b=++a;
            c=++a;
        }
    }
}
stdout этого кода:
{
    int var1=0;
    int var2=0;
    var1=var2;
    ++var1;
    int var3=0;
    {
        var2=var3;
        var1=var2;
    }
    ++var2;
    {
        ++var1;
        var2=var1;
        ++var1;
        var3=var1;
    }
}

Получается эдакий runtime EDSL. Как видно таким способом легко получить и код Python, и C++, и Java.
Re: Синхронизация C++ исходника с Java и Python
От: novitk США  
Дата: 13.10.15 17:42
Оценка:
Здравствуйте, R.O. Prokopiev, Вы писали:

Для явы есть NestedVM, это транслятор какой-то целевого ассемблера gcc(MIPS?) в jvm байткод. Он вроде использовался(yется) для создания pure java sqlite. Вещь древняя и с Питоном облом.
Re[2]: Синхронизация C++ исходника с Java и Python
От: T4r4sB Россия  
Дата: 13.10.15 18:10
Оценка:
Здравствуйте, BulatZiganshin, Вы писали:

BZ>думаю, куда реалистичней найти 4-й язык, с которого моджно генерить проги на этих трёх. но даже в таком раскладе я ничго не припомню.


m4
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re: Синхронизация C++ исходника с Java и Python
От: Erop Россия  
Дата: 16.10.15 09:59
Оценка:
Здравствуйте, R.O. Prokopiev, Вы писали:

ROP>ЗЫ: Посмотрел llvvm+clang. Даже простая конструкция вида "return 42;" превращается в кучу монструзных библиотечных вызовов. Может я не умею его готовить...


По идее можно взять какой-то язык с развитой макраснёй, и писать макросы так, что бы оно в 4-х режимах работало
1) Исполнение прямо на этом языке
2) вывод куда-то текста на С++
3) и 4) так же для двух других...

Ну и вперёд.

В связи с этим вопрос. А немерле у вас юзать можно?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.