1- use std:: collections:: HashMap ;
2- use crate :: ir:: * ;
1+ use crate :: mir:: * ;
32
43// TODO: REFACTOR THIS 100%
54
6- pub struct KosEmitter < ' a > {
5+ pub struct KosEmitter {
76 indent : usize ,
87 out : String ,
9- temp_exprs : HashMap < TempId , & ' a Instr >
108}
11- impl < ' e > KosEmitter < ' e > {
12- pub fn emit_program ( prog : & ProgramIR ) -> String {
9+ impl KosEmitter {
10+ pub fn emit_program ( prog : & Body ) -> String {
1311 let mut emitter = KosEmitter {
1412 indent : 0 ,
1513 out : String :: new ( ) ,
16- temp_exprs : HashMap :: new ( ) ,
1714 } ;
1815
19- for ( fidx, func) in prog. functions . iter ( ) . enumerate ( ) {
20- emitter. emit_function ( & format ! ( "f{}" , fidx) , func) ;
21- }
16+ emitter. emit_function ( "main" , prog) ;
2217
23- if !prog. functions . is_empty ( ) {
24- emitter. emitln ( "f0()." ) ;
25- }
18+
19+ emitter. emit ( "main().\n " ) ;
2620
2721 emitter. out
2822 }
2923
30- fn emit_local ( & mut self , id : LocalId ) {
31- self . out . push_str ( & format ! ( "l{}" , id. index( ) ) )
32- }
33-
3424 fn emit_const ( & mut self , c : & Const ) {
3525 match c {
3626 Const :: Number ( n) => self . out . push_str ( & n. to_string ( ) ) ,
3727 Const :: Unit => self . out . push_str ( "0" ) ,
3828 }
3929 }
4030
41- fn emit_value ( & mut self , v : & Value ) {
42- match v {
43- Value :: Const ( c) => self . emit_const ( c) ,
44- Value :: Temp ( id) => {
45- let instr = * self . temp_exprs . get ( id) . unwrap ( ) ;
46- self . emit_instr ( instr) ;
47- } ,
31+ fn emit_operand ( & mut self , op : & Operand ) {
32+ match op {
33+ Operand :: Const ( c) => self . emit_const ( c) ,
34+ Operand :: Move ( place) | Operand :: Copy ( place) => self . emit_place ( place) ,
4835 }
4936 }
5037
5138 fn emit_place ( & mut self , p : & Place ) {
52- match p {
53- Place :: Local ( id) => self . emit_local ( * id) ,
54- }
39+ self . emit ( & format ! ( "l{}" , p. local. index( ) ) ) ;
5540 }
5641
57- fn emit_instr ( & mut self , instr : & ' e Instr ) {
58- match instr {
59- Instr :: LoadConst { dst, value } => {
60- if self . temp_exprs . insert ( * dst, instr) . is_some ( ) {
61- self . emit_const ( value) ;
62- // self.temp_exprs.remove(dst);
63- }
42+ fn emit_rval ( & mut self , rval : & RValue ) {
43+ match rval {
44+ RValue :: Use ( op) => self . emit_operand ( op) ,
45+
46+ RValue :: Binary ( op, lhs, rhs) => {
47+ let op_str = match op {
48+ BinaryOp :: Add => " + " ,
49+ BinaryOp :: Sub => " - " ,
50+ BinaryOp :: Mul => " * " ,
51+ BinaryOp :: Div => " / " ,
52+ } ;
53+ self . emit_operand ( lhs) ;
54+ self . emit ( op_str) ;
55+ self . emit_operand ( rhs) ;
6456 }
65- Instr :: Binary { dst, op, lhs, rhs } => {
66- if self . temp_exprs . insert ( * dst, instr) . is_some ( ) {
67- let op_str = match op {
68- BinaryOp :: Add => "+" ,
69- BinaryOp :: Sub => "-" ,
70- BinaryOp :: Mul => "*" ,
71- BinaryOp :: Div => "/" ,
72- } ;
73- self . emit_value ( lhs) ;
74- self . emit ( " " ) ;
75- self . emit ( op_str) ;
76- self . emit ( " " ) ;
77- self . emit_value ( rhs) ;
78- // self.temp_exprs.remove(dst);
79- }
57+
58+ RValue :: Poison => {
59+ todo ! ( "TOOD: Some good way to handle this." )
8060 }
81- Instr :: Store { place, value } => {
61+ }
62+ }
63+
64+ fn emit_instr ( & mut self , instr : & Instr ) {
65+ match instr {
66+ Instr :: Assign ( place, rval) => {
8267 self . emit_indent ( ) ;
8368 self . emit ( "set " ) ;
8469 self . emit_place ( place) ;
8570 self . emit ( " to " ) ;
86- self . emit_value ( value) ;
87- self . emitln ( "." ) ;
88- }
89- Instr :: Load { dst, place} => {
90- if self . temp_exprs . insert ( * dst, instr) . is_some ( ) {
91- self . emit_place ( place) ;
92- // self.temp_exprs.remove(dst);
93- }
94- }
95- Instr :: Poision { .. } => {
96- todo ! ( "TOOD: Some good way to handle this." )
71+ self . emit_rval ( rval) ;
72+ self . emit ( ".\n " ) ;
9773 }
9874 }
9975 }
@@ -102,51 +78,51 @@ impl<'e> KosEmitter<'e> {
10278 self . emit_indent ( ) ;
10379 match term {
10480 Terminator :: Goto ( _) => todo ! ( "Some good way to handle this too." ) ,
105- Terminator :: Return ( v ) => {
81+ Terminator :: Return ( op ) => {
10682 self . emit ( "return " ) ;
107- self . emit_value ( v ) ;
108- self . emitln ( "." ) ;
83+ self . emit_operand ( op ) ;
84+ self . emit ( ".\n " ) ;
10985 }
11086 Terminator :: Unreachable => {
111- self . emitln ( "print \" UNREACHABLE has been reached\" ." ) ;
112- self . emitln ( "shutdown. ") ;
87+ self . emit ( "print \" UNREACHABLE has been reached\" .\n " ) ;
88+ self . emit ( "wait until false. \n ") ;
11389 }
11490 }
11591 }
11692
117- fn emit_block ( & mut self , id : usize , block : & ' e Block ) {
93+ fn emit_block ( & mut self , id : usize , block : & Block ) {
11894 self . emit_indent ( ) ;
11995 self . emit ( "// block" ) ;
12096 self . emit ( & id. to_string ( ) ) ;
121- self . emitln ( ":" ) ;
97+ self . emit ( ":\n " ) ;
12298
12399 for instr in & block. instrs {
124100 self . emit_instr ( instr) ;
125101 }
126102 self . emit_terminator ( & block. terminator ) ;
127103 }
128104
129- fn emit_function ( & mut self , name : & str , func : & ' e FunctionIR ) {
105+ fn emit_function ( & mut self , name : & str , func : & Body ) {
130106 self . emit_indent ( ) ;
131107 self . emit ( "function " ) ;
132108 self . emit ( name) ;
133- self . emitln ( " {" ) ;
109+ self . emit ( " {\n " ) ;
134110
135111 self . increase_indent ( ) ;
136112
137113 for ( lidx, _) in func. locals . iter ( ) . enumerate ( ) {
138114 self . emit_indent ( ) ;
139115 self . emit ( "local l" ) ;
140116 self . emit ( & lidx. to_string ( ) ) ;
141- self . emitln ( " is 0." ) ;
117+ self . emit ( " is 0.\n " ) ;
142118 }
143119
144120 for ( bidx, block) in func. blocks . iter ( ) . enumerate ( ) {
145121 self . emit_block ( bidx, block) ;
146122 }
147123
148124 self . decrease_indent ( ) ;
149- self . emitln ( "}\n " ) ;
125+ self . emit ( "}\n \n " ) ;
150126 }
151127
152128 fn emit_indent ( & mut self ) {
@@ -157,11 +133,6 @@ impl<'e> KosEmitter<'e> {
157133 self . out . push_str ( str) ;
158134 }
159135
160- fn emitln ( & mut self , str : & str ) {
161- self . out . push_str ( str) ;
162- self . out . push ( '\n' ) ;
163- }
164-
165136 fn increase_indent ( & mut self ) {
166137 self . indent += 4 ;
167138 }
0 commit comments