Obligatorisk oppgave 2 i INF5110 v�ren 2008

Merk: Dette er en tidlig utgave. Det vil komme presiseringer.

Merk: Koden for interpreten er n� klar. Det vil kommer det mer dokumentasjon om bytekoden.

Dette er den andre av to oppgaver v�ren 2008. Den bygger videre p� det som er gjort i oblig 1.

Innhold

Hensikten med oppgaven

Tanken bak denne oppgaven er at man skal f� enn� mer praktisk erfaring med hva som gj�res i en kompilator, nemlig:

Oppgaven

Del to av den obligatoriske oppgaven bygger p� den f�rste delen, og g�r ut p� � implementere kravene til statisk semantikk, beskrevet i spr�knotatet. Det holder med � levere inn �n parser. I tillegg skal resultatene fra kj�ring av en testsuite leveres. Dere skal ogs� levere inn listing av byte-koden for eksempelprogrammet RunMe.d.

Frist

Fristen er fredag 9. mai. Fristen er endelig.

Virtuell maskin og byte-kode

Merk: Det vil komme mer detaljert dokumentasjon til bytecode-biblioteket. Mens dere venter kan dere jo kikke i koden i pakken bytecode.*

Det er laget en pakke med klasser for � lage byte-kode. Det er bare � opprette et objekt av klassen CodeFile og s� legge til variabler, structer metoder, osv. N�r man er ferdig med � legge til alt henter man ut byte-koden med getBytecode() som lager en array med bytes (byte[]). Se dette skallet:

  CodeFile codeFile = new CodeFile();

  // Her bygges bytekoden opp ...

  byte[] bytecode = codeFile.getBytecode();
  DataOutputStream stream = new DataOutputStream(new FileOutputStream ("Navnet p� filen her ..."));
  stream.write(bytecode);
  stream.close();
      

Bytekoden er stack-basert og har ca. 30 instruksjoner. Her kommer et notat med flere detaljer om instruksjonene, bytecode-biblioteket og den virtuelle maskinen.

Byte-koden er ikke like uttrykkskraftig som spr�ket Db, derfor er reglene for programmene dere skal generere byte-kode for forskjellige fra de dere skal implementere i semantikksjekken. Forskjellen er:

  • Det er ikke blokkniv�er. Alts� m� alle strukter v�re deklarert p� det �verste niv�et og det er ikke funksjoner inne i funksjoner.
  • Det er ikke referanseparamtere, s� basisparamterene overf�re by-value og struktvariablene er pekerverdier og overf�res ogs� by-value. Alts�, det er p� sammen m�te som i Java.
  • Det er ogs� brukt litt andre navn, slik som at funksjonene kalles prosedyrer (Procedure).
Et eksempel p� et program som f�lger de begrensede reglene er ./code-examples/RunMe.d.

Her er et kort eksempel p� hvordan man bygger opp byte-koden til et enkelt program med en global variabel og en enkel prosedyre med to parametere (float og Complex) og en lokal variabel (int). Den printer ut float-parameteren og returnere. Strukten Complex blir ogs� definert. Legg spesielt merke til at alle deklarasjonene blir definert f�rst og oppdatert senere. Legg ogs� merke til at parameterene f�r nummer fra 0 og oppover og at variabler inne i metoden blir nummerert etter det. Man m� ogs� fortelle den virtuelle maskinen hva som er main-funksjonen. Dette vil alts� v�re kode som for eksempel er spredt rundt i det abstrakte syntakstreet.

  // Lage example.bin:
  CodeFile codeFile = new CodeFile();
  codeFile.addProcedure("Main");
  codeFile.addVariable("myGlobalVar");
  codeFile.addProcedure("test");
  codeFile.addStruct("Complex");

  CodeProcedure main = new CodeProcedure("Main", VoidType.TYPE, codeFile);
  main.addInstruction(new RETURN());
  codeFile.updateProcedure(main);

  codeFile.updateVariable("myGlobalVar", new RefType(codeFile.structNumber("Complex")));

  CodeProcedure test = new CodeProcedure("test", VoidType.TYPE, codeFile);
  test.addParameter("firstPar", FloatType.TYPE);
  test.addParameter("secondPar", new RefType(test.structNumber("Complex")));
  test.addInstruction(new LOADLOCAL(test.variableNumber("firstPar")));
  test.addInstruction(new CALL(test.procedureNumber("print_float")));
  test.addInstruction(new RETURN());
  codeFile.updateProcedure(test);

  CodeStruct complex = new CodeStruct("Complex");
  complex.addVariable("Real", FloatType.TYPE);
  complex.addVariable("Imag", FloatType.TYPE);
  codeFile.updateStruct(complex);
		
  codeFile.setMain("Main");

  byte[] bytecode = codeFile.getBytecode();
  // ... Lagre i filen ./code-examples/example.bin
      
Resultatet (listingen) av dette blir (Ved � kj�re biten med kode ovenfor og s� kj�re komandoen java runtime.VirtualMachine -l ./code-examples/example.bin)
  Loading from file: ./code-examples/example.bin
  Variables:
  0: var Complex myGlobalVar
  Procedures:
  0: func void Main()
      0: return
  1: func void test(float 0, Complex 1)
      0: loadlocal 0
      1: call print_float {100}
      2: return
  Structs:
  0: Complex
      0: float
      1: float
  Constants:
  STARTWITH: Main    
      

Testsuite

Det er laget en patch til det prosjktet som ble delt ut og som dere har bygd p� i oblig 1. Den ligger her og best�r av f�lgende.

  • En ny Compiler-klasse (.\src\compiler\Compiler.java). Den inneholder et skall som brukes av testen. Den forutsetter at metoden compile() returnere en int 0, 1, eller 2, som forklart ovenfor.
  • En hjelpeklasse til testen (.\src\test\FileEndingFilter.java).
  • Klassen som utf�rer testen (.\src\test\Tester.java).
  • En katalog med filer det testes mot (./tests/). Filene med navn som inneholder fail skal gi semantikkfeil (2). Ingen av filene skal gi syntaksfeil (1).
  • Et testprogram for den virtuelle maskinen (./code-examples/RunMe.d).
  • Noen linjer som kan legges til build-filen for �
    (1) kalle testen (compile-test, test).
    (2) kompilerer og kj�re eksemplet RunMe (compile-runme, list-runme, run-runme).
    De ligger i filen ./build.xml.patch.

Plass�r filene slik katalognavnene er angitt her relativt til banen til prosjektet deres (Pass p� � legge til innholdet i Compiler.java og build.xml uten � skrive over de filene dere har!).

Etter det kan testen kj�res med ant test og dere kan kompilere RunMe med ant compile-runme og liste ut byte-koden med ant list-runme.

Klassen Tester kaller opp klassen Compiler for alle testene i katalogen ./tests/. Det skrives ut �n linje pr test og en oppsummering.

Sjekkliste for del to

Under f�lger en sjekkliste for semantikken (merk at det kan v�re flere krav, les ogs� spr�knotatet) i Db:

Gjennomf�ring og levering

Man leverer sammen med den samme gruppen som man leverte oblig 1. Det som skal leveres er:

Levering

Besvarelsen leveres som ett pakket filarkiv (zip- eller tgz-format) til gruppel�rer Fredrik S�rensen <fredrso@ifi.uio.no>.

Subversion-brukere kan ogs� levere via et repository (bare gi meg leseaksess, og kommandoen for � lese ut prosjektet). Rapporten skal ved bruk av SVN enten sendes p� epost, eller ligge p� "roten" (/) i repositoriet.

Sist oppdatert 2008-04-10 21:24
Fredrik S�rensen