about summary refs log blame commit diff stats
path: root/client.c
blob: cb5334e7a42df96b3734e39f6d725d8598addc35 (plain) (tree)
1
2
3
4
5
6
7
8
9



                                                              
                
                   

                      
                      
 
                      
 
           












                                                                                              
                      
 

              
                  
                                  
                              
                                                




                                        
                        
                                                                             
            
                                                                                      
 
 
 








                                                                              







                                            
    
              
 

                                                          
 
 



                          
 

                       
                                         
                                
                

                                              
                               

                                      

                                                                      







                   
                       
 

                                     
               
                         
                          
         

 
    
                   
 




                       




                                                            
                         
                          
         





                   
 









                                        
 











                                        

                      








                               
                                             



                              
                             
                      
         

                          

                      








                               
                                             



                              
                                         
                      
         



                         
         

                   


    
                    
 

                       
                                    
                                                                           

                                           


    
                                       
 
                       
                     
                                 

                                     
                                                 
                   




                                 
 
                      

                   
                                


                                     
                                
                                     
                                   
                          
 
                                    
                                 
                                                                            
                                                  

                                               
                                                        
 
                                                                       
                                                                     

                                                                               
 

                                  

                          
 


                                       
 
                   
                       

                                                 
                                                                          
                    


                        

                                  
                        
                         


    
                                                
 
                                 
                                
                          
 
                       
                           
                                                            
                           
                                                            







                                             
         
                                                    
                                    
                                                   
                                     
 
                       



                         




                                                                                   
                          

 

                  
 
                   

                        



































                                                                         
                           

                           


                        
                                                                 















                                                                              


    














                                        

                                     
 
                          
                                                         











                                                          
                   
 
                         
                                      
 
                                                           

                                      



                                        

                                  

                                       
                      

                
                          
                                 
                           

                           
                      
 
 


              
                  
 
                                                                     

                       
                                      
                                            
                                

                               

         
                 
                                    

                                            
                         
                            

                            
                   
                      
 
/*
 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
 * See LICENSE file for license details.
 */
#include "dwm.h"
#include <stdlib.h>
#include <string.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>

/* static functions */

static void
grabbutton(Client *c, unsigned int button, unsigned int modifier)
{
	XGrabButton(dpy, button, modifier, c->win, False, BUTTONMASK,
			GrabModeAsync, GrabModeSync, None, None);
	XGrabButton(dpy, button, modifier | LockMask, c->win, False, BUTTONMASK,
			GrabModeAsync, GrabModeSync, None, None);
	XGrabButton(dpy, button, modifier | numlockmask, c->win, False, BUTTONMASK,
			GrabModeAsync, GrabModeSync, None, None);
	XGrabButton(dpy, button, modifier | numlockmask | LockMask, c->win, False, BUTTONMASK,
			GrabModeAsync, GrabModeSync, None, None);
}

static void
resizetitle(Client *c)
{
	int i;

	c->tw = 0;
	for(i = 0; i < ntags; i++)
		if(c->tags[i])
			c->tw += textw(tags[i]);
	c->tw += textw(c->name);
	if(c->tw > c->w)
		c->tw = c->w + 2;
	c->tx = c->x + c->w - c->tw + 2;
	c->ty = c->y;
	if(isvisible(c))
		XMoveResizeWindow(dpy, c->title, c->tx, c->ty, c->tw, c->th);
	else
		XMoveResizeWindow(dpy, c->title, c->tx + 2 * sw, c->ty, c->tw, c->th);

}

static void
ungrabbutton(Client *c, unsigned int button, unsigned int modifier)
{
	XUngrabButton(dpy, button, modifier, c->win);
	XUngrabButton(dpy, button, modifier | LockMask, c->win);
	XUngrabButton(dpy, button, modifier | numlockmask, c->win);
	XUngrabButton(dpy, button, modifier | numlockmask | LockMask, c->win);
}

static int
xerrordummy(Display *dsply, XErrorEvent *ee)
{
	return 0;
}

/* extern functions */

void
ban(Client *c)
{
	XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
	XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty);
}

void
focus(Client *c)
{
	Client *old = sel;

	if (!issel)
		return;
	if(sel && sel->ismax && sel != c)
		togglemax(NULL);
	sel = c;
	if(old && old != c) {
		grabbutton(old, AnyButton, 0);
		drawtitle(old);
	}
	ungrabbutton(c, AnyButton, 0);
	drawtitle(c);
	XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
}

void
focusnext(Arg *arg)
{
	Client *c;
   
	if(!sel)
		return;

	if(!(c = getnext(sel->next)))
		c = getnext(clients);
	if(c) {
		focus(c);
		restack();
	}
}

void
focusprev(Arg *arg)
{
	Client *c;

	if(!sel)
		return;

	if(!(c = getprev(sel->prev))) {
		for(c = clients; c && c->next; c = c->next);
		c = getprev(c);
	}
	if(c) {
		focus(c);
		restack();
	}
}

Client *
getclient(Window w)
{
	Client *c;

	for(c = clients; c; c = c->next)
		if(c->win == w)
			return c;
	return NULL;
}

Client *
getctitle(Window w)
{
	Client *c;

	for(c = clients; c; c = c->next)
		if(c->title == w)
			return c;
	return NULL;
}

void
gravitate(Client *c, Bool invert)
{
	int dx = 0, dy = 0;

	switch(c->grav) {
	default:
		break;
	case StaticGravity:
	case NorthWestGravity:
	case NorthGravity:
	case NorthEastGravity:
		dy = c->border;
		break;
	case EastGravity:
	case CenterGravity:
	case WestGravity:
		dy = -(c->h / 2) + c->border;
		break;
	case SouthEastGravity:
	case SouthGravity:
	case SouthWestGravity:
		dy = -(c->h);
		break;
	}

	switch (c->grav) {
	default:
		break;
	case StaticGravity:
	case NorthWestGravity:
	case WestGravity:
	case SouthWestGravity:
		dx = c->border;
		break;
	case NorthGravity:
	case CenterGravity:
	case SouthGravity:
		dx = -(c->w / 2) + c->border;
		break;
	case NorthEastGravity:
	case EastGravity:
	case SouthEastGravity:
		dx = -(c->w + c->border);
		break;
	}

	if(invert) {
		dx = -dx;
		dy = -dy;
	}
	c->x += dx;
	c->y += dy;
}

void
killclient(Arg *arg)
{
	if(!sel)
		return;
	if(sel->proto & PROTODELWIN)
		sendevent(sel->win, wmatom[WMProtocols], wmatom[WMDelete]);
	else
		XKillClient(dpy, sel->win);
}

void
manage(Window w, XWindowAttributes *wa)
{
	Client *c, *tc;
	Window trans;
	XSetWindowAttributes twa;

	c = emallocz(sizeof(Client));
	c->tags = emallocz(ntags * sizeof(Bool));
	c->win = w;
	c->x = c->tx = wa->x;
	c->y = c->ty = wa->y;
	c->w = c->tw = wa->width;
	c->h = wa->height;
	c->th = bh;

	c->border = 0;
	setsize(c);

	if(c->x + c->w + 2 > sw)
		c->x = sw - c->w - 2;
	if(c->x < 0)
		c->x = 0;
	if(c->y + c->h + 2 > sh)
		c->y = sh - c->h - 2;
	if(c->h != sh && c->y < bh)
		c->y = bh;

	c->proto = getproto(c->win);
	XSelectInput(dpy, c->win,
		StructureNotifyMask | PropertyChangeMask | EnterWindowMask);
	XGetTransientForHint(dpy, c->win, &trans);
	twa.override_redirect = 1;
	twa.background_pixmap = ParentRelative;
	twa.event_mask = ExposureMask | EnterWindowMask;

	c->title = XCreateWindow(dpy, root, c->tx, c->ty, c->tw, c->th,
			0, DefaultDepth(dpy, screen), CopyFromParent,
			DefaultVisual(dpy, screen),
			CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa);

	if(clients)
		clients->prev = c;
	c->next = clients;
	clients = c;

	grabbutton(c, Button1, MODKEY);
	grabbutton(c, Button2, MODKEY);
	grabbutton(c, Button3, MODKEY);

	settags(c);
	if(!c->isfloat)
		c->isfloat = trans
			|| (c->maxw && c->minw &&
				c->maxw == c->minw && c->maxh == c->minh);
	settitle(c);
	if(isvisible(c))
		sel = c;
	arrange(NULL);
	XMapWindow(dpy, c->win);
	XMapWindow(dpy, c->title);
	if(isvisible(c))
		focus(c);
}

