@@ -54,7 +54,7 @@ impl Compiler {
5454
5555 fn compile_statement ( & mut self , stmt : Stmt ) {
5656 match stmt {
57- Stmt :: Template { name, args, expr } => self . compile_template ( name, args, expr) ,
57+ Stmt :: Template { name, this , args, expr } => self . compile_template ( name, this , args, expr) ,
5858 Stmt :: Function { name, expr } => self . compile_function ( name, expr) ,
5959 Stmt :: Module { name, statements } => self . compile_module ( name, statements) ,
6060 Stmt :: Include { path } => self . compile_include ( path) ,
@@ -63,11 +63,12 @@ impl Compiler {
6363 }
6464 }
6565
66- fn compile_template ( & mut self , name : Token , args : Vec < Token > , expr : Expr ) {
66+ fn compile_template ( & mut self , name : Token , this : Option < Token > , args : Vec < Token > , expr : Expr ) {
6767 let current_module = self . current_module ( ) ;
6868 let mut current_module = current_module. borrow_mut ( ) ;
6969
70- if current_module. templates . iter ( ) . any ( |template| * template. borrow ( ) . name == * name. source ( ) && template. borrow ( ) . args . len ( ) == args. len ( ) ) {
70+ if current_module. templates . iter ( ) . any ( |template|
71+ * template. borrow ( ) . name == * name. source ( ) && template. borrow ( ) . args . len ( ) == args. len ( ) && template. borrow ( ) . receiver == this. is_some ( ) ) {
7172 self . error_at ( * name. start ( ) , "Tried to define multiple templates with the same name" , false ) ;
7273 return ;
7374 }
@@ -77,6 +78,7 @@ impl Compiler {
7778
7879 current_module. templates . push ( Rc :: new ( RefCell :: new ( Template {
7980 name : name. source ( ) . to_owned ( ) ,
81+ receiver : this. is_some ( ) ,
8082 args : args. iter ( ) . map ( |arg| arg. source ( ) . to_owned ( ) ) . collect ( ) ,
8183 expr,
8284 current_modules : template_current_modules,
@@ -265,33 +267,31 @@ impl Compiler {
265267 if let Some ( ( _, element) ) = self . template_scopes . last ( ) . map ( |scope| scope. args . iter ( ) . rfind ( |( arg, _) | * arg == * name. source ( ) ) ) . flatten ( ) {
266268 element. clone ( )
267269 } else {
268- self . error_at ( * name. start ( ) , & format ! ( "Unresolved reference: '{}'" , name. source( ) ) , false ) ;
269- JsonElement :: Error
270+ self . evaluate_identifier ( name)
270271 }
271272 }
272- Expr :: Group ( expr) => self . compile_expr ( * expr) ,
273+ // Expr::Group(expr) => self.compile_expr(*expr),
273274 Expr :: UnaryOperator { operator, expr } => {
274275 let compiled_expr = self . compile_expr ( * expr) ;
275276
276- self . evaluate_template ( None , operator, vec ! [ compiled_expr] )
277+ let pos = * operator. start ( ) ;
278+ self . evaluate_template ( Expr :: Identifier ( operator) , pos, vec ! [ compiled_expr] )
277279 } ,
278280 Expr :: BinaryOperator { left, operator, right } => {
279281 let compiled_left = self . compile_expr ( * left) ;
280282 let compiled_right = self . compile_expr ( * right) ;
281283
282- self . evaluate_template ( None , operator, vec ! [ compiled_left, compiled_right] )
284+ let pos = * operator. start ( ) ;
285+ self . evaluate_template ( Expr :: Identifier ( operator) , pos, vec ! [ compiled_left, compiled_right] )
283286 } ,
284- Expr :: FunctionCall { receiver, name, args } => {
285- let compiled_receiver = receiver. map ( |receiver| self . compile_expr ( * receiver) ) ;
287+ Expr :: FunctionCall { callee, paren_left, args } => {
286288 let compiled_args = args. into_iter ( ) . map ( |arg| self . compile_expr ( arg) ) . collect ( ) ;
287289
288- self . evaluate_template ( compiled_receiver , name , compiled_args)
290+ self . evaluate_template ( * callee , * paren_left . start ( ) , compiled_args)
289291 } ,
290292 Expr :: Member { receiver, name } => {
291- let _ = self . compile_expr ( * receiver) ;
292-
293- self . error_at ( * name. start ( ) , & format ! ( "Unresolved reference: '{}'" , name. source( ) ) , false ) ;
294- JsonElement :: Error
293+ let compiled_receiver = self . compile_expr ( * receiver) ;
294+ self . evaluate_member ( compiled_receiver, name)
295295 } ,
296296 Expr :: Object ( fields) => {
297297 JsonElement :: Object ( fields. into_iter ( ) . map ( |( name, field) | ( name. source ( ) . to_owned ( ) , self . compile_expr ( field) ) ) . collect ( ) )
@@ -303,21 +303,32 @@ impl Compiler {
303303 }
304304 }
305305
306- fn evaluate_template ( & mut self , receiver : Option < JsonElement > , name : Token , args : Vec < JsonElement > ) -> JsonElement {
307- if let Some ( _) = receiver {
308- self . error_at ( * name. start ( ) , "Member functions are not implemented yet" , false ) ;
309- }
306+ fn evaluate_template ( & mut self , callee : Expr , token_pos : TokenPos , args : Vec < JsonElement > ) -> JsonElement {
307+ let ( receiver, name) = match callee {
308+ Expr :: Member { receiver, name} => ( Some ( self . compile_expr ( * receiver) ) , name) ,
309+ Expr :: Identifier ( name) => ( None , name) ,
310+ _ => {
311+ self . error_at ( token_pos, "Cannot call non-identifier expression" , true ) ;
312+ return JsonElement :: Error ;
313+ } ,
314+ } ;
310315
311- let template = match self . find_template ( & name, args. len ( ) ) {
316+ let template = match self . find_template ( & name, receiver . as_ref ( ) , args. len ( ) ) {
312317 Some ( template) => template,
313318 None => {
314319 self . error_at ( * name. start ( ) , & format ! ( "Unresolved function call: {}" , name. source( ) ) , false ) ;
315320 return JsonElement :: Error ;
316- } ,
321+ }
317322 } ;
318323 let template_borrow = template. borrow ( ) ;
319324
320325 let mut scope_args = vec ! [ ] ;
326+ // eprintln!("name: {}; template receiver: {}; provided receiver: {}; template args: {:?}; provided args: {:?}",
327+ // &template_borrow.name, template_borrow.receiver, receiver.is_some(), &template_borrow.args, &args);
328+
329+ if let Some ( receiver) = receiver {
330+ scope_args. push ( ( String :: from ( "this" ) , receiver) ) ;
331+ }
321332
322333 for i in 0 ..template_borrow. args . len ( ) {
323334 let name = template_borrow. args [ i] . clone ( ) ;
@@ -346,15 +357,22 @@ impl Compiler {
346357 expr
347358 }
348359
349- fn find_template ( & mut self , name : & Token , arg_count : usize ) -> Option < Rc < RefCell < Template > > > {
360+ fn find_template ( & mut self , name : & Token , receiver : Option < & JsonElement > , arg_count : usize ) -> Option < Rc < RefCell < Template > > > {
361+ if let Some ( receiver) = receiver {
362+ match receiver {
363+ JsonElement :: Module ( module) => return Self :: find_template_on ( module, name, false , arg_count) ,
364+ _ => { } ,
365+ }
366+ }
367+
350368 let mut module_index: isize = self . current_module . len ( ) as isize - 1 ;
351369
352370 while module_index >= -1 {
353371 let module = Rc :: clone ( if module_index >= 0 {
354372 & self . current_module [ module_index as usize ]
355373 } else { & self . top_level_module } ) ;
356374
357- if let Some ( template) = Self :: find_template_on ( & module, & name, arg_count) {
375+ if let Some ( template) = Self :: find_template_on ( & module, & name, receiver . is_some ( ) , arg_count) {
358376 return Some ( template) ;
359377 }
360378
@@ -364,16 +382,68 @@ impl Compiler {
364382 None
365383 }
366384
367- fn find_template_on ( module : & Rc < RefCell < Module > > , name : & Token , arg_count : usize ) -> Option < Rc < RefCell < Template > > > {
385+ fn find_template_on ( module : & Rc < RefCell < Module > > , name : & Token , receiver : bool , arg_count : usize ) -> Option < Rc < RefCell < Template > > > {
368386 for template in & module. borrow ( ) . templates {
369- if * template. borrow ( ) . name == * name. source ( ) && template. borrow ( ) . args . len ( ) == arg_count {
387+ if * template. borrow ( ) . name == * name. source ( ) && template. borrow ( ) . args . len ( ) == arg_count && ( template . borrow ( ) . receiver == receiver ) {
370388 return Some ( Rc :: clone ( template) ) ;
371389 }
372390 }
373391
374392 None
375393 }
376394
395+ fn evaluate_identifier ( & mut self , name : Token ) -> JsonElement {
396+ let mut module_index: isize = self . current_module . len ( ) as isize - 1 ;
397+
398+ while module_index >= -1 {
399+ let module = Rc :: clone ( if module_index >= 0 {
400+ & self . current_module [ module_index as usize ]
401+ } else { & self . top_level_module } ) ;
402+
403+ for template in & module. borrow ( ) . templates {
404+ if * template. borrow ( ) . name == * name. source ( ) && !template. borrow ( ) . receiver {
405+ return JsonElement :: Template ( Rc :: clone ( template) ) ;
406+ }
407+ }
408+
409+ for sub_module in & module. borrow ( ) . sub_modules {
410+ if * sub_module. borrow ( ) . name == * name. source ( ) {
411+ return JsonElement :: Module ( Rc :: clone ( sub_module) ) ;
412+ }
413+ }
414+
415+ module_index -= 1 ;
416+ }
417+
418+ self . error_at ( * name. start ( ) , & format ! ( "Unresolved reference: '{}'" , name. source( ) ) , false ) ;
419+ JsonElement :: Error
420+ }
421+
422+ fn evaluate_member ( & mut self , receiver : JsonElement , name : Token ) -> JsonElement {
423+ match receiver {
424+ JsonElement :: Module ( module) => {
425+ for template in & module. borrow ( ) . templates {
426+ if * template. borrow ( ) . name == * name. source ( ) {
427+ return JsonElement :: Template ( Rc :: clone ( template) ) ;
428+ }
429+ }
430+
431+ for sub_module in & module. borrow ( ) . sub_modules {
432+ if * sub_module. borrow ( ) . name == * name. source ( ) {
433+ return JsonElement :: Module ( Rc :: clone ( sub_module) ) ;
434+ }
435+ }
436+
437+ self . error_at ( * name. start ( ) , & format ! ( "Unresolved reference: '{}'" , name. source( ) ) , false ) ;
438+ JsonElement :: Error
439+ } ,
440+ _ => {
441+ self . error_at ( * name. start ( ) , "Tried to get a member of non-module value" , true ) ;
442+ JsonElement :: Error
443+ } ,
444+ }
445+ }
446+
377447 fn current_module ( & self ) -> Rc < RefCell < Module > > {
378448 self . current_module . last ( ) . map ( |module| Rc :: clone ( & module) ) . unwrap_or_else ( || Rc :: clone ( & self . top_level_module ) )
379449 }
0 commit comments