11use crate :: compiler:: ast:: ssa_ir:: OpCode :: Push ;
2- use crate :: compiler:: ast:: ssa_ir:: ValueGuessType :: {
3- Bool , Float , Null , Number , String , This , Unknown ,
4- } ;
2+ use crate :: compiler:: ast:: ssa_ir:: ValueGuessType :: { Bool , Float , Null , Number , Ref , String , This , Unknown } ;
53use crate :: compiler:: ast:: ssa_ir:: { Code , OpCode , OpCodeTable , Operand , ValueGuessType } ;
64use crate :: compiler:: ast:: { ASTExprTree , ExprOp } ;
75use crate :: compiler:: lexer:: { Token , TokenType } ;
@@ -72,6 +70,9 @@ fn guess_check_type(src: ValueGuessType, args: &[ValueGuessType]) -> bool {
7270}
7371
7472fn check_opts ( op : & ExprOp , args : & [ ExprOp ] ) -> bool {
73+ if matches ! ( op, ExprOp :: Store | ExprOp :: Equ | ExprOp :: NotEqu ) {
74+ return true ;
75+ }
7576 for ty in args {
7677 if op == ty {
7778 return true ;
@@ -115,6 +116,10 @@ fn guess_type(
115116 return Ok ( Unknown ) ;
116117 }
117118
119+ if matches ! ( op, ExprOp :: Store ) {
120+ return Ok ( second) ;
121+ }
122+
118123 match first {
119124 Bool => {
120125 if guess_check_type ( second, & [ Bool ] )
@@ -136,9 +141,9 @@ fn guess_type(
136141 }
137142 String => {
138143 if guess_check_type ( second, & [ String , Float , Number , Null ] )
139- && check_opts ( op, & [ ExprOp :: Add , ExprOp :: Equ , ExprOp :: NotEqu ] )
144+ && check_opts ( op, & [ ExprOp :: Add ] )
140145 {
141- if check_opts ( op, & [ ExprOp :: Equ , ExprOp :: NotEqu ] ) {
146+ if check_opts ( op, & [ ] ) {
142147 Ok ( Bool )
143148 } else {
144149 Ok ( String )
@@ -248,7 +253,7 @@ fn lower_ref(
248253
249254 if matches ! ( left_tree, ASTExprTree :: Call { .. } ) || matches ! ( left_tree, ASTExprTree :: This ( _token) ) ||
250255 matches ! ( left_tree, ASTExprTree :: Var ( _token) ) {
251- let mut table = lower_expr ( semantic, left_tree, code) ?. 2 ;
256+ let mut table = lower_expr ( semantic, left_tree, code, None ) ?. 2 ;
252257 opcode_table. append_code ( & mut table) ;
253258 } else {
254259 unreachable ! ( )
@@ -279,10 +284,24 @@ fn lower_ref(
279284 Ok ( ( path. finish ( ) , opcode_table) )
280285}
281286
287+ fn operand_to_guess ( operand : Operand ) -> ValueGuessType {
288+ match operand {
289+ Operand :: ImmBool ( _) => Bool ,
290+ Operand :: Null => Null ,
291+ Operand :: This => This ,
292+ Operand :: ImmNum ( _) => Number ,
293+ Operand :: ImmFlot ( _) => Float ,
294+ Operand :: ImmStr ( _) => String ,
295+ Operand :: Reference ( _) => Ref ,
296+ _=> Unknown ,
297+ }
298+ }
299+
282300pub ( crate ) fn lower_expr (
283301 semantic : & mut Semantic ,
284302 expr_tree : & ASTExprTree ,
285303 code : & mut Code ,
304+ store : Option < Operand > ,
286305) -> Result < ( Operand , ValueGuessType , OpCodeTable ) , ParserError > {
287306 let mut opcode_table = OpCodeTable :: new ( ) ;
288307 match expr_tree {
@@ -314,13 +333,13 @@ pub(crate) fn lower_expr(
314333 Ok ( ( Operand :: Null , Null , opcode_table) )
315334 }
316335 _ => {
317- todo ! ( )
336+ unreachable ! ( )
318337 }
319338 }
320339 }
321340 ASTExprTree :: Ref ( token) => {
322341 opcode_table. add_opcode ( Push ( None , Operand :: Reference ( token. text ( ) . to_smolstr ( ) ) ) ) ;
323- Ok ( ( Operand :: Reference ( token. text ( ) . to_smolstr ( ) ) , ValueGuessType :: Ref , opcode_table) )
342+ Ok ( ( Operand :: Reference ( token. text ( ) . to_smolstr ( ) ) , Ref , opcode_table) )
324343 }
325344 ASTExprTree :: This ( _token) => {
326345 opcode_table. add_opcode ( Push ( None , Operand :: This ) ) ;
@@ -331,7 +350,7 @@ pub(crate) fn lower_expr(
331350 op : u_op,
332351 code : u_code,
333352 } => {
334- let mut a = lower_expr ( semantic, u_code. as_ref ( ) , code) ?;
353+ let mut a = lower_expr ( semantic, u_code. as_ref ( ) , code, None ) ?;
335354 let g_type = guess_type_unary ( u_token, a. 1 , u_op) ?;
336355 if let Some ( operand) = unary_optimizer ( u_op, & a. 0 ) {
337356 opcode_table. add_opcode ( Push ( None , operand) ) ;
@@ -347,24 +366,33 @@ pub(crate) fn lower_expr(
347366 left : e_left,
348367 right : e_right,
349368 } => {
350- let mut left = lower_expr ( semantic, e_left. as_ref ( ) , code) ?;
351- let mut right = lower_expr ( semantic, e_right. as_ref ( ) , code) ?;
352- let left_opd = Box :: new ( left. 0 . clone ( ) ) ;
369+ let mut right = lower_expr ( semantic, e_right. as_ref ( ) , code, None ) ?;
353370 let right_opd = Box :: new ( right. 0 . clone ( ) ) ;
371+ let stores = if matches ! ( e_op, ExprOp :: Store ) {
372+ Some ( right. 0 . clone ( ) )
373+ } else {
374+ None
375+ } ;
376+ let mut left = lower_expr ( semantic, e_left. as_ref ( ) , code, stores) ?;
377+
378+ let left_opd = Box :: new ( left. 0 . clone ( ) ) ;
354379 let guess_type = guess_type ( e_token, left. 1 , right. 1 , e_op) ?;
355380 let n_operand;
356381
357382 if let Some ( operand) = expr_optimizer ( & left. 0 , & right. 0 , e_op) {
358383 n_operand = operand. clone ( ) ;
359384 opcode_table. add_opcode ( Push ( None , operand) ) ;
360385 } else {
361- opcode_table. append_code ( & mut left. 2 ) ;
362- opcode_table. append_code ( & mut right. 2 ) ;
363-
364386 let opcode = astop_to_opcode ( e_op) ;
365- n_operand = Operand :: Expression ( left_opd, right_opd, Box :: from ( opcode. clone ( ) ) ) ;
366-
367- opcode_table. add_opcode ( opcode) ;
387+ if matches ! ( e_op, ExprOp :: Store ) {
388+ opcode_table. append_code ( & mut right. 2 ) ;
389+ opcode_table. append_code ( & mut left. 2 ) ;
390+ } else {
391+ opcode_table. append_code ( & mut left. 2 ) ;
392+ opcode_table. append_code ( & mut right. 2 ) ;
393+ opcode_table. add_opcode ( opcode. clone ( ) ) ;
394+ }
395+ n_operand = Operand :: Expression ( left_opd, right_opd, Box :: from ( opcode) ) ;
368396 }
369397 Ok ( ( n_operand, guess_type, opcode_table) )
370398 }
@@ -380,22 +408,28 @@ pub(crate) fn lower_expr(
380408 if let Some ( key) = code. find_value_key ( var_name. clone ( ) ) {
381409 let value = code. find_value ( key) . unwrap ( ) ;
382410 value. variable = true ;
411+ let type_ = value. type_ . clone ( ) ;
383412 match value. type_ {
384- ValueGuessType :: Ref => {
413+ Ref => {
385414 opcode_table. add_opcode ( Push ( None , Operand :: Library ( var_name) ) ) ;
386415 }
387416 _ => {
388- opcode_table. add_opcode ( OpCode :: StoreLocal ( None , key, Operand :: Val ( key) ) ) ;
417+ if let Some ( operand) = store{
418+ value. type_ = operand_to_guess ( operand) ;
419+ opcode_table. add_opcode ( OpCode :: LoadLocal ( None , key, Operand :: Val ( key) ) ) ;
420+ } else {
421+ opcode_table. add_opcode ( OpCode :: StoreLocal ( None , key, Operand :: Val ( key) ) ) ;
422+ }
389423 }
390424 } ;
391- Ok ( ( Operand :: Val ( key) , value . type_ . clone ( ) , opcode_table) )
425+ Ok ( ( Operand :: Val ( key) , type_, opcode_table) )
392426 } else {
393427 unreachable ! ( )
394428 }
395429 }
396430 ASTExprTree :: Call { name, args } => {
397431 for arg in args {
398- let mut expr = lower_expr ( semantic, arg, code) ?;
432+ let mut expr = lower_expr ( semantic, arg, code, None ) ?;
399433 opcode_table. append_code ( & mut expr. 2 ) ;
400434 }
401435
@@ -458,7 +492,7 @@ pub fn expr_semantic(
458492 let mut opcode_vec = OpCodeTable :: new ( ) ;
459493
460494 if let Some ( expr) = expr {
461- let mut exp = lower_expr ( semantic, & expr, code) ?;
495+ let mut exp = lower_expr ( semantic, & expr, code, None ) ?;
462496 opcode_vec. append_code ( & mut exp. 2 ) ;
463497 operand = exp. 0 ;
464498 guess_type = exp. 1 ;
0 commit comments