Skip to content

Commit f037892

Browse files
committed
parser: reorg function parser
1 parent a2400e9 commit f037892

File tree

2 files changed

+122
-119
lines changed

2 files changed

+122
-119
lines changed

crates/leanVm/src/parser/function.rs

Lines changed: 122 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ use std::collections::BTreeMap;
22

33
use pest::iterators::Pair;
44

5-
use super::{ParseError, Rule, parse_parameter, parse_statement};
6-
use crate::lang::Function;
5+
use super::{ParseError, Rule, parse_parameter, parse_statement, parse_var_list};
6+
use crate::{
7+
lang::{Function, Line, SimpleExpr},
8+
parser::{PRECOMPILES, parse_tuple_expression},
9+
};
710

811
pub(crate) fn parse_function(
912
pair: Pair<'_, Rule>,
@@ -49,3 +52,120 @@ pub(crate) fn parse_function(
4952
body,
5053
})
5154
}
55+
56+
#[allow(clippy::too_many_lines)]
57+
pub(crate) fn parse_function_call(
58+
pair: &Pair<'_, Rule>,
59+
constants: &BTreeMap<String, usize>,
60+
trash_var_count: &mut usize,
61+
) -> Result<Line, ParseError> {
62+
let inner = pair.clone().into_inner();
63+
let mut return_data = Vec::new();
64+
let mut function_name = String::new();
65+
let mut args = Vec::new();
66+
67+
for item in inner {
68+
match item.as_rule() {
69+
Rule::function_res => {
70+
for res_item in item.into_inner() {
71+
if res_item.as_rule() == Rule::var_list {
72+
return_data = parse_var_list(res_item, constants)?
73+
.into_iter()
74+
.filter_map(|v| {
75+
if let SimpleExpr::Var(var) = v {
76+
Some(var)
77+
} else {
78+
None
79+
}
80+
})
81+
.collect();
82+
}
83+
}
84+
}
85+
Rule::identifier => function_name = item.as_str().to_string(),
86+
Rule::tuple_expression => args = parse_tuple_expression(item, constants)?,
87+
_ => {}
88+
}
89+
}
90+
91+
for var in &mut return_data {
92+
if var == "_" {
93+
*trash_var_count += 1;
94+
*var = format!("@trash_{trash_var_count}");
95+
}
96+
}
97+
98+
match function_name.as_str() {
99+
"malloc" => {
100+
assert!(
101+
args.len() == 1 && return_data.len() == 1,
102+
"Invalid malloc call"
103+
);
104+
Ok(Line::MAlloc {
105+
var: return_data[0].clone(),
106+
size: args[0].clone(),
107+
vectorized: false,
108+
})
109+
}
110+
"malloc_vec" => {
111+
assert!(
112+
args.len() == 1 && return_data.len() == 1,
113+
"Invalid malloc_vec call"
114+
);
115+
Ok(Line::MAlloc {
116+
var: return_data[0].clone(),
117+
size: args[0].clone(),
118+
vectorized: true,
119+
})
120+
}
121+
"print" => {
122+
assert!(
123+
return_data.is_empty(),
124+
"Print function should not return values"
125+
);
126+
Ok(Line::Print {
127+
line_info: pair.as_str().to_string(),
128+
content: args,
129+
})
130+
}
131+
"decompose_bits" => {
132+
assert!(
133+
args.len() == 1 && return_data.len() == 1,
134+
"Invalid decompose_bits call"
135+
);
136+
Ok(Line::DecomposeBits {
137+
var: return_data[0].clone(),
138+
to_decompose: args[0].clone(),
139+
})
140+
}
141+
"panic" => {
142+
assert!(
143+
return_data.is_empty() && args.is_empty(),
144+
"Panic has no args and returns no values"
145+
);
146+
Ok(Line::Panic)
147+
}
148+
_ => {
149+
if let Some(precompile) = PRECOMPILES
150+
.iter()
151+
.find(|p| p.name.to_string() == function_name)
152+
{
153+
assert!(
154+
args.len() == precompile.n_inputs && return_data.len() == precompile.n_outputs,
155+
"Invalid precompile call"
156+
);
157+
Ok(Line::Precompile {
158+
precompile: precompile.clone(),
159+
args,
160+
res: return_data,
161+
})
162+
} else {
163+
Ok(Line::FunctionCall {
164+
function_name,
165+
args,
166+
return_data,
167+
})
168+
}
169+
}
170+
}
171+
}

