32#ifndef _QORE_FUNCTIONCALLNODE_H
34#define _QORE_FUNCTIONCALLNODE_H
37#include "qore/intern/QoreParseListNode.h"
38#include "qore/intern/FunctionList.h"
40class FunctionCallBase {
42 QoreParseListNode* parse_args =
nullptr;
44 const AbstractQoreFunctionVariant* variant =
nullptr;
47 DLLLOCAL FunctionCallBase(QoreParseListNode* parse_args,
QoreListNode* args =
nullptr) : parse_args(parse_args), args(args) {
50 DLLLOCAL FunctionCallBase(
const FunctionCallBase& old) :
51 parse_args(old.parse_args ? old.parse_args->listRefSelf() : nullptr),
52 args(old.args ? old.args->listRefSelf() : nullptr),
53 variant(old.variant) {
56 DLLLOCAL FunctionCallBase(
const FunctionCallBase& old,
QoreListNode* n_args) : args(n_args), variant(old.variant) {
59 DLLLOCAL ~FunctionCallBase() {
66 DLLLOCAL
const QoreParseListNode* getParseArgs()
const {
return parse_args; }
68 DLLLOCAL
const QoreListNode* getArgs()
const {
return args; }
71 DLLLOCAL
int parseArgsVariant(
const QoreProgramLocation* loc, QoreParseContext& parse_context, QoreFunction* func,
74 DLLLOCAL
const AbstractQoreFunctionVariant* getVariant()
const {
79class AbstractFunctionCallNode :
public ParseNode,
public FunctionCallBase {
83 bool tmp_args =
false;
87 DLLLOCAL
void doFlags(
int64 flags) {
88 if (flags & QCF_RET_VALUE_ONLY) {
90 set_effect_as_root(
false);
92 if (flags & QCF_CONSTANT) {
93 set_effect_as_root(
false);
98 DLLLOCAL AbstractFunctionCallNode(
const QoreProgramLocation* loc,
qore_type_t t, QoreParseListNode* n_args,
bool needs_eval =
true) : ParseNode(loc, t,
needs_eval), FunctionCallBase(n_args) {
101 DLLLOCAL AbstractFunctionCallNode(
const QoreProgramLocation* loc,
qore_type_t t, QoreParseListNode* parse_args,
QoreListNode* args,
bool needs_eval =
true) : ParseNode(loc, t,
needs_eval), FunctionCallBase(parse_args, args) {
104 DLLLOCAL AbstractFunctionCallNode(
const AbstractFunctionCallNode& old) : ParseNode(old), FunctionCallBase(old) {
107 DLLLOCAL AbstractFunctionCallNode(
const AbstractFunctionCallNode& old,
QoreListNode* n_args) : ParseNode(old), FunctionCallBase(old, n_args), tmp_args(true) {
110 DLLLOCAL
virtual ~AbstractFunctionCallNode() {
120 DLLLOCAL
int parseArgs(QoreParseContext& parse_context, QoreFunction* func, qore_ns_private* ns) {
121 int err = parseArgsVariant(loc, parse_context, func, ns);
124 doFlags(variant->getFlags());
126 doFlags(func->parseGetUniqueFlags());
131 DLLLOCAL
virtual const char* getName()
const = 0;
134class FunctionCallNode :
public AbstractFunctionCallNode {
136 DLLLOCAL FunctionCallNode(
const FunctionCallNode& old,
QoreListNode* args) : AbstractFunctionCallNode(old, args), fe(old.fe), pgm(old.pgm), finalized(old.finalized) {
139 DLLLOCAL FunctionCallNode(
const QoreProgramLocation* loc,
const FunctionEntry* f, QoreParseListNode* a) : AbstractFunctionCallNode(loc,
NT_FUNCTION_CALL, a), fe(f) {
142 DLLLOCAL FunctionCallNode(
const QoreProgramLocation* loc,
const FunctionEntry* f,
QoreListNode* a,
QoreProgram* n_pgm) : AbstractFunctionCallNode(loc,
NT_FUNCTION_CALL, nullptr, a), fe(f), pgm(n_pgm) {
146 DLLLOCAL FunctionCallNode(
const QoreProgramLocation* loc,
char* name, QoreParseListNode* a) : AbstractFunctionCallNode(loc,
NT_FUNCTION_CALL, a), c_str(name) {
149 DLLLOCAL
virtual ~FunctionCallNode() {
150 printd(5,
"FunctionCallNode::~FunctionCallNode(): fe: %p c_str: %p (%s) args: %p\n", fe, c_str, c_str ? c_str :
"n/a", args);
159 DLLLOCAL
virtual const char* getTypeName()
const {
160 return "function call";
167 DLLLOCAL
int parseInitCall(
QoreValue& val, QoreParseContext& parse_context);
169 DLLLOCAL
int parseInitFinalizedCall(
QoreValue& val, QoreParseContext& parse_context);
171 DLLLOCAL
virtual const char* getName()
const {
172 return fe ? fe->getName() : c_str;
175 DLLLOCAL
const QoreFunction* getFunction()
const {
176 return fe ? fe->getFunction() :
nullptr;
180 DLLLOCAL
char* takeName() {
187 DLLLOCAL QoreParseListNode* takeParseArgs() {
188 QoreParseListNode* rv = parse_args;
189 parse_args =
nullptr;
201 parse_error(*loc,
"argument given to call reference");
213 DLLLOCAL
bool isFinalized()
const {
217 DLLLOCAL
void setFinalized() {
222 const FunctionEntry* fe =
nullptr;
224 char* c_str =
nullptr;
226 bool finalized =
false;
228 using AbstractFunctionCallNode::evalImpl;
231 DLLLOCAL FunctionCallNode(
const QoreProgramLocation* loc,
char* name, QoreParseListNode* a,
qore_type_t n_type) : AbstractFunctionCallNode(loc, n_type, a), c_str(name), finalized(false) {
234 DLLLOCAL
virtual int parseInitImpl(
QoreValue& val, QoreParseContext& parse_context);
236 DLLLOCAL
virtual const QoreTypeInfo* getTypeInfo()
const {
238 ? variant->parseGetReturnTypeInfo()
239 : (fe ? fe->getFunction()->parseGetUniqueReturnTypeInfo() :
nullptr);
243class ProgramFunctionCallNode :
public FunctionCallNode {
245 DLLLOCAL ProgramFunctionCallNode(
const QoreProgramLocation* loc,
char* name, QoreParseListNode* a) : FunctionCallNode(loc, name, a,
NT_PROGRAM_FUNC_CALL) {
248 DLLLOCAL
virtual int parseInitImpl(
QoreValue& val, QoreParseContext& parse_context) {
249 return parseInitCall(val, parse_context);
255class AbstractMethodCallNode :
public AbstractFunctionCallNode {
263 DLLLOCAL
virtual int parseInitImpl(
QoreValue& val, QoreParseContext& parse_context) = 0;
265 DLLLOCAL
virtual const QoreTypeInfo* getTypeInfo()
const;
268 DLLLOCAL AbstractMethodCallNode(
const QoreProgramLocation* loc,
qore_type_t t, QoreParseListNode* n_args,
const QoreClass* n_qc =
nullptr,
const QoreMethod* m =
nullptr) : AbstractFunctionCallNode(loc, t, n_args), qc(n_qc), method(m) {
271 DLLLOCAL AbstractMethodCallNode(
const AbstractMethodCallNode& old) : AbstractFunctionCallNode(old), qc(old.qc), method(old.method) {
274 DLLLOCAL AbstractMethodCallNode(
const AbstractMethodCallNode& old,
QoreListNode* n_args) : AbstractFunctionCallNode(old, n_args), qc(old.qc), method(old.method) {
279 DLLLOCAL
const QoreClass* getClass()
const {
283 DLLLOCAL
const QoreMethod* getMethod()
const {
288class MethodCallNode :
public AbstractMethodCallNode {
290 DLLLOCAL MethodCallNode(
const QoreProgramLocation* loc,
char* name, QoreParseListNode* n_args)
291 : AbstractMethodCallNode(loc,
NT_METHOD_CALL, n_args), c_str(name) {
296 DLLLOCAL MethodCallNode(
const MethodCallNode& old,
QoreListNode* n_args)
297 : AbstractMethodCallNode(old, n_args), c_str(old.c_str ? strdup(old.c_str) : nullptr), pseudo(old.pseudo) {
300 DLLLOCAL
virtual ~MethodCallNode() {
305 using AbstractMethodCallNode::exec;
310 DLLLOCAL
virtual const char* getName()
const {
311 return c_str ? c_str :
"copy";
314 DLLLOCAL
const char* getRawName()
const {
319 str.
sprintf(
"'%s' %smethod call (%p)", getName(), pseudo ?
"pseudo " :
"",
this);
326 getAsString(*rv, foff, xsink);
330 DLLLOCAL
char* takeName() {
337 DLLLOCAL
virtual const char* getTypeName()
const {
338 return getStaticTypeName();
341 DLLLOCAL
static const char* getStaticTypeName() {
342 return "method call";
354 DLLLOCAL
void setPseudo(
const QoreTypeInfo* pti) {
355 assert(!pseudo && !pseudoTypeInfo);
357 pseudoTypeInfo = pti;
360 DLLLOCAL
bool isPseudo()
const {
364 DLLLOCAL
const QoreTypeInfo* getPseudoTypeInfo()
const {
365 return pseudoTypeInfo;
370 const QoreTypeInfo* pseudoTypeInfo =
nullptr;
373 using AbstractFunctionCallNode::evalImpl;
380 DLLLOCAL
virtual int parseInitImpl(
QoreValue& val, QoreParseContext& parse_context) {
381 parse_context.typeInfo =
nullptr;
382 return parseArgs(parse_context,
nullptr,
nullptr);
386class SelfFunctionCallNode :
public AbstractMethodCallNode {
388 DLLLOCAL SelfFunctionCallNode(
const QoreProgramLocation* loc,
char* n, QoreParseListNode* n_args)
389 : AbstractMethodCallNode(loc,
NT_SELF_CALL, n_args, parse_get_class()), ns(n), is_copy(false) {
392 DLLLOCAL SelfFunctionCallNode(
const QoreProgramLocation* loc,
char* n, QoreParseListNode* n_args,
394 AbstractMethodCallNode(loc,
NT_SELF_CALL, n_args, n_qc, m), ns(n),
395 class_ctx(class_ctx), is_copy(false) {
398 DLLLOCAL SelfFunctionCallNode(
const QoreProgramLocation* loc,
char* n, QoreParseListNode* n_args,
399 const QoreClass* n_qc) : AbstractMethodCallNode(loc,
NT_SELF_CALL, n_args, n_qc), ns(n), is_copy(false) {
402 DLLLOCAL SelfFunctionCallNode(
const QoreProgramLocation* loc, NamedScope* n_ns, QoreParseListNode* n_args)
403 : AbstractMethodCallNode(loc,
NT_SELF_CALL, n_args, parse_get_class()), ns(n_ns), is_copy(false) {
406 DLLLOCAL SelfFunctionCallNode(
const SelfFunctionCallNode& old,
QoreListNode* n_args)
407 : AbstractMethodCallNode(old, n_args), ns(old.ns), is_copy(old.is_copy) {
410 DLLLOCAL
int parseInitCall(
QoreValue& val, QoreParseContext& parse_context);
412 DLLLOCAL
virtual ~SelfFunctionCallNode() {
415 DLLLOCAL
virtual const char* getTypeName()
const {
416 return "in-object method call";
419 DLLLOCAL
virtual const char* getName()
const {
423 using AbstractFunctionCallNode::evalImpl;
433 const qore_class_private* class_ctx =
nullptr;
435 bool is_abstract =
false;
437 DLLLOCAL
virtual int parseInitImpl(
QoreValue& val, QoreParseContext& parse_context);
447 using AbstractFunctionCallNode::evalImpl;
450 using AbstractFunctionCallNode::deref;
460 const qore_class_private* cls;
461 mutable bool deref_self =
true;
464class StaticMethodCallNode :
public AbstractFunctionCallNode {
466 NamedScope* scope =
nullptr;
469 using AbstractFunctionCallNode::evalImpl;
472 DLLLOCAL
virtual int parseInitImpl(
QoreValue& val, QoreParseContext& parse_context);
474 DLLLOCAL
virtual const QoreTypeInfo* getTypeInfo()
const;
477 DLLLOCAL StaticMethodCallNode(
const QoreProgramLocation* loc, NamedScope* n_scope, QoreParseListNode* args) : AbstractFunctionCallNode(loc,
NT_STATIC_METHOD_CALL, args), scope(n_scope) {
481 DLLLOCAL StaticMethodCallNode(
const StaticMethodCallNode& old,
QoreListNode* args) : AbstractFunctionCallNode(old, args), method(old.method) {
484 DLLLOCAL StaticMethodCallNode(
const QoreProgramLocation* loc,
const QoreMethod* m, QoreParseListNode* args) : AbstractFunctionCallNode(loc,
NT_STATIC_METHOD_CALL, args), method(m) {
487 DLLLOCAL
virtual ~StaticMethodCallNode() {
491 DLLLOCAL
const QoreMethod* getMethod()
const {
503 getAsString(*rv, foff, xsink);
507 DLLLOCAL
virtual const char* getName()
const {
512 DLLLOCAL
virtual const char* getTypeName()
const {
513 return getStaticTypeName();
518 DLLLOCAL
static const char* getStaticTypeName() {
519 return "static method call";
522 DLLLOCAL NamedScope* takeScope() {
523 NamedScope* rv = scope;
528 DLLLOCAL QoreParseListNode* takeParseArgs() {
529 QoreParseListNode* rv = parse_args;
530 parse_args =
nullptr;
The base class for all value and parse types in Qore expression trees.
Definition: AbstractQoreNode.h:57
DLLLOCAL bool needs_eval() const
returns true if the object needs evaluation to return a value, false if not
Definition: AbstractQoreNode.h:145
DLLEXPORT void deref(ExceptionSink *xsink)
decrements the reference count and calls derefImpl() if there_can_be_only_one is false,...
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:50
defines a Qore-language class
Definition: QoreClass.h:249
DLLEXPORT const char * getName() const
returns the class name
This is the list container type in Qore, dynamically allocated only, reference counted.
Definition: QoreListNode.h:52
a method in a QoreClass
Definition: QoreClass.h:135
DLLEXPORT const char * getName() const
returns the method's name
DLLEXPORT const QoreClass * getClass() const
returns a pointer to the parent class
the implementation of Qore's object data type, reference counted, dynamically-allocated only
Definition: QoreObject.h:60
supports parsing and executing Qore-language code, reference counted, dynamically-allocated only
Definition: QoreProgram.h:128
Qore's string type supported by the QoreEncoding class.
Definition: QoreString.h:93
DLLEXPORT int sprintf(const char *fmt,...)
this will concatentate a formatted string to the existing string according to the format string and t...
Used in arguments background expressions to ensure that the object context is set for the call.
Definition: FunctionCallNode.h:443
virtual DLLLOCAL QoreValue evalImpl(bool &needs_deref, ExceptionSink *xsink) const
optionally evaluates the argument
int16_t qore_type_t
used to identify unique Qore data and parse types (descendents of AbstractQoreNode)
Definition: common.h:70
long long int64
64bit integer type, cannot use int64_t here since it breaks the API on some 64-bit systems due to equ...
Definition: common.h:260
const qore_type_t NT_STATIC_METHOD_CALL
type value for StaticMethodCallNode (private class)
Definition: node_types.h:74
const qore_type_t NT_FUNCTION_CALL
type value for FunctionCallNode
Definition: node_types.h:59
const qore_type_t NT_SELF_CALL
type value for SelfFunctionCallNode (private class)
Definition: node_types.h:75
const qore_type_t NT_PROGRAM_FUNC_CALL
type value for ProgramFunctionCallNode (private class)
Definition: node_types.h:79
const qore_type_t NT_METHOD_CALL
type value for MethodCallNode (private class)
Definition: node_types.h:73
DLLEXPORT QoreProgram * getProgram()
returns the current QoreProgram
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:276