Dagens tema: Formålet. Kodegenerering NB! Introduksjon Modulen Code. Enkle variable Noen enkle setninger Uttrykk

Like dokumenter
Dagens tema: Formålet. Kodegenerering NB! Introduksjon Modulen Code. Enkle variable Noen enkle setninger Uttrykk

Oversikt Oversettelse Logging Implementasjon Oppsummering

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen Oppsummering

Dagens tema. Hva er kompilering? Anta at vi lager dette lille programmet (kalt kildekoden): Hva er kompilering?

Dagens tema. Hva er kompilering? Anta at vi lager dette lille programmet doble.rusc (kalt kildekoden): Hva er kompilering?

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen

Oversikt Kodegenerering Variabler Setninger Uttrykk While-setningen

Dagens tema: Generelt om variable. Kodegenerering. Deklarasjon av array er. Versjonskontroll. Oppslag i array er

Hovedansvarlig. Symbolgenerator. Tregenerator. Litt mer kompliserte setninger med betingelser

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen

Dagens tema: Kodegenerering. Redigeringsverktøy. Versjonskontroll. Array-er Funksjoner og kall Hovedprogrammet Noen siste gode råd.

Oversikt Kodegenerering Variable Setninger Uttrykk While-setningen

Dagens tema: Maskinkode. Litt datamaskinhistorie Hva er maskin- og assemblerkode? x86-prosessoren Programkode og variabler

Dagens tema: 12 gode råd for en kompilatorskriver. Prosjektet. Modifikasjon av grammatikken. Utifra dette RusC programmet:

Dagens tema: 12 gode råd for en kompilatorskriver. Prosjektet. Koblingen mellom grammatikken og klasser. Utifra dette RusC-programmet:

Hva skal gjøres? Dagens tema: Hva gjør en kompilator? Forenkling

Dagens tema. Rask-maskinen. Rasko-kode Raskas-kode. Litt datamaskinhistorie Registre og lagre Instruksjoner

En overikt. Dagens tema. Datamaskinenes historie. Rask-maskinen Litt datamaskinhistorie Registre og lagre Instruksjoner. Rasko-kode.

Dagens tema: Prosjektet. Hva er en god feilmelding? Melding med mening. Ubrukelig. Hvor på linjen? Noe bedre. Enda bedre

Dagens tema. Datamaskinenes historie. De første moderne datamaskiner. Løsning. Menneskene har alltid prøvd å lage maskiner for å løse sine problemer.

Kompilering Statiske Syntaksanalyse Feilsjekking Eksempel Oppsummering

Oversikt Kompilering Syntaksanalyse Java Feilsjekking Oppsummering

Oversikt Deklarasjoner Typesjekk Programmering Datamaskinhistorie x86 Kodegenerering

Dagens tema: Kompilatorens struktur. De ulike modulene Prosjektet. Oppbyggingen Pakker i Java Avbrudd («exceptions») Enum-klasser i Java

Dagens tema: Resten av det dere trenger til del 1

2 Parser. 1 Skanner. 4 Kodegenerator. 3 Sjekker. Oversikt Datamaskinhistorie x86 Kodegenerering Setninger Uttrykk.

Prosjektet. Dagens tema: Moduler i prosjektet error log chargenerator scanner. Enum klasser i Java. Programmeringsverktøy Emacs Eclipse

Dagens tema: Mer av det dere trenger til del 1

INF 1010, vår 2005 Løsningsforslag uke 11

Dagens tema: Kompilatorens struktur. De ulike modulene Prosjektet. Oppbyggingen Pakker i Java Avbrudd («exceptions») Enum-klasser i Java

INF2100. Oppgaver 23. og 24. september 2010

INF2100. Oppgaver uke 40 og

Dagens tema: Resten av det dere trenger til del 1

INF2100. Oppgaver 9. oktober 2012 C 100 X 10

Dagens tema: Hva skal gjøres? Hva gjør en kompilator? Hva gjør en kompilator?

Array&ArrayList Lagring Liste Klasseparametre Arrayliste Testing Lenkelister

Array&ArrayList Lagring Liste Klasseparametre Arrayliste Testing Lenkelister Videre

INF1010 våren 2017 Onsdag 25. januar. Litt om unntak i Java

Hvordan skrive Flok og Flass kode? I mange tilfelle er det svært enkelt:

INF2100. Oppgaver 6. og 11. oktober 2011 C 100 X 10

INF2100. Oppgave 1. Oppgave 2 4. Løsningsforslag til oppgaver uke 40 og Se figur 1 på neste side.

Dagens tema: 12 gode råd for en kompilatorskriver