void
resize(Client *c, Bool sizehints, Corner sticky)
{
	int bottom = c->y + c->h;
	int right = c->x + c->w;
	XWindowChanges wc;

	if(sizehints) {
		if(c->incw)
			c->w -= (c->w - c->basew) % c->incw;
		if(c->inch)
			c->h -= (c->h - c->baseh) % c->inch;
		if(c->minw && c->w < c->minw)
			c->w = c->minw;
		if(c->minh && c->h < c->minh)
			c->h = c->minh;
		if(c->maxw && c->w > c->maxw)
			c->w = c->maxw;
		if(c->maxh && c->h > c->maxh)
			c->h = c->maxh;
	}
	if(sticky == TopRight || sticky == BotRight)
		c->x = right - c->w;
	if(sticky == BotLeft || sticky == BotRight)
		c->y = bottom - c->h;

	resizetitle(c);
	wc.x = c->x;
	wc.y = c->y;
	wc.width = c->w;
	wc.height = c->h;
	if(c->w == sw && c->h == sh)
		wc.border_width = 0;
	else
		wc.border_width = 1;
	XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
	XSync(dpy, False);
}

void
setsize(Client *c)
{
	long msize;
	XSizeHints size;

	if(!XGetWMNormalHints(dpy, c->win, &size, &msize) || !size.flags)
		size.flags = PSize;
	c->flags = size.flags;
	if(c->flags & PBaseSize) {
		c->basew = size.base_width;
		c->baseh = size.base_height;
	}
	else
		c->basew = c->baseh = 0;
	if(c->flags & PResizeInc) {
		c->incw = size.width_inc;
		c->inch = size.height_inc;
	}
	else
		c->incw = c->inch = 0;
	if(c->flags & PMaxSize) {
		c->maxw = size.max_width;
		c->maxh = size.max_height;
	}
	else
		c->maxw = c->maxh = 0;
	if(c->flags & PMinSize) {
		c->minw = size.min_width;
		c->minh = size.min_height;
	}
	else
		c->minw = c->minh = 0;
	if(c->flags & PWinGravity)
		c->grav = size.win_gravity;
	else
		c->grav = NorthWestGravity;
}

void
settitle(Client *c)
{
	char **list = NULL;
	int n;
	XTextProperty name;

	name.nitems = 0;
	c->name[0] = 0;
	XGetTextProperty(dpy, c->win, &name, netatom[NetWMName]);
	if(!name.nitems)
		XGetWMName(dpy, c->win, &name);
	if(!name.nitems)
		return;
	if(name.encoding == XA_STRING)
		strncpy(c->name, (char *)name.value, sizeof(c->name));
	else {
		if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success
				&& n > 0 && *list)
		{
			strncpy(c->name, *list, sizeof(c->name));
			XFreeStringList(list);
		}
	}
	XFree(name.value);
	resizetitle(c);
}

void
togglemax(Arg *arg)
{
	int ox, oy, ow, oh;
	XEvent ev;

	if(!sel)
		return;

	if((sel->ismax = !sel->ismax)) {
		ox = sel->x;
		oy = sel->y;
		ow = sel->w;
		oh = sel->h;
		sel->x = sx;
		sel->y = sy + bh;
		sel->w = sw - 2;
		sel->h = sh - 2 - bh;

		restack();
		resize(sel, arrange == dofloat, TopLeft);

		sel->x = ox;
		sel->y = oy;
		sel->w = ow;
		sel->h = oh;
	}
	else
		resize(sel, False, TopLeft);
	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
}

void
unmanage(Client *c)
{
	XGrabServer(dpy);
	XSetErrorHandler(xerrordummy);

	XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
	XDestroyWindow(dpy, c->title);

	if(c->prev)
		c->prev->next = c->next;
	if(c->next)
		c->next->prev = c->prev;
	if(c == clients)
		clients = c->next;
	if(sel == c)
		sel = getnext(clients);
	free(c->tags);
	free(c);

	XSync(dpy, False);
	XSetErrorHandler(xerror);
	XUngrabServer(dpy);
	if(sel)
		focus(sel);
	arrange(NULL);
}

void
zoom(Arg *arg)
{
	Client *c;

	if(!sel || (arrange != dotile) || sel->isfloat || sel->ismax)
		return;

	if(sel == getnext(clients))  {
		if((c = getnext(sel->next)))
			sel = c;
		else
			return;
	}

	/* pop */
	sel->prev->next = sel->next;
	if(sel->next)
		sel->next->prev = sel->prev;
	sel->prev = NULL;
	clients->prev = sel;
	sel->next = clients;
	clients = sel;
	focus(sel);
	arrange(NULL);
}

                                                                                                                                                                                                                                                     
                                                                                                                                                                                                                                                                                                                                 


                                                                                                                                                                                                                                                                                                                                             
                                                                                                                        
                                  
                                                                                                                   

                                


                                                                                                                                                                                                                                                                                                                                                                                                                   
                                                                                                                                                                                                                                                                                                                                                                      


                                                                                                                                                                                                                                                                                                                                                                                                                               

                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                   


                                                                                                                                                                                                                                                                                                                                                                                                                         




                                                                                                                





                                                                                                                                                                            
                                                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                            



                                                                                                                                                                                                                                                                                                         
                                                                                                             
                                                                                                                                                                                               
                                                                                                                                                                                                                                                                                                     
                                                                                                                                                                                               



                                                                                                                                                                                                                                                                                                     

                                
                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                               

                                                                                                                  
                                                                                                                                                                                                                                        







                                                                                                                     
                                        
                                                                                                                                                                                                                                                 
 
                                                                                        

                                                                           
                                                                                                                              



                                                                           

                                                                                                        
                                                                                                                                                                                                                                                                                                                                       
                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
 
                                                                                                                                                                               
                                                                                        

                                                                                                                                                                                      








                                                                                                           
                                      
                                                                                                                                                                                                           
                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                       
                                                                                                                                                                                      

                                                                                                                                                                                                                                                                                                                                                                                                                                   
                                                                                                                                                                                                                                                                                                                                                                           

                                                                                                                                                                  
                                                                                                                                                     
                                                                                                                                                   
                                                                                         


                                                                                                                                                                                          


                                  
                                                                                                                                                                                                                                     
                                                                                                                                                                                                           



                                                                                                                                                       
                                                                                                                                                                                                                                                                                                                                                           
 


                                                                                                                                                                                                                                                                                                                                                           

                                                         

                                                                            

                                                         



                                                                                                                                                                                                                                                                                                                                                           
                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                           

                                                
                                                                                                                                                                                                                                                                                                                                                                                                               
                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                       


                                                                                                                                                                                                                                                                                             
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
                                      
                                                                                                                                                                                                                                                                                                                                                         
                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
                                                              




                                                                                                                                                                                                                                                                                                                                                                                                                                               



                                        
                                                                                                                   

                                
                                       
                                                                                                                                                                                                                                                                                          
                                                                     
                                                                                                                                                                                                                                                                                                                                 
                                                                                                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                  
                                  
                                                                               

                                
                                                                                                                                                                                                                                                                                                                 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                                                                                    


                                                                                                                                                                                                                                                                                                                                               
                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              

                                                                                                                                                                                                                                                                                                                                                                                                                                                              

                                                                                                                                                                                                                                                                                                                                            
                                    



                                                                                                           


                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                 
                                                                                                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   






                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                        


                                                                                                                
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              

                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                     






                                                                                                                                                                                                                                                                                                                               






                                                                                                                                                                                                                                                                                                                                    
                                                                     
                                                                                                                                                                                                                                                                                                                                 
                                                                                                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                            




                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                        
                                                                                                                
                                    
                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                     
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                     
                                                                                                                
                                    



                                                                                                           
                                                                                                                                                                                                                                                                                                                                     

                                                                                                                                                                                                                                                             
                                                                                                                                                                                                         


                                       
                                                                                                                                                                                                                                                                                 
                                                                     
                                                                                                                                                                                                                                                                                                                                 
                                                                                                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                         




                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                                                                                                        
                                                                                                                
                                    
                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              

                                                                                                                                                                                                                                                                                                                                                                                                                                                     
                                                                                                                                                                                                                                                                                                                                     
                                                                                                                
                                    




                                                                                                           
                                                                                                                                                                                                                                                                                               
                                                                                                                           

                                                                                                               
                                                                                                                                                                                                                                                                                                                                   
                                                                                                                                                                                                                                                       
                                                                                                                                                                                                                                                                                                                      

                                                                                                                                                                                                                                                                                                             
                                                                                                                                                        

                                                       
                                    



                                                                                                                                                                                                                                          

                                                                                                                                                                                         
                                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                           


                                                                               

                                                                                                                                                                                                                                                 
                                                                                                                             
                                                                                                                                                                                                                                                                                                                            

                                                                                                                                                                                                                               

                                                                                                               
                                    
                                  
                                                                                                            

                                
                                                                                              
                                        
                                                                                                             
 
                                        
                                                                                                                                         
                                                                         


                                                                 
                                                                                            
                                                  
                                                                                        

                                                                           
                                        
                                                                         
 
                                                                 

                                                                                              
                                                  
                                        
                                                                         
 
                                                                                        

                                                                           
                                                                 

                                                                             
                                        





                                                                                                                                                                                                                                                                             
 
                                                                                  
                                                                                                                                                            








                                                                                                               
                                                                                                  
                                        

                                                                                                                                           
                                                                                          



                                                                                                              
                                                                                                                                






                                                                                                                                

                                                                                                                                                   

        
                                           
                                   
 
                                                                                              

                  
                                                                                                                                                    



                                                                                                                                 

                                                                                                                                                   

        
                                                                                              

                  
                                                                                                                                                    
 
                                           
                                   


                                       
                                                                                                               
                                        
                                                                                                            
 
                                                                                             
                                                                         
 
                                                                                       
                                                                         




                                                                                                                
                                        
             

                                                                                                                                                 
 
                                                                                       
                  
                                                                         
 
                                                                                                           


                                                                                                         
                                        
                                                                                                                                                                          
 
                                                                                                                    

                  
                                                                         
 
                                                                                                                    

                  
                                                                         




                                                                                                                    
                                        
                                                                                                                                                                                 
 
                                                                                                                    

                  
                                                                         
 
                                                                                                                    

                  
                                                                         




                                                                                                          
                                        
                                                                                                                 
 
                                                                                                                    

                  
                                                                         
 
                                                                                       

                  
                                                                         



                                                                 
                                      
                                                                                                                                                                      


                                                                                                                                                                                                  

                                                                                                                                                    
                                                                                                                                                                                                                                                                                                                                         
                                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                                                     
                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                        

                                                                                                                 

                                                                                
                                        

                                                                                                                
 
                                                                                       

                  
                                                                         
 
                                                                                             

                  
                                                                         
 
                                                                                              

                  
                                                                         


                                                                 


                                                                                         
                                        
                                                                            
 
                                                                                       

                  
                                                                         
 
                                                                                                                    

                  
                                                                         
 

                                                                                                       
 
                                                                                   
                                        
             

                                                                                                             
 
                                                                                                                   

                                                                         
                                                                                                          
                                                                                              



                                                                         
                                                                 
                                                                          


       
                                     
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Mu - 054static_dispatch.cc</title>
<meta name="Generator" content="Vim/7.4">
<meta name="plugin-version" content="vim7.4_v2">
<meta name="syntax" content="cpp">
<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
<meta name="colorscheme" content="minimal">
<style type="text/css">
<!--
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 12pt; font-size: 1em; }
.Constant { color: #00a0a0; }
.traceAbsent { color: #c00000; }
.cSpecial { color: #008000; }
.muRecipe { color: #ff8700; }
.Comment { color: #9090ff; }
.Delimiter { color: #800080; }
.Special { color: #c00000; }
.traceContains { color: #008000; }
.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; }
.muData { color: #ffff00; }
.Identifier { color: #c0a020; }
-->
</style>

<script type='text/javascript'>
<!--

-->
</script>
</head>
<body>
<pre id='vimCodeElement'>
<span class="Comment">//: Transform to maintain multiple variants of a recipe depending on the</span>
<span class="Comment">//: number and types of the ingredients and products. Allows us to use nice</span>
<span class="Comment">//: names like 'print' or 'length' in many mutually extensible ways.</span>

<span class="Delimiter">:(scenario static_dispatch)</span>
<span class="muRecipe">def</span> main [
  <span class="Constant">7</span>:num/<span class="Special">raw &lt;- </span>test <span class="Constant">3</span>
]
<span class="muRecipe">def</span> test a:num<span class="muRecipe"> -&gt; </span>z:num [
  z<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>
]
<span class="muRecipe">def</span> test a:num<span class="Delimiter">,</span> b:num<span class="muRecipe"> -&gt; </span>z:num [
  z<span class="Special"> &lt;- </span>copy <span class="Constant">2</span>
]
<span class="traceContains">+mem: storing 1 in location 7</span>

<span class="Comment">//: When loading recipes, accumulate variants if headers don't collide, and</span>
<span class="Comment">//: flag an error if headers collide.</span>

<span class="Delimiter">:(before &quot;End Globals&quot;)</span>
map&lt;string<span class="Delimiter">,</span> vector&lt;recipe_ordinal&gt; &gt; Recipe_variants<span class="Delimiter">;</span>
<span class="Delimiter">:(before &quot;End One-time Setup&quot;)</span>
put<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> <span class="Constant">&quot;main&quot;</span><span class="Delimiter">,</span> vector&lt;recipe_ordinal&gt;<span class="Delimiter">());</span>  <span class="Comment">// since we manually added main to Recipe_ordinal</span>

<span class="Delimiter">:(before &quot;End Globals&quot;)</span>
map&lt;string<span class="Delimiter">,</span> vector&lt;recipe_ordinal&gt; &gt; Recipe_variants_snapshot<span class="Delimiter">;</span>
<span class="Delimiter">:(before &quot;End save_snapshots&quot;)</span>
Recipe_variants_snapshot = Recipe_variants<span class="Delimiter">;</span>
<span class="Delimiter">:(before &quot;End restore_snapshots&quot;)</span>
Recipe_variants = Recipe_variants_snapshot<span class="Delimiter">;</span>

<span class="Delimiter">:(before &quot;End Load Recipe Header(result)&quot;)</span>
<span class="Comment">// there can only ever be one variant for main</span>
<span class="Normal">if</span> <span class="Delimiter">(</span>result<span class="Delimiter">.</span>name != <span class="Constant">&quot;main&quot;</span> &amp;&amp; contains_key<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span>
  <span class="Normal">const</span> recipe_ordinal r = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
  <span class="Normal">if</span> <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">)</span> || get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>has_header<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    string new_name = matching_variant_name<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>new_name<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
      <span class="Comment">// variant doesn't already exist</span>
      new_name = next_unused_recipe_name<span class="Delimiter">(</span>result<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
      put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> new_name<span class="Delimiter">,</span> Next_recipe_ordinal++<span class="Delimiter">);</span>
      get_or_insert<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> new_name<span class="Delimiter">));</span>
    <span class="Delimiter">}</span>
    trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">&quot;load&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;switching &quot;</span> &lt;&lt; result<span class="Delimiter">.</span>name &lt;&lt; <span class="Constant">&quot; to &quot;</span> &lt;&lt; new_name &lt;&lt; end<span class="Delimiter">();</span>
    result<span class="Delimiter">.</span>name = new_name<span class="Delimiter">;</span>
    result<span class="Delimiter">.</span>is_autogenerated = <span class="Constant">true</span><span class="Delimiter">;</span>
  <span class="Delimiter">}</span>
<span class="Delimiter">}</span>
<span class="Normal">else</span> <span class="Delimiter">{</span>
  <span class="Comment">// save first variant</span>
  put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">,</span> Next_recipe_ordinal++<span class="Delimiter">);</span>
  get_or_insert<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">));</span>
<span class="Delimiter">}</span>

<span class="Delimiter">:(code)</span>
string matching_variant_name<span class="Delimiter">(</span><span class="Normal">const</span> recipe&amp; rr<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  <span class="Normal">const</span> vector&lt;recipe_ordinal&gt;&amp; variants = get_or_insert<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> rr<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; SIZE<span class="Delimiter">(</span>variants<span class="Delimiter">);</span>  ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
    <span class="Normal">const</span> recipe&amp; candidate = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>!all_reagents_match<span class="Delimiter">(</span>rr<span class="Delimiter">,</span> candidate<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
    <span class="Identifier">return</span> candidate<span class="Delimiter">.</span>name<span class="Delimiter">;</span>
  <span class="Delimiter">}</span>
  <span class="Identifier">return</span> <span class="Constant">&quot;&quot;</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>

<span class="Normal">bool</span> all_reagents_match<span class="Delimiter">(</span><span class="Normal">const</span> recipe&amp; r1<span class="Delimiter">,</span> <span class="Normal">const</span> recipe&amp; r2<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>r1<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != SIZE<span class="Delimiter">(</span>r2<span class="Delimiter">.</span>ingredients<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
  <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>r1<span class="Delimiter">.</span>products<span class="Delimiter">)</span> != SIZE<span class="Delimiter">(</span>r2<span class="Delimiter">.</span>products<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; SIZE<span class="Delimiter">(</span>r1<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span>  ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    expand_type_abbreviations<span class="Delimiter">(</span>r1<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">);</span>
    expand_type_abbreviations<span class="Delimiter">(</span>r2<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">);</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>!deeply_equal_type_names<span class="Delimiter">(</span>r1<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> r2<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span>
      <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
  <span class="Delimiter">}</span>
  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; SIZE<span class="Delimiter">(</span>r1<span class="Delimiter">.</span>products<span class="Delimiter">);</span>  ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    expand_type_abbreviations<span class="Delimiter">(</span>r1<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">);</span>
    expand_type_abbreviations<span class="Delimiter">(</span>r2<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">);</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>!deeply_equal_type_names<span class="Delimiter">(</span>r1<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> r2<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span>
      <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
  <span class="Delimiter">}</span>
  <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>

<span class="Delimiter">:(before &quot;End Globals&quot;)</span>
set&lt;string&gt; Literal_type_names<span class="Delimiter">;</span>
<span class="Delimiter">:(before &quot;End One-time Setup&quot;)</span>
Literal_type_names<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">&quot;number&quot;</span><span class="Delimiter">);</span>
Literal_type_names<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">&quot;character&quot;</span><span class="Delimiter">);</span>
<span class="Delimiter">:(code)</span>
<span class="Normal">bool</span> deeply_equal_type_names<span class="Delimiter">(</span><span class="Normal">const</span> reagent&amp; a<span class="Delimiter">,</span> <span class="Normal">const</span> reagent&amp; b<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  <span class="Identifier">return</span> deeply_equal_type_names<span class="Delimiter">(</span>a<span class="Delimiter">.</span>type<span class="Delimiter">,</span> b<span class="Delimiter">.</span>type<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
<span class="Normal">bool</span> deeply_equal_type_names<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* a<span class="Delimiter">,</span> <span class="Normal">const</span> type_tree* b<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  <span class="Normal">if</span> <span class="Delimiter">(</span>!a<span class="Delimiter">)</span> <span class="Identifier">return</span> !b<span class="Delimiter">;</span>
  <span class="Normal">if</span> <span class="Delimiter">(</span>!b<span class="Delimiter">)</span> <span class="Identifier">return</span> !a<span class="Delimiter">;</span>
  <span class="Normal">if</span> <span class="Delimiter">(</span>a<span class="Delimiter">-&gt;</span>name == <span class="Constant">&quot;literal&quot;</span> &amp;&amp; b<span class="Delimiter">-&gt;</span>name == <span class="Constant">&quot;literal&quot;</span><span class="Delimiter">)</span>
    <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
  <span class="Normal">if</span> <span class="Delimiter">(</span>a<span class="Delimiter">-&gt;</span>name == <span class="Constant">&quot;literal&quot;</span><span class="Delimiter">)</span>
    <span class="Identifier">return</span> Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>b<span class="Delimiter">-&gt;</span>name<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">();</span>
  <span class="Normal">if</span> <span class="Delimiter">(</span>b<span class="Delimiter">-&gt;</span>name == <span class="Constant">&quot;literal&quot;</span><span class="Delimiter">)</span>
    <span class="Identifier">return</span> Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>a<span class="Delimiter">-&gt;</span>name<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">();</span>
  <span class="Identifier">return</span> a<span class="Delimiter">-&gt;</span>name == b<span class="Delimiter">-&gt;</span>name
      &amp;&amp; deeply_equal_type_names<span class="Delimiter">(</span>a<span class="Delimiter">-&gt;</span>left<span class="Delimiter">,</span> b<span class="Delimiter">-&gt;</span>left<span class="Delimiter">)</span>
      &amp;&amp; deeply_equal_type_names<span class="Delimiter">(</span>a<span class="Delimiter">-&gt;</span>right<span class="Delimiter">,</span> b<span class="Delimiter">-&gt;</span>right<span class="Delimiter">);</span>
<span class="Delimiter">}</span>

string next_unused_recipe_name<span class="Delimiter">(</span><span class="Normal">const</span> string&amp; recipe_name<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">2</span><span class="Delimiter">;</span>  <span class="Comment">/*</span><span class="Comment">forever</span><span class="Comment">*/</span><span class="Delimiter">;</span>  ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    ostringstream out<span class="Delimiter">;</span>
    out &lt;&lt; recipe_name &lt;&lt; <span class="Constant">'_'</span> &lt;&lt; i<span class="Delimiter">;</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> out<span class="Delimiter">.</span>str<span class="Delimiter">()))</span>
      <span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
  <span class="Delimiter">}</span>
<span class="Delimiter">}</span>

<span class="Comment">//: Once all the recipes are loaded, transform their bodies to replace each</span>
<span class="Comment">//: call with the most suitable variant.</span>

<span class="Delimiter">:(scenario static_dispatch_picks_most_similar_variant)</span>
<span class="muRecipe">def</span> main [
  <span class="Constant">7</span>:num/<span class="Special">raw &lt;- </span>test <span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">4</span><span class="Delimiter">,</span> <span class="Constant">5</span>
]
<span class="muRecipe">def</span> test a:num<span class="muRecipe"> -&gt; </span>z:num [
  z<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>
]
<span class="muRecipe">def</span> test a:num<span class="Delimiter">,</span> b:num<span class="muRecipe"> -&gt; </span>z:num [
  z<span class="Special"> &lt;- </span>copy <span class="Constant">2</span>
]
<span class="traceContains">+mem: storing 2 in location 7</span>

<span class="Comment">//: support recipe headers in a previous transform to fill in missing types</span>
<span class="Delimiter">:(before &quot;End check_or_set_invalid_types&quot;)</span>
<span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; SIZE<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span>  ++i<span class="Delimiter">)</span>
  check_or_set_invalid_types<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">,</span> maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">),</span> <span class="Constant">&quot;recipe header ingredient&quot;</span><span class="Delimiter">);</span>
<span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; SIZE<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>products<span class="Delimiter">);</span>  ++i<span class="Delimiter">)</span>
  check_or_set_invalid_types<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">,</span> maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">),</span> <span class="Constant">&quot;recipe header product&quot;</span><span class="Delimiter">);</span>

<span class="Comment">//: after filling in all missing types (because we'll be introducing 'blank' types in this transform in a later layer, for shape-shifting recipes)</span>
<span class="Delimiter">:(after &quot;Transform.push_back(transform_names)&quot;)</span>
Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>resolve_ambiguous_calls<span class="Delimiter">);</span>  <span class="Comment">// idempotent</span>

<span class="Comment">//: In a later layer we'll introduce recursion in resolve_ambiguous_calls, by</span>
<span class="Comment">//: having it generate code for shape-shifting recipes and then transform such</span>
<span class="Comment">//: code. This data structure will help error messages be more useful.</span>
<span class="Comment">//:</span>
<span class="Comment">//: We're punning the 'call' data structure just because it has slots for</span>
<span class="Comment">//: calling recipe and calling instruction.</span>
<span class="Delimiter">:(before &quot;End Globals&quot;)</span>
list&lt;call&gt; resolve_stack<span class="Delimiter">;</span>

<span class="Delimiter">:(code)</span>
<span class="Normal">void</span> resolve_ambiguous_calls<span class="Delimiter">(</span><span class="Normal">const</span> recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  recipe&amp; caller_recipe = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
  trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;--- resolve ambiguous calls for recipe &quot;</span> &lt;&lt; caller_recipe<span class="Delimiter">.</span>name &lt;&lt; end<span class="Delimiter">();</span>
  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> index = <span class="Constant">0</span><span class="Delimiter">;</span>  index &lt; SIZE<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">);</span>  ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    instruction&amp; inst = caller_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>is_label<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>non_ghost_size<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">))</span> == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
    trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;instruction &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>original_string &lt;&lt; end<span class="Delimiter">();</span>
    resolve_stack<span class="Delimiter">.</span>push_front<span class="Delimiter">(</span>call<span class="Delimiter">(</span>r<span class="Delimiter">));</span>
    resolve_stack<span class="Delimiter">.</span>front<span class="Delimiter">().</span>running_step_index = index<span class="Delimiter">;</span>
    string new_name = best_variant<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">);</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>!new_name<span class="Delimiter">.</span>empty<span class="Delimiter">())</span>
      inst<span class="Delimiter">.</span>name = new_name<span class="Delimiter">;</span>
    assert<span class="Delimiter">(</span>resolve_stack<span class="Delimiter">.</span>front<span class="Delimiter">().</span>running_recipe == r<span class="Delimiter">);</span>
    assert<span class="Delimiter">(</span>resolve_stack<span class="Delimiter">.</span>front<span class="Delimiter">().</span>running_step_index == index<span class="Delimiter">);</span>
    resolve_stack<span class="Delimiter">.</span>pop_front<span class="Delimiter">();</span>
  <span class="Delimiter">}</span>
<span class="Delimiter">}</span>

string best_variant<span class="Delimiter">(</span>instruction&amp; inst<span class="Delimiter">,</span> <span class="Normal">const</span> recipe&amp; caller_recipe<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  vector&lt;recipe_ordinal&gt;&amp; variants = get<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
  vector&lt;recipe_ordinal&gt; candidates<span class="Delimiter">;</span>

  <span class="Comment">// Static Dispatch Phase 1</span>
  candidates = strictly_matching_variants<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> variants<span class="Delimiter">);</span>
  <span class="Normal">if</span> <span class="Delimiter">(</span>!candidates<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> best_variant<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> candidates<span class="Delimiter">).</span>name<span class="Delimiter">;</span>

  <span class="Comment">// Static Dispatch Phase 2</span>
  candidates = strictly_matching_variants_except_literal_zero_against_address<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> variants<span class="Delimiter">);</span>
  <span class="Normal">if</span> <span class="Delimiter">(</span>!candidates<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> best_variant<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> candidates<span class="Delimiter">).</span>name<span class="Delimiter">;</span>

  <span class="Comment">// Static Dispatch Phase 3</span>
  <span class="Comment">//: (shape-shifting recipes in a later layer)</span>
  <span class="Comment">// End Static Dispatch Phase 3</span>

  <span class="Comment">// Static Dispatch Phase 4</span>
  candidates = strictly_matching_variants_except_literal_against_address_or_boolean<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> variants<span class="Delimiter">);</span>
  <span class="Normal">if</span> <span class="Delimiter">(</span>!candidates<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> best_variant<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> candidates<span class="Delimiter">).</span>name<span class="Delimiter">;</span>

  <span class="Comment">// Static Dispatch Phase 5</span>
  candidates = matching_variants<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> variants<span class="Delimiter">);</span>
  <span class="Normal">if</span> <span class="Delimiter">(</span>!candidates<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> best_variant<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> candidates<span class="Delimiter">).</span>name<span class="Delimiter">;</span>

  <span class="Comment">// error messages</span>
  <span class="Normal">if</span> <span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &gt;= MAX_PRIMITIVE_RECIPES<span class="Delimiter">)</span> <span class="Delimiter">{</span>  <span class="Comment">// we currently don't check types for primitive variants</span>
    raise &lt;&lt; maybe<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;failed to find a matching call for '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
    <span class="Normal">for</span> <span class="Delimiter">(</span>list&lt;call&gt;::iterator p = <span class="Comment">/*</span><span class="Comment">skip</span><span class="Comment">*/</span>++resolve_stack<span class="Delimiter">.</span>begin<span class="Delimiter">();</span>  p != resolve_stack<span class="Delimiter">.</span>end<span class="Delimiter">();</span>  ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
      <span class="Normal">const</span> recipe&amp; specializer_recipe = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> p<span class="Delimiter">-&gt;</span>running_recipe<span class="Delimiter">);</span>
      <span class="Normal">const</span> instruction&amp; specializer_inst = specializer_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>p<span class="Delimiter">-&gt;</span>running_step_index<span class="Delimiter">);</span>
      <span class="Normal">if</span> <span class="Delimiter">(</span>specializer_recipe<span class="Delimiter">.</span>name != <span class="Constant">&quot;interactive&quot;</span><span class="Delimiter">)</span>
        raise &lt;&lt; <span class="Constant">&quot;  (from '&quot;</span> &lt;&lt; to_original_string<span class="Delimiter">(</span>specializer_inst<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;' in &quot;</span> &lt;&lt; specializer_recipe<span class="Delimiter">.</span>name &lt;&lt; <span class="Constant">&quot;)</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
      <span class="Normal">else</span>
        raise &lt;&lt; <span class="Constant">&quot;  (from '&quot;</span> &lt;&lt; to_original_string<span class="Delimiter">(</span>specializer_inst<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;')</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
      <span class="Comment">// One special-case to help with the rewrite_stash transform. (cross-layer)</span>
      <span class="Normal">if</span> <span class="Delimiter">(</span>specializer_inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">&quot;stash_&quot;</span><span class="Delimiter">)</span> == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
        instruction stash_inst<span class="Delimiter">;</span>
        <span class="Normal">if</span> <span class="Delimiter">(</span>next_stash<span class="Delimiter">(</span>*p<span class="Delimiter">,</span> &amp;stash_inst<span class="Delimiter">))</span> <span class="Delimiter">{</span>
          <span class="Normal">if</span> <span class="Delimiter">(</span>specializer_recipe<span class="Delimiter">.</span>name != <span class="Constant">&quot;interactive&quot;</span><span class="Delimiter">)</span>
            raise &lt;&lt; <span class="Constant">&quot;  (part of '&quot;</span> &lt;&lt; stash_inst<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;' in &quot;</span> &lt;&lt; specializer_recipe<span class="Delimiter">.</span>name &lt;&lt; <span class="Constant">&quot;)</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
          <span class="Normal">else</span>
            raise &lt;&lt; <span class="Constant">&quot;  (part of '&quot;</span> &lt;&lt; stash_inst<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;')</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
        <span class="Delimiter">}</span>
      <span class="Delimiter">}</span>
    <span class="Delimiter">}</span>
  <span class="Delimiter">}</span>
  <span class="Identifier">return</span> <span class="Constant">&quot;&quot;</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>

<span class="Comment">// phase 1</span>
vector&lt;recipe_ordinal&gt; strictly_matching_variants<span class="Delimiter">(</span><span class="Normal">const</span> instruction&amp; inst<span class="Delimiter">,</span> vector&lt;recipe_ordinal&gt;&amp; variants<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  vector&lt;recipe_ordinal&gt; result<span class="Delimiter">;</span>
  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; SIZE<span class="Delimiter">(</span>variants<span class="Delimiter">);</span>  ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> == -<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
    trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;checking variant (strict) &quot;</span> &lt;&lt; i &lt;&lt; <span class="Constant">&quot;: &quot;</span> &lt;&lt; header_label<span class="Delimiter">(</span>variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> &lt;&lt; end<span class="Delimiter">();</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>all_header_reagents_strictly_match<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))))</span>
      result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
  <span class="Delimiter">}</span>
  <span class="Identifier">return</span> result<span class="Delimiter">;</span>
<span class="Delimiter">}</span>

<span class="Normal">bool</span> all_header_reagents_strictly_match<span class="Delimiter">(</span><span class="Normal">const</span> instruction&amp; inst<span class="Delimiter">,</span> <span class="Normal">const</span> recipe&amp; variant<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; min<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">),</span> SIZE<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>ingredients<span class="Delimiter">));</span>  ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>!types_strictly_match<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
      trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;strict match failed: ingredient &quot;</span> &lt;&lt; i &lt;&lt; end<span class="Delimiter">();</span>
      <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
    <span class="Delimiter">}</span>
  <span class="Delimiter">}</span>
  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; min<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">),</span> SIZE<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>products<span class="Delimiter">));</span>  ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>is_dummy<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>!types_strictly_match<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
      trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;strict match failed: product &quot;</span> &lt;&lt; i &lt;&lt; end<span class="Delimiter">();</span>
      <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
    <span class="Delimiter">}</span>
  <span class="Delimiter">}</span>
  <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>

