Eivind Gard Lund 24. Mars 2009 Foilene bygger på 2009 utgaven av Andreas Svendsen
Informasjon Semantikksjekk Kodegenerering
Oblig 2 tilgjengelig på kurssiden Bygger på deres oblig 1 kode. Det er lagt ut en patch for oblig 2. Inneholder hovedsaklig tester for semantikksjekken og kodegenereringen. Nye versjoner av Compiler.java og build.xml Frist: Fredag 7. mai
test Kjører testene (ca. 40 stk) compile-runme Kompilerer eksemplet RunMe.d list-runme Lister innholdet i bytekoden laget for RunMe.d run-runme Kjører RunMe.bin på den virtuelle maskinen
Kontrollere at syntakstreet (programmet) oppfyller alle kravene i språknotatet Statisk semantikk Gi en kort feilmelding dersom det er feil Kompilatoren returnerer en av følgende verdier: (0) Godkjent (1) Syntaksfeil (2) Semantikkfeil Generere byte-kode ved hjelp av biblioteksklasser Teste semantikksjekken mot programmene i testsuiten Teste byte-kode-genereringen mot eksempelet RunMe.d Rapport som beskriver løsningen
Multiple deklarasjoner av et navn på samme nivå må detekteres Typekonvertering int is-a float Main-funksjonen Må være deklarert på øverste blokknivå Ingen argumenter eller returverdi Funksjonsdeklarasjoners returverdi ikke noe (void) type i symboltabellen (predefinert eller en instans av en klasse)
AssignStmt Variabelen på venstresiden må være deklarert Typene på venstre side og høyre side må være like, etter evt. typekonvertering ReturnStmt Typen til uttrykket skal stemme overens med funksjonens deklarerte type WhileStmt Må ha en betingelse av typen bool IfStmt Må ha en betingelse av typen bool
NewExp Argumentet må være en deklarert klasse Literals Må være av en de forhåndsdefinerte typene i språket float, int, string, bool eller null Binære uttrykk Lik type, etter evt. typeforfremming, på begge sider av operatoren Aritmetiske uttrykk Begrenses til aritmetiske typer (int eller float) Logiske uttrykk (med "&&", " " eller "!") Begge operander må være av typen bool
CallStmt Navnet som kalles må være deklarert som funksjon Kallet må ha likt antall aktuelle, som funksjonen har formelle parametre De aktuelle parametrene må ha lik type (eller mulig å tilordne) som de formelle parametrene Bruk av referanser ("ref") må stemme overens med funksjondeklarasjonen Var Navnet må være deklarert. Hvis instansvariabel (på formen x.y) X må være deklarert og ha medlemsvariabelen y
Benytte bytecode-biblioteket til å lage bytekode Beskrevet i notat om bytecode og interpreter (bytecode-interpreter.pdf) Det er en begrenset semantikk for kodegenereringen RunMe.d skal benyttes for å teste kodegenereringen Testprogrammene i katalogen test skal ikke benyttes
Forskjeller i semantikken Ikke blokkstruktur Kun et globalt og et lokalt nivå Ikke referanseparametere Litt annen bruk av navn Funksjoner kalles Procedure Klasser kalles strukter
// Make code: CodeFile codefile = new CodeFile(); codefile.addprocedure("print_float"); Alt starter her codefile.addprocedure("main"); codefile.addvariable("myglobalvar"); codefile.addprocedure("test"); codefile.addstruct("complex"); Legge til globale deklarasjoner
CodeProcedure main = new CodeProcedure("Main", VoidType.TYPE,codeFile); main.addinstruction(new RETURN()); codefile.updateprocedure(main); Nytt objekt for en metode // Oppdatering av global variabel codefile.updatevariable("myglobalvar", new RefType(codeFile.structNumber("Complex"))); Husk å oppdatere metoder og variable
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); En variabel må legges på stacken før den kan brukes som parameter Husk RETURNinstruksjon for metoder
Husk at det vi i syntaks og semantikkdelen kalte klasser, kalles for strukter i biblioteket vi benytter. CodeStruct complex = new CodeStruct("Complex"); complex.addvariable("real", FloatType.TYPE); complex.addvariable("imag", FloatType.TYPE); codefile.updatestruct(complex);
CodeProcedure printfloat = new CodeProcedure("print_float", VoidType.TYPE, codefile); test.addparameter("f", FloatType.TYPE); codefile.updateprocedure(printfloat); Husk å sette hvilken metode som er Main codefile.setmain("main"); byte[] bytecode = codefile.getbytecode(); //... Write the bytes to a file.
Loading from file:./example.bin Variables: 0: var Complex myglobalvar Procedures: 0: func void print_float() 1: func void Main() 0: return 2: func void test(float 0, Complex 1, float 2) 0: loadlocal 0 3: call print_float {0} 6: return Structs: 0: Complex 0: float 1: float Constants: STARTWITH: Main
Antall variable Antall prosedyrer Antall structer Lengden på variabelnavn Lengden på prosedyrenavn Mainnummer Ant: par, var, inst Variabeltype (Ref) Struct nummer 0 RETURN (24)
Expression Instruction (NOP) Statements (IF-part) Instruction (NOP) Instruction (NOP) Statments (ELSE-part) Instruction (NOP) to put jump if exp=false to put jump to end of else jump to here if exp=false jump to here when finished with IF-part
Kontrollere statisk semantikk Utvide syntakstre-nodene Lage en context-klasse som håndterer symboltabell etc. Kjøre testene i katalogen test Generere byte-kode Utvide syntakstre-nodene Holde orden på stack etc. Kjøre RunMe.d Dokumentere løsningen i en rapport Frist: Fredag 7. mai