Здравствуйте, 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.
Здравствуйте, R.O. Prokopiev, Вы писали:
Для явы есть NestedVM, это транслятор какой-то целевого ассемблера gcc(MIPS?) в jvm байткод. Он вроде использовался(yется) для создания pure java sqlite. Вещь древняя и с Питоном облом.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, R.O. Prokopiev, Вы писали:
ROP>ЗЫ: Посмотрел llvvm+clang. Даже простая конструкция вида "return 42;" превращается в кучу монструзных библиотечных вызовов. Может я не умею его готовить...
По идее можно взять какой-то язык с развитой макраснёй, и писать макросы так, что бы оно в 4-х режимах работало
1) Исполнение прямо на этом языке
2) вывод куда-то текста на С++
3) и 4) так же для двух других...
Ну и вперёд.
В связи с этим вопрос. А немерле у вас юзать можно?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском