Obligatorisk oppgave 2 i INF5110 v?ren 2009

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

Dette er den andre av to oppgaver v?ren 2009. 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. Resultatene fra kj?ring av en testsuite skal leveres. I tillegg skal det ogs? leveres en listing av byte-koden for eksempelprogrammet RunMe.d.

Frist

Fristen er fredag 8. mai.

Virtuell maskin og byte-kode

Den virtuelle maskinen og byte-kode er grundig beskrevet i notat om bytecode og interpreter.

Det er laget en pakke med klasser for ? lage byte-kode. For ? lage byte-kode, opprettes et objekt av klassen CodeFile, hvor variabler, structer, metoder m.m. kan legges til. N?r alt er lagt til, kan man hente ut byte-koden med getBytecode() som lager en array med bytes (byte[]). F.eks. se p? 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.

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 referanseparametere, s? basisparameterene overf?rer 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 metode med to parametere (float og Complex) og en lokal variabel (int). Metoden printer ut float-parameteren og returnerer. Strukten Complex blir ogs? definert. Legg spesielt merke til at alle deklarasjonene blir definert f?rst og oppdatert senere. Legg ogs? merke til at parameterne 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, hvor hver node har ansvar for sine egne instruksjoner.

  // 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 prosjektet 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() returnerer en int 0, 1 eller 2, som nevnt tidligere.
  • 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) kompilere 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 klassen Compiler for alle testene i katalogen ./tests/. Det skrives ut ?n linje for hver test, samt 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 Andreas Svendsen <Andreas.Svendsen@sintef.no>.

Subversion-brukere kan ogs? levere via et repository (bare gi meg leseaksess, og kommandoen for ? lese ut prosjektet).

Sist oppdatert 2009-03-24 14:45
Andreas Svendsen