# Kellerspeicher



## gee_20_4_7 (9. Feb 2011)

Hallo Freunde,
im Zuge meiner Vorbereitung zur Prüfung von Prinzipien von Programmiersprachen tut sich mir folgende Frage auf.
Ich habe einen Term gegeben:

```
("foo" + "bar").length() < 2 * (1+4)
```
*Syntaxbaum:*


 
und ich soll das entsprechende Programm des Kellerautomaten erstellen und den Inhalt des Stacks in jedem Schritt angeben.

Ich habe folgendes (zur Vereinfachung gebe ich nur den Inhalt für signifikante Stellen an und lasse die pops raus):

push("foo"), push("bar")
*stack*={"foo"; "bar"}
(+)
*stack*={"foobar"}
push(length())----------->bin ich mir nicht sicher, was hier gemacht wird....ob das so stimmt (lenth() hat ja keinen Wert, wird das trotzdem gepusht?)
(.)
*stack*={6}
push(2)------------------->hier bin ich mir nicht sicher, ob erst 1 und 4 gepusht und berechnet werden 
push(1)
push(4)
*stack*={6;2;1;4}
(+)
*stack*={6;2;5}
(*)
*stack*={6;10}
(<)
*stack*={true}

Was sagt ihr dazu? Ist das so richtig, oder hab ich irgendwas übersehen?
Der Aufruf des Bytecodes mittels "javap -c Classfile" ergab:

```
Code:
   0:	ldc	#2; //String foobar
   2:	invokevirtual	#3; //Method java/lang/String.length:()I
   5:	bipush	10
   7:	if_icmpge	14
   10:	iconst_1
   11:	goto	15
   14:	iconst_0
   15:	ireturn
```
Aus diesem werde ich auch nicht so richtig schlau. Frage am Rand, wie kann man sich jede Zeile ausgeben lassen?
Kann mir jemand weiterhelfen?

Vielen Dank!


----------



## Marco13 (9. Feb 2011)

Beim ersten Drüberschauen sieht's plausibel aus. Entscheidend ist die Frage, um welchen Kellerautomaten es geht: Um einen "theoretischen", "Java-ähnlichen", oder um Java selbst? Für ersteren wäre das, was du geschrieben hast, soweit ich das sehe(!), nicht falsch. Für Java selbst ist es etwas anders, wie man auch am bytecode sieht: Dort wird 2*(1+4) nicht zur Laufzeit berechnet, sondern schon zur Compilezeit (da kommt 10 raus, das braucht man nur einmal auszurechnen, und nicht jedes mal wenn das Programm läuft). Deswegen wird da "bipush	10" gemacht. Wenn du mit "Jede Zeile ausgeben" meinst, dass du dort den ablauf von 2*(1+4) sehen willst: Ich wüßte nicht, wie das geht - vielleicht kann man irgendwo versuchen, Optimierungen abzuschalten, aber ich schätze eher nicht.


----------



## Andi_CH (10. Feb 2011)

Marco13 hat gesagt.:


> Wenn du mit "Jede Zeile ausgeben" meinst, dass du dort den ablauf von 2*(1+4) sehen willst: Ich wüßte nicht, wie das geht - vielleicht kann man irgendwo versuchen, Optimierungen abzuschalten, aber ich schätze eher nicht.



Wenn es keine Konstanten sondern Variablen sieht es so aus

```
public static void main(java.lang.String[]);
  Code:
   0:   iconst_2
   1:   istore_1
   2:   iconst_1
   3:   istore_2
   4:   iconst_4
   5:   istore_3
   6:   ldc     #16; //String foobar
   8:   invokevirtual   #18; //Method java/lang/String.length:()I
   11:  iload_1
   12:  iload_2
   13:  iload_3
   14:  iadd
   15:  imul
   16:  if_icmpge       23
   19:  iconst_1
   20:  goto    24
   23:  iconst_0
   24:  istore  4
   26:  return

}
```


```
public static void main(String[] args) {
		int zwei = 2;
		int eins = 1;
		int vier = 4;
		boolean x =	("foo" + "bar").length() < zwei * (eins+vier);	
	}
```


----------



## gee_20_4_7 (10. Feb 2011)

Ja vielen Dank euch beiden, auf die Idee den Ausdruck in einer Methode mit Parametern zu berechnen bin ich heute auch gekommen. Jetzt ist nur noch die Frage offen, ob das length mit gepusht wird.

Danke!


----------



## Marco13 (10. Feb 2011)

Es wird indirekt gepusht: Bei invokevirtual	wird das Ergebnis auf den Stack gelegt. VM Spec


----------