<span class="Comment">// phase 2</span>
vector&lt;recipe_ordinal&gt; strictly_matching_variants_except_literal_zero_against_address<span class="Delimiter">(</span><span class="Normal">const</span> instruction&amp; inst<span class="Delimiter">,</span> vector&lt;recipe_ordinal&gt;&amp; variants<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  vector&lt;recipe_ordinal&gt; result<span class="Delimiter">;</span>
  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; SIZE<span class="Delimiter">(</span>variants<span class="Delimiter">);</span>  ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> == -<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
    trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;checking variant (strict except literal-zero-against-address) &quot;</span> &lt;&lt; i &lt;&lt; <span class="Constant">&quot;: &quot;</span> &lt;&lt; header_label<span class="Delimiter">(</span>variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> &lt;&lt; end<span class="Delimiter">();</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>all_header_reagents_strictly_match_except_literal_zero_against_address<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))))</span>
      result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
  <span class="Delimiter">}</span>
  <span class="Identifier">return</span> result<span class="Delimiter">;</span>
<span class="Delimiter">}</span>

<span class="Normal">bool</span> all_header_reagents_strictly_match_except_literal_zero_against_address<span class="Delimiter">(</span><span class="Normal">const</span> instruction&amp; inst<span class="Delimiter">,</span> <span class="Normal">const</span> recipe&amp; variant<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; min<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">),</span> SIZE<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>ingredients<span class="Delimiter">));</span>  ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>!types_strictly_match_except_literal_zero_against_address<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
      trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;match failed: ingredient &quot;</span> &lt;&lt; i &lt;&lt; end<span class="Delimiter">();</span>
      <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
    <span class="Delimiter">}</span>
  <span class="Delimiter">}</span>
  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; min<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">),</span> SIZE<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>products<span class="Delimiter">));</span>  ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>is_dummy<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>!types_strictly_match<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
      trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;match failed: product &quot;</span> &lt;&lt; i &lt;&lt; end<span class="Delimiter">();</span>
      <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
    <span class="Delimiter">}</span>
  <span class="Delimiter">}</span>
  <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>

<span class="Normal">bool</span> types_strictly_match_except_literal_zero_against_address<span class="Delimiter">(</span><span class="Normal">const</span> reagent&amp; to<span class="Delimiter">,</span> <span class="Normal">const</span> reagent&amp; from<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>from<span class="Delimiter">)</span> &amp;&amp; is_mu_address<span class="Delimiter">(</span>to<span class="Delimiter">))</span>
    <span class="Identifier">return</span> from<span class="Delimiter">.</span>name == <span class="Constant">&quot;0&quot;</span><span class="Delimiter">;</span>
  <span class="Identifier">return</span> types_strictly_match<span class="Delimiter">(</span>to<span class="Delimiter">,</span> from<span class="Delimiter">);</span>
<span class="Delimiter">}</span>

<span class="Comment">// phase 4</span>
vector&lt;recipe_ordinal&gt; strictly_matching_variants_except_literal_against_address_or_boolean<span class="Delimiter">(</span><span class="Normal">const</span> instruction&amp; inst<span class="Delimiter">,</span> vector&lt;recipe_ordinal&gt;&amp; variants<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  vector&lt;recipe_ordinal&gt; result<span class="Delimiter">;</span>
  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; SIZE<span class="Delimiter">(</span>variants<span class="Delimiter">);</span>  ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> == -<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
    trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;checking variant (strict except literal-against-boolean) &quot;</span> &lt;&lt; i &lt;&lt; <span class="Constant">&quot;: &quot;</span> &lt;&lt; header_label<span class="Delimiter">(</span>variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> &lt;&lt; end<span class="Delimiter">();</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>all_header_reagents_strictly_match_except_literal_against_address_or_boolean<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))))</span>
      result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
  <span class="Delimiter">}</span>
  <span class="Identifier">return</span> result<span class="Delimiter">;</span>
<span class="Delimiter">}</span>

<span class="Normal">bool</span> all_header_reagents_strictly_match_except_literal_against_address_or_boolean<span class="Delimiter">(</span><span class="Normal">const</span> instruction&amp; inst<span class="Delimiter">,</span> <span class="Normal">const</span> recipe&amp; variant<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; min<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">),</span> SIZE<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>ingredients<span class="Delimiter">));</span>  ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>!types_strictly_match_except_literal_against_address_or_boolean<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
      trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;match failed: ingredient &quot;</span> &lt;&lt; i &lt;&lt; end<span class="Delimiter">();</span>
      <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
    <span class="Delimiter">}</span>
  <span class="Delimiter">}</span>
  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; min<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>products<span class="Delimiter">),</span> SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">));</span>  ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>is_dummy<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>!types_strictly_match_except_literal_against_address_or_boolean<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
      trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;match failed: product &quot;</span> &lt;&lt; i &lt;&lt; end<span class="Delimiter">();</span>
      <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
    <span class="Delimiter">}</span>
  <span class="Delimiter">}</span>
  <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>

<span class="Normal">bool</span> types_strictly_match_except_literal_against_address_or_boolean<span class="Delimiter">(</span><span class="Normal">const</span> reagent&amp; to<span class="Delimiter">,</span> <span class="Normal">const</span> reagent&amp; from<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>from<span class="Delimiter">)</span> &amp;&amp; is_mu_boolean<span class="Delimiter">(</span>to<span class="Delimiter">))</span>
    <span class="Identifier">return</span> from<span class="Delimiter">.</span>name == <span class="Constant">&quot;0&quot;</span> || from<span class="Delimiter">.</span>name == <span class="Constant">&quot;1&quot;</span><span class="Delimiter">;</span>
  <span class="Identifier">return</span> types_strictly_match_except_literal_zero_against_address<span class="Delimiter">(</span>to<span class="Delimiter">,</span> from<span class="Delimiter">);</span>
<span class="Delimiter">}</span>

<span class="Comment">// phase 5</span>
vector&lt;recipe_ordinal&gt; matching_variants<span class="Delimiter">(</span><span class="Normal">const</span> instruction&amp; inst<span class="Delimiter">,</span> vector&lt;recipe_ordinal&gt;&amp; variants<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  vector&lt;recipe_ordinal&gt; result<span class="Delimiter">;</span>
  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; SIZE<span class="Delimiter">(</span>variants<span class="Delimiter">);</span>  ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> == -<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
    trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;checking variant &quot;</span> &lt;&lt; i &lt;&lt; <span class="Constant">&quot;: &quot;</span> &lt;&lt; header_label<span class="Delimiter">(</span>variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> &lt;&lt; end<span class="Delimiter">();</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>all_header_reagents_match<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))))</span>
      result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
  <span class="Delimiter">}</span>
  <span class="Identifier">return</span> result<span class="Delimiter">;</span>
<span class="Delimiter">}</span>

<span class="Normal">bool</span> all_header_reagents_match<span class="Delimiter">(</span><span class="Normal">const</span> instruction&amp; inst<span class="Delimiter">,</span> <span class="Normal">const</span> recipe&amp; variant<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; min<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">),</span> SIZE<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>ingredients<span class="Delimiter">));</span>  ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
      trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;match failed: ingredient &quot;</span> &lt;&lt; i &lt;&lt; end<span class="Delimiter">();</span>
      <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
    <span class="Delimiter">}</span>
  <span class="Delimiter">}</span>
  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; min<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>products<span class="Delimiter">),</span> SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">));</span>  ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>is_dummy<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
      trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;match failed: product &quot;</span> &lt;&lt; i &lt;&lt; end<span class="Delimiter">();</span>
      <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
    <span class="Delimiter">}</span>
  <span class="Delimiter">}</span>
  <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>

