AppendixA.TheMicroJavaLanguageExtended
ThissectiondescribesextensionoftheMicroJavalanguagethatisusedinthepracticalpartofthe
compilerconstructioncourse.MicroJavaissimilartoJava,butmuchsimpler.
A.1GeneralCharacteristics
- AMicroJavaprogrammeconsistsofasingleclasswithstaticfieldsandstaticmethods.Thereareno
otherexternalclassesbutonlyinnerclassesthatcanbeusedasdatatypes.
- ThemainmethodofaMicroJavaprogramisalwayscalledmain().WhenaMicroJavaprogrammeis
calledthismethodisexecuted.
- Thereare
- Constantsoftypeintandcharbutnostringconstants.
- Variables:allvariablescontainreferences(pointers);variablesinthemainclassarestatic.
- Basictypes:int,char(Ascii).
- Structuredtypes:onedim.ArrayslikeinJava,innerclasseswithfieldsanddynamicmethods.
- Staticmethodsinthemainclass.
- Dynamicmethodsininnerclasses.Therearenoconstructors.
- Everyinnerclasscaninheritfromsomeotherinnerclass,exceptfromitself.MicroJavaisasingle
inheritancelanguage.
- InheritanceinMicroJavahasthesameprinciplesasinJava.Subclassobjectisalsoatypeofits
superclass.Thesubclassreferencecanbeassignedtoanyofitssuperclassreferences.Theactof
convertingasubclassreferenceintoasuperclassreferenceiscalledupcasting.
- Superclassmethodscanbeoverriddeninitssubclass.Becauseofthat,innerclassmethodsbinding
occursatruntime,basedonthetypeofobject. Thisispolymorphism(alsocalleddynamicbindingorlate
bindingorruntimebinding).
- Withinaninstancemethod,thenameofaninstancevariablereferstothecurrentobjectsinstance
variable,assumingthattheinstancevariableisnthiddenbyamethodparameter.Ifitishidden,wecan
accessinstancevariablethroughthis.variableName.Inthebodyofinnermethodsthisrepresents
referencetotheobjectthatinvokedmethod.
- MethodoverloadingisnotsupportedinMicroJava.
- ThereisnoObjectclass,thetopmostclass,theclassfromwhichallotherclassesareimplicitlyderived.
- Thereisnogarbagecollector(allocatedobjectsareonlydeallocatedwhentheprogrammeends).
- Predeclaredstaticmethodsareord,chr,len.
Sampleprogramme(keywordsareunderlined)
classDeliveryShop
finalintSIZE=100;
finalintDEADLINE=7;
finalcharANSWERP=Y;
finalcharANSWERN=N;
10
classTable{
intpos[];
intneg[];
{
voidinitialize()
inti;
{//InitializeTableobject
pos=newint[SIZE];neg=newint[SIZE];
i=0;
while(i<SIZE){
pos[i]=0;neg[i]=0;
i++;
}
}
voidsetRating(inttime)
intx;
{
read(x);
if(x>=0&&x<=SIZE)
if(time>=0&&time<=DEADLINE)pos[x]=pos[x]+5;
elseif(time<2*DEADLINE)neg[x]=3;
elseneg[x]=15;
}
charpermission()
ints,j;
{
s=0;j=0;
while(j<SIZE){s=s+pos[j]+neg[j];j++;}
if(s<0)returnANSWERN;
elsereturnANSWERP;
}
}
}
classBox{
intweight;
intwidth;
intheight;
intdepth;
intunitPrice;
{
voidBox1(intweight,intwidth,intheight,intdepth,intunitPrice)
{
this.weight=weight;
this.width=width;
this.height=height;
this.depth=depth;
11
this.unitPrice=unitPrice;
}
intvolume()
{
returnweight*width*height;
}
inttotalPrice()
{
returnweight*unitPrice+10;
}
}
}
classGiftBoxextendsBox{
intkind;
{
voidGiftBox1(intwe,intwi,inthe,intde,intup,intk)
{
this.Box1(we,wi,he,de,up);
kind=k;
}
inttotalPrice()//overriddenmethod
intad;
{
if(kind==1)ad=5;
elseif(kind==2)ad=10;
elseif(kind==3)ad=15;
returnweight*unitPrice+10+ad;
}
}
}
classCustomer{
intidNum;
Tableval;
}
TabletableConstructor()//staticmethod
Tablet;
{
t=newTable;
returnt;
}
voidmain()
CustomerJohn;
12
Boxb;
GiftBoxgb;
intbill;
inttime;
{
John=newCustomer;
John.idNum=0;
John.val=tableConstructor();
John.val.initialize();
gb=newGiftBox;
gb.GiftBox1(2,500,500,500,40,2);
b=gb;//upcasting
if(John.val.permission()==ANSWERP)bill=b.totalPrice();//polymorphism
else{print(E);
print(R);
print(O);
print(R);}
read(time);
John.val.setRating(time);
}
A.2Syntax
Program
ConstDec1
VarDec1
ClassDec1
MethodDec1
FormPars
Type
Statement
ActPars
Condition
CondTerm
CondFact
Expr
Term
Factor
=classident{ConstDecl|VarDecl|ClassDecl}{{MethodDecl}}.
=finalTypeident=(number|charConst);.
=Typeident[[]]{,ident[[]]};.
=classident[extends]{{VarDecl}[{{MethodDec1}}]}.
=(Type|void)ident([FormPars]){VarDecl}{{Statement}}.
=Typeident[[]]{,Typeident[[]]}.
=ident.
=Designator(=Expr|([ActPars])|++|);
|if(Condition)Statement[elseStatement]
|while(Condition)Statement
|break;
|return[Expr];
|read(Designator);
|print(Expr[,number]);
|{{Statement}}.
=Expr{,Expr}.
=CondTerm{||CondTerm}.
=CondFact{&&CondFact}.
=ExprRelopExpr.
=[]Term{AddopTerm}.
=Factor{MulopFactor}.
=Designator[([ActPars])]
|number
|charConst
|newType[[Expr]]
13
Designator
Relop
Addop
Mulop
|(Expr).
=ident{.ident|[Expr]}.
===|!=|>|>=|<|<=.
=+|.
=*|/|%.
LexicalStructure
Keywords:
Tokenclasses:
Operators:
Comments:
break,class,else,extends,final,if,new,print,read,return,void,while
ident=letter{letter|digit|_}.
number=digit{digit}.
charConst=printableChar.
+,,*,/,%,==,!=,>,>=,<,<=,&&,||,=,++,,;,comma,.(,),[,],{,}
//totheendoftheline
A.3Semantics
Alltermsinthisdocumentthathaveadefinitionareunderlinedtoemphasizetheirspecial
meaning.Thedefinitionsofthesetermsaregivenhere.
Referencetype
Arraysandclassesarecalledreferencetypes.
Typeofaconstant
Thetypeofanintegerconstant(e.g.17)isint.
Thetypeofacharacterconstant(e.g.x)ischar.
Sametype
Twotypesarethesame
iftheyaredenotedbythesametypename,or
ifbothtypesarearraysandtheirelementtypesarethesame.
Typecompatibility
Twotypesarecompatible
iftheyarethesame,or
ifoneofthemisareferencetypeandtheotheristhetypeofnull.
Assignmentcompatibility
Atypesrcisassignmentcompatiblewithatypedst
ifsrcanddstarethesame,or
ifdstisareferencetypeandsrcisthetypeofnull,or
ifdstisasuperclassreferenceandsrcisasubclassreference.
Predeclarednames
int
thetypeofallintegervalues
char
thetypeofallcharactervalues
null
thenullvalueofaclassorarrayvariable,meaningpointingtonovalue
14
eol
chr
ord
len
endoflinecharacter(correspondsto\n);print(eol)skipstothenextoutputline.
standardmethod;chr(i)convertstheintexpressioniintoacharvalue
standardmethod;ord(ch)convertsthecharvaluechintoanintvalue
standardmethod;len(a)returnsthenumberofelementsofthearraya
Scope
Ascopeisthetextualrangeofamethodoraclass.Itextendsfromthepointafterthedeclaring
methodorclassnametotheclosingcurlybracketofthemethodorclassdeclaration.Ascope
excludesotherscopesthatarenestedwithinit.Weassumethatthereisan(artificial)outermost
scope,towhichthemainclassislocalandwhichcontainsallpredeclarednames.
The declaration of a name in an inner scope S hides the declarations of the same name in
outerscopes.
Note
Indirect recursion is not allowed, sinceevery namemust be declared before it is used. This
wouldnotbepossibleifindirectrecursionwereallowed.
A predeclared name (e.g. int or char) can be redeclared in an inner scope (but this is not
recommended).
Namethisisnotpredeclared,oritiskeyword,butitisnotrecommendedtouseit,exceptin
dynamicmethodsasitisexplained.
A.4ContextConditions
Generalcontextconditions
Everynamemustbedeclaredbeforeitisused.
Anamemustnotbedeclaredtwiceinthesamescope.
Aprogrammemustcontainamethodnamedmain.Itmustbedeclaredwithavoidfunction
typeandmustnothaveparameters.
Contextconditionsforstandardmethods
chr(e) emustbeanexpressionoftypeint.
ord(c) cmustbeoftypechar
len(a) amustbeanarray
ContextconditionsforMicroJavaproductions
Program=classident{ConstDecl|VarDecl|ClassDecl}{{MethodDecl}}.
ConstDec1=finalTypeident=(number|charConst);.
ThetypeofnumberorcharConstmustbethesameasthetypeofType.
VarDec1=Typeident[[]]{,ident[[]]};.
ClassDec1=classident[extends]{{VarDecl}[{{MethodDec1}}]}.
MethodDec1=(Type|void)ident([FormPars]){VarDecl}{{Statement}}.
Ifamethodisafunctionitmustbeleftviaareturnstatement(thisischeckedatruntime).
FormPars=Typeident[[]]{,Typeident[[]]}.
Type=ident.
identmustdenoteatype.
Statement=Designator=Expr;.
15
Designatormustdenoteavariable,anarray element or an object field.
ThetypeofExprmustbeassignmentcompatiblewiththetypeofDesignator.
Statement=Designator(++|);.
Designatormustdenoteavariable,anarrayelementoranobjectfield.
Designatormustbeoftypeint.
Statement=Designator([ActPars]);.
Designatormustdenoteamethod.
Statement=break.
Thebreakstatementmustbecontainedinawhilestatement.
Statement=read(Designator);.
Designatormustdenoteavariable,anarrayelementoranobjectfield.
Designatormustbeoftypeintorchar.
Statement=print(Expr[,number]);.
Exprmustbeoftypeintorchar.
Statement=return[Expr].
ThetypeofExprmustbeassignmentcompatiblewiththefunctiontypeofthecurrent
method.
IfExprismissingthecurrentmethodmustbedeclaredasvoid.
Statement=if(Condition)Statement[elseStatement]
|while(Condition)Statement
|{{Statement}}
|;.
ActPars=Expr{,Expr}.
Thenumbersofactualandformalparametersmustmatch.
Thetypeofeveryactualparametermustbeassignmentcompatiblewiththetypeofevery
formalparameteratcorrespondingpositions.
Condition=CondTerm{||CondTerm}.
CondTerm=CondFact{&&CondFact}.
CondFact=ExprRelopExpr.
Thetypesofbothexpressionsmustbecompatible.
Classesandarrayscanonlybecheckedforequalityorinequality.
Expr=Term.
Expr=Term.
Termmustbeoftypeint.
Expr=ExprAddopTerm.
ExprandTermmustbeoftypeint.
Term=Factor.
Term=TermMulopFactor.
TermandFactormustbeoftypeint.
Factor=Designator|number|charConst|(Expr).
16
Factor=Designator([ActPars]).
Designatormustdenoteamethod.
Factor=newType.
Typemustdenoteaclass.
Factor=newType[Expr].
ThetypeofExprmustbeint.
Designator=Designator.ident.
ThetypeofDesignatormustbeaclass.
IdentmustbeafieldormethodofDesignator.
Designator=Designator[Expr].
ThetypeofDesignatormustbeanarray.
ThetypeofExprmustbeint.
Relop===|!=|>|>=|<|<=.
Addop=+|.
Mulop=*|/|%.
A.5ImplementationRestrictions
Theremustnotbemorethan256localvariables.
Theremustnotbemorethan65536globalvariables.
Aclassmustnothavemorethan65536classmembers(fieldsandmethods).
Thecodeoftheprogrammustnotbelongerthan8KBytes.
17
AppendixB.TheMicroJavaVM
This section describes the architecture of the MicroJava Virtual Machine that is used in the
practicalpartofthiscompilerconstructioncourse.TheMicroJavaVMissimilartotheJavaVM
but has less instruction. Some instructions were also simplified. Where the Java VM uses
operandnamesfromtheconstantpoolthatareresolvedbytheloader,theMicroJavaVMuses
fixedoperandaddresses.Javainstructionsencodethetypesoftheiroperandssothataverifier
canchecktheconsistencyofanobjectfile.MicroJavainstructionsdonotencodeoperandtypes.
B.1MemoryLayout
ThememoryareasoftheMicroJavaVMareasfollows.
Code
StaticData
Heap
ProcStack
(bytearray)(wordarray)(wordarray)(wordarray)
Code
StaticData
Heap
ProcStack
Thisareacontainsthecodeofthemethods.Theregisterpccontainstheindex
ofthecurrentlyexecutedinstruction.mainpccontainsthestartaddressofthe
methodmain().
Thisareaholdsthe(staticorglobal)dataofthemainprogram(i.e.oftheclass
tobecompiled).Itisanarrayofvariables.Everyvariableoccupiesoneword
(32 bits). The addresses of the variables are indexes into the array. This area
alsoholdsmethodtables(virtualtables)forallinnerclasses.
This area holds the dynamically allocated objects and arrays. The blocks are
allocatedconsecutively.freepointstothebeginningofthestillunusedareaof
the heap. Dynamically allocated memory is only returned at the end of the
program.Thereisnogarbagecollector.Allobjectfieldsoccupyasingleword
(32bits).Firstfield,onposition0,ofeveryobjectcontainsthestartaddressof
themethodtableforthatobjectinStaticData.Arraysofcharelementsarebyte
arrays.Theirlengthisamultipleof4.Pointersarebyteoffsetsintotheheap.
Arrayobjectsstartwithaninvisibleword,containingthearraylength.
InthisareatheVMmaintainstheactivationframesoftheinvokedmethods.
Every frame consists of an array of local variables, each occupying a single
word (32 bits). Their addresses are indexes into the array. ra is the return
address of the method, dl is the dynamic link (a pointer to the frame of the
caller).Anewlyallocatedframeisinitializedwithallzeroes.
18
ExprStack
This area is used to store the operands of the instructions. After every
MicroJava statement ExprStack is empty. Method parameters are passed on
theexpressionstackandareremovedbytheEnterinstructionoftheinvoked
method. The expression stack is also used to pass the return value of the
methodbacktothecaller.
Alldata(globalvariables,localvariables,heapvariables)areinitializedwithanullvalue(0for
int,chr(0)forchar,nullforreferences).
B.2InstructionSet
...,val,val
...,val
meansthatthisinstructionremovestwowordsfromExprStackandpushesanewwordontoit.
Theoperandsoftheinstructionshavethefollowingmeaning:
babyte
sashortint(16bits)
waword(32bits)
Variablesoftypechararestoredinthelowestbyteofawordandaremanipulatedwithword
instructions (e.g. load, store). Array elements of type char are stored in a byte array and are
loadedandstoredwithspecialinstructions.
Loadingandstoringoflocalvariables
opcode instr.
opds
ExprStack
meaning
load
1
b
...
Load
...,val
push(local[b]);
load_n
2..5
...
Load(n=0..3)
...,val
push(local[n]);
store
6
b
...,val
Store
...
local[b]=pop();
store_n
7..10
...,val
Store(n=0..3)
...
local[n]=pop();
Loadingandstoringofglobalvariables
getstatic s
11
...
Loadstaticvariable
...,val
push(data[s]);
putstatic s
12
...,val
Storestaticvariable
...
data[s]=pop();
19
Loadingandstoringofobjectfields
getfield
13
s
...,adr
...,val
putfield
14
s
...,adr,val
...
Loadobjectfield
adr=pop()/4;push(heap[adr+s]);
Storeobjectfield
val=pop();adr=pop()/4;
heap[adr+s]=val;
Loadingofconstants
15..20 const_n
21
const_m1
22
const
...
...,val
...
...,1
...
...,val
Loadconstant(n=0..5)
push(n)
Loadminusone
push(1)
Loadconstant
push(w)
Arithmetic
23
add
24
sub
25
mul
26
div
27
rem
28
neg
29
shl
30
shr
31
inc
...,val1,val2
...,val1+val2
...,val1,val2
...,val1val2
...,val1,val2
...,val1*val2
...,val1,val2
...,val1/val2
...,val1,val2
...,val1%val2
...,val
...,val
...,val
...,val1
...,val
...,val1
b1,b2 ...
...
Add
push(pop()+pop());
Subtract
push(pop()+pop());
Multiply
push(pop()*pop());
Divide
x=pop();push(pop()/x);
Remainder
x=pop();push(pop()%x);
Negate
push(pop());
Shiftleft
x=pop();push(pop()<<x);
Shiftright(arithmetically)
x=pop();push(pop()>>x);
Incrementvariable
local[b1]=local[b1]+b2;
20
Objectcreation
new
32
33
newarray
...
...,adr
...,n
...,adr
Arrayaccess
aload
34
...,adr,index
...,val
35
astore
...,adr,index,val
...
36
baload
...,adr,index
...,val
37
bastore
...,adr,index,val
...
38
arraylength
...,adr
...,len
Stackmanipulation
pop
39
40
dup
41
dup2
...,val
...
...,val
...,val,val
...,v1,v2
...,v1,v2,v1,v2
Newobject
allocateareaofsbytes;
initializeareatoall0;
push(adr(area));
e.g.ifclasshastwofields,thennew8,
becauseeveryfieldoccupiesoneword
Newarray
nisarraylength
n=pop();
if(b==0)
alloc.arraywithnelemsofbytesize;
elseif(b==1)
alloc.arraywithnelemsofword
size;
initializearraytoall0;
push(adr(array));
Loadarrayelement(+indexcheck)
i=pop();adr=pop()/4+1;
push(heap[adr+i]);
Storearrayelement(+indexcheck)
val=pop();i=pop();adr=pop()/4+1;
heap[adr+i]=val
Loadbytearrayelement(+indexcheck)
i=pop();adr=pop()/4+1;
x=heap[adr+i/4];
push(bytei%4ofx);
Storebytearrayelement(+indexcheck)
val=pop();i=pop();adr=pop()/4+1;
x=heap[adr+i/4];
setbytei%4inx;
heap[adr+i/4]=x;
Getarraylength
adr=pop();
push(heap[adr]);
Removetopmoststackelement
dummy=pop();
Duplicatetopmoststackelement
x=pop();push(x);push(x);
Duplicatetoptwostackelements
y=pop();x=pop();
push(x);push(y);push(x);push(y);
21
Jumps
Thejumpdistanceisrelativetothestartofthejumpinstruction.
jmp
42
s
Jumpunconditionally
pc=pc+s;
43..48 j<cond>
s
...,val1,val2
Jumpconditionally(eq,ne,lt,le,gt,ge)
...
y=pop();x=pop();
if(xcondy)pc=pc+s;
Methodcall(PUSHandPOPworkontheprocedurestack)
call
49
s
Callstaticmethod
PUSH(pc+3);pc=pc+s;
invokevirtual w1,w2,w3,...,wn,wn+1 ...,adr Calldynamicmethod
58
...
methodnamehasncharacters;
thesecharactersarestoredinthe
instructionitself,inwordsw1..wn;
wordwn+1isequal1,andmarksthe
endoftheinstruction;instruction
firstremovesadrfromexpression
stack;adrisaddressinthestatic
datawherestartsmethodtablefor
objectthatinvokedmethod;ifname
ininstructionmatcheswithoneof
thenamesintableinstruction
providesjumptomethodbody;
return
50
Return
pc=POP();
enter
51
b1,b2
Entermethod
psize=b1;lsize=b2;//inwords
PUSH(fp);fp=sp;sp=sp+lsize;
initializeframeto0;
for(i=psize1;i>=0;i)local[i]=pop();
exit
52
Exitmethod
sp=fp;fp=POP();
Input/Output
read
53
...,val
Read
...
readInt(x);push(x);
//readsfromstandardinput
print
54
...,val,width
Print
...
width=pop();writeInt(pop(),width);
//writestostandardoutput
bread
55
...
Readbyte
...,val
readChar(ch);push(ch);
bprint
56
...,val,width
Printbyte
...
width=pop();writeChar(pop(),width)
22
Other
57
trap
Generateruntimeerror
printerrormessagedependingonb;
stopexecution;
B.3ObjectFileFormat
2bytes:MJ
4bytes:codesizeinbytes
4bytes:numberofwordsfortheglobaldata
4bytes:mainPC:theaddressofmain()relativetothebeginningofthecodearea
nbytes:thecodearea(n=codesizespecifiednbytes:thecodearea(n=codesizespecified
B.4RunTimeErrors
1Missingreturnstatementinfunction.