| 353 | ); |
| 354 | |
| 355 | Error parse_function(Tokenizer &tokenizer, StdVector<UniquePtr<Node>> &operand_stack, Span<const Function> functions) { |
| 356 | std::string_view fname; |
| 357 | { |
| 358 | // We'll replace the variable with a function call node |
| 359 | UniquePtr<Node> top = pop(operand_stack); |
| 360 | ZN_ASSERT(top->type == Node::VARIABLE); |
| 361 | const VariableNode *node = static_cast<VariableNode *>(top.get()); |
| 362 | fname = node->name; |
| 363 | } |
| 364 | |
| 365 | const Function *fn = find_function_by_name(fname, functions); |
| 366 | if (fn == nullptr) { |
| 367 | Error error; |
| 368 | error.id = ERROR_UNKNOWN_FUNCTION; |
| 369 | error.position = tokenizer.get_position(); |
| 370 | error.symbol = fname; |
| 371 | return error; |
| 372 | } |
| 373 | |
| 374 | UniquePtr<FunctionNode> fnode = make_unique_instance<FunctionNode>(); |
| 375 | fnode->function_id = fn->id; |
| 376 | ZN_ASSERT(fn->argument_count < fnode->args.size()); |
| 377 | |
| 378 | Token last_token; |
| 379 | |
| 380 | for (unsigned int arg_index = 0; arg_index < fn->argument_count; ++arg_index) { |
| 381 | Result arg_result = parse_expression(tokenizer, true, functions, &last_token); |
| 382 | |
| 383 | if (arg_result.error.id != ERROR_NONE) { |
| 384 | return arg_result.error; |
| 385 | } |
| 386 | |
| 387 | if (arg_result.root == nullptr) { |
| 388 | Error error; |
| 389 | error.id = ERROR_EXPECTED_ARGUMENT; |
| 390 | error.position = tokenizer.get_position(); |
| 391 | error.symbol = fname; |
| 392 | return error; |
| 393 | |
| 394 | } else if (last_token.type == Token::PARENTHESIS_CLOSE && arg_index + 1 < fn->argument_count) { |
| 395 | Error error; |
| 396 | error.id = ERROR_TOO_FEW_ARGUMENTS; |
| 397 | error.position = tokenizer.get_position(); |
| 398 | error.symbol = fname; |
| 399 | return error; |
| 400 | } |
| 401 | |
| 402 | fnode->args[arg_index] = std::move(arg_result.root); |
| 403 | } |
| 404 | |
| 405 | if (last_token.type != Token::PARENTHESIS_CLOSE) { |
| 406 | Error error; |
| 407 | error.id = ERROR_TOO_MANY_ARGUMENTS; |
| 408 | error.position = tokenizer.get_position(); |
| 409 | error.symbol = fname; |
| 410 | return error; |
| 411 | } |
| 412 |
no test coverage detected