<span class="Comment">// tie-breaker for each phase</span>
<span class="Normal">const</span> recipe&amp; best_variant<span class="Delimiter">(</span><span class="Normal">const</span> instruction&amp; inst<span class="Delimiter">,</span> vector&lt;recipe_ordinal&gt;&amp; candidates<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  assert<span class="Delimiter">(</span>!candidates<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
  <span class="Normal">int</span> min_score = <span class="Constant">999</span><span class="Delimiter">;</span>
  <span class="Normal">int</span> min_index = <span class="Constant">0</span><span class="Delimiter">;</span>
  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; SIZE<span class="Delimiter">(</span>candidates<span class="Delimiter">);</span>  ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    <span class="Normal">const</span> recipe&amp; candidate = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> candidates<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
    <span class="Normal">int</span> score = abs<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>candidate<span class="Delimiter">.</span>products<span class="Delimiter">)</span>-SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">))</span>
                          + abs<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>candidate<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span>-SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">));</span>
    assert<span class="Delimiter">(</span>score &lt; <span class="Constant">999</span><span class="Delimiter">);</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>score &lt; min_score<span class="Delimiter">)</span> <span class="Delimiter">{</span>
      min_score = score<span class="Delimiter">;</span>
      min_index = i<span class="Delimiter">;</span>
    <span class="Delimiter">}</span>
  <span class="Delimiter">}</span>
  <span class="Identifier">return</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> candidates<span class="Delimiter">.</span>at<span class="Delimiter">(</span>min_index<span class="Delimiter">));</span>
<span class="Delimiter">}</span>

<span class="Normal">int</span> non_ghost_size<span class="Delimiter">(</span>vector&lt;recipe_ordinal&gt;&amp; variants<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  <span class="Normal">int</span> result = <span class="Constant">0</span><span class="Delimiter">;</span>
  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; SIZE<span class="Delimiter">(</span>variants<span class="Delimiter">);</span>  ++i<span class="Delimiter">)</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> != -<span class="Constant">1</span><span class="Delimiter">)</span> ++result<span class="Delimiter">;</span>
  <span class="Identifier">return</span> result<span class="Delimiter">;</span>
<span class="Delimiter">}</span>

<span class="Normal">bool</span> next_stash<span class="Delimiter">(</span><span class="Normal">const</span> call&amp; c<span class="Delimiter">,</span> instruction* stash_inst<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  <span class="Normal">const</span> recipe&amp; specializer_recipe = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> c<span class="Delimiter">.</span>running_recipe<span class="Delimiter">);</span>
  <span class="Normal">int</span> index = c<span class="Delimiter">.</span>running_step_index<span class="Delimiter">;</span>
  <span class="Normal">for</span> <span class="Delimiter">(</span>++index<span class="Delimiter">;</span>  index &lt; SIZE<span class="Delimiter">(</span>specializer_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">);</span>  ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    <span class="Normal">const</span> instruction&amp; inst = specializer_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span>
    <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <span class="Constant">&quot;stash&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
      *stash_inst = inst<span class="Delimiter">;</span>
      <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
    <span class="Delimiter">}</span>
  <span class="Delimiter">}</span>
  <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>

<span class="Delimiter">:(scenario static_dispatch_disabled_in_recipe_without_variants)</span>
<span class="muRecipe">def</span> main [
  <span class="Constant">1</span>:num<span class="Special"> &lt;- </span>test <span class="Constant">3</span>
]
<span class="muRecipe">def</span> test [
  <span class="Constant">2</span>:num<span class="Special"> &lt;- </span>next-ingredient  <span class="Comment"># ensure no header</span>
  <span class="Identifier">return</span> <span class="Constant">34</span>
]
<span class="traceContains">+mem: storing 34 in location 1</span>

<span class="Delimiter">:(scenario static_dispatch_disabled_on_headerless_definition)</span>
<span class="Special">% Hide_errors = true;</span>
<span class="muRecipe">def</span> test a:num<span class="muRecipe"> -&gt; </span>z:num [
  z<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>
]
<span class="muRecipe">def</span> test [
  <span class="Identifier">return</span> <span class="Constant">34</span>
]
<span class="traceContains">+error: redefining recipe test</span>

<span class="Delimiter">:(scenario static_dispatch_disabled_on_headerless_definition_2)</span>
<span class="Special">% Hide_errors = true;</span>
<span class="muRecipe">def</span> test [
  <span class="Identifier">return</span> <span class="Constant">34</span>
]
<span class="muRecipe">def</span> test a:num<span class="muRecipe"> -&gt; </span>z:num [
  z<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>
]
<span class="traceContains">+error: redefining recipe test</span>

<span class="Delimiter">:(scenario static_dispatch_on_primitive_names)</span>
<span class="muRecipe">def</span> main [
  <span class="Constant">1</span>:num<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
  <span class="Constant">2</span>:num<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
  <span class="Constant">3</span>:<span class="Normal">bool</span><span class="Special"> &lt;- </span>equal <span class="Constant">1</span>:num<span class="Delimiter">,</span> <span class="Constant">2</span>:num
  <span class="Constant">4</span>:<span class="Normal">bool</span><span class="Special"> &lt;- </span>copy <span class="Constant">0</span>/<span class="Constant">false</span>
  <span class="Constant">5</span>:<span class="Normal">bool</span><span class="Special"> &lt;- </span>copy <span class="Constant">0</span>/<span class="Constant">false</span>
  <span class="Constant">6</span>:<span class="Normal">bool</span><span class="Special"> &lt;- </span>equal <span class="Constant">4</span>:<span class="Normal">bool</span><span class="Delimiter">,</span> <span class="Constant">5</span>:<span class="Normal">bool</span>
]
<span class="Comment"># temporarily hardcode number equality to always fail</span>
<span class="muRecipe">def</span> equal x:num<span class="Delimiter">,</span> y:num<span class="muRecipe"> -&gt; </span>z:<span class="Normal">bool</span> [
  local-scope
  load-ingredients
  z<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>/<span class="Constant">false</span>
]
<span class="Comment"># comparing numbers used overload</span>
<span class="traceContains">+mem: storing 0 in location 3</span>
<span class="Comment"># comparing booleans continues to use primitive</span>
<span class="traceContains">+mem: storing 1 in location 6</span>

<span class="Delimiter">:(scenario static_dispatch_works_with_dummy_results_for_containers)</span>
<span class="muRecipe">def</span> main [
  _<span class="Special"> &lt;- </span>test <span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">4</span>
]
<span class="muRecipe">def</span> test a:num<span class="muRecipe"> -&gt; </span>z:point [
  local-scope
  load-ingredients
  z<span class="Special"> &lt;- </span>merge a<span class="Delimiter">,</span> <span class="Constant">0</span>
]
<span class="muRecipe">def</span> test a:num<span class="Delimiter">,</span> b:num<span class="muRecipe"> -&gt; </span>z:point [
  local-scope
  load-ingredients
  z<span class="Special"> &lt;- </span>merge a<span class="Delimiter">,</span> b
]
$error: <span class="Constant">0</span>

<span class="Delimiter">:(scenario static_dispatch_works_with_compound_type_containing_container_defined_after_first_use)</span>
<span class="muRecipe">def</span> main [
  <span class="Normal">x</span>:&amp;:foo<span class="Special"> &lt;- </span><span class="Normal">new</span> <span class="Constant">foo:type</span>
  test x
]
<span class="muData">container</span> foo [
  <span class="Normal">x</span>:num
]
<span class="muRecipe">def</span> test a:&amp;:foo<span class="muRecipe"> -&gt; </span>z:num [
  local-scope
  load-ingredients
  <span class="Normal">z</span>:num<span class="Special"> &lt;- </span>get *a<span class="Delimiter">,</span> <span class="Constant">x:offset</span>
]
$error: <span class="Constant">0</span>

<span class="Delimiter">:(scenario static_dispatch_works_with_compound_type_containing_container_defined_after_second_use)</span>
<span class="muRecipe">def</span> main [
  <span class="Normal">x</span>:&amp;:foo<span class="Special"> &lt;- </span><span class="Normal">new</span> <span class="Constant">foo:type</span>
  test x
]
<span class="muRecipe">def</span> test a:&amp;:foo<span class="muRecipe"> -&gt; </span>z:num [
  local-scope
  load-ingredients
  <span class="Normal">z</span>:num<span class="Special"> &lt;- </span>get *a<span class="Delimiter">,</span> <span class="Constant">x:offset</span>
]
<span class="muData">container</span> foo [
  <span class="Normal">x</span>:num
]
$error: <span class="Constant">0</span>

