Pre-allocates local variables for command output arguments.
(
span: &CallSpan,
md: &Rc<CallableMetadata>,
symtable: &mut LocalSymtable<'_>,
codegen: &mut Codegen,
)
| 112 | |
| 113 | /// Pre-allocates local variables for command output arguments. |
| 114 | pub(super) fn define_new_args( |
| 115 | span: &CallSpan, |
| 116 | md: &Rc<CallableMetadata>, |
| 117 | symtable: &mut LocalSymtable<'_>, |
| 118 | codegen: &mut Codegen, |
| 119 | ) -> Result<()> { |
| 120 | let Some(syntax) = md.find_syntax(span.args.len()) else { |
| 121 | return Err(Error::CallableSyntax(span.vref_pos, md.as_ref().clone())); |
| 122 | }; |
| 123 | |
| 124 | let mut arg_iter = span.args.iter(); |
| 125 | |
| 126 | for syn in syntax.singular.iter() { |
| 127 | match syn { |
| 128 | SingularArgSyntax::RequiredValue(_details, _exp_sep) => { |
| 129 | arg_iter.next().expect("Args and their syntax must advance in unison"); |
| 130 | } |
| 131 | |
| 132 | SingularArgSyntax::RequiredRef(details, _exp_sep) => { |
| 133 | let ArgSpan { expr, .. } = |
| 134 | arg_iter.next().expect("Args and their syntax must advance in unison"); |
| 135 | |
| 136 | if let Some(Expr::Symbol(span)) = expr |
| 137 | && let Err(syms::Error::UndefinedSymbol(..)) = |
| 138 | symtable.get_local_or_global(&span.vref) |
| 139 | && details.define_undefined |
| 140 | { |
| 141 | let key = SymbolKey::from(&span.vref.name); |
| 142 | if symtable.get_callable(&key).is_some() { |
| 143 | continue; |
| 144 | } |
| 145 | define_new_arg(symtable, &span.vref, span.pos, codegen)?; |
| 146 | } |
| 147 | } |
| 148 | |
| 149 | SingularArgSyntax::OptionalValue(_details, _exp_sep) => { |
| 150 | arg_iter.next(); |
| 151 | } |
| 152 | |
| 153 | SingularArgSyntax::AnyValue(_details, _exp_sep) => { |
| 154 | arg_iter.next(); |
| 155 | } |
| 156 | }; |
| 157 | } |
| 158 | |
| 159 | if let Some(syn) = syntax.repeated.as_ref() |
| 160 | && let RepeatedTypeSyntax::VariableRef = syn.type_syn |
| 161 | { |
| 162 | for arg in arg_iter { |
| 163 | let Some(Expr::Symbol(span)) = &arg.expr else { |
| 164 | continue; |
| 165 | }; |
| 166 | |
| 167 | let Err(syms::Error::UndefinedSymbol(..)) = symtable.get_local_or_global(&span.vref) |
| 168 | else { |
| 169 | continue; |
| 170 | }; |
| 171 |
no test coverage detected