@@ -2,8 +2,11 @@ use std::collections::BTreeMap;
22
33use 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
811pub ( 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+ }
0 commit comments