2016-04-20 13 views
0

I haben zwei Klassen C1 und C2, die C++ Code über printCode() Methode kann generieren. Verwendung von Objekten von C1, C2, kann ich C++ Code wie folgt erzeugen:Quellcode generieren mit zur Schleife

C1* array1[100]; 
C2* array2[100]; 

// Create objects to generate code 
for (int i = 0; i < 100; i++) { 
    array1[i] = new C1(i); 
    array2[i] = new C2(i); 
} 
[...] 
// Generate code 
for (int i = 0; i < 100; i++) { 
    array1[i]->printCode(); 
    array2[i]->printCode(); 
} 

Der generierte Code:

// f represents a set of operations 
// code generated by array1[0], array2[0] 
(x[0], x[1], ..., x[n]) := f(0, x[0], x[1], ..., x[n]); 
// code generated by array1[1], array2[1] 
(x[0], x[1], ..., x[n]) := f(1, x[0], x[1], ..., x[n]); 
[...] 
// code generated by array1[99], array2[99] 
(x[0], x[1], ..., x[n]) := f(99, x[0], x[1], ..., x[n]); 

Wie kann ich diese stattdessen erzeugen (gleiche Leistung, kleinere Codegröße):

for (int i = 0; i < 100; i++) 
    (x[0], x[1], ..., x[n]) := f(i, x[0], x[1], ..., x[n]); 

Edit: Beispiel Definitionen von C1, C2:

const int n = 1000; 
class C1 { 
public: 
    C1(int x) : my_var(x) {} 
    void printCode() { 
     for (int i = 0; i < n - 1; i++) { 
      // func1 is defined in the generated code 
      // the generated code sees foo(my_var) as a constant 
      cout << "x[" << i << "] = func1(x[" << i << "], x[" << i + 1 "] + " << bar(my_var) << endl; 
     } 
    } 

private: 
    int my_var; 
    int foo(int x) { ... } 
} 

C2 ist ähnlich:

class C2 { 
public: 
    C2(int x) : my_var(x) {} 
    void printCode() { 
     for (int i = 0; i < n - 1; i++) { 
      // func2 is defined in the generated code 
      // the generated code sees bar(my_var) as a constant 
      cout << "x[" << i << "] = func2(x[" << i << "], x[" << i + 1 "] + " << bar(my_var) << endl; 
     } 
    } 

private: 
    int my_var; 
    int bar(int x) { ... } 
} 

Mit C1, C2, wie oben definiert, würde der generierte Code sein:

// definitions of func1, func2 
int func1(int x, int y) { ... } 
int func2(int x, int y) { ... } 

... 

// Code generated by C1(0) 
x[0] = func1(x[0], x[1]) + f0; // f0 = C1.foo(0) 
x[1] = func1(x[1], x[2]) + f0; 
... 
x[998] = func1(x[998], x[999]) + f0; 
// Code generated by C2(0) 
x[1] = func2(x[0], x[1]) + b0; // b0 = C2.bar(0) 
x[2] = func2(x[1], x[2]) + b0; 
... 
x[999] = func2(x[998], x[999]) + b0; 

// Code generated by C1(1), C2(1) 
// Code generated by C1(2), C2(2) 
... 
// Code generated by C1(99), C2(99) 

Was ich will:

for (int i = 0; i < 100; i++) { 
    x[0] = func1(x[0], x[1]) + f[i]; // f[i] = C1.foo(i) 
    x[1] = func1(x[1], x[2]) + f[i]; 
    ... 
    x[998] = func1(x[998], x[999]) + f[i]; 

    x[1] = func2(x[0], x[1]) + b[i]; // b[i] = C2.bar(i) 
    x[2] = func2(x[1], x[2]) + b[i]; 
    ... 
    x[999] = func2(x[998], x[999]) + b[i]; 
} 
+0

Sie benötigen mehr Informationen geben, wie Ihre Klassen 'C1' und' C2' implementiert – teivaz

+0

@teivaz ich den Code für C1, C2 hinzugefügt haben. – vhl

+0

Offensichtlich verursachen die Beispiele, die ich hinzufügte, einige Verwirrung. Die for-Schleife in 'printCode()' dient nur dazu, zu verdeutlichen, dass die Funktion viel Code druckt. In meiner Anwendung kann printCode() nicht optimiert werden. – vhl

Antwort

0

Was Sie brauchen, ist eine Form der abstrakten Darstellung der for-Schleife. Anstatt also eine Schleife von 1 bis 100 zu schreiben, erstellen Sie auf Objekt vom Typ Schleife wie folgt aus:

auto loop = createLoop("int", "i", 1, 100); 
loop->add(createC1("i")); 
loop->add(createC2("i")); 
loop->printCode(stdout); 

durch die Konstrukteure in der Fabrik Methoden Einkapselung, können Sie die Factory-Methoden lassen unique_ptr zurückkehren und damit Speicherlecks vermeiden und die manuelle Verfolgung von Heap-Objekten loszuwerden (verwenden Sie in Ihrer Codebase überhaupt keine neuen Rohdaten).

C1 und C2 brauchen eine Möglichkeit, dass sie Symbole statt nur Konstanten speichern können, wie Sie haben. Der beste Weg, dies zu unterstützen, ist, dass sie einen String-Wert als Member anstelle von Int haben.

printCode von Schleife hat printCode aus seinen Mitgliedern C1 und C2 zu nennen.

0

Es wäre wahrscheinlich so etwas wie:

void printCode() { 
    cout << "for (int i = 0; i < " << n - 1 << " ; i++) {" << endl; 
     // func2 is defined in the generated code 
     // the generated code sees bar(my_var) as a constant 
    cout << "x[i] = func2(x[i], x[i + 1] + " << bar(my_var) << ");" << endl; 
    cout << "}" << endl; 
} 
+0

Entschuldigung, wenn meine Erklärung unklar war. Ihr Fix würde folgendes erzeugen: 'code_generated_by C1 [0], C2 [0]; code_generated_by C1 [1], C2 [1]; ...; code_generated_by C1 [99], C2 [99] '. Was ich wollte, war: 'für (int i = 0; i <100; i ++) {code_generated_by C1 [i], C2 [i]; } ' – vhl

+0

uhm, in so einem Fall können Sie das in Schleife nicht aufrufen. Welcher Code generiert wird, hängt davon ab, wie Sie die Methoden aufrufen (d. H., Wenn Sie 'C1, C2, C1, C2' aufrufen, wird genau das generiert). Sie benötigen einen Wrapper-Generator. –

+0

Also im Grunde ein Generator, der einen Generator erzeugt? – vhl

Verwandte Themen