Oppgaver til kodegenerering etc. INF-5110, 16. mai, 2014

INF1010, 22. mai Prøveeksamen (Eksamen 12. juni 2012) Stein Gjessing Inst. for Informatikk Universitetet i Oslo

Kodegenerering del 3: Tilleggsnotat fra AHU Samt litt om class-filer og byte-kode INF5110 V2007. Stein Krogdahl, Ifi UiO

INF 1000 høsten 2011 Uke september

Del 3: Evaluere uttrykk

INF1000 undervisningen INF 1000 høsten 2011 Uke september

Oppsummering Assemblerkode Hopp Multiplikasjon Kode og data Array Oppsummering

Dagens tema: 12 gode råd for en kompilatorskriver. Sjekking av navn. Lagring av navn. Hvordan finne et navn?

INF2100. Oppgave 1, 2 og 3. Løsningsforslag til oppgaver 23. og 24. september Her er det mange mulige løsninger her er én: import java.io.

Del 1 En oversikt over C-programmering

Hva er verdien til variabelen j etter at følgende kode er utført? int i, j; i = 5; j = 10; while ( i < j ) { i = i + 2; j = j - 1; }

Kompilering Statiske Syntaksanalyse Feilsjekking Eksempel Oppsummering

INF1010 våren 2019 Onsdag 30. januar. Mer om unntak i Java (med litt repetisjon av I/O først)

2 Om statiske variable/konstanter og statiske metoder.

Bakgrunnen for INF2100. Velkommen til INF2100. Prosjektet. Hva gjør en kompilator?

Del 4 Noen spesielle C-elementer

Hvordan en prosessor arbeider, del 1

LITT OM OPPLEGGET. INF1000 EKSTRATILBUD Stoff fra uke September 2012 Siri Moe Jensen EKSEMPLER

Velkommen til INF2100

Repetisjon. INF gruppe 13

IN1010. Fra Python til Java. En introduksjon til programmeringsspråkenes verden Dag Langmyhr

Tema for siste forelesning:

INF Noen oppgaver til kap. 8

Oppbygningen av en datamaskin Det viktigste i en moderne datamaskin er hovedkortet («motherboard»):

INF1000: Forelesning 4. Mer om arrayer Metoder

MER OM ARRAYER. INF1000: Forelesning 4. Anta at vi ønsker å lagre en liste med navnene på alle INF1000-studentene:

INF-5110 Oppgaver kodegenerering etc. INF-5110, vår 2011

Det viktigste i en moderne datamaskin er hovedkortet («motherboard»):

Oversikt. INF1000 Uke 1 time 2. Repetisjon - Introduksjon. Repetisjon - Program

En oppsummering (og litt som står igjen)

Fra Python til Java, del 2

Oblig 4Hybelhus litt mer tips enn i oppgaven

Forkurs INF1010. Dag 3. Andreas Færøvig Olsen Gard Inge Rosvold Institutt for Informatikk, 15.

INF Noen oppgaver til kap. 8

INF april, 2014 Stein Krogdahl Ifi, UiO. Svar på oppgaver til kap. 8

Kapittel 1 En oversikt over C-språket

Velkommen til INF2100

Kapittel 8: Programutvikling

INF april, 2013 Kap. 8 Noen oppgaver som er meget relevante for Oblig 2

Dagens tema: Mer av det dere trenger til del 1

INF Repetisjon: Hvordan bygge treet og analysere? 8. september Typisk situasjon. De problematiske syntaks-diagrammene

IN2030. Oppgave 1. Løsningsforslag. Uke (Disse filene finnes også i mappen ~inf2100/e/e2/.)

INF april, 2015 Stein Krogdahl Ifi, UiO. Svar på oppgaver til kap. 8. Ble lagt ut 24. april

Oppgaver til kodegenerering etc. INF-5110, 12. mai, 2015

Kort om meg. INF1000 Uke 2. Oversikt. Repetisjon - Introduksjon

Dagens tema: Semantisk sjekking. Maskinkode. Hvordan finne deklarasjoner? Hvordan programmere sjekking av riktig navnebruk?

Den siste dagen. Pensumoversikt Hovedtanker i kurset Selvmodifiserende kode Overflyt Veien videre... Eksamen

Programmeringsspråket C

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

Jentetreff INF1000 Debugging i Java

Repetisjon: Statiske språk uten rekursive metoder (C1 og C2) Dagens tema Kjøresystemer (Ghezzi&Jazayeri 2.6, 2.7)

INF2100. Oppgaver 26. september til 1. oktober 2007

