@@ -134,6 +134,16 @@ pub enum Error {
134134 } ,
135135}
136136
137+ /// Result of compilation containing all outputs
138+ pub struct CompilationResult {
139+ pub instructions : Vec < Instruction > ,
140+ pub result_type : Type ,
141+ pub variables : HashMap < String , ( Type , usize ) > ,
142+ pub program : Program ,
143+ pub type_aliases : HashMap < String , Type > ,
144+ pub module_cache : ModuleCache ,
145+ }
146+
137147struct Scope {
138148 variables : HashMap < String , ( Type , usize ) > ,
139149 parameter : Option < ( Type , usize ) > ,
@@ -169,6 +179,7 @@ pub struct Compiler<'a> {
169179}
170180
171181impl < ' a > Compiler < ' a > {
182+ #[ allow( clippy:: too_many_arguments) ]
172183 pub fn compile (
173184 program : ast:: Program ,
174185 type_aliases : HashMap < String , Type > ,
@@ -178,17 +189,7 @@ impl<'a> Compiler<'a> {
178189 module_path : Option < PathBuf > ,
179190 existing_variables : Option < & HashMap < String , ( Type , usize ) > > ,
180191 parameter_type : Type ,
181- ) -> Result <
182- (
183- Vec < Instruction > ,
184- Type ,
185- HashMap < String , ( Type , usize ) > ,
186- Program ,
187- HashMap < String , Type > ,
188- ModuleCache ,
189- ) ,
190- Error ,
191- > {
192+ ) -> Result < CompilationResult , Error > {
192193 let mut compiler = Self {
193194 codegen : InstructionBuilder :: new ( ) ,
194195 type_context : TypeContext :: new ( type_aliases) ,
@@ -271,14 +272,14 @@ impl<'a> Compiler<'a> {
271272 . map ( |( name, ( var_type, index) ) | ( name. clone ( ) , ( var_type. clone ( ) , * index) ) )
272273 . collect ( ) ;
273274
274- Ok ( (
275- compiler. codegen . instructions ,
275+ Ok ( CompilationResult {
276+ instructions : compiler. codegen . instructions ,
276277 result_type,
277278 variables,
278- compiler. program ,
279- compiler. type_context . into_type_aliases ( ) ,
280- compiler. module_cache ,
281- ) )
279+ program : compiler. program ,
280+ type_aliases : compiler. type_context . into_type_aliases ( ) ,
281+ module_cache : compiler. module_cache ,
282+ } )
282283 }
283284
284285 fn compile_statement ( & mut self , statement : ast:: Statement ) -> Result < Type , Error > {
@@ -356,19 +357,24 @@ impl<'a> Compiler<'a> {
356357
357358 // Check if this is a tuple merge (value present, no ripples)
358359 let contains_ripple = Self :: tuple_contains_ripple ( & fields) ;
359- if value_type. is_some ( ) && !contains_ripple {
360- return self . compile_tuple_merge ( tuple_name, fields, value_type. unwrap ( ) ) ;
360+ if let Some ( val_type) = value_type. clone ( )
361+ && !contains_ripple
362+ {
363+ return self . compile_tuple_merge ( tuple_name, fields, val_type) ;
361364 }
362365
363366 // Allocate ripple variable if this tuple contains ripples and we have a value
364- let ripple_index = if contains_ripple && value_type. is_some ( ) {
365- let val_type = value_type. unwrap ( ) ;
366- let ripple_var_name = format ! ( "~{}" , self . ripple_depth) ;
367- self . ripple_depth += 1 ;
368- let index = self . define_variable ( & ripple_var_name, & [ ] , val_type) ;
369- self . codegen . add_instruction ( Instruction :: Allocate ( 1 ) ) ;
370- self . codegen . add_instruction ( Instruction :: Store ( index) ) ;
371- Some ( index)
367+ let ripple_index = if contains_ripple {
368+ if let Some ( val_type) = value_type {
369+ let ripple_var_name = format ! ( "~{}" , self . ripple_depth) ;
370+ self . ripple_depth += 1 ;
371+ let index = self . define_variable ( & ripple_var_name, & [ ] , val_type) ;
372+ self . codegen . add_instruction ( Instruction :: Allocate ( 1 ) ) ;
373+ self . codegen . add_instruction ( Instruction :: Store ( index) ) ;
374+ Some ( index)
375+ } else {
376+ None
377+ }
372378 } else {
373379 None
374380 } ;
@@ -1003,10 +1009,10 @@ impl<'a> Compiler<'a> {
10031009 } ) ;
10041010
10051011 // If last_type is NIL, subsequent chains are unreachable - break early
1006- if let Some ( ref last_type) = last_type {
1007- if last_type. as_concrete ( ) == Some ( & Type :: nil ( ) ) {
1008- break ;
1009- }
1012+ if let Some ( ref last_type) = last_type
1013+ && last_type. as_concrete ( ) == Some ( & Type :: nil ( ) )
1014+ {
1015+ break ;
10101016 }
10111017
10121018 if i < expression. chains . len ( ) - 1 {
@@ -1313,9 +1319,9 @@ impl<'a> Compiler<'a> {
13131319 Ok ( accessed_type)
13141320 }
13151321 } else {
1316- return Err ( Error :: FeatureUnsupported (
1322+ Err ( Error :: FeatureUnsupported (
13171323 "Field/positional access requires a value" . to_string ( ) ,
1318- ) ) ;
1324+ ) )
13191325 }
13201326 }
13211327 Some ( name) => {
@@ -1368,12 +1374,8 @@ impl<'a> Compiler<'a> {
13681374 // If there's an argument, compile it first (may contain ripples using value_type)
13691375 let arg_type = if let Some ( args) = & tail_call. argument {
13701376 Some ( self . compile_tuple ( args. name . clone ( ) , args. fields . clone ( ) , value_type) ?)
1371- } else if let Some ( val_type) = value_type {
1372- // No argument but have piped value - use it as the argument
1373- Some ( val_type)
13741377 } else {
1375- // No argument and no piped value
1376- None
1378+ value_type
13771379 } ;
13781380
13791381 self . compile_tail_call (
@@ -1538,20 +1540,20 @@ impl<'a> Compiler<'a> {
15381540 if !matches ! ( called_receive_type, Type :: Union ( v) if v. is_empty( ) ) {
15391541 // Called function has receives - verify current context matches
15401542 // Check if current context is never (empty union = can't receive)
1541- if let Type :: Union ( variants) = & self . current_receive_type {
1542- if variants. is_empty ( ) {
1543- // Current context can't receive - can't call a receiving function
1544- return Err ( Error :: TypeMismatch {
1545- expected : "function without receive type" . to_string ( ) ,
1546- found : format ! (
1547- "function with receive type {}" ,
1548- quiver_core :: format :: format_type (
1549- & self . program ,
1550- called_receive_type
1551- )
1552- ) ,
1553- } ) ;
1554- }
1543+ if let Type :: Union ( variants) = & self . current_receive_type
1544+ && variants. is_empty ( )
1545+ {
1546+ // Current context can't receive - can't call a receiving function
1547+ return Err ( Error :: TypeMismatch {
1548+ expected : "function without receive type" . to_string ( ) ,
1549+ found : format ! (
1550+ "function with receive type {}" ,
1551+ quiver_core :: format :: format_type (
1552+ & self . program ,
1553+ called_receive_type
1554+ )
1555+ ) ,
1556+ } ) ;
15551557 }
15561558
15571559 // Check compatibility
@@ -1717,8 +1719,8 @@ impl<'a> Compiler<'a> {
17171719 for type_id in & tuple_types {
17181720 let ( _, fields) = self
17191721 . program
1720- . lookup_type ( & type_id)
1721- . ok_or_else ( || Error :: TypeNotInRegistry { type_id : * type_id } ) ?;
1722+ . lookup_type ( type_id)
1723+ . ok_or ( Error :: TypeNotInRegistry { type_id : * type_id } ) ?;
17221724
17231725 let field_count = fields. len ( ) ;
17241726
@@ -1739,7 +1741,7 @@ impl<'a> Compiler<'a> {
17391741 } else {
17401742 common_field_count = Some ( field_count) ;
17411743 // Collect first field types for return type
1742- if let Some ( ( _, first_field_type) ) = fields. get ( 0 ) {
1744+ if let Some ( ( _, first_field_type) ) = fields. first ( ) {
17431745 first_field_types. push ( first_field_type. clone ( ) ) ;
17441746 }
17451747 }
@@ -1841,15 +1843,14 @@ impl<'a> Compiler<'a> {
18411843 accessors : Vec < ast:: AccessPath > ,
18421844 ) -> Result < Type , Error > {
18431845 // Check if we have a capture for the full path (base + accessors)
1844- if !accessors. is_empty ( ) {
1845- if let Some ( ( capture_type, capture_index) ) =
1846+ if !accessors. is_empty ( )
1847+ && let Some ( ( capture_type, capture_index) ) =
18461848 self . lookup_variable ( & self . scopes , target, & accessors)
1847- {
1848- // We have a pre-evaluated capture for this exact path
1849- self . codegen
1850- . add_instruction ( Instruction :: Load ( capture_index) ) ;
1851- return Ok ( capture_type) ;
1852- }
1849+ {
1850+ // We have a pre-evaluated capture for this exact path
1851+ self . codegen
1852+ . add_instruction ( Instruction :: Load ( capture_index) ) ;
1853+ return Ok ( capture_type) ;
18531854 }
18541855
18551856 // No pre-evaluated capture, use standard member access
@@ -1922,10 +1923,10 @@ impl<'a> Compiler<'a> {
19221923 ) -> Result < ( ) , Error > {
19231924 let mut seen_names = HashSet :: new ( ) ;
19241925 for field in fields {
1925- if let Some ( field_name) = get_name ( field) {
1926- if !seen_names. insert ( field_name. clone ( ) ) {
1927- return Err ( Error :: FieldDuplicated ( field_name . clone ( ) ) ) ;
1928- }
1926+ if let Some ( field_name) = get_name ( field)
1927+ && !seen_names. insert ( field_name. clone ( ) )
1928+ {
1929+ return Err ( Error :: FieldDuplicated ( field_name . clone ( ) ) ) ;
19291930 }
19301931 }
19311932 Ok ( ( ) )
@@ -1944,7 +1945,7 @@ impl<'a> Compiler<'a> {
19441945 let ( _, fields) = self
19451946 . program
19461947 . lookup_type ( type_id)
1947- . ok_or_else ( || Error :: TypeNotInRegistry { type_id : * type_id } ) ?;
1948+ . ok_or ( Error :: TypeNotInRegistry { type_id : * type_id } ) ?;
19481949
19491950 if let Some ( ( _, field_type) ) = fields. get ( position) {
19501951 field_types. push ( field_type. clone ( ) ) ;
0 commit comments