<span class="Delimiter">:(scenario static_dispatch_prefers_literals_to_be_numbers_rather_than_addresses)</span>
<span class="muRecipe">def</span> main [
  <span class="Constant">1</span>:num<span class="Special"> &lt;- </span>foo <span class="Constant">0</span>
]
<span class="muRecipe">def</span> foo x:&amp;:num<span class="muRecipe"> -&gt; </span>y:num [
  <span class="Identifier">return</span> <span class="Constant">34</span>
]
<span class="muRecipe">def</span> foo x:num<span class="muRecipe"> -&gt; </span>y:num [
  <span class="Identifier">return</span> <span class="Constant">35</span>
]
<span class="traceContains">+mem: storing 35 in location 1</span>

<span class="Delimiter">:(scenario static_dispatch_on_non_literal_character_ignores_variant_with_numbers)</span>
<span class="Special">% Hide_errors = true;</span>
<span class="muRecipe">def</span> main [
  local-scope
  <span class="Normal">x</span>:<span class="Normal">char</span><span class="Special"> &lt;- </span>copy <span class="Constant">10</span>/newline
  <span class="Constant">1</span>:num/<span class="Special">raw &lt;- </span>foo x
]
<span class="muRecipe">def</span> foo x:num<span class="muRecipe"> -&gt; </span>y:num [
  load-ingredients
  <span class="Identifier">return</span> <span class="Constant">34</span>
]
<span class="traceContains">+error: main: ingredient 0 has the wrong type at '1:num/raw &lt;- foo x'</span>
<span class="traceAbsent">-mem: storing 34 in location 1</span>

<span class="Delimiter">:(scenario static_dispatch_dispatches_literal_to_boolean_before_character)</span>
<span class="muRecipe">def</span> main [
  <span class="Constant">1</span>:num/<span class="Special">raw &lt;- </span>foo <span class="Constant">0</span>  <span class="Comment"># valid literal for boolean</span>
]
<span class="muRecipe">def</span> foo x:<span class="Normal">char</span><span class="muRecipe"> -&gt; </span>y:num [
  local-scope
  load-ingredients
  <span class="Identifier">return</span> <span class="Constant">34</span>
]
<span class="muRecipe">def</span> foo x:<span class="Normal">bool</span><span class="muRecipe"> -&gt; </span>y:num [
  local-scope
  load-ingredients
  <span class="Identifier">return</span> <span class="Constant">35</span>
]
<span class="Comment"># boolean variant is preferred</span>
<span class="traceContains">+mem: storing 35 in location 1</span>

<span class="Delimiter">:(scenario static_dispatch_dispatches_literal_to_character_when_out_of_boolean_range)</span>
<span class="muRecipe">def</span> main [
  <span class="Constant">1</span>:num/<span class="Special">raw &lt;- </span>foo <span class="Constant">97</span>  <span class="Comment"># not a valid literal for boolean</span>
]
<span class="muRecipe">def</span> foo x:<span class="Normal">char</span><span class="muRecipe"> -&gt; </span>y:num [
  local-scope
  load-ingredients
  <span class="Identifier">return</span> <span class="Constant">34</span>
]
<span class="muRecipe">def</span> foo x:<span class="Normal">bool</span><span class="muRecipe"> -&gt; </span>y:num [
  local-scope
  load-ingredients
  <span class="Identifier">return</span> <span class="Constant">35</span>
]
<span class="Comment"># character variant is preferred</span>
<span class="traceContains">+mem: storing 34 in location 1</span>

<span class="Delimiter">:(scenario static_dispatch_dispatches_literal_to_number_if_at_all_possible)</span>
<span class="muRecipe">def</span> main [
  <span class="Constant">1</span>:num/<span class="Special">raw &lt;- </span>foo <span class="Constant">97</span>
]
<span class="muRecipe">def</span> foo x:<span class="Normal">char</span><span class="muRecipe"> -&gt; </span>y:num [
  local-scope
  load-ingredients
  <span class="Identifier">return</span> <span class="Constant">34</span>
]
<span class="muRecipe">def</span> foo x:num<span class="muRecipe"> -&gt; </span>y:num [
  local-scope
  load-ingredients
  <span class="Identifier">return</span> <span class="Constant">35</span>
]
<span class="Comment"># number variant is preferred</span>
<span class="traceContains">+mem: storing 35 in location 1</span>

<span class="Delimiter">:(code)</span>
string header_label<span class="Delimiter">(</span><span class="Normal">const</span> recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  <span class="Identifier">return</span> header_label<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">));</span>
<span class="Delimiter">}</span>
string header_label<span class="Delimiter">(</span><span class="Normal">const</span> recipe&amp; caller<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  ostringstream out<span class="Delimiter">;</span>
  out &lt;&lt; <span class="Constant">&quot;recipe &quot;</span> &lt;&lt; caller<span class="Delimiter">.</span>name<span class="Delimiter">;</span>
  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; SIZE<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span>  ++i<span class="Delimiter">)</span>
    out &lt;&lt; <span class="Constant">' '</span> &lt;&lt; to_string<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
  <span class="Normal">if</span> <span class="Delimiter">(</span>!caller<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> out &lt;&lt; <span class="Constant">&quot; -&gt;&quot;</span><span class="Delimiter">;</span>
  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; SIZE<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>products<span class="Delimiter">);</span>  ++i<span class="Delimiter">)</span>
    out &lt;&lt; <span class="Constant">' '</span> &lt;&lt; to_string<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
  <span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
<span class="Delimiter">}</span>

<span class="Delimiter">:(scenario reload_variant_retains_other_variants)</span>
<span class="muRecipe">def</span> main [
  <span class="Constant">1</span>:num<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
  <span class="Constant">2</span>:num<span class="Special"> &lt;- </span>foo <span class="Constant">1</span>:num
]
<span class="muRecipe">def</span> foo x:num<span class="muRecipe"> -&gt; </span>y:num [
  local-scope
  load-ingredients
  <span class="Identifier">return</span> <span class="Constant">34</span>
]
<span class="muRecipe">def</span> foo x:&amp;:num<span class="muRecipe"> -&gt; </span>y:num [
  local-scope
  load-ingredients
  <span class="Identifier">return</span> <span class="Constant">35</span>
]
<span class="muRecipe">def</span>! foo x:&amp;:num<span class="muRecipe"> -&gt; </span>y:num [
  local-scope
  load-ingredients
  <span class="Identifier">return</span> <span class="Constant">36</span>
]
<span class="traceContains">+mem: storing 34 in location 2</span>
$error: <span class="Constant">0</span>

<span class="Delimiter">:(scenario dispatch_errors_come_after_unknown_name_errors)</span>
<span class="Special">% Hide_errors = true;</span>
<span class="muRecipe">def</span> main [
  <span class="Normal">y</span>:num<span class="Special"> &lt;- </span>foo x
]
<span class="muRecipe">def</span> foo a:num<span class="muRecipe"> -&gt; </span>b:num [
  local-scope
  load-ingredients
  <span class="Identifier">return</span> <span class="Constant">34</span>
]
<span class="muRecipe">def</span> foo a:<span class="Normal">bool</span><span class="muRecipe"> -&gt; </span>b:num [
  local-scope
  load-ingredients
  <span class="Identifier">return</span> <span class="Constant">35</span>
]
<span class="traceContains">+error: main: missing type for 'x' in 'y:num &lt;- foo x'</span>
<span class="traceContains">+error: main: failed to find a matching call for 'y:num &lt;- foo x'</span>

<span class="Delimiter">:(scenario override_methods_with_type_abbreviations)</span>
<span class="muRecipe">def</span> main [
  local-scope
  <span class="Normal">s</span>:text<span class="Special"> &lt;- </span><span class="Normal">new</span> [abc]
  <span class="Constant">1</span>:num/<span class="Special">raw &lt;- </span>foo s
]
<span class="muRecipe">def</span> foo a:address:array:character<span class="muRecipe"> -&gt; </span>result:number [
  <span class="Identifier">return</span> <span class="Constant">34</span>
]
<span class="Comment"># identical to previous variant once you take type abbreviations into account</span>
<span class="muRecipe">def</span>! foo a:text<span class="muRecipe"> -&gt; </span>result:num [
  <span class="Identifier">return</span> <span class="Constant">35</span>
]
<span class="traceContains">+mem: storing 35 in location 1</span>

<span class="Delimiter">:(before &quot;End Includes&quot;)</span>
<span class="Normal">using</span> std::abs<span class="Delimiter">;</span>
</pre>
</body>
</html>
<!-- vim: set foldmethod=manual : -->