Dagens tema Kjøresystemer (Ghezzi&Jazayeri 2.6, 2.7)

Gjennomgang prøveeksamen oppgave 1, 2, 4, 5, 7

UNIVERSITETET I OSLO

Dagens tema: Kodegenerering. Versjonskontroll. Variabler, spesielt vektorer Funksjoner, kall og parametre Noen siste gode råd.

Transkript:

Dagens tema Prosjektoversikt Dagens tema: Del-0 Del-1 Del-2 Kodegenerering frusc Rusc frask Introduksjon Modulen Code Char- Generator Scanner Syntax Code Enkle variable Noen enkle setninger Error Log Litt mer kompliserte setninger med betingelser (Alt unntatt program, funksjoner og array-er) flog Formålet Formålet Et eksempel Anta at vi har RusC-koden putchar(? ); Formålet med kodegenereringen er å lage Rasko-kode som Rask-maskinen kan utføre: Inndata er trerepresentasjonen av RusC-programmet laget i del 1 Utdata er en fil med Rasko-kode Disse Rask-instruksjonene gjør dette: SET R11,63 CALL 9993 Det finnes mange mulige kodebiter som gjør det samme I kompendiet står angitt ganske nøyaktig hvilke som skal brukes NB! Det er viktigere at koden er riktig enn at den er rask!

