Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
197 changes: 142 additions & 55 deletions crates/lean_compiler/src/a_simplify_lang.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,12 +360,7 @@
for line in block.iter() {
match line {
Line::ForwardDeclaration { var } => {
let last_scope = ctx.scopes.last_mut().unwrap();
assert!(
!last_scope.vars.contains(var),
"Variable declared multiple times in the same scope: {var}",
);
last_scope.vars.insert(var.clone());
ctx.add_var(var);
}
Line::Match { value, arms } => {
check_expr_scoping(value, ctx);
Expand All @@ -377,12 +372,9 @@
}
Line::Assignment { var, value } => {
check_expr_scoping(value, ctx);
let last_scope = ctx.scopes.last_mut().unwrap();
assert!(
!last_scope.vars.contains(var),
"Variable declared multiple times in the same scope: {var}",
);
last_scope.vars.insert(var.clone());
if !ctx.defines(var) {
ctx.add_var(var);
}
}
Line::ArrayAssign { array, index, value } => {
check_simple_expr_scoping(array, ctx);
Expand Down Expand Up @@ -431,15 +423,12 @@
for arg in args {
check_expr_scoping(arg, ctx);
}
let last_scope = ctx.scopes.last_mut().unwrap();
for target in return_data {
match target {
AssignmentTarget::Var(var) => {
assert!(
!last_scope.vars.contains(var),
"Variable declared multiple times in the same scope: {var}",
);
last_scope.vars.insert(var.clone());
if !ctx.defines(var) {
ctx.add_var(var);
}
}
AssignmentTarget::ArrayAccess { .. } => {}
}
Expand Down Expand Up @@ -478,36 +467,25 @@
} => {
check_expr_scoping(size, ctx);
check_expr_scoping(vectorized_len, ctx);
let last_scope = ctx.scopes.last_mut().unwrap();
assert!(
!last_scope.vars.contains(var),
"Variable declared multiple times in the same scope: {var}",
);
last_scope.vars.insert(var.clone());
if !ctx.defines(var) {
ctx.add_var(var);
}
}
Line::DecomposeBits { var, to_decompose } => {
for expr in to_decompose {
check_expr_scoping(expr, ctx);
}
let last_scope = ctx.scopes.last_mut().unwrap();
assert!(
!last_scope.vars.contains(var),
"Variable declared multiple times in the same scope: {var}",
);
last_scope.vars.insert(var.clone());
if !ctx.defines(var) {
ctx.add_var(var);
}
}
Line::DecomposeCustom { args } => {
for arg in args {
check_expr_scoping(arg, ctx);
}
}
Line::PrivateInputStart { result } => {
let last_scope = ctx.scopes.last_mut().unwrap();
assert!(
!last_scope.vars.contains(result),
"Variable declared multiple times in the same scope: {result}"
);
last_scope.vars.insert(result.clone());
ctx.add_var(result);
}
}
}
Expand Down Expand Up @@ -1973,7 +1951,17 @@
let mut counter2 = Counter::new();
let old_body = func.body.clone();

handle_inlined_functions_helper(&mut func.body, &inlined_functions, &mut counter1, &mut counter2);
let mut ctx = Context::new();
for (var, _) in func.arguments.iter() {
ctx.add_var(var);
}
func.body = handle_inlined_functions_helper(
&mut ctx,
&func.body,
&inlined_functions,
&mut counter1,
&mut counter2,
);

if func.body != old_body {
any_changes = true;
Expand All @@ -1989,7 +1977,17 @@
let mut counter2 = Counter::new();
let old_body = func.body.clone();

handle_inlined_functions_helper(&mut func.body, &inlined_functions, &mut counter1, &mut counter2);
let mut ctx = Context::new();
for (var, _) in func.arguments.iter() {

Check warning on line 1981 in crates/lean_compiler/src/a_simplify_lang.rs

View workflow job for this annotation

GitHub Actions / Rustfmt Check

Diff in /home/runner/work/leanMultisig/leanMultisig/crates/lean_compiler/src/a_simplify_lang.rs
ctx.add_var(var);
}
handle_inlined_functions_helper(
&mut ctx,
&func.body,
&inlined_functions,
&mut counter1,
&mut counter2,
);

if func.body != old_body {
any_changes = true;
Expand All @@ -2013,26 +2011,59 @@
}

fn handle_inlined_functions_helper(
lines: &mut Vec<Line>,
ctx: &mut Context,
lines_in: &Vec<Line>,
inlined_functions: &BTreeMap<String, Function>,
inlined_var_counter: &mut Counter,
total_inlined_counter: &mut Counter,
) {
for i in (0..lines.len()).rev() {
match &mut lines[i] {
) -> Vec<Line> {
let mut lines_out: Vec<Line> = Vec::new();
for line in lines_in {
match line {
Line::ForwardDeclaration { var } => {
lines_out.push(line.clone());
ctx.add_var(var);
}
Line::Assignment { var, .. } => {
lines_out.push(line.clone());
if !ctx.defines(var) {
ctx.add_var(var);
}
}
Line::DecomposeBits { var, .. } => {
lines_out.push(line.clone());
if !ctx.defines(var) {
ctx.add_var(var);
}
}
Line::PrivateInputStart { result } => {
lines_out.push(line.clone());
if !ctx.defines(result) {
ctx.add_var(result);
}
}
Line::MAlloc { var, .. } => {
lines_out.push(line.clone());
if !ctx.defines(var) {
ctx.add_var(var);
}
}
Line::FunctionCall {
function_name,
args,
return_data,
line_number: _,
} => {
if let Some(func) = inlined_functions.get(&*function_name) {

Check failure on line 2057 in crates/lean_compiler/src/a_simplify_lang.rs

View workflow job for this annotation

GitHub Actions / Clippy

deref on an immutable reference
let mut inlined_lines = vec![];

// Only add forward declarations for variable targets, not array accesses
for target in return_data.iter() {
if let AssignmentTarget::Var(var) = target {
if let AssignmentTarget::Var(var) = target
&& !ctx.defines(var)
{
inlined_lines.push(Line::ForwardDeclaration { var: var.clone() });
ctx.add_var(var);
}
}

Expand All @@ -2059,40 +2090,96 @@
let mut func_body = func.body.clone();
inline_lines(&mut func_body, &inlined_args, return_data, total_inlined_counter.next());
inlined_lines.extend(func_body);

lines.remove(i); // remove the call to the inlined function
lines.splice(i..i, inlined_lines);
lines_out.extend(inlined_lines);
} else {
lines_out.push(line.clone());
}
}
Line::IfCondition {
condition,
then_branch,
else_branch,
..
line_number,
} => {
handle_inlined_functions_helper(
ctx.scopes.push(Scope::default());
let then_branch_out = handle_inlined_functions_helper(
ctx,
then_branch,
inlined_functions,
inlined_var_counter,
total_inlined_counter,
);
handle_inlined_functions_helper(
ctx.scopes.pop();
ctx.scopes.push(Scope::default());
let else_branch_out = handle_inlined_functions_helper(
ctx,
else_branch,
inlined_functions,
inlined_var_counter,
total_inlined_counter,
);
ctx.scopes.pop();
lines_out.push(Line::IfCondition {
condition: condition.clone(),
then_branch: then_branch_out,
else_branch: else_branch_out,
line_number: *line_number,
});
}
Line::ForLoop { body, unroll: _, .. } => {
handle_inlined_functions_helper(body, inlined_functions, inlined_var_counter, total_inlined_counter);
Line::ForLoop {
iterator,
start,
end,
body,
rev,
unroll,
line_number,
} => {
ctx.scopes.push(Scope::default());
ctx.add_var(iterator);
let loop_body_out = handle_inlined_functions_helper(
ctx,
body,
inlined_functions,
inlined_var_counter,
total_inlined_counter,
);
ctx.scopes.pop();
lines_out.push(Line::ForLoop {
iterator: iterator.clone(),
start: start.clone(),
end: end.clone(),
body: loop_body_out,
rev: *rev,
unroll: *unroll,
line_number: *line_number,
});
}
Line::Match { arms, .. } => {
for (_, arm) in arms {
handle_inlined_functions_helper(arm, inlined_functions, inlined_var_counter, total_inlined_counter);
Line::Match { value, arms } => {
let mut arms_out: Vec<(usize, Vec<Line>)> = Vec::new();
for (i, arm) in arms {
ctx.scopes.push(Scope::default());
let arm_out = handle_inlined_functions_helper(
ctx,
arm,
inlined_functions,
inlined_var_counter,
total_inlined_counter,
);
ctx.scopes.pop();
arms_out.push((*i, arm_out));
}
lines_out.push(Line::Match {
value: value.clone(),
arms: arms_out,
});
}
line => {
lines_out.push(line.clone());
}
_ => {}
}
}
lines_out
}

fn handle_const_arguments(program: &mut Program) -> bool {
Expand Down
19 changes: 18 additions & 1 deletion crates/lean_compiler/src/lang.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@ pub enum Line {
}

/// A context specifying which variables are in scope.
#[derive(Debug)]
pub struct Context {
/// A list of lexical scopes, innermost scope last.
pub scopes: Vec<Scope>,
Expand All @@ -469,6 +470,13 @@ pub struct Context {
}

impl Context {
pub fn new() -> Context {
Context {
scopes: vec![Scope::default()],
const_arrays: BTreeMap::new(),
}
}

pub fn defines(&self, var: &Var) -> bool {
if self.const_arrays.contains_key(var) {
return true;
Expand All @@ -480,9 +488,18 @@ impl Context {
}
false
}

pub fn add_var(&mut self, var: &Var) {
let last_scope = self.scopes.last_mut().unwrap();
assert!(
!last_scope.vars.contains(var),
"Variable declared multiple times in the same scope: {var}",
);
last_scope.vars.insert(var.clone());
}
}

#[derive(Default)]
#[derive(Debug, Default)]
pub struct Scope {
/// A set of declared variables.
pub vars: BTreeSet<Var>,
Expand Down
2 changes: 1 addition & 1 deletion crates/lean_compiler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub fn compile_program(program: String) -> Bytecode {
let (parsed_program, function_locations) = parse_program(&program).unwrap();
// println!("Parsed program: {}", parsed_program.to_string());
let simple_program = simplify_program(parsed_program);
// println!("Simplified program: {}", simple_program);
println!("Simplified program: {}", simple_program);
let intermediate_bytecode = compile_to_intermediate_bytecode(simple_program).unwrap();
// println!("Intermediate Bytecode:\n\n{}", intermediate_bytecode.to_string());

Expand Down
22 changes: 22 additions & 0 deletions crates/lean_compiler/tests/test_compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,28 @@ fn test_inlined_2() {
compile_and_run(program.to_string(), (&[], &[]), DEFAULT_NO_VEC_RUNTIME_MEMORY, false);
}

#[test]
fn test_inlined_3() {
let program = r#"
fn main() {
x = func();
return;
}
fn func() -> 1 {
var a;
if 0 == 0 {
a = aux();
}
return a;
}

fn aux() inline -> 1 {
return 1;
}
"#;
compile_and_run(program.to_string(), (&[], &[]), DEFAULT_NO_VEC_RUNTIME_MEMORY, false);
}

#[test]
fn test_match() {
let program = r#"
Expand Down
Loading