package Ġedu . cit adel . c vm ĊĊ Ċ import Ġedu . cit adel . compiler . util . Byte Util Ċ import Ġedu . cit adel . compiler . util . format Ċ Ċ import Ġjava . io .* Ċ import Ġjava . nio . charset . StandardCharsets Ċ import Ġkotlin . system . exit Process ĊĊ Ċ private Ġconst Ġval ĠSU FF IX Ġ= Ġ". obj " Ċ private Ġconst Ġval ĠFIELD _ WIDTH Ġ= Ġ 4 ĊĊ Ċ /** Ċ Ġ* ĠTrans lates ĠC VM Ġmachine Ġcode Ġinto ĠC VM Ġassembly Ġlanguage . Ċ Ġ*/ Ċ fun Ġmain ( args Ġ: ĠArray < String >) ĊĠ Ġ{ ĊĠĠĠ Ġif Ġ( args . isEmpty () Ġ|| Ġargs . size Ġ> Ġ 1 ) ĊĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ ĠSystem . err . println (" Usage : Ġjava Ġedu . cit adel . c vm . Dis assembler Ġfilename ") ĊĠĠĠĠĠĠĠ Ġexit Process ( 0 ) ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġval ĠfileName Ġ= Ġargs [ 0 ] ĊĠĠĠ Ġval Ġfile ĠĠĠĠ Ġ= ĠFileInputStream ( fileName ) ĊĊĠĠĠ Ġ// Ġget Ġobject Ġcode Ġfile Ġname Ġminus Ġthe Ġsuffix ĊĠĠĠ Ġval Ġsuffix Index Ġ= ĠfileName . lastIndexOf ( SUFFIX ) ĊĠĠĠ Ġval Ġbase Name ĠĠĠ Ġ= ĠfileName . substring ( 0 , Ġsuffix Index ) ĊĊĠĠĠ Ġval Ġoutput FileName Ġ= Ġ"$ base Name . dis . txt " ĊĠĠĠ Ġval Ġfile Writer Ġ= ĠFile Writer ( output FileName , ĠStandard Charsets . UTF _ 8 ) ĊĠĠĠ Ġval Ġout Ġ= ĠPrintWriter ( Buffered Writer ( file Writer ), Ġtrue ) ĊĊĠĠĠ Ġprintln (" dis as semb ling Ġ$ fileName Ġto Ġ$ output FileName ") ĊĊĠĠĠ Ġvar Ġin Byte Ġ: ĠInt ĊĠĠĠ Ġvar Ġop Code Addr Ġ= Ġ 0 ĊĠĠĠ Ġvar Ġstr Length Ġ: ĠInt ĊĊĠĠĠ Ġvar Ġc Ġ: ĠChar ĊĊĠĠĠ Ġin Byte Ġ= Ġfile . read () ĊĠĠĠ Ġwhile Ġ( in Byte Ġ!= Ġ- 1 ) ĊĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( val Ġop Code Ġ= Ġin Byte . to Byte ()) ĊĠĠĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġop codes Ġwith Ġzero Ġoperands ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . ADD , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . CMP , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . DEC , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . DIV , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . GET CH , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . GET INT , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . HAL T , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . LOAD B , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . LOAD 2 B , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . LOAD W , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . L DC B 0 , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . L DC B 1 , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . L DC INT 0 , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . L DC INT 1 , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . INC , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . MOD , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . MUL , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . NEG , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . NOT , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . PUT BYTE , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . PUT CH , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . PUT INT , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . PUT EOL , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . PUT STR , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . STORE B , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . STORE 2 B , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . STORE W , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . SUB ĠĠ Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout . println ("${ format ( op Code Addr , ĠFIELD _ WIDTH )} : Ġ Ġ${ OpCode . toString ( op Code )} ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġop Code Addr Ġ= Ġop Code Addr Ġ+ Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġop codes Ġwith Ġone Ġbyte Ġoperand ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . SH L , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . SH R , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . L DC B Ġ Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout . print ("${ format ( op Code Addr , ĠFIELD _ WIDTH )} : Ġ Ġ${ OpCode . toString ( op Code )} ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout . println (" Ġ" Ġ+ Ġread Byte ( file )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġop Code Addr Ġ= Ġop Code Addr Ġ+ Ġ 2 Ġ Ġ// Ġone Ġbyte Ġfor Ġopcode Ġand Ġone Ġbyte Ġfor Ġshift Ġamount ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġop codes Ġwith Ġone Ġint Ġoperand ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . ALLOC , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . BR , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . BG , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . B GE , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . BL , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . BLE , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . BN Z , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . BZ , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . CALL , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . LOAD , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . L DC INT , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . L DL ADDR , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . LD G ADDR , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . PROC , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . PROGRAM , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . RET , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . STORE Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout . print ("${ format ( op Code Addr , ĠFIELD _ WIDTH )} : Ġ Ġ${ OpCode . toString ( op Code )} ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout . println (" Ġ" Ġ+ Ġread Int ( file )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġop Code Addr Ġ= Ġop Code Addr Ġ+ Ġ 1 Ġ+ ĠConstants . BYTES _ PER _ INTEGER ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġspecial Ġcase : Ġ ĠL DC CH ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . L DC CH Ġ Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout . print ("${ format ( op Code Addr , ĠFIELD _ WIDTH )} : Ġ Ġ${ OpCode . toString ( op Code )} ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout . print (" Ġ\' ") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġc Ġ= Ġread Char ( file ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( c Ġ== Ġ'\ b ' Ġ|| Ġc Ġ== Ġ'\ t ' Ġ|| Ġc Ġ== Ġ'\ n ' Ġ|| Ġc Ġ== Ġ'\ r ' Ġ|| Ġc Ġ== Ġ'\" ' Ġ|| Ġc Ġ== Ġ'\'' Ġ|| Ġc Ġ== Ġ'\\ ') ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout . print ( getUn escaped Char ( c )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout . print ( c ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout . println ("\ '") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġop Code Addr Ġ= Ġop Code Addr Ġ+ Ġ 1 Ġ+ ĠConstants . BYTES _ PER _ CHAR ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġspecial Ġcase : Ġ ĠL DC STR ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOp Code . L DC STR Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout . print ("${ format ( op Code Addr , ĠFIELD _ WIDTH )} : Ġ Ġ${ OpCode . toString ( op Code )} ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġnow Ġprint Ġthe Ġstring ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout . print (" Ġ Ġ\" ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstr Length Ġ= Ġread Int ( file ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 Ġuntil Ġstr Length ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġc Ġ= Ġread Char ( file ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( c Ġ== Ġ'\ b ' Ġ|| Ġc Ġ== Ġ'\ t ' Ġ|| Ġc Ġ== Ġ'\ n ' Ġ|| Ġc Ġ== Ġ'\ r ' Ġ|| Ġc Ġ== Ġ'\" ' Ġ|| Ġc Ġ== Ġ'\'' Ġ|| Ġc Ġ== Ġ'\\ ') ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout . print ( getUn escaped Char ( c )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout . print ( c ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout . println ("\" ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġop Code Addr Ġ= Ġ( op Code Addr Ġ+ Ġ 1 Ġ+ ĠConstants . BYTES _ PER _ INTEGER ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ+ Ġstr Length * Constants . BYTES _ PER _ CHAR ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠSystem . err . println (" *** ĠUnknown Ġop Code Ġin Ġfile Ġ$ fileName Ġ*** ") ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġin Byte Ġ= Ġfile . read () ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġout . close () ĊĠ Ġ} ĊĊ Ċ /** Ċ Ġ* ĠReads Ġan Ġinteger Ġargument Ġfrom Ġthe Ġstream . Ċ Ġ*/ Ċ private Ġfun Ġread Int ( i Stream Ġ: ĠInputStream ) Ġ: ĠInt ĊĠ Ġ{ ĊĠĠĠ Ġval Ġb 0 Ġ= Ġi Stream . read (). to Byte () ĊĠĠĠ Ġval Ġb 1 Ġ= Ġi Stream . read (). to Byte () ĊĠĠĠ Ġval Ġb 2 Ġ= Ġi Stream . read (). to Byte () ĊĠĠĠ Ġval Ġb 3 Ġ= Ġi Stream . read (). to Byte () ĊĊĠĠĠ Ġreturn ĠByte Util . bytes ToInt ( b 0 , Ġb 1 , Ġb 2 , Ġb 3 ) ĊĠ Ġ} ĊĊ Ċ /** Ċ Ġ* ĠReads Ġa Ġcurrent Char Ġargument Ġfrom Ġthe Ġstream . Ċ Ġ*/ Ċ private Ġfun Ġread Char ( i Stream Ġ: ĠInputStream ) Ġ: ĠChar ĊĠ Ġ{ ĊĠĠĠ Ġval Ġb 0 Ġ= Ġi Stream . read (). to Byte () ĊĠĠĠ Ġval Ġb 1 Ġ= Ġi Stream . read (). to Byte () ĊĊĠĠĠ Ġreturn ĠByte Util . bytes To Char ( b 0 , Ġb 1 ) ĊĠ Ġ} ĊĊ Ċ /** Ċ Ġ* ĠReads Ġa Ġbyte Ġargument Ġfrom Ġthe Ġstream . Ċ Ġ*/ Ċ private Ġfun Ġread Byte ( i Stream Ġ: ĠInputStream ) Ġ: ĠByte ĊĠ Ġ{ ĊĠĠĠ Ġreturn Ġi Stream . read (). to Byte () ĊĠ Ġ} ĊĊ Ċ /** Ċ Ġ* ĠUn es cap es Ġcharacters . Ġ ĠFor Ġexample , Ġif Ġthe Ġparameter Ġc Ġis Ġa Ġtab , Ċ Ġ* Ġthis Ġmethod Ġwill Ġreturn Ġ"\\ t " Ċ Ġ* Ċ Ġ* Ġ@ return Ġthe Ġstring Ġfor Ġan Ġescaped Ġcharacter . Ċ Ġ*/ Ċ private Ġfun Ġget Un escaped Char ( c Ġ: ĠChar ) Ġ: ĠString ĊĠ Ġ{ ĊĠĠĠ Ġwhen Ġ( c ) ĊĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠ Ġ'\ b ' Ġ-> Ġreturn Ġ"\\ b " ĠĠĠ Ġ// Ġback space ĊĠĠĠĠĠĠĠ Ġ'\ t ' Ġ-> Ġreturn Ġ"\\ t " ĠĠĠ Ġ// Ġtab ĊĠĠĠĠĠĠĠ Ġ'\ n ' Ġ-> Ġreturn Ġ"\\ n " ĠĠĠ Ġ// Ġline feed Ġ( a . k . a . Ġnewline ) ĊĠĠĠĠĠĠĠ Ġ'\ r ' Ġ-> Ġreturn Ġ"\\ r " ĠĠĠ Ġ// Ġcar riage Ġreturn ĊĠĠĠĠĠĠĠ Ġ'\" ' Ġ-> Ġreturn Ġ"\\ \"" ĠĠ Ġ// Ġdouble Ġquote ĊĠĠĠĠĠĠĠ Ġ'\'' Ġ-> Ġreturn Ġ"\\ \' " ĠĠ Ġ// Ġsingle Ġquote ĊĠĠĠĠĠĠĠ Ġ'\\ ' Ġ-> Ġreturn Ġ"\\ \ \" ĠĠ Ġ// Ġback slash ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġreturn Ġc . toString () ĊĠĠĠĠĠ Ġ} ĊĠ Ġ} ĊĊ Ċ private Ġfun Ġprint Usage Message And Exit () ĊĠ Ġ{ ĊĠĠĠ Ġprintln (" Usage : Ġjava Ġedu . cit adel . c vm . Dis assembler Ġfilename ") ĊĠĠĠ Ġprintln () ĊĠĠĠ Ġexit Process ( 0 ) ĊĠ Ġ} Ċ