@@ -5,7 +5,7 @@ use crate::ast::{BinaryOperation, Expression, Statement, Value};
55#[ derive( Debug ) ]
66pub struct FunctionBytecode {
77 pub params : Vec < String > ,
8- pub instructions : Vec < Instruction >
8+ pub instructions : Vec < Instruction > ,
99}
1010
1111pub struct LoopContext {
@@ -17,7 +17,7 @@ pub struct LoopContext {
1717#[ derive( Debug ) ]
1818pub struct Program {
1919 pub main : Vec < Instruction > ,
20- pub functions : HashMap < String , FunctionBytecode >
20+ pub functions : HashMap < String , FunctionBytecode > ,
2121}
2222
2323#[ derive( Debug , Clone ) ]
@@ -45,13 +45,15 @@ pub enum Instruction {
4545 CallFunction ( String , usize ) ,
4646 CreateArray ( usize ) ,
4747 LoadIndex ,
48- StoreIndex
48+ StoreIndex ,
4949}
5050
5151fn compile_expr ( instructions : & mut Vec < Instruction > , expr : & Expression ) {
5252 match expr {
5353 Expression :: Number ( x) => instructions. push ( Instruction :: LoadConst ( Value :: Number ( * x) ) ) ,
54- Expression :: String ( s) => instructions. push ( Instruction :: LoadConst ( Value :: String ( s. clone ( ) ) ) ) ,
54+ Expression :: String ( s) => {
55+ instructions. push ( Instruction :: LoadConst ( Value :: String ( s. clone ( ) ) ) )
56+ }
5557 Expression :: Identifier ( val) => instructions. push ( Instruction :: LoadVar ( val. to_string ( ) ) ) ,
5658 Expression :: Binary { left, op, right } => {
5759 if * op != BinaryOperation :: And && * op != BinaryOperation :: Or {
@@ -75,37 +77,38 @@ fn compile_expr(instructions: &mut Vec<Instruction>, expr: &Expression) {
7577 let jump_instructions_index = instructions. len ( ) - 1 ;
7678 instructions. push ( Instruction :: PopTop ) ;
7779 compile_expr ( instructions, right) ;
78- instructions[ jump_instructions_index] = Instruction :: JumpIfFalse ( instructions. len ( ) ) ;
80+ instructions[ jump_instructions_index] =
81+ Instruction :: JumpIfFalse ( instructions. len ( ) ) ;
7982 }
8083 BinaryOperation :: Or => {
8184 instructions. push ( Instruction :: DuplicateTop ) ;
8285 instructions. push ( Instruction :: JumpIfTrue ( 0 ) ) ;
8386 let jump_instructions_index = instructions. len ( ) - 1 ;
8487 instructions. push ( Instruction :: PopTop ) ;
8588 compile_expr ( instructions, right) ;
86- instructions[ jump_instructions_index] = Instruction :: JumpIfTrue ( instructions. len ( ) ) ;
89+ instructions[ jump_instructions_index] =
90+ Instruction :: JumpIfTrue ( instructions. len ( ) ) ;
8791 }
8892 }
8993 }
9094 Expression :: Unary { op, expr } => {
9195 compile_expr ( instructions, expr) ;
92- match op {
93- BinaryOperation :: Subtraction => instructions. push ( Instruction :: Negate ) ,
94- _ => { }
96+ if op == & BinaryOperation :: Subtraction {
97+ instructions. push ( Instruction :: Negate ) ;
9598 }
96- } ,
99+ }
97100 Expression :: Call { name, args } => {
98101 for arg in args {
99102 compile_expr ( instructions, arg) ;
100103 }
101104 instructions. push ( Instruction :: CallFunction ( name. clone ( ) , args. len ( ) ) ) ;
102- } ,
105+ }
103106 Expression :: ArrayLiteral ( elements) => {
104107 for element in elements {
105108 compile_expr ( instructions, element) ;
106109 }
107110 instructions. push ( Instruction :: CreateArray ( elements. len ( ) ) ) ;
108- } ,
111+ }
109112 Expression :: Index { array, index } => {
110113 compile_expr ( instructions, array) ;
111114 compile_expr ( instructions, index) ;
@@ -124,12 +127,16 @@ pub fn compile_statements(
124127 Statement :: VarDecl { name, value } => {
125128 compile_expr ( instructions, & value) ;
126129 instructions. push ( Instruction :: DeclareVar ( name) ) ;
127- } ,
130+ }
128131 Statement :: Print { value } => {
129132 compile_expr ( instructions, & value) ;
130133 instructions. push ( Instruction :: Print ) ;
131134 }
132- Statement :: If { condition, body, else_body } => {
135+ Statement :: If {
136+ condition,
137+ body,
138+ else_body,
139+ } => {
133140 compile_expr ( instructions, & condition) ;
134141
135142 let jump_if_false_index = instructions. len ( ) ;
@@ -140,11 +147,13 @@ pub fn compile_statements(
140147 if let Some ( else_body) = else_body {
141148 let jump_to_end_index = instructions. len ( ) ;
142149 instructions. push ( Instruction :: Jump ( 0 ) ) ;
143- instructions[ jump_if_false_index] = Instruction :: JumpIfFalse ( instructions. len ( ) ) ;
150+ instructions[ jump_if_false_index] =
151+ Instruction :: JumpIfFalse ( instructions. len ( ) ) ;
144152 compile_statements ( else_body, instructions, loop_ctx. as_deref_mut ( ) ) ;
145153 instructions[ jump_to_end_index] = Instruction :: Jump ( instructions. len ( ) ) ;
146154 } else {
147- instructions[ jump_if_false_index] = Instruction :: JumpIfFalse ( instructions. len ( ) ) ;
155+ instructions[ jump_if_false_index] =
156+ Instruction :: JumpIfFalse ( instructions. len ( ) ) ;
148157 }
149158 }
150159 Statement :: While { condition, body } => {
@@ -171,8 +180,13 @@ pub fn compile_statements(
171180 for idx in ctx. break_placeholders {
172181 instructions[ idx] = Instruction :: Jump ( instructions. len ( ) ) ;
173182 }
174- } ,
175- Statement :: For { init, condition, update, body } => {
183+ }
184+ Statement :: For {
185+ init,
186+ condition,
187+ update,
188+ body,
189+ } => {
176190 compile_statements ( vec ! [ * init] , instructions, loop_ctx. as_deref_mut ( ) ) ;
177191
178192 let loop_start_index = instructions. len ( ) ;
@@ -201,44 +215,50 @@ pub fn compile_statements(
201215 for idx in ctx. break_placeholders {
202216 instructions[ idx] = Instruction :: Jump ( instructions. len ( ) ) ;
203217 }
204- } ,
218+ }
205219 Statement :: Assignment { name, value } => {
206220 compile_expr ( instructions, & value) ;
207221 instructions. push ( Instruction :: AssignVar ( name) ) ;
208- } ,
222+ }
209223 Statement :: Break => {
210224 if let Some ( ctx) = loop_ctx. as_deref_mut ( ) {
211225 instructions. push ( Instruction :: Jump ( 0 ) ) ;
212226 ctx. break_placeholders . push ( instructions. len ( ) - 1 ) ;
213227 } else {
214228 panic ! ( "'break' used outside of a loop" ) ;
215229 }
216- } ,
230+ }
217231 Statement :: Continue => {
218232 if let Some ( ctx) = loop_ctx. as_deref_mut ( ) {
219233 instructions. push ( Instruction :: Jump ( 0 ) ) ;
220234 ctx. continue_placeholders . push ( instructions. len ( ) - 1 ) ;
221235 } else {
222236 panic ! ( "'continue' used outside of a loop" ) ;
223237 }
224- } ,
225- Statement :: Function { name : _, params : _, body : _ } => { } ,
238+ }
239+ Statement :: Function {
240+ name : _,
241+ params : _,
242+ body : _,
243+ } => { }
226244 Statement :: Return { value } => {
227245 compile_expr ( instructions, & value) ;
228246 instructions. push ( Instruction :: Return ) ;
229- } ,
230- Statement :: Expression ( expr) => {
231- match expr {
232- Expression :: Call { name, args } => {
233- for arg in & args {
234- compile_expr ( instructions, arg) ;
235- }
236- instructions. push ( Instruction :: CallFunction ( name. clone ( ) , args. len ( ) ) ) ;
237- } ,
238- _ => compile_expr ( instructions, & expr)
247+ }
248+ Statement :: Expression ( expr) => match expr {
249+ Expression :: Call { name, args } => {
250+ for arg in & args {
251+ compile_expr ( instructions, arg) ;
252+ }
253+ instructions. push ( Instruction :: CallFunction ( name. clone ( ) , args. len ( ) ) ) ;
239254 }
255+ _ => compile_expr ( instructions, & expr) ,
240256 } ,
241- Statement :: AssignmentIndex { array, index, value } => {
257+ Statement :: AssignmentIndex {
258+ array,
259+ index,
260+ value,
261+ } => {
242262 instructions. push ( Instruction :: LoadVar ( array. clone ( ) ) ) ;
243263
244264 // index is expression
@@ -262,11 +282,20 @@ pub fn compile_program(statements: Vec<Statement>) -> Program {
262282 if let Statement :: Function { name, params, body } = statement {
263283 let mut func_instructions = Vec :: new ( ) ;
264284 compile_statements ( body, & mut func_instructions, None ) ;
265- functions. insert ( name, FunctionBytecode { params, instructions : func_instructions } ) ;
285+ functions. insert (
286+ name,
287+ FunctionBytecode {
288+ params,
289+ instructions : func_instructions,
290+ } ,
291+ ) ;
266292 } else {
267293 compile_statements ( vec ! [ statement] , & mut main_instructions, None ) ;
268294 }
269295 }
270296
271- Program { main : main_instructions, functions }
272- }
297+ Program {
298+ main : main_instructions,
299+ functions,
300+ }
301+ }
0 commit comments