MCPcopy Index your code
hub / github.com/endbasic/endbasic / compile_args

Function compile_args

core/src/compiler/args.rs:205–496  ·  view source on GitHub ↗

Compiles the arguments of a callable invocation. Returns the first register containing the compiled arguments and the source positions for all allocated registers. The register layout depends on the callable's syntax: Singular arguments and variable repeated arguments use `VarArgTag` tag registers followed by optional value registers. See the `VarArgTag` documentation for details. Repeated ar

(
    span: CallSpan,
    md: Rc<CallableMetadata>,
    symtable: &mut TempSymtable<'_, '_>,
    codegen: &mut Codegen,
)

Source from the content-addressed store, hash-verified

203/// another lookup from the symtable. Or maybe we could make `Metadata` objects static by
204/// eliminating the `MetadataBuilder` and pass a static reference here.
205pub(super) fn compile_args(
206 span: CallSpan,
207 md: Rc<CallableMetadata>,
208 symtable: &mut TempSymtable<'_, '_>,
209 codegen: &mut Codegen,
210) -> Result<(Register, Vec<LineCol>)> {
211 let key_pos = span.vref_pos;
212
213 let Some(syntax) = md.find_syntax(span.args.len()) else {
214 return Err(Error::CallableSyntax(key_pos, md.as_ref().clone()));
215 };
216
217 let mut scope = symtable.temp_scope();
218
219 // Collects the source position for each register slot allocated below, in allocation order.
220 // This is used to populate the UPCALL instruction's arg_linecols metadata so that callables
221 // can query the source position of any argument via `Scope::get_pos`.
222 let mut arg_linecols: Vec<LineCol> = Vec::new();
223
224 let input_nargs = span.args.len();
225 let mut arg_iter = span.args.into_iter().peekable();
226
227 for (i, syn) in syntax.singular.iter().enumerate() {
228 let end_ok = i + 1 == syntax.singular.len()
229 && input_nargs == syntax.singular.len()
230 && syntax.repeated.as_ref().is_some_and(|syn| !syn.require_one);
231
232 match syn {
233 SingularArgSyntax::RequiredValue(details, exp_sep) => {
234 let ArgSpan { expr, sep, sep_pos } =
235 arg_iter.next().expect("Args and their syntax must advance in unison");
236 let arg_pos = expr.as_ref().map(|e| e.start_pos()).unwrap_or(sep_pos);
237
238 match expr {
239 None => return Err(Error::CallableSyntax(key_pos, md.as_ref().clone())),
240 Some(expr) => {
241 let temp_value = scope.alloc().map_err(|e| Error::from_syms(e, arg_pos))?;
242 arg_linecols.push(arg_pos);
243 compile_expr_as_type(codegen, symtable, temp_value, expr, details.vtype)?;
244 validate_syn_argsep(
245 &md,
246 exp_sep,
247 end_ok,
248 arg_iter.peek().is_none(),
249 sep,
250 sep_pos,
251 )?;
252 }
253 }
254 }
255
256 SingularArgSyntax::RequiredRef(details, exp_sep) => {
257 let ArgSpan { expr, sep, sep_pos } =
258 arg_iter.next().expect("Args and their syntax must advance in unison");
259 let arg_pos = expr.as_ref().map(|e| e.start_pos()).unwrap_or(sep_pos);
260
261 match expr {
262 None => return Err(Error::CallableSyntax(key_pos, md.as_ref().clone())),

Callers 3

compile_exprFunction · 0.85
compile_stmtFunction · 0.85

Calls 15

CallableSyntaxClass · 0.85
compile_expr_as_typeFunction · 0.85
validate_syn_argsepFunction · 0.85
compile_exprFunction · 0.85
find_syntaxMethod · 0.80
temp_scopeMethod · 0.80
peekableMethod · 0.80
iterMethod · 0.80
start_posMethod · 0.80
allocMethod · 0.80
pushMethod · 0.80
get_local_or_globalMethod · 0.80