summary refs log blame commit diff stats
path: root/widgets/account-wizard.go
blob: 5acd26c56b217ebc1b50ee8b7f6a565ad720503c (plain) (tree)
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
<!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 - 072recipe.cc</title>
<meta name="Generator" content="Vim/8.0">
<meta name="plugin-version" content="vim7.4_v2">
<meta name="syntax" content="cpp">
<meta name="settings" content="number_lines,use_css,pre_wrap,no_foldcolumn,expand_tabs,line_ids,prevent_copy=">
<meta name="colorscheme" content="minimal">
<style type="text/css">
<!--
pre { white-space: pre-wrap; font-family: monospace; color: #aaaaaa; background-color: #080808; }
body { font-size: 12pt; font-family: monospace; color: #aaaaaa; background-color: #080808; }
a { color:#eeeeee; text-decoration: none; }
a:hover { text-decoration: underline; }
* { font-size: 12pt; font-size: 1em; }
.SalientComment { color: #00ffff; }
.LineNr { color: #444444; }
.Constant { color: #00a0a0; }
.muRecipe { color: #ff8700; }
.Delimiter { color: #800080; }
.Special { color: #c00000; }
.Identifier { color: #c0a020; }
.Normal { color: #aaaaaa; background-color: #080808; padding-bottom: 1px; }
.Comment { color: #9090ff; }
.Comment a { color:#0000ee; text-decoration:underline; }
.cSpecial { color: #008000; }
.traceContains { color: #008000; }
-->
</style>

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

/* function to open any folds containing a jumped-to line before jumping to it */
function JumpToLine()
{
  var lineNum;
  lineNum = window.location.hash;
  lineNum = lineNum.substr(1); /* strip off '#' */

  if (lineNum.indexOf('L') == -1) {
    lineNum = 'L'+lineNum;
  }
  lineElem = document.getElementById(lineNum);
  /* Always jump to new location even if the line was hidden inside a fold, or
   * we corrected the raw number to a line ID.
   */
  if (lineElem) {
    lineElem.scrollIntoView(true);
  }
  return true;
}
if ('onhashchange' in window) {
  window.onhashchange = JumpToLine;
}

-->
</script>
</head>
<body onload='JumpToLine();'>
<pre id='vimCodeElement'>
<span id="L1" class="LineNr">  1 </span><span class="Comment">//: So far we've been calling a fixed recipe in each instruction, but we'd</span>
<span id="L2" class="LineNr">  2 </span><span class="Comment">//: also like to make the recipe a variable, pass recipes to &quot;higher-order&quot;</span>
<span id="L3" class="LineNr">  3 </span><span class="Comment">//: recipes, return recipes from recipes and so on.</span>
<span id="L4" class="LineNr">  4 </span>
<span id="L5" class="LineNr">  5 </span><span class="Delimiter">:(scenario call_literal_recipe)</span>
<span id="L6" class="LineNr">  6 </span><span class="muRecipe">def</span> <a href='000organization.cc.html#L113'>main</a> [
<span id="L7" class="LineNr">  7 </span>  <span class="Constant">1</span>:num<span class="Special"> &lt;- </span>call f<span class="Delimiter">,</span> <span class="Constant">34</span>
<span id="L8" class="LineNr">  8 </span>]
<span id="L9" class="LineNr">  9 </span><span class="muRecipe">def</span> f x:num<span class="muRecipe"> -&gt; </span>y:num [
<span id="L10" class="LineNr"> 10 </span>  local-scope
<span id="L11" class="LineNr"> 11 </span>  load-ingredients
<span id="L12" class="LineNr"> 12 </span>  y<span class="Special"> &lt;- </span>copy x
<span id="L13" class="LineNr"> 13 </span>]
<span id="L14" class="LineNr"> 14 </span><span class="traceContains">+mem: storing 34 in location 1</span>
<span id="L15" class="LineNr"> 15 </span>
<span id="L16" class="LineNr"> 16 </span><span class="Delimiter">:(before &quot;End Mu Types Initialization&quot;)</span>
<span id="L17" class="LineNr"> 17 </span><a href='001help.cc.html#L221'>put</a><span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;recipe-literal&quot;</span><span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span>
<span id="L18" class="LineNr"> 18 </span><span class="Comment">// 'recipe' variables can store recipe-literal</span>
<span id="L19" class="LineNr"> 19 </span><a href='010vm.cc.html#L125'>type_ordinal</a> <a href='010vm.cc.html#L19'>recipe</a> = <a href='001help.cc.html#L221'>put</a><span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;recipe&quot;</span><span class="Delimiter">,</span> Next_type_ordinal++<span class="Delimiter">);</span>
<span id="L20" class="LineNr"> 20 </span><a href='001help.cc.html#L229'>get_or_insert</a><span class="Delimiter">(</span>Type<span class="Delimiter">,</span> <a href='010vm.cc.html#L19'>recipe</a><span class="Delimiter">).</span>name = <span class="Constant">&quot;recipe&quot;</span><span class="Delimiter">;</span>
<span id="L21" class="LineNr"> 21 </span>
<span id="L22" class="LineNr"> 22 </span><span class="Delimiter">:(after &quot;Deduce Missing Type(x, caller)&quot;)</span>
<span id="L23" class="LineNr"> 23 </span><span class="Normal">if</span> <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>type<span class="Delimiter">)</span>
<span id="L24" class="LineNr"> 24 </span>  <a href='072recipe.cc.html#L29'>try_initialize_recipe_literal</a><span class="Delimiter">(</span>x<span class="Delimiter">,</span> caller<span class="Delimiter">);</span>
<span id="L25" class="LineNr"> 25 </span><span class="Delimiter">:(before &quot;Type Check in Type-ingredient-aware check_or_set_types_by_name&quot;)</span>
<span id="L26" class="LineNr"> 26 </span><span class="Normal">if</span> <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>type<span class="Delimiter">)</span>
<span id="L27" class="LineNr"> 27 </span>  <a href='072recipe.cc.html#L29'>try_initialize_recipe_literal</a><span class="Delimiter">(</span>x<span class="Delimiter">,</span> variant<span class="Delimiter">);</span>
<span id="L28" class="LineNr"> 28 </span><span class="Delimiter">:(code)</span>
<span id="L29" class="LineNr"> 29 </span><span classpre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
package widgets

import (
	"errors"
	"fmt"
	"net"
	"net/url"
	"os"
	"os/exec"
	"path"
	"strconv"
	"strings"
	"time"

	"github.com/gdamore/tcell"
	"github.com/go-ini/ini"
	"github.com/kyoh86/xdg"

	"git.sr.ht/~sircmpwn/aerc/config"
	"git.sr.ht/~sircmpwn/aerc/lib/ui"
)

const (
	CONFIGURE_BASICS   = iota
	CONFIGURE_INCOMING = iota
	CONFIGURE_OUTGOING = iota
	CONFIGURE_COMPLETE = iota
)

const (
	IMAP_OVER_TLS = iota
	IMAP_STARTTLS = iota
	IMAP_INSECURE = iota
)

const (
	SMTP_OVER_TLS = iota
	SMTP_STARTTLS = iota
	SMTP_INSECURE = iota
)

type AccountWizard struct {
	ui.Invalidatable
	aerc      *Aerc
	conf      *config.AercConfig
	step      int
	steps     []*ui.Grid
	focus     int
	temporary bool
	testing   bool
	// CONFIGURE_BASICS
	accountName *ui.TextInput
	email       *ui.TextInput
	fullName    *ui.TextInput
	basics      []ui.Interactive
	// CONFIGURE_INCOMING
	imapUsername *ui.TextInput
	imapPassword *ui.TextInput
	imapServer   *ui.TextInput
	imapMode     int
	imapStr      *ui.Text
	imapUrl      url.URL
	incoming     []ui.Interactive
	// CONFIGURE_OUTGOING
	smtpUsername *ui.TextInput
	smtpPassword *ui.TextInput
	smtpServer   *ui.TextInput
	smtpMode     int
	smtpStr      *ui.Text
	smtpUrl      url.URL
	copySent     bool
	outgoing     []ui.Interactive
	// CONFIGURE_COMPLETE
	complete []ui.Interactive
}

func NewAccountWizard(conf *config.AercConfig, aerc *Aerc) *AccountWizard {
	wizard := &AccountWizard{
		accountName:  ui.NewTextInput("").Prompt("> "),
		aerc:         aerc,
		conf:         conf,
		temporary:    false,
		copySent:     true,
		email:        ui.NewTextInput("").Prompt("> "),
		fullName:     ui.NewTextInput("").Prompt("> "),
		imapPassword: ui.NewTextInput("").Prompt("] ").Password(true),
		imapServer:   ui.NewTextInput("").Prompt("> "),
		imapStr:      ui.NewText("imaps://"),
		imapUsername: ui.NewTextInput("").Prompt("> "),
		smtpPassword: ui.NewTextInput("").Prompt("] ").Password(true),
		smtpServer:   ui.NewTextInput("").Prompt("> "),
		smtpStr:      ui.NewText("smtps://"),
		smtpUsername: ui.NewTextInput("").Prompt("> "),
	}

	// Autofill some stuff for the user
	wizard.email.OnChange(func(_ *ui.TextInput) {
		value := wizard.email.String()
		wizard.imapUsername.Set(value)
		wizard.smtpUsername.Set(value)
		if strings.ContainsRune(value, '@') {
			server := value[strings.IndexRune(value, '@')+1:]
			wizard.imapServer.Set(server)
			wizard.smtpServer.Set(server)
		}
		wizard.imapUri()
		wizard.smtpUri()
	})
	wizard.imapServer.OnChange(func(_ *ui.TextInput) {
		imapServerURI := wizard.imapServer.String()
		smtpServerURI := imapServerURI
		if strings.HasPrefix(imapServerURI, "imap.") {
			smtpServerURI = strings.Replace(imapServerURI, "imap.", "smtp.", 1)
		}
		wizard.smtpServer.Set(smtpServerURI)
		wizard.imapUri()
		wizard.smtpUri()
	})
	wizard.imapUsername.OnChange(func(_ *ui.TextInput) {
		wizard.smtpUsername.Set(wizard.imapUsername.String())
		wizard.imapUri()
		wizard.smtpUri()
	})
	wizard.imapPassword.OnChange(func(_ *ui.TextInput) {
		wizard.smtpPassword.Set(wizard.imapPassword.String())
		wizard.imapUri()
		wizard.smtpUri()
	})
	wizard.smtpServer.OnChange(func(_ *ui.TextInput) {
		wizard.smtpUri()
	})
	wizard.smtpUsername.OnChange(func(_ *ui.TextInput) {
		wizard.smtpUri()
	})
	wizard.smtpPassword.OnChange(func(_ *ui.TextInput) {
		wizard.smtpUri()
	})

	basics := ui.NewGrid().Rows([]ui.GridSpec{
		{ui.SIZE_EXACT, 8}, // Introduction
		{ui.SIZE_EXACT, 1}, // Account name (label)
		{ui.SIZE_EXACT, 1}, // (input)
		{ui.SIZE_EXACT, 1}, // Padding
		{ui.SIZE_EXACT, 1}, // Full name (label)
		{ui.SIZE_EXACT, 1}, // (input)
		{ui.SIZE_EXACT, 1}, // Padding
		{ui.SIZE_EXACT, 1}, // Email address (label)
		{ui.SIZE_EXACT, 1}, // (input)
		{ui.SIZE_WEIGHT, 1},
	}).Columns([]ui.GridSpec{
		{ui.SIZE_WEIGHT, 1},
	})
	basics.AddChild(
		ui.NewText("\nWelcome to aerc! Let's configure your account.\n\n" +
			"This wizard supports basic IMAP & SMTP configuration.\n" +
			"For other configurations, use <Ctrl+q> to exit and read the " +
			"aerc-config(5) man page.\n" +
			"Press <Tab> and <Shift+Tab> to cycle between each field in this form, or <Ctrl+j> and <Ctrl+k>."))
	basics.AddChild(
		ui.NewText("Name for this account? (e.g. 'Personal' or 'Work')").
			Bold(true)).
		At(1, 0)
	basics.AddChild(wizard.accountName).
		At(2, 0)
	basics.AddChild(ui.NewFill(' ')).
		At(3, 0)
	basics.AddChild(
		ui.NewText("Full name for outgoing emails? (e.g. 'John Doe')").
			Bold(true)).
		At(4, 0)
	basics.AddChild(wizard.fullName).
		At(5, 0)
	basics.AddChild(ui.NewFill(' ')).
		At(6, 0)
	basics.AddChild(
		ui.NewText("Your email address? (e.g. 'john@example.org')").Bold(true)).
		At(7, 0)
	basics.AddChild(wizard.email).
		At(8, 0)
	selecter := newSelecter([]string{"Next"}, 0).
		OnChoose(func(option string) {
			email := wizard.email.String()
			if strings.ContainsRune(email, '@') {
				server := email[strings.IndexRune(email, '@')+1:]
				hostport, srv := getSRV(server, []string{"imaps", "imap"})
				if hostport != "" {
					wizard.imapServer.Set(hostport)
					if srv == "imaps" {
						wizard.imapMode = IMAP_OVER_TLS
					} else {
						wizard.imapMode = IMAP_STARTTLS
					}
					wizard.imapUri()
				}
				hostport, srv = getSRV(server, []string{"submission"})
				if hostport != "" {
					wizard.smtpServer.Set(hostport)
					wizard.smtpMode = SMTP_STARTTLS
					wizard.smtpUri()
				}
			}
			wizard.advance(option)
		})
	basics.AddChild(selecter).At(9, 0)
	wizard.basics = []ui.Interactive{
		wizard.accountName, wizard.fullName, wizard.email, selecter,
	}
	basics.OnInvalidate(func(_ ui.Drawable) {
		wizard.Invalidate()
	})

	incoming := ui.NewGrid().Rows([]ui.GridSpec{
		{ui.SIZE_EXACT, 3}, // Introduction
		{ui.SIZE_EXACT, 1}, // Username (label)
		{ui.SIZE_EXACT, 1}, // (input)
		{ui.SIZE_EXACT, 1}, // Padding
		{ui.SIZE_EXACT, 1}, // Password (label)
		{ui.SIZE_EXACT, 1}, // (input)
		{ui.SIZE_EXACT, 1}, // Padding
		{ui.SIZE_EXACT, 1}, // Server (label)
		{ui.SIZE_EXACT, 1}, // (input)
		{ui.SIZE_EXACT, 1}, // Padding
		{ui.SIZE_EXACT, 1}, // Connection mode (label)
		{ui.SIZE_EXACT, 2}, // (input)
		{ui.SIZE_EXACT, 1}, // Padding
		{ui.SIZE_EXACT, 1}, // Connection string
		{ui.SIZE_WEIGHT, 1},
	}).Columns([]ui.GridSpec{
		{ui.SIZE_WEIGHT, 1},
	})
	incoming.AddChild(ui.NewText("\nConfigure incoming mail (IMAP)"))
	incoming.AddChild(
		ui.NewText("Username").Bold(true)).
		At(1, 0)
	incoming.AddChild(wizard.imapUsername).
		At(2, 0)
	incoming.AddChild(ui.NewFill(' ')).
		At(3, 0)
	incoming.AddChild(
		ui.NewText("Password").Bold(true)).
		At(4, 0)
	incoming.AddChild(wizard.imapPassword).
		At(5, 0)
	incoming.AddChild(ui.NewFill(' ')).
		At(6, 0)
	incoming.AddChild(
		ui.NewText("Server address "+
			"(e.g. 'mail.example.org' or 'mail.example.org:1313')").Bold(true)).
		At(7, 0)
	incoming.AddChild(wizard.imapServer).
		At(8, 0)
	incoming.AddChild(ui.NewFill(' ')).
		At(9, 0)
	incoming.AddChild(
		ui.NewText("Connection mode").Bold(true)).
		At(10, 0)
	imapMode := newSelecter([]string{
		"IMAP over SSL/TLS",
		"IMAP with STARTTLS",
		"Insecure IMAP",
	}, 0).Chooser(true).OnSelect(func(option string) {
		switch option {
		case "IMAP over SSL/TLS":
			wizard.imapMode = IMAP_OVER_TLS
		case "IMAP with STARTTLS":
			wizard.imapMode = IMAP_STARTTLS
		case "Insecure IMAP":
			wizard.imapMode = IMAP_INSECURE
		}
		wizard.imapUri()
	})
	incoming.AddChild(imapMode).At(11, 0)
	selecter = newSelecter([]string{"Previous", "Next"}, 1).
		OnChoose(wizard.advance)
	incoming.AddChild(ui.NewFill(' ')).At(12, 0)
	incoming.AddChild(wizard.imapStr).At(13, 0)
	incoming.AddChild(selecter).At(14, 0)
	wizard.incoming = []ui.Interactive{
		wizard.imapUsername, wizard.imapPassword, wizard.imapServer,
		imapMode, selecter,
	}
	incoming.OnInvalidate(func(_ ui.Drawable) {
		wizard.Invalidate()
	})

	outgoing := ui.NewGrid().Rows([]ui.GridSpec{
		{ui.SIZE_EXACT, 3}, // Introduction
		{ui.SIZE_EXACT, 1}, // Username (label)
		{ui.SIZE_EXACT, 1}, // (input)
		{ui.SIZE_EXACT, 1}, // Padding
		{ui.SIZE_EXACT, 1}, // Password (label)
		{ui.SIZE_EXACT, 1}, // (input)
		{ui.SIZE_EXACT, 1}, // Padding
		{ui.SIZE_EXACT, 1}, // Server (label)
		{ui.SIZE_EXACT, 1}, // (input)
		{ui.SIZE_EXACT, 1}, // Padding
		{ui.SIZE_EXACT, 1}, // Connection mode (label)
		{ui.SIZE_EXACT, 2}, // (input)
		{ui.SIZE_EXACT, 1}, // Padding
		{ui.SIZE_EXACT, 1}, // Connection string
		{ui.SIZE_EXACT, 1}, // Padding
		{ui.SIZE_EXACT, 1}, // Copy to sent (label)
		{ui.SIZE_EXACT, 2}, // (input)
		{ui.SIZE_WEIGHT, 1},
	}).Columns([]ui.GridSpec{
		{ui.SIZE_WEIGHT, 1},
	})
	outgoing.AddChild(ui.NewText("\nConfigure outgoing mail (SMTP)"))
	outgoing.AddChild(
		ui.NewText("Username").Bold(true)).
		At(1, 0)
	outgoing.AddChild(wizard.smtpUsername).
		At(2, 0)
	outgoing.AddChild(ui.NewFill(' ')).
		At(3, 0)
	outgoing.AddChild(
		ui.NewText("Password").Bold(true)).
		At(4, 0)
	outgoing.AddChild(wizard.smtpPassword).
		At(5, 0)
	outgoing.AddChild(ui.NewFill(' ')).
		At(6, 0)
	outgoing.AddChild(
		ui.NewText("Server address "+
			"(e.g. 'mail.example.org' or 'mail.example.org:1313')").Bold(true)).
		At(7, 0)
	outgoing.AddChild(wizard.smtpServer).
		At(8, 0)
	outgoing.AddChild(ui.NewFill(' ')).
		At(9, 0)
	outgoing.AddChild(
		ui.NewText("Connection mode").Bold(true)).
		At(10, 0)
	smtpMode := newSelecter([]string{
		"SMTP over SSL/TLS",
		"SMTP with STARTTLS",
		"Insecure SMTP",
	}, 0).Chooser(true).OnSelect(func(option string) {
		switch option {
		case "SMTP over SSL/TLS":
			wizard.smtpMode = SMTP_OVER_TLS
		case "SMTP with STARTTLS":
			wizard.smtpMode = SMTP_STARTTLS
		case "Insecure SMTP":
			wizard.smtpMode = SMTP_INSECURE
		}
		wizard.smtpUri()
	})
	outgoing.AddChild(smtpMode).At(11, 0)
	selecter = newSelecter([]string{"Previous", "Next"}, 1).
		OnChoose(wizard.advance)
	outgoing.AddChild(ui.NewFill(' ')).At(12, 0)
	outgoing.AddChild(wizard.smtpStr).At(13, 0)
	outgoing.AddChild(ui.NewFill(' ')).At(14, 0)
	outgoing.AddChild(
		ui.NewText("Copy sent messages to 'Sent' folder?").Bold(true)).
		At(15, 0)
	copySent := newSelecter([]string{"Yes", "No"}, 0).
		Chooser(true).OnChoose(func(option string) {
		switch option {
		case "Yes":
			wizard.copySent = true
		case "No":
			wizard.copySent = false
		}
	})
	outgoing.AddChild(copySent).At(16, 0)
	outgoing.AddChild(selecter).At(17, 0)
	wizard.outgoing = []ui.Interactive{
		wizard.smtpUsername, wizard.smtpPassword, wizard.smtpServer,
		smtpMode, copySent, selecter,
	}
	outgoing.OnInvalidate(func(_ ui.Drawable) {
		wizard.Invalidate()
	})

	complete := ui.NewGrid().Rows([]ui.GridSpec{
		{ui.SIZE_EXACT, 7},  // Introduction
		{ui.SIZE_WEIGHT, 1}, // Previous / Finish / Finish & open tutorial
	}).Columns([]ui.GridSpec{
		{ui.SIZE_WEIGHT, 1},
	})
	complete.AddChild(ui.NewText(
		"\nConfiguration complete!\n\n" +
			"You can go back and double check your settings, or choose 'Finish' to\n" +
			"save your settings to accounts.conf.\n\n" +
			"To add another account in the future, run ':new-account'."))
	selecter = newSelecter([]string{
		"Previous",
		"Finish & open tutorial",
		"Finish",
	}, 1).OnChoose(func(option string) {
		switch option {
		case "Previous":
			wizard.advance("Previous")
		case "Finish & open tutorial":
			wizard.finish(true)
		case "Finish":
			wizard.finish(false)
		}
	})
	complete.AddChild(selecter).At(1, 0)
	wizard.complete = []ui.Interactive{selecter}
	complete.OnInvalidate(func(_ ui.Drawable) {
		wizard.Invalidate()
	})

	wizard.steps = []*ui.Grid{basics, incoming, outgoing, complete}
	return wizard
}

func (wizard *AccountWizard) ConfigureTemporaryAccount(temporary bool) {
	wizard.temporary = temporary
}

func (wizard *AccountWizard) errorFor(d ui.Interactive, err error) {
	if d == nil {
		wizard.aerc.PushStatus(" "+err.Error(), 10*time.Second).
			Color(tcell.ColorDefault, tcell.ColorRed)
		wizard.Invalidate()
		return
	}
	for step, interactives := range [][]ui.Interactive{
		wizard.basics,
		wizard.incoming,
		wizard.outgoing,
	} {
		for focus, item := range interactives {
			if item == d {
				wizard.Focus(false)
				wizard.step = step
				wizard.focus = focus
				wizard.Focus(true)
				wizard.aerc.PushStatus(" "+err.Error(), 10*time.Second).
					Color(tcell.ColorDefault, tcell.ColorRed)
				wizard.Invalidate()
				return
			}
		}
	}
}

func (wizard *AccountWizard) finish(tutorial bool) {
	accountsConf := path.Join(xdg.ConfigHome(), "aerc", "accounts.conf")

	// Validation
	if wizard.accountName.String() == "" {
		wizard.errorFor(wizard.accountName,
			errors.New("Account name is required"))
		return
	}
	if wizard.email.String() == "" {
		wizard.errorFor(wizard.email,
			errors.New("Email address is required"))
		return
	}
	if wizard.fullName.String() == "" {
		wizard.errorFor(wizard.fullName,
			errors.New("Full name is required"))
		return
	}
	if wizard.imapServer.String() == "" {
		wizard.errorFor(wizard.imapServer,
			errors.New("IMAP server is required"))
		return
	}
	if wizard.imapServer.String() == "" {
		wizard.errorFor(wizard.smtpServer,
			errors.New("SMTP server is required"))
		return
	}

	file, err := ini.Load(accountsConf)
	if err != nil {
		file = ini.Empty()
	}

	var sec *ini.Section
	if sec, _ = file.GetSection(wizard.accountName.String()); sec != nil {
		wizard.errorFor(wizard.accountName,
			errors.New("An account by this name already exists"))
		return
	}
	sec, _ = file.NewSection(wizard.accountName.String())
	sec.NewKey("source", wizard.imapUrl.String())
	sec.NewKey("outgoing", wizard.smtpUrl.String())
	sec.NewKey("default", "INBOX")
	if wizard.smtpMode == SMTP_STARTTLS {
		sec.NewKey("smtp-starttls", "yes")
	}
	sec.NewKey("from", fmt.Sprintf("%s <%s>",
		wizard.fullName.String(), wizard.email.String()))
	if wizard.copySent {
		sec.NewKey("copy-to", "Sent")
	}

	if !wizard.temporary {
		f, err := os.OpenFile(accountsConf, os.O_WRONLY|os.O_CREATE, 0600)
		if err != nil {
			wizard.errorFor(nil, err)
			return
		}
		if _, err = file.WriteTo(f); err != nil {
			wizard.errorFor(nil, err)
			return
		}
	}

	account := config.AccountConfig{
		Name:     sec.Name(),
		Default:  "INBOX",
		From:     sec.Key("from").String(),
		Source:   sec.Key("source").String(),
		Outgoing: sec.Key("outgoing").String(),
	}
	if wizard.smtpMode == SMTP_STARTTLS {
		account.Params = map[string]string{
			"smtp-starttls": "yes",
		}
	}
	if wizard.copySent {
		account.CopyTo = "Sent"
	}
	wizard.conf.Accounts = append(wizard.conf.Accounts, account)

	view := NewAccountView(wizard.conf, &account,
		wizard.aerc.logger, wizard.aerc)
	wizard.aerc.accounts[account.Name] = view
	wizard.aerc.NewTab(view, account.Name)

	if tutorial {
		name := "aerc-tutorial"
		if _, err := os.Stat("./aerc-tutorial.7"); !os.IsNotExist(err) {
			// For development
			name = "./aerc-tutorial.7"
		}
		term, err := NewTerminal(exec.Command("man", name))
		if err != nil {
			wizard.errorFor(nil, err)
			return
		}
		wizard.aerc.NewTab(term, "Tutorial")
		term.OnClose = func(err error) {
			wizard.aerc.RemoveTab(term)
			if err != nil {
				wizard.aerc.PushStatus(" "+err.Error(), 10*time.Second).
					Color(tcell.ColorDefault, tcell.ColorRed)
			}
		}
	}

	wizard.aerc.RemoveTab(wizard)
}

func (wizard *AccountWizard) imapUri() url.URL {
	host := wizard.imapServer.String()
	user := wizard.imapUsername.String()
	pass := wizard.imapPassword.String()
	var scheme string
	switch wizard.imapMode {
	case IMAP_OVER_TLS:
		scheme = "imaps"
	case IMAP_STARTTLS:
		scheme = "imap"
	case IMAP_INSECURE:
		scheme = "imap+insecure"
	}
	var (
		userpass   *url.Userinfo
		userwopass *url.Userinfo
	)
	if pass == "" {
		userpass = url.User(user)
		userwopass = userpass
	} else {
		userpass = url.UserPassword(user, pass)
		userwopass = url.UserPassword(user, strings.Repeat("*", len(pass)))
	}
	uri := url.URL{
		Scheme: scheme,
		Host:   host,
		User:   userpass,
	}
	clean := url.URL{
		Scheme: scheme,
		Host:   host,
		User:   userwopass,
	}
	wizard.imapStr.Text("Connection URL: " +
		strings.ReplaceAll(clean.String(), "%2A", "*"))
	wizard.imapUrl = uri
	return uri
}

func (wizard *AccountWizard) smtpUri() url.URL {
	host := wizard.smtpServer.String()
	user := wizard.smtpUsername.String()
	pass := wizard.smtpPassword.String()
	var scheme string
	switch wizard.smtpMode {
	case SMTP_OVER_TLS:
		scheme = "smtps+plain"
	case SMTP_STARTTLS:
		scheme = "smtp+plain"
	case SMTP_INSECURE:
		scheme = "smtp+plain"
	}
	var (
		userpass   *url.Userinfo
		userwopass *url.Userinfo
	)
	if pass == "" {
		userpass = url.User(user)
		userwopass = userpass
	} else {
		userpass = url.UserPassword(user, pass)
		userwopass = url.UserPassword(user, strings.Repeat("*", len(pass)))
	}
	uri := url.URL{
		Scheme: scheme,
		Host:   host,
		User:   userpass,
	}
	clean := url.URL{
		Scheme: scheme,
		Host:   host,
		User:   userwopass,
	}
	wizard.smtpStr.Text("Connection URL: " +
		strings.ReplaceAll(clean.String(), "%2A", "*"))
	wizard.smtpUrl = uri
	return uri
}

func (wizard *AccountWizard) Invalidate() {
	wizard.DoInvalidate(wizard)
}

func (wizard *AccountWizard) Draw(ctx *ui.Context) {
	wizard.steps[wizard.step].Draw(ctx)
}

func (wizard *AccountWizard) getInteractive() []ui.Interactive {
	switch wizard.step {
	case CONFIGURE_BASICS:
		return wizard.basics
	case CONFIGURE_INCOMING:
		return wizard.incoming
	case CONFIGURE_OUTGOING:
		return wizard.outgoing
	case CONFIGURE_COMPLETE:
		return wizard.complete
	}
	return nil
}

func (wizard *AccountWizard) advance(direction string) {
	wizard.Focus(false)
	if direction == "Next" && wizard.step < len(wizard.steps)-1 {
		wizard.step++
	}
	if direction == "Previous" && wizard.step > 0 {
		wizard.step--
	}
	wizard.focus = 0
	wizard.Focus(true)
	wizard.Invalidate()
}

func (wizard *AccountWizard) Focus(focus bool) {
	if interactive := wizard.getInteractive(); interactive != nil {
		interactive[wizard.focus].Focus(focus)
	}
}

func (wizard *AccountWizard) Event(event tcell.Event) bool {
	interactive := wizard.getInteractive()
	switch event := event.(type) {
	case *tcell.EventKey:
		switch event.Key() {
		case tcell.KeyUp:
			fallthrough
		case tcell.KeyBacktab:
			fallthrough
		case tcell.KeyCtrlK:
			if interactive != nil {
				interactive[wizard.focus].Focus(false)
				wizard.focus--
				if wizard.focus < 0 {
					wizard.focus = len(interactive) - 1
				}
				interactive[wizard.focus].Focus(true)
			}
			wizard.Invalidate()
			return true
		case tcell.KeyDown:
			fallthrough
		case tcell.KeyTab:
			fallthrough
		case tcell.KeyCtrlJ:
			if interactive != nil {
				interactive[wizard.focus].Focus(false)
				wizard.focus++
				if wizard.focus >= len(interactive) {
					wizard.focus = 0
				}
				interactive[wizard.focus].Focus(true)
			}
			wizard.Invalidate()
			return true
		}
	}
	if interactive != nil {
		return interactive[wizard.focus].Event(event)
	}
	return false
}

type selecter struct {
	ui.Invalidatable
	chooser bool
	focused bool
	focus   int
	options []string

	onChoose func(option string)
	onSelect func(option string)
}

func newSelecter(options []string, focus int) *selecter {
	return &selecter{
		focus:   focus,
		options: options,
	}
}

func (sel *selecter) Chooser(chooser bool) *selecter {
	sel.chooser = chooser
	return sel
}

func (sel *selecter) Invalidate() {
	sel.DoInvalidate(sel)
}

func (sel *selecter) Draw(ctx *ui.Context) {
	ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', tcell.StyleDefault)
	x := 2
	for i, option := range sel.options {
		style := tcell.StyleDefault
		if sel.focus == i {
			if sel.focused {
				style = style.Reverse(true)
			} else if sel.chooser {
				style = style.Bold(true)
			}
		}
		x += ctx.Printf(x, 1, style, "[%s]", option)
		x += 5
	}
}

func (sel *selecter) OnChoose(fn func(option string)) *selecter {
	sel.onChoose = fn
	return sel
}

func (sel *selecter) OnSelect(fn func(option string)) *selecter {
	sel.onSelect = fn
	return sel
}

func (sel *selecter) Selected() string {
	return sel.options[sel.focus]
}

func (sel *selecter) Focus(focus bool) {
	sel.focused = focus
	sel.Invalidate()
}

func (sel *selecter) Event(event tcell.Event) bool {
	switch event := event.(type) {
	case *tcell.EventKey:
		switch event.Key() {
		case tcell.KeyCtrlH:
			fallthrough
		case tcell.KeyLeft:
			if sel.focus > 0 {
				sel.focus--
				sel.Invalidate()
			}
			if sel.onSelect != nil {
				sel.onSelect(sel.Selected())
			}
		case tcell.KeyCtrlL:
			fallthrough
		case tcell.KeyRight:
			if sel.focus < len(sel.options)-1 {
				sel.focus++
				sel.Invalidate()
			}
			if sel.onSelect != nil {
				sel.onSelect(sel.Selected())
			}
		case tcell.KeyEnter:
			if sel.onChoose != nil {
				sel.onChoose(sel.Selected())
			}
		}
	}
	return false
}

func getSRV(host string, services []string) (string, string) {
	var hostport, srv string
	for _, srv = range services {
		_, addrs, err := net.LookupSRV(srv, "tcp", host)
		if err != nil {
			continue
		}
		if addrs[0].Target != "" && addrs[0].Port > 0 {
			hostport = net.JoinHostPort(
				strings.TrimSuffix(addrs[0].Target, "."),
				strconv.Itoa(int(addrs[0].Port)))
			break
		}
	}
	return hostport, srv
}
>)}</span><span class="Special"> &lt;- </span>copy f <span id="L192" class="LineNr">192 </span> <span class="Constant">2</span>:num<span class="Special"> &lt;- </span>call <span class="Delimiter">{</span><span class="Constant">1</span>: <span class="Delimiter">(</span><a href='010vm.cc.html#L19'>recipe</a> point<span class="muRecipe"> -&gt; </span>point<span class="Delimiter">)},</span> <span class="Constant">34</span> <span id="L193" class="LineNr">193 </span>] <span id="L194" class="LineNr">194 </span><span class="muRecipe">def</span> f x:point<span class="muRecipe"> -&gt; </span>y:point [ <span id="L195" class="LineNr">195 </span> local-scope <span id="L196" class="LineNr">196 </span> load-ingredients <span id="L197" class="LineNr">197 </span> y<span class="Special"> &lt;- </span>copy x <span id="L198" class="LineNr">198 </span>] <span id="L199" class="LineNr">199 </span><span class="traceContains">+error: <a href='000organization.cc.html#L113'>main</a>: ingredient 0 has the wrong type at '2:num &lt;- call {1: (recipe point -&gt; point)}, 34'</span> <span id="L200" class="LineNr">200 </span><span class="traceContains">+error: <a href='000organization.cc.html#L113'>main</a>: product 0 has the wrong type at '2:num &lt;- call {1: (recipe point -&gt; point)}, 34'</span> <span id="L201" class="LineNr">201 </span> <span id="L202" class="LineNr">202 </span><span class="Delimiter">:(before &quot;End resolve_ambiguous_call(r, index, inst, caller_recipe) Special-cases&quot;)</span> <span id="L203" class="LineNr">203 </span><span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <span class="Constant">&quot;call&quot;</span> &amp;&amp; !inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> &amp;&amp; <a href='072recipe.cc.html#L208'>is_recipe_literal</a><span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span> <span id="L204" class="LineNr">204 </span> <a href='072recipe.cc.html#L211'>resolve_indirect_ambiguous_call</a><span class="Delimiter">(</span>r<span class="Delimiter">,</span> index<span class="Delimiter">,</span> inst<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">);</span> <span id="L205" class="LineNr">205 </span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span id="L206" class="LineNr">206 </span><span class="Delimiter">}</span> <span id="L207" class="LineNr">207 </span><span class="Delimiter">:(code)</span> <span id="L208" class="LineNr">208 </span><span class="Normal">bool</span> <a href='072recipe.cc.html#L208'>is_recipe_literal</a><span class="Delimiter">(</span><span class="Normal">const</span> reagent&amp; x<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L209" class="LineNr">209 </span> <span class="Identifier">return</span> x<span class="Delimiter">.</span>type &amp;&amp; x<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>atom &amp;&amp; x<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>name == <span class="Constant">&quot;recipe-literal&quot;</span><span class="Delimiter">;</span> <span id="L210" class="LineNr">210 </span><span class="Delimiter">}</span> <span id="L211" class="LineNr">211 </span><span class="Normal">void</span> <a href='072recipe.cc.html#L211'>resolve_indirect_ambiguous_call</a><span class="Delimiter">(</span><span class="Normal">const</span> <a href='010vm.cc.html#L14'>recipe_ordinal</a> r<span class="Delimiter">,</span> <span class="Normal">int</span> index<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> <span id="L212" class="LineNr">212 </span> <a href='010vm.cc.html#L33'>instruction</a> inst2<span class="Delimiter">;</span> <span id="L213" class="LineNr">213 </span> inst2<span class="Delimiter">.</span>name = inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">;</span> <span id="L214" class="LineNr">214 </span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Comment">/*</span><span class="Comment">skip <a href='010vm.cc.html#L19'>recipe</a></span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> i &lt; <a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span id="L215" class="LineNr">215 </span> inst2<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>push_back<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 id="L216" class="LineNr">216 </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; <a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span id="L217" class="LineNr">217 </span> inst2<span class="Delimiter">.</span>products<span class="Delimiter">.</span>push_back<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 id="L218" class="LineNr">218 </span> <a href='054static_dispatch.cc.html#L173'>resolve_ambiguous_call</a><span class="Delimiter">(</span>r<span class="Delimiter">,</span> index<span class="Delimiter">,</span> inst2<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">);</span> <span id="L219" class="LineNr">219 </span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name = inst2<span class="Delimiter">.</span>name<span class="Delimiter">;</span> <span id="L220" class="LineNr">220 </span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span><a href='010vm.cc.html#L67'>set_value</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> inst2<span class="Delimiter">.</span>name<span class="Delimiter">));</span> <span id="L221" class="LineNr">221 </span><span class="Delimiter">}</span> <span id="L222" class="LineNr">222 </span> <span id="L223" class="LineNr">223 </span><span class="Delimiter">:(after &quot;Transform.push_back(check_instruction)&quot;)</span> <span id="L224" class="LineNr">224 </span>Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><a href='072recipe.cc.html#L226'>check_indirect_calls_against_header</a><span class="Delimiter">);</span> <span class="Comment">// idempotent</span> <span id="L225" class="LineNr">225 </span><span class="Delimiter">:(code)</span> <span id="L226" class="LineNr">226 </span><span class="Normal">void</span> <a href='072recipe.cc.html#L226'>check_indirect_calls_against_header</a><span class="Delimiter">(</span><span class="Normal">const</span> <a href='010vm.cc.html#L14'>recipe_ordinal</a> r<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L227" class="LineNr">227 </span> <a href='003trace.cc.html#L190'>trace</a><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;--- type-check 'call' instructions inside <a href='010vm.cc.html#L19'>recipe</a> &quot;</span> &lt;&lt; get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name &lt;&lt; <a href='003trace.cc.html#L226'>end</a><span class="Delimiter">();</span> <span id="L228" class="LineNr">228 </span> <span class="Normal">const</span> recipe&amp; caller = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span> <span id="L229" class="LineNr">229 </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; <a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>caller<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L230" class="LineNr">230 </span> <span class="Normal">const</span> instruction&amp; inst = caller<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> <span id="L231" class="LineNr">231 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>!is_indirect_call<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span id="L232" class="LineNr">232 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Comment">// error raised above</span> <span id="L233" class="LineNr">233 </span> <span class="Normal">const</span> reagent&amp; callee = inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> <span id="L234" class="LineNr">234 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>!is_mu_recipe<span class="Delimiter">(</span>callee<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Comment">// error raised above</span> <span id="L235" class="LineNr">235 </span> <span class="Normal">const</span> <a href='010vm.cc.html#L19'>recipe</a> callee_header = is_literal<span class="Delimiter">(</span>callee<span class="Delimiter">)</span> ? get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> callee<span class="Delimiter">.</span>value<span class="Delimiter">)</span> : <a href='072recipe.cc.html#L268'>from_reagent</a><span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> <span id="L236" class="LineNr">236 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>!callee_header<span class="Delimiter">.</span>has_header<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span id="L237" class="LineNr">237 </span> <span class="Normal">if</span> <span class="Delimiter">(</span><a href='072recipe.cc.html#L257'>is_indirect_call_with_ingredients</a><span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span id="L238" class="LineNr">238 </span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Comment">/*</span><span class="Comment">skip callee</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> i &lt; min<span class="Delimiter">(</span><a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">),</span> <a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>callee_header<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span>+<span class="Comment">/*</span><span class="Comment">skip callee</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L239" class="LineNr">239 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>!types_coercible<span class="Delimiter">(</span>callee_header<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i-<span class="Comment">/*</span><span class="Comment">skip callee</span><span class="Comment">*/</span><span class="Constant">1</span><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 id="L240" class="LineNr">240 </span> <a href='003trace.cc.html#L197'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;ingredient &quot;</span> &lt;&lt; i-<span class="Comment">/*</span><span class="Comment">skip callee</span><span class="Comment">*/</span><span class="Constant">1</span> &lt;&lt; <span class="Constant">&quot; has the wrong type at '&quot;</span> &lt;&lt; to_original_string<span class="Delimiter">(</span>inst<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; <a href='003trace.cc.html#L226'>end</a><span class="Delimiter">();</span> <span id="L241" class="LineNr">241 </span> <span class="Delimiter">}</span> <span id="L242" class="LineNr">242 </span> <span class="Delimiter">}</span> <span id="L243" class="LineNr">243 </span> <span class="Normal">if</span> <span class="Delimiter">(</span><a href='072recipe.cc.html#L262'>is_indirect_call_with_products</a><span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span id="L244" class="LineNr">244 </span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; min<span class="Delimiter">(</span><a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">),</span> <a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>callee_header<span class="Delimiter">.</span>products<span class="Delimiter">));</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L245" class="LineNr">245 </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 id="L246" class="LineNr">246 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>!types_coercible<span class="Delimiter">(</span>callee_header<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 id="L247" class="LineNr">247 </span> <a href='003trace.cc.html#L197'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;product &quot;</span> &lt;&lt; i &lt;&lt; <span class="Constant">&quot; has the wrong type at '&quot;</span> &lt;&lt; to_original_string<span class="Delimiter">(</span>inst<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; <a href='003trace.cc.html#L226'>end</a><span class="Delimiter">();</span> <span id="L248" class="LineNr">248 </span> <span class="Delimiter">}</span> <span id="L249" class="LineNr">249 </span> <span class="Delimiter">}</span> <span id="L250" class="LineNr">250 </span> <span class="Delimiter">}</span> <span id="L251" class="LineNr">251 </span><span class="Delimiter">}</span> <span id="L252" class="LineNr">252 </span> <span id="L253" class="LineNr">253 </span><span class="Normal">bool</span> <a href='072recipe.cc.html#L253'>is_indirect_call</a><span class="Delimiter">(</span><span class="Normal">const</span> <a href='010vm.cc.html#L14'>recipe_ordinal</a> r<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L254" class="LineNr">254 </span> <span class="Identifier">return</span> <a href='072recipe.cc.html#L257'>is_indirect_call_with_ingredients</a><span class="Delimiter">(</span>r<span class="Delimiter">)</span> || <a href='072recipe.cc.html#L262'>is_indirect_call_with_products</a><span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span id="L255" class="LineNr">255 </span><span class="Delimiter">}</span> <span id="L256" class="LineNr">256 </span> <span id="L257" class="LineNr">257 </span><span class="Normal">bool</span> <a href='072recipe.cc.html#L257'>is_indirect_call_with_ingredients</a><span class="Delimiter">(</span><span class="Normal">const</span> <a href='010vm.cc.html#L14'>recipe_ordinal</a> r<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L258" class="LineNr">258 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>r == CALL<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Constant"> true</span><span class="Delimiter">;</span> <span id="L259" class="LineNr">259 </span> <span class="Comment">// End is_indirect_call_with_ingredients Special-cases</span> <span id="L260" class="LineNr">260 </span> <span class="Identifier">return</span><span class="Constant"> false</span><span class="Delimiter">;</span> <span id="L261" class="LineNr">261 </span><span class="Delimiter">}</span> <span id="L262" class="LineNr">262 </span><span class="Normal">bool</span> <a href='072recipe.cc.html#L262'>is_indirect_call_with_products</a><span class="Delimiter">(</span><span class="Normal">const</span> <a href='010vm.cc.html#L14'>recipe_ordinal</a> r<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L263" class="LineNr">263 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>r == CALL<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Constant"> true</span><span class="Delimiter">;</span> <span id="L264" class="LineNr">264 </span> <span class="Comment">// End is_indirect_call_with_products Special-cases</span> <span id="L265" class="LineNr">265 </span> <span class="Identifier">return</span><span class="Constant"> false</span><span class="Delimiter">;</span> <span id="L266" class="LineNr">266 </span><span class="Delimiter">}</span> <span id="L267" class="LineNr">267 </span> <span id="L268" class="LineNr">268 </span><span class="muRecipe"><a href='010vm.cc.html#L19'>recipe</a></span> <a href='072recipe.cc.html#L268'>from_reagent</a><span class="Delimiter">(</span><span class="Normal">const</span> reagent&amp; r<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L269" class="LineNr">269 </span> assert<span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">);</span> <span id="L270" class="LineNr">270 </span> <a href='010vm.cc.html#L19'>recipe</a> result_header<span class="Delimiter">;</span> <span class="Comment">// will contain only ingredients and products, nothing else</span> <span id="L271" class="LineNr">271 </span> result_header<span class="Delimiter">.</span>has_header =<span class="Constant"> true</span><span class="Delimiter">;</span> <span id="L272" class="LineNr">272 </span> <span class="Comment">// Begin Reagent-&gt;Recipe(r, recipe_header)</span> <span id="L273" class="LineNr">273 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>atom<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L274" class="LineNr">274 </span> assert<span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>name == <span class="Constant">&quot;recipe&quot;</span><span class="Delimiter">);</span> <span id="L275" class="LineNr">275 </span> <span class="Identifier">return</span> result_header<span class="Delimiter">;</span> <span id="L276" class="LineNr">276 </span> <span class="Delimiter">}</span> <span id="L277" class="LineNr">277 </span> <span class="Normal">const</span> type_tree* root_type = r<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>atom ? r<span class="Delimiter">.</span>type : r<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>left<span class="Delimiter">;</span> <span id="L278" class="LineNr">278 </span> assert<span class="Delimiter">(</span>root_type<span class="Delimiter">-&gt;</span>atom<span class="Delimiter">);</span> <span id="L279" class="LineNr">279 </span> assert<span class="Delimiter">(</span>root_type<span class="Delimiter">-&gt;</span>name == <span class="Constant">&quot;recipe&quot;</span><span class="Delimiter">);</span> <span id="L280" class="LineNr">280 </span> <span class="Normal">const</span> type_tree* curr = r<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>right<span class="Delimiter">;</span> <span id="L281" class="LineNr">281 </span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">nada</span><span class="Comment">*/</span><span class="Delimiter">;</span> curr &amp;&amp; !curr<span class="Delimiter">-&gt;</span>atom<span class="Delimiter">;</span> curr = curr<span class="Delimiter">-&gt;</span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L282" class="LineNr">282 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">-&gt;</span>left<span class="Delimiter">-&gt;</span>atom &amp;&amp; curr<span class="Delimiter">-&gt;</span>left<span class="Delimiter">-&gt;</span>name == <span class="Constant">&quot;-&gt;&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L283" class="LineNr">283 </span> curr = curr<span class="Delimiter">-&gt;</span>right<span class="Delimiter">;</span> <span class="Comment">// skip delimiter</span> <span id="L284" class="LineNr">284 </span> <span class="Identifier">goto</span> read_products<span class="Delimiter">;</span> <span id="L285" class="LineNr">285 </span> <span class="Delimiter">}</span> <span id="L286" class="LineNr">286 </span> result_header<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><a href='072recipe.cc.html#L330'>next_recipe_reagent</a><span class="Delimiter">(</span>curr<span class="Delimiter">-&gt;</span>left<span class="Delimiter">));</span> <span id="L287" class="LineNr">287 </span> <span class="Delimiter">}</span> <span id="L288" class="LineNr">288 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L289" class="LineNr">289 </span> assert<span class="Delimiter">(</span>curr<span class="Delimiter">-&gt;</span>atom<span class="Delimiter">);</span> <span id="L290" class="LineNr">290 </span> result_header<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><a href='072recipe.cc.html#L330'>next_recipe_reagent</a><span class="Delimiter">(</span>curr<span class="Delimiter">));</span> <span id="L291" class="LineNr">291 </span> <span class="Identifier">return</span> result_header<span class="Delimiter">;</span> <span class="Comment">// no products</span> <span id="L292" class="LineNr">292 </span> <span class="Delimiter">}</span> <span id="L293" class="LineNr">293 </span> <span class="Normal">read_products</span>: <span id="L294" class="LineNr">294 </span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">nada</span><span class="Comment">*/</span><span class="Delimiter">;</span> curr &amp;&amp; !curr<span class="Delimiter">-&gt;</span>atom<span class="Delimiter">;</span> curr = curr<span class="Delimiter">-&gt;</span>right<span class="Delimiter">)</span> <span id="L295" class="LineNr">295 </span> result_header<span class="Delimiter">.</span>products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><a href='072recipe.cc.html#L330'>next_recipe_reagent</a><span class="Delimiter">(</span>curr<span class="Delimiter">-&gt;</span>left<span class="Delimiter">));</span> <span id="L296" class="LineNr">296 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L297" class="LineNr">297 </span> assert<span class="Delimiter">(</span>curr<span class="Delimiter">-&gt;</span>atom<span class="Delimiter">);</span> <span id="L298" class="LineNr">298 </span> result_header<span class="Delimiter">.</span>products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><a href='072recipe.cc.html#L330'>next_recipe_reagent</a><span class="Delimiter">(</span>curr<span class="Delimiter">));</span> <span id="L299" class="LineNr">299 </span> <span class="Delimiter">}</span> <span id="L300" class="LineNr">300 </span> <span class="Identifier">return</span> result_header<span class="Delimiter">;</span> <span id="L301" class="LineNr">301 </span><span class="Delimiter">}</span> <span id="L302" class="LineNr">302 </span> <span id="L303" class="LineNr">303 </span><span class="Delimiter">:(before &quot;End Unit Tests&quot;)</span> <span id="L304" class="LineNr">304 </span><span class="Normal">void</span> <a href='072recipe.cc.html#L304'>test_from_reagent_atomic</a><span class="Delimiter">()</span> <span class="Delimiter">{</span> <span id="L305" class="LineNr">305 </span> reagent a<span class="Delimiter">(</span><span class="Constant">&quot;{f: recipe}&quot;</span><span class="Delimiter">);</span> <span id="L306" class="LineNr">306 </span> <a href='010vm.cc.html#L19'>recipe</a> r_header = <a href='072recipe.cc.html#L268'>from_reagent</a><span class="Delimiter">(</span>a<span class="Delimiter">);</span> <span id="L307" class="LineNr">307 </span> <a href='002test.cc.html#L24'>CHECK</a><span class="Delimiter">(</span>r_header<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">());</span> <span id="L308" class="LineNr">308 </span> <a href='002test.cc.html#L24'>CHECK</a><span class="Delimiter">(</span>r_header<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">());</span> <span id="L309" class="LineNr">309 </span><span class="Delimiter">}</span> <span id="L310" class="LineNr">310 </span><span class="Normal">void</span> <a href='072recipe.cc.html#L310'>test_from_reagent_non_atomic</a><span class="Delimiter">()</span> <span class="Delimiter">{</span> <span id="L311" class="LineNr">311 </span> reagent a<span class="Delimiter">(</span><span class="Constant">&quot;{f: (recipe number -&gt; number)}&quot;</span><span class="Delimiter">);</span> <span id="L312" class="LineNr">312 </span> <a href='010vm.cc.html#L19'>recipe</a> r_header = <a href='072recipe.cc.html#L268'>from_reagent</a><span class="Delimiter">(</span>a<span class="Delimiter">);</span> <span id="L313" class="LineNr">313 </span> <a href='002test.cc.html#L31'>CHECK_EQ</a><span class="Delimiter">(</span><a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>r_header<span class="Delimiter">.</span>ingredients<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> <span id="L314" class="LineNr">314 </span> <a href='002test.cc.html#L31'>CHECK_EQ</a><span class="Delimiter">(</span><a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>r_header<span class="Delimiter">.</span>products<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> <span id="L315" class="LineNr">315 </span><span class="Delimiter">}</span> <span id="L316" class="LineNr">316 </span><span class="Normal">void</span> <a href='072recipe.cc.html#L316'>test_from_reagent_reads_ingredient_at_end</a><span class="Delimiter">()</span> <span class="Delimiter">{</span> <span id="L317" class="LineNr">317 </span> reagent a<span class="Delimiter">(</span><span class="Constant">&quot;{f: (recipe number number)}&quot;</span><span class="Delimiter">);</span> <span id="L318" class="LineNr">318 </span> <a href='010vm.cc.html#L19'>recipe</a> r_header = <a href='072recipe.cc.html#L268'>from_reagent</a><span class="Delimiter">(</span>a<span class="Delimiter">);</span> <span id="L319" class="LineNr">319 </span> <a href='002test.cc.html#L31'>CHECK_EQ</a><span class="Delimiter">(</span><a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>r_header<span class="Delimiter">.</span>ingredients<span class="Delimiter">),</span> <span class="Constant">2</span><span class="Delimiter">);</span> <span id="L320" class="LineNr">320 </span> <a href='002test.cc.html#L24'>CHECK</a><span class="Delimiter">(</span>r_header<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">());</span> <span id="L321" class="LineNr">321 </span><span class="Delimiter">}</span> <span id="L322" class="LineNr">322 </span><span class="Normal">void</span> <a href='072recipe.cc.html#L322'>test_from_reagent_reads_sole_ingredient_at_end</a><span class="Delimiter">()</span> <span class="Delimiter">{</span> <span id="L323" class="LineNr">323 </span> reagent a<span class="Delimiter">(</span><span class="Constant">&quot;{f: (recipe number)}&quot;</span><span class="Delimiter">);</span> <span id="L324" class="LineNr">324 </span> <a href='010vm.cc.html#L19'>recipe</a> r_header = <a href='072recipe.cc.html#L268'>from_reagent</a><span class="Delimiter">(</span>a<span class="Delimiter">);</span> <span id="L325" class="LineNr">325 </span> <a href='002test.cc.html#L31'>CHECK_EQ</a><span class="Delimiter">(</span><a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>r_header<span class="Delimiter">.</span>ingredients<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> <span id="L326" class="LineNr">326 </span> <a href='002test.cc.html#L24'>CHECK</a><span class="Delimiter">(</span>r_header<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">());</span> <span id="L327" class="LineNr">327 </span><span class="Delimiter">}</span> <span id="L328" class="LineNr">328 </span> <span id="L329" class="LineNr">329 </span><span class="Delimiter">:(code)</span> <span id="L330" class="LineNr">330 </span>reagent <a href='072recipe.cc.html#L330'>next_recipe_reagent</a><span class="Delimiter">(</span><span class="Normal">const</span> type_tree* curr<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L331" class="LineNr">331 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>!curr<span class="Delimiter">-&gt;</span>left<span class="Delimiter">)</span> <span class="Identifier">return</span> reagent<span class="Delimiter">(</span><span class="Constant">&quot;recipe:&quot;</span>+curr<span class="Delimiter">-&gt;</span>name<span class="Delimiter">);</span> <span id="L332" class="LineNr">332 </span> <span class="Identifier">return</span> reagent<span class="Delimiter">(</span><span class="Normal">new</span> type_tree<span class="Delimiter">(</span>*curr<span class="Delimiter">));</span> <span id="L333" class="LineNr">333 </span><span class="Delimiter">}</span> <span id="L334" class="LineNr">334 </span> <span id="L335" class="LineNr">335 </span><span class="Normal">bool</span> <a href='072recipe.cc.html#L335'>is_mu_recipe</a><span class="Delimiter">(</span><span class="Normal">const</span> reagent&amp; r<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L336" class="LineNr">336 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>!r<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Constant"> false</span><span class="Delimiter">;</span> <span id="L337" class="LineNr">337 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>atom<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L338" class="LineNr">338 </span> <span class="Comment">// End is_mu_recipe Atom Cases(r)</span> <span id="L339" class="LineNr">339 </span> <span class="Identifier">return</span> r<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>name == <span class="Constant">&quot;recipe-literal&quot;</span><span class="Delimiter">;</span> <span id="L340" class="LineNr">340 </span> <span class="Delimiter">}</span> <span id="L341" class="LineNr">341 </span> <span class="Identifier">return</span> r<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>left<span class="Delimiter">-&gt;</span>atom &amp;&amp; r<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>left<span class="Delimiter">-&gt;</span>name == <span class="Constant">&quot;recipe&quot;</span><span class="Delimiter">;</span> <span id="L342" class="LineNr">342 </span><span class="Delimiter">}</span> <span id="L343" class="LineNr">343 </span> <span id="L344" class="LineNr">344 </span><span class="Delimiter">:(scenario copy_typecheck_recipe_variable)</span> <span id="L345" class="LineNr">345 </span><span class="Special">% Hide_errors = true;</span> <span id="L346" class="LineNr">346 </span><span class="muRecipe">def</span> <a href='000organization.cc.html#L113'>main</a> [ <span id="L347" class="LineNr">347 </span> <span class="Constant">3</span>:num<span class="Special"> &lt;- </span>copy <span class="Constant">34</span> <span class="Comment"># abc def</span> <span id="L348" class="LineNr">348 </span> <span class="Delimiter">{</span><span class="Constant">1</span>: <span class="Delimiter">(</span><a href='010vm.cc.html#L19'>recipe</a> number<span class="muRecipe"> -&gt; </span>number<span class="Delimiter">)}</span><span class="Special"> &lt;- </span>copy f <span class="Comment"># store literal in a matching variable</span> <span id="L349" class="LineNr">349 </span> <span class="Delimiter">{</span><span class="Constant">2</span>: <span class="Delimiter">(</span><a href='010vm.cc.html#L19'>recipe</a> boolean<span class="muRecipe"> -&gt; </span>boolean<span class="Delimiter">)}</span><span class="Special"> &lt;- </span>copy <span class="Delimiter">{</span><span class="Constant">1</span>: <span class="Delimiter">(</span><a href='010vm.cc.html#L19'>recipe</a> number<span class="muRecipe"> -&gt; </span>number<span class="Delimiter">)}</span> <span class="Comment"># mismatch between recipe variables</span> <span id="L350" class="LineNr">350 </span>] <span id="L351" class="LineNr">351 </span><span class="muRecipe">def</span> f x:num<span class="muRecipe"> -&gt; </span>y:num [ <span id="L352" class="LineNr">352 </span> local-scope <span id="L353" class="LineNr">353 </span> load-ingredients <span id="L354" class="LineNr">354 </span> y<span class="Special"> &lt;- </span>copy x <span id="L355" class="LineNr">355 </span>] <span id="L356" class="LineNr">356 </span><span class="traceContains">+error: <a href='000organization.cc.html#L113'>main</a>: can't copy '{1: (recipe number -&gt; number)}' to '{2: (recipe boolean -&gt; boolean)}'; types don't match</span> <span id="L357" class="LineNr">357 </span> <span id="L358" class="LineNr">358 </span><span class="Delimiter">:(scenario copy_typecheck_recipe_variable_2)</span> <span id="L359" class="LineNr">359 </span><span class="Special">% Hide_errors = true;</span> <span id="L360" class="LineNr">360 </span><span class="muRecipe">def</span> <a href='000organization.cc.html#L113'>main</a> [ <span id="L361" class="LineNr">361 </span> <span class="Delimiter">{</span><span class="Constant">1</span>: <span class="Delimiter">(</span><a href='010vm.cc.html#L19'>recipe</a> number<span class="muRecipe"> -&gt; </span>number<span class="Delimiter">)}</span><span class="Special"> &lt;- </span>copy f <span class="Comment"># mismatch with a recipe literal</span> <span id="L362" class="LineNr">362 </span>] <span id="L363" class="LineNr">363 </span><span class="muRecipe">def</span> f x:<span class="Normal">bool</span><span class="muRecipe"> -&gt; </span>y:<span class="Normal">bool</span> [ <span id="L364" class="LineNr">364 </span> local-scope <span id="L365" class="LineNr">365 </span> load-ingredients <span id="L366" class="LineNr">366 </span> y<span class="Special"> &lt;- </span>copy x <span id="L367" class="LineNr">367 </span>] <span id="L368" class="LineNr">368 </span><span class="traceContains">+error: <a href='000organization.cc.html#L113'>main</a>: can't copy 'f' to '{1: (recipe number -&gt; number)}'; types don't match</span> <span id="L369" class="LineNr">369 </span> <span id="L370" class="LineNr">370 </span><span class="Delimiter">:(before &quot;End Matching Types For Literal(to)&quot;)</span> <span id="L371" class="LineNr">371 </span><span class="Normal">if</span> <span class="Delimiter">(</span><a href='072recipe.cc.html#L335'>is_mu_recipe</a><span class="Delimiter">(</span>to<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span id="L372" class="LineNr">372 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> from<span class="Delimiter">.</span>value<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span id="L373" class="LineNr">373 </span> <a href='003trace.cc.html#L197'>raise</a> &lt;&lt; <span class="Constant">&quot;trying to store <a href='010vm.cc.html#L19'>recipe</a> &quot;</span> &lt;&lt; from<span class="Delimiter">.</span>name &lt;&lt; <span class="Constant">&quot; into &quot;</span> &lt;&lt; <a href='028call_return.cc.html#L163'>to_string</a><span class="Delimiter">(</span>to<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; but there's no such recipe</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L374" class="LineNr">374 </span> <span class="Identifier">return</span><span class="Constant"> false</span><span class="Delimiter">;</span> <span id="L375" class="LineNr">375 </span> <span class="Delimiter">}</span> <span id="L376" class="LineNr">376 </span> <span class="Normal">const</span> recipe&amp; rrhs = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> from<span class="Delimiter">.</span>value<span class="Delimiter">);</span> <span id="L377" class="LineNr">377 </span> <span class="Normal">const</span> recipe&amp; rlhs = <a href='072recipe.cc.html#L268'>from_reagent</a><span class="Delimiter">(</span>to<span class="Delimiter">);</span> <span id="L378" class="LineNr">378 </span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; min<span class="Delimiter">(</span><a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>rlhs<span class="Delimiter">.</span>ingredients<span class="Delimiter">),</span> <a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>rrhs<span class="Delimiter">.</span>ingredients<span class="Delimiter">));</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L379" class="LineNr">379 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>rlhs<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> rrhs<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span id="L380" class="LineNr">380 </span> <span class="Identifier">return</span><span class="Constant"> false</span><span class="Delimiter">;</span> <span id="L381" class="LineNr">381 </span> <span class="Delimiter">}</span> <span id="L382" class="LineNr">382 </span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; min<span class="Delimiter">(</span><a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>rlhs<span class="Delimiter">.</span>products<span class="Delimiter">),</span> <a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>rrhs<span class="Delimiter">.</span>products<span class="Delimiter">));</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L383" class="LineNr">383 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>rlhs<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> rrhs<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span id="L384" class="LineNr">384 </span> <span class="Identifier">return</span><span class="Constant"> false</span><span class="Delimiter">;</span> <span id="L385" class="LineNr">385 </span> <span class="Delimiter">}</span> <span id="L386" class="LineNr">386 </span> <span class="Identifier">return</span><span class="Constant"> true</span><span class="Delimiter">;</span> <span id="L387" class="LineNr">387 </span><span class="Delimiter">}</span> <span id="L388" class="LineNr">388 </span> <span id="L389" class="LineNr">389 </span><span class="Delimiter">:(scenario call_variable_compound_ingredient)</span> <span id="L390" class="LineNr">390 </span><span class="muRecipe">def</span> <a href='000organization.cc.html#L113'>main</a> [ <span id="L391" class="LineNr">391 </span> <span class="Delimiter">{</span><span class="Constant">1</span>: <span class="Delimiter">(</span><a href='010vm.cc.html#L19'>recipe</a> <span class="Delimiter">(</span><a href='043space.cc.html#L101'>address</a> number<span class="Delimiter">)</span><span class="muRecipe"> -&gt; </span>number<span class="Delimiter">)}</span><span class="Special"> &lt;- </span>copy f <span id="L392" class="LineNr">392 </span> <span class="Constant">2</span>:&amp;:num<span class="Special"> &lt;- </span>copy<span class="Constant"> null</span> <span id="L393" class="LineNr">393 </span> <span class="Constant">3</span>:num<span class="Special"> &lt;- </span>call <span class="Delimiter">{</span><span class="Constant">1</span>: <span class="Delimiter">(</span><a href='010vm.cc.html#L19'>recipe</a> <span class="Delimiter">(</span><a href='043space.cc.html#L101'>address</a> number<span class="Delimiter">)</span><span class="muRecipe"> -&gt; </span>number<span class="Delimiter">)},</span> <span class="Constant">2</span>:&amp;:num <span id="L394" class="LineNr">394 </span>] <span id="L395" class="LineNr">395 </span><span class="muRecipe">def</span> f x:&amp;:num<span class="muRecipe"> -&gt; </span>y:num [ <span id="L396" class="LineNr">396 </span> local-scope <span id="L397" class="LineNr">397 </span> load-ingredients <span id="L398" class="LineNr">398 </span> y<span class="Special"> &lt;- </span>deaddress x <span id="L399" class="LineNr">399 </span>] <span id="L400" class="LineNr">400 </span>$error: <span class="Constant">0</span> <span id="L401" class="LineNr">401 </span> <span id="L402" class="LineNr">402 </span><span class="Comment">//: make sure we don't accidentally break on a recipe literal</span> <span id="L403" class="LineNr">403 </span><span class="Delimiter">:(scenario jump_forbidden_on_recipe_literals)</span> <span id="L404" class="LineNr">404 </span><span class="Special">% Hide_errors = true;</span> <span id="L405" class="LineNr">405 </span><span class="muRecipe">def</span> foo [ <span id="L406" class="LineNr">406 </span> local-scope <span id="L407" class="LineNr">407 </span>] <span id="L408" class="LineNr">408 </span><span class="muRecipe">def</span> <a href='000organization.cc.html#L113'>main</a> [ <span id="L409" class="LineNr">409 </span> local-scope <span id="L410" class="LineNr">410 </span> <span class="Delimiter">{</span> <span id="L411" class="LineNr">411 </span> <span class="Identifier">break</span>-<span class="Normal">if</span> foo <span id="L412" class="LineNr">412 </span> <span class="Delimiter">}</span> <span id="L413" class="LineNr">413 </span>] <span id="L414" class="LineNr">414 </span><span class="Comment"># error should be as if foo is not a recipe</span> <span id="L415" class="LineNr">415 </span><span class="traceContains">+error: <a href='000organization.cc.html#L113'>main</a>: missing type for 'foo' in 'break-if foo'</span> <span id="L416" class="LineNr">416 </span> <span id="L417" class="LineNr">417 </span><span class="Delimiter">:(before &quot;End JUMP_IF Checks&quot;)</span> <span id="L418" class="LineNr">418 </span><a href='072recipe.cc.html#L422'>check_for_recipe_literals</a><span class="Delimiter">(</span>inst<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">));</span> <span id="L419" class="LineNr">419 </span><span class="Delimiter">:(before &quot;End JUMP_UNLESS Checks&quot;)</span> <span id="L420" class="LineNr">420 </span><a href='072recipe.cc.html#L422'>check_for_recipe_literals</a><span class="Delimiter">(</span>inst<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">));</span> <span id="L421" class="LineNr">421 </span><span class="Delimiter">:(code)</span> <span id="L422" class="LineNr">422 </span><span class="Normal">void</span> <a href='072recipe.cc.html#L422'>check_for_recipe_literals</a><span class="Delimiter">(</span><span class="Normal">const</span> instruction&amp; inst<span class="Delimiter">,</span> <span class="Normal">const</span> recipe&amp; caller<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L423" class="LineNr">423 </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; <a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L424" class="LineNr">424 </span> <span class="Normal">if</span> <span class="Delimiter">(</span><a href='072recipe.cc.html#L335'>is_mu_recipe</a><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> <span id="L425" class="LineNr">425 </span> <a href='003trace.cc.html#L197'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;missing type for '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string &lt;&lt; <span class="Constant">&quot;' in '&quot;</span> &lt;&lt; to_original_string<span class="Delimiter">(</span>inst<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; <a href='003trace.cc.html#L226'>end</a><span class="Delimiter">();</span> <span id="L426" class="LineNr">426 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_present_in_ingredients<span class="Delimiter">(</span>caller<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name<span class="Delimiter">))</span> <span id="L427" class="LineNr">427 </span> <a href='003trace.cc.html#L197'>raise</a> &lt;&lt; <span class="Constant">&quot; did you forget 'load-ingredients'?</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; <a href='003trace.cc.html#L226'>end</a><span class="Delimiter">();</span> <span id="L428" class="LineNr">428 </span> <span class="Delimiter">}</span> <span id="L429" class="LineNr">429 </span> <span class="Delimiter">}</span> <span id="L430" class="LineNr">430 </span><span class="Delimiter">}</span> <span id="L431" class="LineNr">431 </span> <span id="L432" class="LineNr">432 </span><span class="Delimiter">:(scenario load_ingredients_missing_error_3)</span> <span id="L433" class="LineNr">433 </span><span class="Special">% Hide_errors = true;</span> <span id="L434" class="LineNr">434 </span><span class="muRecipe">def</span> foo <span class="Delimiter">{</span>f: <span class="Delimiter">(</span><a href='010vm.cc.html#L19'>recipe</a> num<span class="muRecipe"> -&gt; </span>num<span class="Delimiter">)}</span> [ <span id="L435" class="LineNr">435 </span> local-scope <span id="L436" class="LineNr">436 </span> <span class="Normal">b</span>:num<span class="Special"> &lt;- </span>call f<span class="Delimiter">,</span> <span class="Constant">1</span> <span id="L437" class="LineNr">437 </span>] <span id="L438" class="LineNr">438 </span><span class="traceContains">+error: foo: missing type for 'f' in 'b:num &lt;- call f, 1'</span> <span id="L439" class="LineNr">439 </span><span class="traceContains">+error: did you forget 'load-ingredients'?</span> <span id="L440" class="LineNr">440 </span> <span id="L441" class="LineNr">441 </span><span class="Delimiter">:(before &quot;End Mu Types Initialization&quot;)</span> <span id="L442" class="LineNr">442 </span><a href='001help.cc.html#L221'>put</a><span class="Delimiter">(</span>Type_abbreviations<span class="Delimiter">,</span> <span class="Constant">&quot;function&quot;</span><span class="Delimiter">,</span> <a href='019type_abbreviations.cc.html#L58'>new_type_tree</a><span class="Delimiter">(</span><span class="Constant">&quot;recipe&quot;</span><span class="Delimiter">));</span> <span id="L443" class="LineNr">443 </span><a href='001help.cc.html#L221'>put</a><span class="Delimiter">(</span>Type_abbreviations<span class="Delimiter">,</span> <span class="Constant">&quot;fn&quot;</span><span class="Delimiter">,</span> <a href='019type_abbreviations.cc.html#L58'>new_type_tree</a><span class="Delimiter">(</span><span class="Constant">&quot;recipe&quot;</span><span class="Delimiter">));</span> <span id="L444" class="LineNr">444 </span> <span id="L445" class="LineNr">445 </span><span class="Comment">//: copying functions to variables</span> <span id="L446" class="LineNr">446 </span> <span id="L447" class="LineNr">447 </span><span class="Delimiter">:(scenario copy_recipe_to_variable)</span> <span id="L448" class="LineNr">448 </span><span class="muRecipe">def</span> <a href='000organization.cc.html#L113'>main</a> [ <span id="L449" class="LineNr">449 </span> <span class="Delimiter">{</span><span class="Constant">1</span>: <span class="Delimiter">(</span>fn number<span class="muRecipe"> -&gt; </span>number<span class="Delimiter">)}</span><span class="Special"> &lt;- </span>copy f <span id="L450" class="LineNr">450 </span> <span class="Constant">2</span>:num<span class="Special"> &lt;- </span>call <span class="Delimiter">{</span><span class="Constant">1</span>: <span class="Delimiter">(</span>function number<span class="muRecipe"> -&gt; </span>number<span class="Delimiter">)},</span> <span class="Constant">34</span> <span id="L451" class="LineNr">451 </span>] <span id="L452" class="LineNr">452 </span><span class="muRecipe">def</span> f x:num<span class="muRecipe"> -&gt; </span>y:num [ <span id="L453" class="LineNr">453 </span> local-scope <span id="L454" class="LineNr">454 </span> load-ingredients <span id="L455" class="LineNr">455 </span> y<span class="Special"> &lt;- </span>copy x <span id="L456" class="LineNr">456 </span>] <span id="L457" class="LineNr">457 </span><span class="traceContains">+mem: storing 34 in location 2</span> <span id="L458" class="LineNr">458 </span> <span id="L459" class="LineNr">459 </span><span class="Delimiter">:(scenario copy_overloaded_recipe_to_variable)</span> <span id="L460" class="LineNr">460 </span><span class="muRecipe">def</span> <a href='000organization.cc.html#L113'>main</a> [ <span id="L461" class="LineNr">461 </span> local-scope <span id="L462" class="LineNr">462 </span> <span class="Delimiter">{</span>x: <span class="Delimiter">(</span>fn num<span class="muRecipe"> -&gt; </span>num<span class="Delimiter">)}</span><span class="Special"> &lt;- </span>copy f <span id="L463" class="LineNr">463 </span> <span class="Constant">1</span>:num/<span class="Special">raw &lt;- </span>call x<span class="Delimiter">,</span> <span class="Constant">34</span> <span id="L464" class="LineNr">464 </span>] <span id="L465" class="LineNr">465 </span><span class="Comment"># variant f</span> <span id="L466" class="LineNr">466 </span><span class="muRecipe">def</span> f x:<span class="Normal">bool</span><span class="muRecipe"> -&gt; </span>y:<span class="Normal">bool</span> [ <span id="L467" class="LineNr">467 </span> local-scope <span id="L468" class="LineNr">468 </span> load-ingredients <span id="L469" class="LineNr">469 </span> y<span class="Special"> &lt;- </span>copy x <span id="L470" class="LineNr">470 </span>] <span id="L471" class="LineNr">471 </span><span class="Comment"># variant f_2</span> <span id="L472" class="LineNr">472 </span><span class="muRecipe">def</span> f x:num<span class="muRecipe"> -&gt; </span>y:num [ <span id="L473" class="LineNr">473 </span> local-scope <span id="L474" class="LineNr">474 </span> load-ingredients <span id="L475" class="LineNr">475 </span> y<span class="Special"> &lt;- </span>copy x <span id="L476" class="LineNr">476 </span>] <span id="L477" class="LineNr">477 </span><span class="Comment"># x contains f_2</span> <span id="L478" class="LineNr">478 </span><span class="traceContains">+mem: storing 34 in location 1</span> <span id="L479" class="LineNr">479 </span> <span id="L480" class="LineNr">480 </span><span class="Delimiter">:(before &quot;End resolve_ambiguous_call(r, index, inst, caller_recipe) Special-cases&quot;)</span> <span id="L481" class="LineNr">481 </span><span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <span class="Constant">&quot;copy&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L482" class="LineNr">482 </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; <a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L483" class="LineNr">483 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>!is_recipe_literal<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="Identifier">continue</span><span class="Delimiter">;</span> <span id="L484" class="LineNr">484 </span> <span class="Normal">if</span> <span class="Delimiter">(</span><a href='054static_dispatch.cc.html#L326'>non_ghost_size</a><span class="Delimiter">(</span><a href='001help.cc.html#L229'>get_or_insert</a><span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name<span class="Delimiter">))</span> &lt; <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span id="L485" class="LineNr">485 </span> <span class="Comment">// potentially overloaded recipe</span> <span id="L486" class="LineNr">486 </span> string new_name = <a href='054static_dispatch.cc.html#L173'>resolve_ambiguous_call</a><span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> r<span class="Delimiter">,</span> index<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">);</span> <span id="L487" class="LineNr">487 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>new_name == <span class="Constant">&quot;&quot;</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span id="L488" class="LineNr">488 </span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name = new_name<span class="Delimiter">;</span> <span id="L489" class="LineNr">489 </span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>value = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> new_name<span class="Delimiter">);</span> <span id="L490" class="LineNr">490 </span> <span class="Delimiter">}</span> <span id="L491" class="LineNr">491 </span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span id="L492" class="LineNr">492 </span><span class="Delimiter">}</span> <span id="L493" class="LineNr">493 </span><span class="Delimiter">:(code)</span> <span id="L494" class="LineNr">494 </span>string <a href='054static_dispatch.cc.html#L173'>resolve_ambiguous_call</a><span class="Delimiter">(</span><span class="Normal">const</span> string&amp; recipe_name<span class="Delimiter">,</span> <span class="Normal">const</span> reagent&amp; call_types<span class="Delimiter">,</span> <span class="Normal">const</span> <a href='010vm.cc.html#L14'>recipe_ordinal</a> r<span class="Delimiter">,</span> <span class="Normal">int</span> index<span class="Delimiter">,</span> <span class="Normal">const</span> recipe&amp; caller_recipe<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L495" class="LineNr">495 </span> <a href='010vm.cc.html#L33'>instruction</a> inst<span class="Delimiter">;</span> <span id="L496" class="LineNr">496 </span> inst<span class="Delimiter">.</span>name = recipe_name<span class="Delimiter">;</span> <span id="L497" class="LineNr">497 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>!is_mu_recipe<span class="Delimiter">(</span>call_types<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">&quot;&quot;</span><span class="Delimiter">;</span> <span class="Comment">// error raised elsewhere</span> <span id="L498" class="LineNr">498 </span> <span class="Normal">if</span> <span class="Delimiter">(</span><a href='072recipe.cc.html#L208'>is_recipe_literal</a><span class="Delimiter">(</span>call_types<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">&quot;&quot;</span><span class="Delimiter">;</span> <span class="Comment">// error raised elsewhere</span> <span id="L499" class="LineNr">499 </span> construct_fake_call<span class="Delimiter">(</span>call_types<span class="Delimiter">,</span> inst<span class="Delimiter">);</span> <span id="L500" class="LineNr">500 </span> <a href='054static_dispatch.cc.html#L173'>resolve_ambiguous_call</a><span class="Delimiter">(</span>r<span class="Delimiter">,</span> index<span class="Delimiter">,</span> inst<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">);</span> <span id="L501" class="LineNr">501 </span> <span class="Identifier">return</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">;</span> <span id="L502" class="LineNr">502 </span><span class="Delimiter">}</span> <span id="L503" class="LineNr">503 </span><span class="Normal">void</span> construct_fake_call<span class="Delimiter">(</span><span class="Normal">const</span> reagent&amp; recipe_var<span class="Delimiter">,</span> instruction&amp; out<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L504" class="LineNr">504 </span> assert<span class="Delimiter">(</span>recipe_var<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>left<span class="Delimiter">-&gt;</span>name == <span class="Constant">&quot;recipe&quot;</span><span class="Delimiter">);</span> <span id="L505" class="LineNr">505 </span> type_tree* stem = <span class="Constant">NULL</span><span class="Delimiter">;</span> <span id="L506" class="LineNr">506 </span> <span class="Normal">for</span> <span class="Delimiter">(</span>stem = recipe_var<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>right<span class="Delimiter">;</span> stem &amp;&amp; stem<span class="Delimiter">-&gt;</span>left<span class="Delimiter">-&gt;</span>name != <span class="Constant">&quot;-&gt;&quot;</span><span class="Delimiter">;</span> stem = stem<span class="Delimiter">-&gt;</span>right<span class="Delimiter">)</span> <span id="L507" class="LineNr">507 </span> out<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>copy<span class="Delimiter">(</span>stem<span class="Delimiter">-&gt;</span>left<span class="Delimiter">));</span> <span id="L508" class="LineNr">508 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>stem == <span class="Constant">NULL</span><span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span id="L509" class="LineNr">509 </span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">skip '-&gt;'</span><span class="Comment">*/</span>stem = stem<span class="Delimiter">-&gt;</span>right<span class="Delimiter">;</span> stem<span class="Delimiter">;</span> stem = stem<span class="Delimiter">-&gt;</span>right<span class="Delimiter">)</span> <span id="L510" class="LineNr">510 </span> out<span class="Delimiter">.</span>products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>copy<span class="Delimiter">(</span>stem<span class="Delimiter">-&gt;</span>left<span class="Delimiter">));</span> <span id="L511" class="LineNr">511 </span><span class="Delimiter">}</span> <span id="L512" class="LineNr">512 </span> <span id="L513" class="LineNr">513 </span><span class="Delimiter">:(scenario copy_shape_shifting_recipe_to_variable)</span> <span id="L514" class="LineNr">514 </span><span class="muRecipe">def</span> <a href='000organization.cc.html#L113'>main</a> [ <span id="L515" class="LineNr">515 </span> local-scope <span id="L516" class="LineNr">516 </span> <span class="Delimiter">{</span>x: <span class="Delimiter">(</span>fn num<span class="muRecipe"> -&gt; </span>num<span class="Delimiter">)}</span><span class="Special"> &lt;- </span>copy f <span id="L517" class="LineNr">517 </span> <span class="Constant">1</span>:num/<span class="Special">raw &lt;- </span>call x<span class="Delimiter">,</span> <span class="Constant">34</span> <span id="L518" class="LineNr">518 </span>] <span id="L519" class="LineNr">519 </span><span class="muRecipe">def</span> f x:_elem<span class="muRecipe"> -&gt; </span>y:_elem [ <span id="L520" class="LineNr">520 </span> local-scope <span id="L521" class="LineNr">521 </span> load-inputs <span id="L522" class="LineNr">522 </span> y<span class="Special"> &lt;- </span>copy x <span id="L523" class="LineNr">523 </span>] <span id="L524" class="LineNr">524 </span><span class="traceContains">+mem: storing 34 in location 1</span> <span id="L525" class="LineNr">525 </span> <span id="L526" class="LineNr">526 </span><span class="Comment">//: passing function literals to (higher-order) functions</span> <span id="L527" class="LineNr">527 </span> <span id="L528" class="LineNr">528 </span><span class="Delimiter">:(scenario pass_overloaded_recipe_literal_to_ingredient)</span> <span id="L529" class="LineNr">529 </span><span class="Comment"># like copy_overloaded_recipe_to_variable except we bind 'x' in the course of</span> <span id="L530" class="LineNr">530 </span><span class="Comment"># a 'call' rather than 'copy'</span> <span id="L531" class="LineNr">531 </span><span class="muRecipe">def</span> <a href='000organization.cc.html#L113'>main</a> [ <span id="L532" class="LineNr">532 </span> <span class="Constant">1</span>:num<span class="Special"> &lt;- </span>g f <span id="L533" class="LineNr">533 </span>] <span id="L534" class="LineNr">534 </span><span class="muRecipe">def</span> g <span class="Delimiter">{</span>x: <span class="Delimiter">(</span>fn num<span class="muRecipe"> -&gt; </span>num<span class="Delimiter">)}</span><span class="muRecipe"> -&gt; </span>result:num [ <span id="L535" class="LineNr">535 </span> local-scope <span id="L536" class="LineNr">536 </span> load-ingredients <span id="L537" class="LineNr">537 </span> result<span class="Special"> &lt;- </span>call x<span class="Delimiter">,</span> <span class="Constant">34</span> <span id="L538" class="LineNr">538 </span>] <span id="L539" class="LineNr">539 </span><span class="Comment"># variant f</span> <span id="L540" class="LineNr">540 </span><span class="muRecipe">def</span> f x:<span class="Normal">bool</span><span class="muRecipe"> -&gt; </span>y:<span class="Normal">bool</span> [ <span id="L541" class="LineNr">541 </span> local-scope <span id="L542" class="LineNr">542 </span> load-ingredients <span id="L543" class="LineNr">543 </span> y<span class="Special"> &lt;- </span>copy x <span id="L544" class="LineNr">544 </span>] <span id="L545" class="LineNr">545 </span><span class="Comment"># variant f_2</span> <span id="L546" class="LineNr">546 </span><span class="muRecipe">def</span> f x:num<span class="muRecipe"> -&gt; </span>y:num [ <span id="L547" class="LineNr">547 </span> local-scope <span id="L548" class="LineNr">548 </span> load-ingredients <span id="L549" class="LineNr">549 </span> y<span class="Special"> &lt;- </span>copy x <span id="L550" class="LineNr">550 </span>] <span id="L551" class="LineNr">551 </span><span class="Comment"># x contains f_2</span> <span id="L552" class="LineNr">552 </span><span class="traceContains">+mem: storing 34 in location 1</span> <span id="L553" class="LineNr">553 </span> <span id="L554" class="LineNr">554 </span><span class="Delimiter">:(after &quot;End resolve_ambiguous_call(r, index, inst, caller_recipe) Special-cases&quot;)</span> <span id="L555" class="LineNr">555 </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; <a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L556" class="LineNr">556 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>!is_mu_recipe<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="Identifier">continue</span><span class="Delimiter">;</span> <span id="L557" class="LineNr">557 </span> <span class="Normal">if</span> <span class="Delimiter">(</span><a href='054static_dispatch.cc.html#L326'>non_ghost_size</a><span class="Delimiter">(</span><a href='001help.cc.html#L229'>get_or_insert</a><span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name<span class="Delimiter">))</span> &lt; <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span id="L558" class="LineNr">558 </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> &lt; <a href='010vm.cc.html#L198'>MAX_PRIMITIVE_RECIPES</a><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span id="L559" class="LineNr">559 </span> <span class="Normal">if</span> <span class="Delimiter">(</span><a href='054static_dispatch.cc.html#L326'>non_ghost_size</a><span class="Delimiter">(</span><a href='001help.cc.html#L229'>get_or_insert</a><span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">))</span> &gt; <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L560" class="LineNr">560 </span> <a href='003trace.cc.html#L197'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;sorry, we're not yet smart enough to simultaneously guess which overloads you want for '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>name &lt;&lt; <span class="Constant">&quot;' and '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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 id="L561" class="LineNr">561 </span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span id="L562" class="LineNr">562 </span> <span class="Delimiter">}</span> <span id="L563" class="LineNr">563 </span> <span class="Normal">const</span> recipe&amp; callee = get<span class="Delimiter">(</span>Recipe<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> <span id="L564" class="LineNr">564 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>!callee<span class="Delimiter">.</span>has_header<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L565" class="LineNr">565 </span> <a href='003trace.cc.html#L197'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;sorry, we're not yet smart enough to guess which variant of '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot;' you want, when the caller '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>name &lt;&lt; <span class="Constant">&quot;' doesn't have a header</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; <a href='003trace.cc.html#L226'>end</a><span class="Delimiter">();</span> <span id="L566" class="LineNr">566 </span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span id="L567" class="LineNr">567 </span> <span class="Delimiter">}</span> <span id="L568" class="LineNr">568 </span> string new_name = <a href='054static_dispatch.cc.html#L173'>resolve_ambiguous_call</a><span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name<span class="Delimiter">,</span> callee<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> r<span class="Delimiter">,</span> index<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">);</span> <span id="L569" class="LineNr">569 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>new_name != <span class="Constant">&quot;&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L570" class="LineNr">570 </span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name = new_name<span class="Delimiter">;</span> <span id="L571" class="LineNr">571 </span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>value = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> new_name<span class="Delimiter">);</span> <span id="L572" class="LineNr">572 </span> <span class="Delimiter">}</span> <span id="L573" class="LineNr">573 </span><span class="Delimiter">}</span> <span id="L574" class="LineNr">574 </span> <span id="L575" class="LineNr">575 </span><span class="Delimiter">:(scenario return_overloaded_recipe_literal_to_caller)</span> <span id="L576" class="LineNr">576 </span><span class="muRecipe">def</span> <a href='000organization.cc.html#L113'>main</a> [ <span id="L577" class="LineNr">577 </span> local-scope <span id="L578" class="LineNr">578 </span> <span class="Delimiter">{</span>x: <span class="Delimiter">(</span>fn num<span class="muRecipe"> -&gt; </span>num<span class="Delimiter">)}</span><span class="Special"> &lt;- </span>g <span id="L579" class="LineNr">579 </span> <span class="Constant">1</span>:num/<span class="Special">raw &lt;- </span>call x<span class="Delimiter">,</span> <span class="Constant">34</span> <span id="L580" class="LineNr">580 </span>] <span id="L581" class="LineNr">581 </span><span class="muRecipe">def</span> g<span class="muRecipe"> -&gt; </span><span class="Delimiter">{</span>x: <span class="Delimiter">(</span>fn num<span class="muRecipe"> -&gt; </span>num<span class="Delimiter">)}</span> [ <span id="L582" class="LineNr">582 </span> local-scope <span id="L583" class="LineNr">583 </span> <span class="Identifier">return</span> f <span id="L584" class="LineNr">584 </span>] <span id="L585" class="LineNr">585 </span><span class="Comment"># variant f</span> <span id="L586" class="LineNr">586 </span><span class="muRecipe">def</span> f x:<span class="Normal">bool</span><span class="muRecipe"> -&gt; </span>y:<span class="Normal">bool</span> [ <span id="L587" class="LineNr">587 </span> local-scope <span id="L588" class="LineNr">588 </span> load-ingredients <span id="L589" class="LineNr">589 </span> y<span class="Special"> &lt;- </span>copy x <span id="L590" class="LineNr">590 </span>] <span id="L591" class="LineNr">591 </span><span class="Comment"># variant f_2</span> <span id="L592" class="LineNr">592 </span><span class="muRecipe">def</span> f x:num<span class="muRecipe"> -&gt; </span>y:num [ <span id="L593" class="LineNr">593 </span> local-scope <span id="L594" class="LineNr">594 </span> load-ingredients <span id="L595" class="LineNr">595 </span> y<span class="Special"> &lt;- </span>copy x <span id="L596" class="LineNr">596 </span>] <span id="L597" class="LineNr">597 </span><span class="Comment"># x contains f_2</span> <span id="L598" class="LineNr">598 </span><span class="traceContains">+mem: storing 34 in location 1</span> <span id="L599" class="LineNr">599 </span> <span id="L600" class="LineNr">600 </span><span class="Delimiter">:(before &quot;End resolve_ambiguous_call(r, index, inst, caller_recipe) Special-cases&quot;)</span> <span id="L601" class="LineNr">601 </span><span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <span class="Constant">&quot;return&quot;</span> || inst<span class="Delimiter">.</span>name == <span class="Constant">&quot;reply&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L602" class="LineNr">602 </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; <a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L603" class="LineNr">603 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>!is_recipe_literal<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="Identifier">continue</span><span class="Delimiter">;</span> <span id="L604" class="LineNr">604 </span> <span class="Normal">if</span> <span class="Delimiter">(</span><a href='054static_dispatch.cc.html#L326'>non_ghost_size</a><span class="Delimiter">(</span><a href='001help.cc.html#L229'>get_or_insert</a><span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name<span class="Delimiter">))</span> &lt; <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span id="L605" class="LineNr">605 </span> <span class="Comment">// potentially overloaded recipe</span> <span id="L606" class="LineNr">606 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>!caller_recipe<span class="Delimiter">.</span>has_header<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span id="L607" class="LineNr">607 </span> <a href='003trace.cc.html#L197'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;sorry, we're not yet smart enough to guess which variant of '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot;' you want, without a recipe header</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span id="L608" class="LineNr">608 </span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span id="L609" class="LineNr">609 </span> <span class="Delimiter">}</span> <span id="L610" class="LineNr">610 </span> string new_name = <a href='054static_dispatch.cc.html#L173'>resolve_ambiguous_call</a><span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> r<span class="Delimiter">,</span> index<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">);</span> <span id="L611" class="LineNr">611 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>new_name == <span class="Constant">&quot;&quot;</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span id="L612" class="LineNr">612 </span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name = new_name<span class="Delimiter">;</span> <span id="L613" class="LineNr">613 </span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>value = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> new_name<span class="Delimiter">);</span> <span id="L614" class="LineNr">614 </span> <span class="Delimiter">}</span> <span id="L615" class="LineNr">615 </span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span id="L616" class="LineNr">616 </span><span class="Delimiter">}</span> </pre> </body> </html> <!-- vim: set foldmethod=manual : -->