diff --git a/juno_scheduler/src/compile.rs b/juno_scheduler/src/compile.rs index 9d020c64ccef3b9c0a79694876c5b0ace606f938..0db32bdaee493bf934367072030a91d979f89812 100644 --- a/juno_scheduler/src/compile.rs +++ b/juno_scheduler/src/compile.rs @@ -275,6 +275,35 @@ fn compile_stmt( limit, }]) } + parser::Stmt::IfThenElse { + span: _, + cond, + thn, + els, + } => { + let cond = compile_exp_as_expr(cond, lexer, macrostab, macros)?; + + macros.open_scope(); + let thn = ir::ScheduleStmt::Block { + body: compile_ops_as_block(*thn, lexer, macrostab, macros)?, + }; + macros.close_scope(); + + macros.open_scope(); + let els = match els { + Some(els) => ir::ScheduleStmt::Block { + body: compile_ops_as_block(*els, lexer, macrostab, macros)?, + }, + None => ir::ScheduleStmt::Block { body: vec![] }, + }; + macros.close_scope(); + + Ok(vec![ir::ScheduleStmt::IfThenElse { + cond, + thn: Box::new(thn), + els: Box::new(els), + }]) + } parser::Stmt::MacroDecl { span: _, def } => { let parser::MacroDecl { name, diff --git a/juno_scheduler/src/ir.rs b/juno_scheduler/src/ir.rs index ab1495b816c99452560d03c0addf77a5aec18974..98f8050f2d32494db7a90b10b8c724a4b1848af6 100644 --- a/juno_scheduler/src/ir.rs +++ b/juno_scheduler/src/ir.rs @@ -180,4 +180,9 @@ pub enum ScheduleStmt { device: Device, on: Selector, }, + IfThenElse { + cond: ScheduleExp, + thn: Box<ScheduleStmt>, + els: Box<ScheduleStmt>, + }, } diff --git a/juno_scheduler/src/lang.l b/juno_scheduler/src/lang.l index af154fce3d489b7b078607e52888d76d08f8e5fe..1f4f8723de4d950920d503a11c9145ad1d15d24a 100644 --- a/juno_scheduler/src/lang.l +++ b/juno_scheduler/src/lang.l @@ -20,12 +20,15 @@ \. "." apply "apply" +else "else" fixpoint "fixpoint" +if "if" let "let" macro "macro_keyword" on "on" set "set" target "target" +then "then" true "true" false "false" diff --git a/juno_scheduler/src/lang.y b/juno_scheduler/src/lang.y index 451f035b8122ac1a694567327a44776c9326fff2..55c82b9dc368e7cade9500fb852c9d48320be7d2 100644 --- a/juno_scheduler/src/lang.y +++ b/juno_scheduler/src/lang.y @@ -27,6 +27,10 @@ Stmt -> Stmt { Stmt::ExprStmt { span: $span, exp: $1 } } | 'fixpoint' FixpointLimit '{' Schedule '}' { Stmt::Fixpoint { span: $span, limit: $2, body: Box::new($4) } } + | 'if' Expr '{' Schedule '}' + { Stmt::IfThenElse { span: $span, cond: $2, thn: Box::new($4), els: None } } + | 'if' Expr '{' Schedule '}' 'else' '{' Schedule '}' + { Stmt::IfThenElse { span: $span, cond: $2, thn: Box::new($4), els: Some(Box::new($8)) } } | MacroDecl { Stmt::MacroDecl { span: $span, def: $1 } } ; @@ -163,6 +167,7 @@ pub enum Stmt { AssignStmt { span: Span, var: Span, rhs: Expr }, ExprStmt { span: Span, exp: Expr }, Fixpoint { span: Span, limit: FixpointLimit, body: Box<OperationList> }, + IfThenElse { span: Span, cond: Expr, thn: Box<OperationList>, els: Option<Box<OperationList>> }, MacroDecl { span: Span, def: MacroDecl }, } diff --git a/juno_scheduler/src/pm.rs b/juno_scheduler/src/pm.rs index 62bdaf739b69b52a0b540c6a602e1e5beb632786..db1dfc9a56bb638bcc7af067d76ef16927213a72 100644 --- a/juno_scheduler/src/pm.rs +++ b/juno_scheduler/src/pm.rs @@ -1199,6 +1199,23 @@ fn schedule_interpret( // were made Ok(i > 1) } + ScheduleStmt::IfThenElse { cond, thn, els } => { + let (cond, modified) = interp_expr(pm, cond, stringtab, env, functions)?; + let Value::Boolean { val: cond } = cond else { + return Err(SchedulerError::SemanticError( + "Condition must be a boolean value".to_string(), + )); + }; + let changed = schedule_interpret( + pm, + if cond { &*thn } else { &*els }, + stringtab, + env, + functions, + )?; + + Ok(modified || changed) + } ScheduleStmt::Block { body } => { let mut modified = false; env.open_scope();