@@ -52,7 +52,8 @@ pub enum OpCode {
5252 CallStr , CallInt , CallRange , Phi , CallChr , CallType ,
5353 CallFloat , CallBool , CallRound , CallMin , CallMax , CallSum ,
5454 CallSorted , CallEnumerate , CallZip , CallList , CallTuple , CallDict ,
55- CallIsInstance , CallSet , CallInput , CallOrd , BuildDict , BuildList
55+ CallIsInstance , CallSet , CallInput , CallOrd , BuildDict , BuildList ,
56+ MakeFunction , Add , Sub , Mul , Div
5657}
5758
5859#[ derive( Debug ) ] pub struct Instruction { pub opcode : OpCode , pub operand : u16 }
@@ -65,6 +66,7 @@ pub struct SSAChunk {
6566 pub instructions : Vec < Instruction > ,
6667 pub constants : Vec < Value > ,
6768 pub names : Vec < String > ,
69+ pub functions : Vec < ( Vec < String > , SSAChunk ) >
6870}
6971
7072impl SSAChunk {
@@ -124,11 +126,13 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
124126 }
125127
126128 fn current_version ( & self , name : & str ) -> u32 { self . ssa_versions . get ( name) . copied ( ) . unwrap_or ( 0 ) }
129+
127130 fn increment_version ( & mut self , name : & str ) -> u32 {
128131 let v = self . current_version ( name) + 1 ;
129132 self . ssa_versions . insert ( name. to_string ( ) , v) ;
130133 v
131134 }
135+
132136 fn emit_load_ssa ( & mut self , name : String ) {
133137 let v = self . current_version ( & name) ;
134138 let ssa = format ! ( "{}_{}" , name, v) ;
@@ -176,15 +180,27 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
176180 let t = self . advance ( ) ;
177181 match t. kind {
178182 TokenType :: Name => self . name ( t) ,
183+ TokenType :: Def => { self . func_def ( ) ; return ; } ,
179184 TokenType :: String => self . emit_const ( Value :: Str ( parse_string ( self . lexeme ( & t) ) ) ) ,
180185 TokenType :: Int | TokenType :: Float => self . parse_number ( self . lexeme ( & t) , t. kind ) ,
181186 TokenType :: True => self . emit_const ( Value :: Bool ( true ) ) ,
182187 TokenType :: False => self . emit_const ( Value :: Bool ( false ) ) ,
183188 TokenType :: None => self . emit_const ( Value :: None ) ,
184189 TokenType :: FstringStart => self . fstring ( ) ,
185190 TokenType :: Minus => { self . expr ( ) ; self . chunk . emit ( OpCode :: Minus , 0 ) ; } ,
186- TokenType :: Lbrace => self . dict_literal ( ) , // ← agrega
187- TokenType :: Lsqb => self . list_literal ( ) , // ← agrega
191+ TokenType :: Lbrace => self . dict_literal ( ) ,
192+ TokenType :: Lsqb => self . list_literal ( ) ,
193+ _ => { }
194+ }
195+ self . binary_op ( ) ;
196+ }
197+
198+ fn binary_op ( & mut self ) {
199+ match self . peek ( ) {
200+ Some ( TokenType :: Plus ) => { self . advance ( ) ; self . expr ( ) ; self . chunk . emit ( OpCode :: Add , 0 ) ; }
201+ Some ( TokenType :: Minus ) => { self . advance ( ) ; self . expr ( ) ; self . chunk . emit ( OpCode :: Sub , 0 ) ; }
202+ Some ( TokenType :: Star ) => { self . advance ( ) ; self . expr ( ) ; self . chunk . emit ( OpCode :: Mul , 0 ) ; }
203+ Some ( TokenType :: Slash ) => { self . advance ( ) ; self . expr ( ) ; self . chunk . emit ( OpCode :: Div , 0 ) ; }
188204 _ => { }
189205 }
190206 }
@@ -302,14 +318,52 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
302318 "ord" => { let a = self . parse_args ( ) ; self . chunk . emit ( OpCode :: CallOrd , a) ; }
303319 "range" => self . call_range ( ) ,
304320 _ => {
305- let i = self . chunk . push_name ( & name) ;
321+ let v = self . current_version ( & name) ;
322+ let i = self . chunk . push_name ( & format ! ( "{}_{}" , name, v) ) ;
306323 self . chunk . emit ( OpCode :: LoadName , i) ;
307324 let a = self . parse_args ( ) ;
308325 self . chunk . emit ( OpCode :: Call , a) ;
309326 }
310327 }
311328 }
312329
330+ fn func_def ( & mut self ) {
331+ let fname = { let n = self . advance ( ) ; self . lexeme ( & n) . to_string ( ) } ;
332+ let params = self . parse_params ( ) ;
333+ let body = self . compile_body ( & params) ;
334+
335+ let fi = self . chunk . functions . len ( ) as u16 ;
336+ self . chunk . functions . push ( ( params, body) ) ;
337+ self . chunk . emit ( OpCode :: MakeFunction , fi) ;
338+
339+ let ver = self . increment_version ( & fname) ;
340+ let i = self . chunk . push_name ( & format ! ( "{}_{}" , fname, ver) ) ;
341+ self . chunk . emit ( OpCode :: StoreName , i) ;
342+ }
343+
344+ fn parse_params ( & mut self ) -> Vec < String > {
345+ self . advance ( ) ; // (
346+ let mut params = Vec :: new ( ) ;
347+ while !matches ! ( self . peek( ) , Some ( TokenType :: Rpar ) | None ) {
348+ let p = self . advance ( ) ;
349+ params. push ( self . lexeme ( & p) . to_string ( ) ) ;
350+ if matches ! ( self . peek( ) , Some ( TokenType :: Comma ) ) { self . advance ( ) ; }
351+ }
352+ self . advance ( ) ; // )
353+ if matches ! ( self . peek( ) , Some ( TokenType :: Colon ) ) { self . advance ( ) ; }
354+ params
355+ }
356+
357+ fn compile_body ( & mut self , params : & [ String ] ) -> SSAChunk {
358+ let ( saved_chunk, saved_ver) = ( std:: mem:: take ( & mut self . chunk ) , std:: mem:: take ( & mut self . ssa_versions ) ) ;
359+ for p in params { self . ssa_versions . insert ( p. clone ( ) , 0 ) ; }
360+ self . stmt ( ) ;
361+ self . chunk . emit ( OpCode :: ReturnValue , 0 ) ;
362+ let body = std:: mem:: take ( & mut self . chunk ) ;
363+ ( self . chunk , self . ssa_versions ) = ( saved_chunk, saved_ver) ;
364+ body
365+ }
366+
313367 fn call_range ( & mut self ) {
314368 self . advance ( ) ;
315369 let mut args = Vec :: new ( ) ;
0 commit comments