Et eksempel Logging int pot2 (int x) { int p2; p2 = 1; while (2*p2 <= x) { p2 = 2*p2; return p2; int x; int main () { int v; v = getint(); x = pot2(v); putint(x); putchar(10); skal oversettes til #! /local/bin/rask 1600000000000035 211000000000000 1600000000009990 0 0 0 0 331000000000003 303000000000004 311000000000005 201000000000001 301000000000006 201000000000002 203010000000000 101000000000006 601030000000001 203010000000000 101000000000005 1101030000000001 1401000000000026 201000000000002 203010000000000 101000000000006 601030000000001 301000000000006 1400000000000012 101000000000006 1400000000000028 103000000000004 131000000000003 1700000000000000 0 0 0 0 331000000000032 303000000000033 1600000000009992 301000000000034 111000000000034 1600000000000007 301000000000031 111000000000031 1600000000009994 211000000000010 1600000000009993 103000000000033 131000000000032 1700000000000000 Genererte instruksjoner Til hjelp under uttesting finnes opsjonen logc som lar kompilatoren fortelle hvilken kode den lager: Code 0: 1600000000000000 CALL 0 0 0 # <Dummy main program> Code 1: 211000000000000 SET 11 0 0 # (0) Code 2: 1600000000009990 CALL 0 0 9990 # exit Code 3: RES 1 # <return address> in pot2 Code 4: RES 1 # <refuge for R3> in pot2 Code 5: RES 1 # int x Code 6: RES 1 # int p2 Code 7: 331000000000003 STORE 31 0 3 # <save return address> Code 8: 303000000000004 STORE 3 0 4 # <save R3> Code 9: 311000000000005 STORE 11 0 5 # <save parameter x> Code 10: 201000000000001 SET 1 0 1 # R1 = 1 Code 11: 301000000000006 STORE 1 0 6 # p2 = Code 12: 201000000000002 SET 1 0 2 # R1 = 2 Code 13: 203010000000000 SET 3 1 0 # <save operand> Code 14: 101000000000006 LOAD 1 0 6 # R1 = p2 Code 15: 601030000000001 MUL 1 3 1 # * Code 16: 203010000000000 SET 3 1 0 # <save operand> Code 17: 101000000000005 LOAD 1 0 5 # R1 = x Code 18: 1101030000000001 LESSEQ 1 3 1 # <= Code 19: 1401000000000000 JUMPEQ 1 0 0 # break while if!= 0 Logging Logging Code 20: 201000000000002 SET 1 0 2 # R1 = 2 Code 21: 203010000000000 SET 3 1 0 # <save operand> Code 22: 101000000000006 LOAD 1 0 6 # R1 = p2 Code 23: 601030000000001 MUL 1 3 1 # * Code 24: 301000000000006 STORE 1 0 6 # p2 = Code 25: 1400000000000012 JUMPEQ 0 0 12 # continue while ---> 19: 1401000000000026 26 # <update break address> Code 26: 101000000000006 LOAD 1 0 6 # R1 = p2 Code 27: 1400000000000000 JUMPEQ 0 0 0 # return ---> 27: 1400000000000028 28 # <update address of return> Code 28: 103000000000004 LOAD 3 0 4 # <restore R3> Code 29: 131000000000003 LOAD 31 0 3 # <restore return address> Code 30: 1700000000000000 RET 0 0 0 # return (from pot2) Code 31: RES 1 # int x Code 32: RES 1 # <return address> in main Code 33: RES 1 # <refuge for R3> in main Code 34: RES 1 # int v Code 35: 331000000000032 STORE 31 0 32 # <save return address> Code 36: 303000000000033 STORE 3 0 33 # <save R3> Code 37: 1600000000009992 CALL 0 0 9992 # getint() Code 38: 301000000000034 STORE 1 0 34 # v = Code 39: 111000000000034 LOAD 11 0 34 # R11 = v Code 40: 1600000000000007 CALL 0 0 7 # pot2() Code 41: 301000000000031 STORE 1 0 31 # x = Code 42: 111000000000031 LOAD 11 0 31 # R11 = x Code 43: 1600000000009994 CALL 0 0 9994 # putint() Code 44: 211000000000010 SET 11 0 10 # R11 = 10 Code 45: 1600000000009993 CALL 0 0 9993 # putchar() Code 46: 103000000000033 LOAD 3 0 33 # <restore R3> Code 47: 131000000000032 LOAD 31 0 32 # <restore return address> Code 48: 1700000000000000 RET 0 0 0 # return (from main) ---> 0: 1600000000000035 35 # <address of main > Å implementere denne opsjonen er en del av den obligatoriske oppgaven

Metoden gencode Hvordan implementere kodegenerering Metoden gencode class WhileUnit extends StatementUnit { ExpressionUnit test; StatmListUnit body; Det beste er å følge samme opplegg som for å skrive ut programkoden i del 1: Kodegenerering Legg en metode gencode inn i alle klasser som representerer en del av RusC-programmet public static WhileUnit parse(decllistunit decls) { public void gencode() { public void printtree() { Modulen Code Modulen Code Modulen Code tar seg av kodegenereringen; all koden lagres først i vektoren mem: package nouioifirusccode; import javaio*; import nouioifiruscerrorerror; import nouioifiruscloglog; import nouioifiruscruscrusc; public class Code { public static final int codesize = 10000; public static int curaddr = 0; private static long mem[]; public static void init() { //-- Må endres i del 2: Modulen Code Metoden finish skriver ut den ferdige Rasko-kodefilen: public static void finish() { String codename = RuscsourceName; if (codename == null) return; if (codenameendswith("rusc")) codename = codenamesubstring(0,codenamelength()-5); codename += "rask"; PrintWriter f = null; try { f = new PrintWriter(codeName); catch (FileNotFoundException e) { Errorerror("Cannot create code file " + codename + "!"); f println("#! /local/bin/rask"); fprintln(); for (int ix = 0; ix < curaddr; ++ix) { fprint(mem[ix]); if (ix%5 == 4) fprintln(); else fprint(" "); fprintln(); fclose();

Modulen Code De enkelte instruksjonene lagres med geninstr: Variable Enkle variable private static int geninstr(string instrname, int instrno, int op1, int op2, int op3, String comment) { if (curaddr >= codesize-10) Errorerror("Memory overflow! More than " + (codesize-10) + " instructions/data words generated!"); LognoteCode(curAddr, instrname, instrno, op1, op2, op3, comment); mem[curaddr++] = instrno*100000000000000l + op1*1000000000000l + op2*10000000000l + op3; return curaddr-1; public static int genset(int op1, int op2, int op3, String comment) { return geninstr("set", 2, op1, op2, op3, comment); Det må settes av plass i minnet til alle enkle 1 variable Viktig! Data og instruksjoner ligger i det samme minnet Datamaskinen Rask vet ikke hva som er hva det må vi som genererer kode, passe på! public static int genret(int op1, int op2, int op3, String comment) { return geninstr("ret", 17, op1, op2, op3, comment); 1 Array-er er tema neste uke Variable Reservasjon av variable løses med en metode i Code: Å oversette setninger Setninger public class Code { public static final int codesize = 10000; public static int curaddr = 0; private static long mem[]; public static int resmem(int nwords, String comment) { if (curaddr+nwords > codesize-10) Errorerror("Memory overflow! More than " + (codesize-10) + " instructions/data words generated!"); LognoteRes(curAddr, nwords, comment); curaddr += nwords; return curaddr-nwords; I kompendiet finner vi kodeskjemaer for alle setningene NB! Disse kodeskjemaene skal brukes, selv om de ikke gir optimal kode! Tilordning v = e ; Beregn e, svar i R 1 STORE R1,R0,Adr( v )

Regsitre Et eksempel Registerbruk For å holde oversikt skal registrene brukes slik: R 0 Alltid 0 (gitt av Rask) R 1 Hovedregister for beregning av uttrykk R 2 Hjelperegister ved vektoraksess R 3 Hjelperegister ved beregning av uttrykk R 11 Parameter 1 ved funksjonskall R 12 Parameter 2 ved funksjonskall R 13 Parameter 3 ved funksjonskall R 14 Parameter 4 ved funksjonskall R 31 Returadresse ved funksjonskall (gitt av Rask) Kodegenereringsmetoden blir da: class AssignmentUnit extends StatementUnit { VariableUnit lhs; /* "Left hand side" */ ExpressionUnit rhs; /* "Right hand side" */ public void gencode() { rhsgencode(); if ( er et array-element ) { else { CodegenStore(1, 0, lhsdeclrefmemaddr, lhsdeclrefname+" = "); Hvordan lager vi kode for et uttrykk som 4 * a - 17? Første operand Det er ganske enkelt å lage kode som legger en variabel i R 1 -registeret: Det er nesten like enkelt for konstanter (tall eller tegn); vi må bare spesialbehandle negative tall (Hvorfor det?) n SET R1,R0, n - n SET SUB R1,R0, n R1,R0,R1 v LOAD R1,R0,Adr( v )

Resten av uttrykket Resten av uttrykket består av 0 eller flere par av operator,konstant/variabel som vi kan ta etter tur Slik oversetter vi +: e 1 + e 2 Beregn e 1, svar i R 1 SET R3,R1,0 Beregn e 2, svar i R 1 ADD R1,R3,R1 Ved at alle operander er innom R 1 blir det enklere å skrive kodegenereringen (men koden blir ikke fullt så rask) class ExpressionUnit extends SyntaxUnit { ExprElementUnit elems = null; public void gencode() { elemsgencode(); ExprElementUnit e = elemsnextelem; while (e!= null) { CodegenSet(3, 1, 0, "<save operand>"); enextelemgencode(); egencode(); e = enextelemnextelem; While-setningen Setninger Noen setninger er litt mer kompliserte å generere kode for While-setningen while ( e ) { S Lw: Beregn e, svar i R 1 Lx: JUMPEQ R1,R0,Lx S JUMPEQ R0,R0,Lw Hopp RusC-koden while (a < 10) { a = a + 1; skal generere denne koden: Code 10: 101000000000005 LOAD 1 0 5 Code 11: 203010000000000 SET 3 1 0 Code 12: 201000000000010 SET 1 0 10 Code 13: 1001030000000001 LESS 1 3 1 Code 14: 1401000000000021 JUMPEQ 1 0 21 Code 15: 101000000000005 LOAD 1 0 5 Code 16: 203010000000000 SET 3 1 0 Code 17: 201000000000001 SET 1 0 1 Code 18: 401030000000001 ADD 1 3 1 Code 19: 301000000000005 STORE 1 0 5 Code 20: 1400000000000010 JUMPEQ 0 0 10

Hopp Hopp Hoppadresser Koden inneholder to hopp: Code 10: 101000000000005 LOAD 1 0 5 Code 11: 203010000000000 SET 3 1 0 Code 12: 201000000000010 SET 1 0 10 Code 13: 1001030000000001 LESS 1 3 1 Code 14: 1401000000000021 JUMPEQ 1 0 21 Code 15: 101000000000005 LOAD 1 0 5 Code 16: 203010000000000 SET 3 1 0 Code 17: 201000000000001 SET 1 0 1 Code 18: 401030000000001 ADD 1 3 1 Code 19: 301000000000005 STORE 1 0 5 Code 20: 1400000000000010 JUMPEQ 0 0 10 Hopp til ukjent adresse Hva med det første hoppet? Hvor skal vi hoppe? Løsningen er: 1 Generér en hoppinstruksjon til adresse 0 2 Når vi en stund senere vet den riktige adressen, kan vi sette inn denne i stedet Hopp til kjent adresse Den siste hoppet er greit nok: Bare husk adressen da man begynte å lage kode for setningen Oppsummering Hva vi har lært Hele koden class WhileUnit extends StatementUnit { ExpressionUnit test; StatmListUnit body; public void gencode() { int startaddr = CodecurAddr; testgencode(); int jumpaddr = CodegenJumpEq(1, 0, 0, "break"); bodygencode(); CodegenJumpEq(0, 0, startaddr, "continue while"); I dag kodegenerering generelt kodegenerering for Neste uke uttrykk tilordning while-setninger CodeupdateInstr(jumpAddr, CodecurAddr, "<update break address>"); Kodegenerering for array-er funksjoner og funksjonskall hovedprogrammet