@@ -11,7 +11,7 @@ use bumpalo::{Bump, collections::Vec};
1111use parser:: {
1212 ArrayOperator , Ast , Atom , BinaryOperator , BinaryPlaceOperator , Body , Command , Expr , ExprNode ,
1313 Function as AstFunction , FunctionTable , Identifier , MetaId , Place , Rule , RulePattern ,
14- SimpleStatement , Statement , UnaryPlaceOperator , Variable ,
14+ SimpleStatement , Statement , UnaryOperator , UnaryPlaceOperator , Variable ,
1515} ;
1616
1717use crate :: {
@@ -218,21 +218,16 @@ impl<'a> CodeGen<'a> {
218218 // body:
219219 // ...; jmp continue
220220 this. with_break_scope ( |this| {
221- let to_body = this. emit ( Instruction :: Jump { to : Label ( 0 ) } ) ;
222- let continue_label = this. following_instr ( 0 ) ;
223-
224- let cond_reg = this. alloc_reg ( ) ;
225- this. lower_expr_into ( condition, * cond_reg) ;
226- let branch = this. emit ( Instruction :: Branch {
227- condition : * cond_reg,
228- then_label : Label ( 0 ) ,
229- else_label : Label ( 0 ) ,
221+ let ( branch , continue_label ) = this. emit_jump ( |this| {
222+ let continue_label = this. following_instr ( 0 ) ;
223+
224+ let cond_reg = this. alloc_reg ( ) ;
225+ this. lower_expr_into ( condition, * cond_reg) ;
226+ let then_label = this. following_instr ( 1 ) ;
227+ let branch = this . emit ( Instruction :: br ( * cond_reg, then_label ) ) ;
228+ this . free_reg ( cond_reg ) ;
229+ ( branch , continue_label )
230230 } ) ;
231- this. free_reg ( cond_reg) ;
232-
233- let body_label = this. following_instr ( 0 ) ;
234- this. bc . nth ( to_body) . set_label ( body_label) ;
235- this. bc . nth ( branch) . set_then_label ( body_label) ;
236231
237232 this. with_continue_label ( continue_label, |this| {
238233 this. lower_body ( then_body) ;
@@ -254,32 +249,30 @@ impl<'a> CodeGen<'a> {
254249 // init; jmp cond
255250 // continue: update
256251 // cond: brif body / end; body; jmp continue
257- let to_cond = this. emit ( Instruction :: Jump { to : Label ( 0 ) } ) ;
258- let continue_label = this. following_instr ( 0 ) ;
259- if let Some ( SimpleStatement :: Expression ( expr, metadata) ) = update {
260- this. with_metadata ( * metadata, |this| {
261- this. lower_expr ( expr) . free ( this) ;
262- } ) ;
263- }
264- let cond_label = this. following_instr ( 0 ) ;
265- this. bc . nth ( to_cond) . set_label ( cond_label) ;
266-
267- if let Some ( condition) = condition {
268- this. emit_branch ( condition, |this| {
269- this. with_break_scope ( |this| {
270- this. with_continue_label ( continue_label, |this| {
271- this. lower_body ( body) ;
272- } ) ;
273- this. emit ( Instruction :: Jump { to : continue_label } ) ;
252+ let continue_label = this. emit_jump ( |this| {
253+ let continue_label = this. following_instr ( 0 ) ;
254+ if let Some ( SimpleStatement :: Expression ( expr, metadata) ) = update {
255+ this. with_metadata ( * metadata, |this| {
256+ this. lower_expr ( expr) . free ( this) ;
274257 } ) ;
275- } ) ;
276- } else {
258+ }
259+ continue_label
260+ } ) ;
261+
262+ let lower_for_body = |this : & mut Self | {
277263 this. with_break_scope ( |this| {
278264 this. with_continue_label ( continue_label, |this| {
279265 this. lower_body ( body) ;
280266 } ) ;
281267 this. emit ( Instruction :: Jump { to : continue_label } ) ;
282268 } ) ;
269+ } ;
270+
271+ match condition {
272+ Some ( condition) => {
273+ this. emit_branch ( condition, lower_for_body) ;
274+ }
275+ None => lower_for_body ( this) ,
283276 }
284277 } ) ;
285278 }
@@ -952,6 +945,42 @@ impl<'a> Bytecode<'a> {
952945 }
953946}
954947
948+ impl Instruction {
949+ pub ( super ) fn from_unary ( op : UnaryOperator , dest : Reg , arg : TypedArg ) -> Self {
950+ let ( arg, ty) = arg. into ( ) ;
951+ match op {
952+ UnaryOperator :: Record => Self :: Record { dest, arg, ty } ,
953+ UnaryOperator :: Negation => Self :: Negation { dest, arg, ty } ,
954+ UnaryOperator :: ToInt => Self :: ToInt { dest, arg, ty } ,
955+ UnaryOperator :: Negative => Self :: Negative { dest, arg, ty } ,
956+ }
957+ }
958+
959+ pub ( super ) fn from_binary ( op : BinaryOperator , dest : Reg , lhs : TypedArg , rhs : TypedArg ) -> Self {
960+ let ( ( lhs, tyl) , ( rhs, tyr) ) = ( lhs. into ( ) , rhs. into ( ) ) ;
961+ match op {
962+ BinaryOperator :: Concat => Self :: Concat { dest, lhs, rhs, tyl, tyr } ,
963+ BinaryOperator :: Eq => Self :: Eq { dest, lhs, rhs, tyl, tyr } ,
964+ BinaryOperator :: NEq => Self :: NEq { dest, lhs, rhs, tyl, tyr } ,
965+ BinaryOperator :: Gt => Self :: Gt { dest, lhs, rhs, tyl, tyr } ,
966+ BinaryOperator :: Lt => Self :: Lt { dest, lhs, rhs, tyl, tyr } ,
967+ BinaryOperator :: LtE => Self :: LtE { dest, lhs, rhs, tyl, tyr } ,
968+ BinaryOperator :: GtE => Self :: GtE { dest, lhs, rhs, tyl, tyr } ,
969+ BinaryOperator :: And | BinaryOperator :: Or => {
970+ unreachable ! ( "&& and || are lowered with branches" )
971+ }
972+ BinaryOperator :: Matches => Self :: Matches { dest, lhs, rhs, tyl, tyr } ,
973+ BinaryOperator :: MatchesNot => Self :: MatchesNot { dest, lhs, rhs, tyl, tyr } ,
974+ BinaryOperator :: Add => Self :: Add { dest, lhs, rhs, tyl, tyr } ,
975+ BinaryOperator :: Subtract => Self :: Subtract { dest, lhs, rhs, tyl, tyr } ,
976+ BinaryOperator :: Multiply => Self :: Multiply { dest, lhs, rhs, tyl, tyr } ,
977+ BinaryOperator :: Divide => Self :: Divide { dest, lhs, rhs, tyl, tyr } ,
978+ BinaryOperator :: Raise => Self :: Raise { dest, lhs, rhs, tyl, tyr } ,
979+ BinaryOperator :: Modulo => Self :: Modulo { dest, lhs, rhs, tyl, tyr } ,
980+ }
981+ }
982+ }
983+
955984fn lower_assign_ops ( op : BinaryPlaceOperator ) -> Option < BinaryOperator > {
956985 match op {
957986 BinaryPlaceOperator :: Assignment => None ,
0 commit comments