crates/leanVm/src/parser/mod.rs

Lines changed: 0 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -211,123 +211,6 @@ fn parse_tuple_expression(
211211
.collect()
212212
}
213213

214-
#[allow(clippy::too_many_lines)]
215-
fn parse_function_call(
216-
pair: &Pair<'_, Rule>,
217-
constants: &BTreeMap<String, usize>,
218-
trash_var_count: &mut usize,
219-
) -> Result<Line, ParseError> {
220-
let inner = pair.clone().into_inner();
221-
let mut return_data = Vec::new();
222-
let mut function_name = String::new();
223-
let mut args = Vec::new();
224-
225-
for item in inner {
226-
match item.as_rule() {
227-
Rule::function_res => {
228-
for res_item in item.into_inner() {
229-
if res_item.as_rule() == Rule::var_list {
230-
return_data = parse_var_list(res_item, constants)?
231-
.into_iter()
232-
.filter_map(|v| {
233-
if let SimpleExpr::Var(var) = v {
234-
Some(var)
235-
} else {
236-
None
237-
}
238-
})
239-
.collect();
240-
}
241-
}
242-
}
243-
Rule::identifier => function_name = item.as_str().to_string(),
244-
Rule::tuple_expression => args = parse_tuple_expression(item, constants)?,
245-
_ => {}
246-
}
247-
}
248-
249-
for var in &mut return_data {
250-
if var == "_" {
251-
*trash_var_count += 1;
252-
*var = format!("@trash_{trash_var_count}");
253-
}
254-
}
255-
256-
match function_name.as_str() {
257-
"malloc" => {
258-
assert!(
259-
args.len() == 1 && return_data.len() == 1,
260-
"Invalid malloc call"
261-
);
262-
Ok(Line::MAlloc {
263-
var: return_data[0].clone(),
264-
size: args[0].clone(),
265-
vectorized: false,
266-
})
267-
}
268-
"malloc_vec" => {
269-
assert!(
270-
args.len() == 1 && return_data.len() == 1,
271-
"Invalid malloc_vec call"
272-
);
273-
Ok(Line::MAlloc {
274-
var: return_data[0].clone(),
275-
size: args[0].clone(),
276-
vectorized: true,
277-
})
278-
}
279-
"print" => {
280-
assert!(
281-
return_data.is_empty(),
282-
"Print function should not return values"
283-
);
284-
Ok(Line::Print {
285-
line_info: pair.as_str().to_string(),
286-
content: args,
287-
})
288-
}
289-
"decompose_bits" => {
290-
assert!(
291-
args.len() == 1 && return_data.len() == 1,
292-
"Invalid decompose_bits call"
293-
);
294-
Ok(Line::DecomposeBits {
295-
var: return_data[0].clone(),
296-
to_decompose: args[0].clone(),
297-
})
298-
}
299-
"panic" => {
300-
assert!(
301-
return_data.is_empty() && args.is_empty(),
302-
"Panic has no args and returns no values"
303-
);
304-
Ok(Line::Panic)
305-
}
306-
_ => {
307-
if let Some(precompile) = PRECOMPILES
308-
.iter()
309-
.find(|p| p.name.to_string() == function_name)
310-
{
311-
assert!(
312-
args.len() == precompile.n_inputs && return_data.len() == precompile.n_outputs,
313-
"Invalid precompile call"
314-
);
315-
Ok(Line::Precompile {
316-
precompile: precompile.clone(),
317-
args,
318-
res: return_data,
319-
})
320-
} else {
321-
Ok(Line::FunctionCall {
322-
function_name,
323-
args,
324-
return_data,
325-
})
326-
}
327-
}
328-
}
329-
}
330-
331214
fn parse_condition(
332215
pair: Pair<'_, Rule>,
333216
constants: &BTreeMap<String, usize>,

0 commit comments

Comments
 (0)