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,
102 DLLLOCAL AbstractFunctionCallNode(
const QoreProgramLocation* loc,
qore_type_t t, QoreParseListNode* parse_args,
107 DLLLOCAL AbstractFunctionCallNode(
const AbstractFunctionCallNode& old) : ParseNode(old), FunctionCallBase(old) {
110 DLLLOCAL AbstractFunctionCallNode(
const AbstractFunctionCallNode& old,
QoreListNode* n_args) : ParseNode(old),
111 FunctionCallBase(old, n_args), tmp_args(true) {
114 DLLLOCAL
virtual ~AbstractFunctionCallNode() {
124 DLLLOCAL
int parseArgs(QoreParseContext& parse_context, QoreFunction* func, qore_ns_private* ns) {
125 int err = parseArgsVariant(loc, parse_context, func, ns);
128 doFlags(variant->getFlags());
130 doFlags(func->parseGetUniqueFlags());
135 DLLLOCAL
virtual const char* getName()
const = 0;
155 return new QoreStringMaker(
"new object for class '%s'", qc->
getName());
158 DLLEXPORT
virtual const char*
getTypeName()
const {
162 DLLLOCAL
virtual int parseInitImpl(
QoreValue& val, QoreParseContext& parse_context) {
167 DLLLOCAL
virtual const QoreTypeInfo* getTypeInfo()
const {
171 DLLLOCAL
virtual const char* getName()
const {
176 return new NewObjectCallNode(qc, args ? args->
listRefSelf() :
nullptr);
188class FunctionCallNode :
public AbstractFunctionCallNode {
190 DLLLOCAL FunctionCallNode(
const FunctionCallNode& old,
QoreListNode* args) : AbstractFunctionCallNode(old, args),
191 fe(old.fe), pgm(old.pgm), finalized(old.finalized) {
194 DLLLOCAL FunctionCallNode(
const QoreProgramLocation* loc,
const FunctionEntry* f, QoreParseListNode* a)
198 DLLLOCAL FunctionCallNode(
const QoreProgramLocation* loc,
const FunctionEntry* f,
QoreListNode* a,
203 DLLLOCAL FunctionCallNode(
const QoreProgramLocation* loc,
char* name, QoreParseListNode* a)
207 DLLLOCAL
virtual ~FunctionCallNode() {
208 printd(5,
"FunctionCallNode::~FunctionCallNode(): fe: %p c_str: %p (%s) args: %p\n", fe, c_str,
209 c_str ? c_str :
"n/a", args);
218 DLLLOCAL
virtual const char* getTypeName()
const {
219 return "function call";
226 DLLLOCAL
int parseInitCall(
QoreValue& val, QoreParseContext& parse_context);
228 DLLLOCAL
int parseInitFinalizedCall(
QoreValue& val, QoreParseContext& parse_context);
230 DLLLOCAL
virtual const char* getName()
const {
231 return fe ? fe->getName() : c_str;
234 DLLLOCAL
const QoreFunction* getFunction()
const {
235 return fe ? fe->getFunction() :
nullptr;
239 DLLLOCAL
char* takeName() {
246 DLLLOCAL QoreParseListNode* takeParseArgs() {
247 QoreParseListNode* rv = parse_args;
248 parse_args =
nullptr;
260 parse_error(*loc,
"argument given to call reference");
272 DLLLOCAL
bool isFinalized()
const {
276 DLLLOCAL
void setFinalized() {
281 const FunctionEntry* fe =
nullptr;
283 char* c_str =
nullptr;
285 bool finalized =
false;
287 using AbstractFunctionCallNode::evalImpl;
290 DLLLOCAL FunctionCallNode(
const QoreProgramLocation* loc,
char* name, QoreParseListNode* a,
qore_type_t n_type)
291 : AbstractFunctionCallNode(loc, n_type, a), c_str(name), finalized(false) {
294 DLLLOCAL
virtual int parseInitImpl(
QoreValue& val, QoreParseContext& parse_context);
296 DLLLOCAL
virtual const QoreTypeInfo* getTypeInfo()
const {
298 ? variant->parseGetReturnTypeInfo()
299 : (fe ? fe->getFunction()->parseGetUniqueReturnTypeInfo() :
nullptr);
303class ProgramFunctionCallNode :
public FunctionCallNode {
305 DLLLOCAL ProgramFunctionCallNode(
const QoreProgramLocation* loc,
char* name, QoreParseListNode* a)
309 DLLLOCAL
virtual int parseInitImpl(
QoreValue& val, QoreParseContext& parse_context) {
310 return parseInitCall(val, parse_context);
316class AbstractMethodCallNode :
public AbstractFunctionCallNode {
324 DLLLOCAL
virtual int parseInitImpl(
QoreValue& val, QoreParseContext& parse_context) = 0;
326 DLLLOCAL
virtual const QoreTypeInfo* getTypeInfo()
const;
329 DLLLOCAL AbstractMethodCallNode(
const QoreProgramLocation* loc,
qore_type_t t, QoreParseListNode* n_args,
331 : AbstractFunctionCallNode(loc, t, n_args), qc(n_qc), method(m) {
334 DLLLOCAL AbstractMethodCallNode(
const AbstractMethodCallNode& old) : AbstractFunctionCallNode(old), qc(old.qc),
338 DLLLOCAL AbstractMethodCallNode(
const AbstractMethodCallNode& old,
QoreListNode* n_args)
339 : AbstractFunctionCallNode(old, n_args), qc(old.qc), method(old.method) {
344 DLLLOCAL
const QoreClass* getClass()
const {
348 DLLLOCAL
const QoreMethod* getMethod()
const {
353class MethodCallNode :
public AbstractMethodCallNode {
355 DLLLOCAL MethodCallNode(
const QoreProgramLocation* loc,
char* name, QoreParseListNode* n_args)
356 : AbstractMethodCallNode(loc,
NT_METHOD_CALL, n_args), c_str(name) {
361 DLLLOCAL MethodCallNode(
const MethodCallNode& old,
QoreListNode* n_args)
362 : AbstractMethodCallNode(old, n_args), c_str(old.c_str ? strdup(old.c_str) : nullptr), pseudo(old.pseudo) {
365 DLLLOCAL
virtual ~MethodCallNode() {
370 using AbstractMethodCallNode::exec;
375 DLLLOCAL
virtual const char* getName()
const {
376 return c_str ? c_str :
"copy";
379 DLLLOCAL
const char* getRawName()
const {
384 str.
sprintf(
"'%s' %smethod call (%p)", getName(), pseudo ?
"pseudo " :
"",
this);
391 getAsString(*rv, foff, xsink);
395 DLLLOCAL
char* takeName() {
402 DLLLOCAL
virtual const char* getTypeName()
const {
403 return getStaticTypeName();
406 DLLLOCAL
static const char* getStaticTypeName() {
407 return "method call";
419 DLLLOCAL
void setPseudo(
const QoreTypeInfo* pti) {
420 assert(!pseudo && !pseudoTypeInfo);
422 pseudoTypeInfo = pti;
425 DLLLOCAL
bool isPseudo()
const {
429 DLLLOCAL
const QoreTypeInfo* getPseudoTypeInfo()
const {
430 return pseudoTypeInfo;
435 const QoreTypeInfo* pseudoTypeInfo =
nullptr;
438 using AbstractFunctionCallNode::evalImpl;
445 DLLLOCAL
virtual int parseInitImpl(
QoreValue& val, QoreParseContext& parse_context) {
446 parse_context.typeInfo =
nullptr;
447 return parseArgs(parse_context,
nullptr,
nullptr);
451class SelfFunctionCallNode :
public AbstractMethodCallNode {
453 DLLLOCAL SelfFunctionCallNode(
const QoreProgramLocation* loc,
char* n, QoreParseListNode* n_args)
454 : AbstractMethodCallNode(loc,
NT_SELF_CALL, n_args, parse_get_class()), ns(n), is_copy(false) {
457 DLLLOCAL SelfFunctionCallNode(
const QoreProgramLocation* loc,
char* n, QoreParseListNode* n_args,
459 AbstractMethodCallNode(loc,
NT_SELF_CALL, n_args, n_qc, m), ns(n),
460 class_ctx(class_ctx), is_copy(false) {
463 DLLLOCAL SelfFunctionCallNode(
const QoreProgramLocation* loc,
char* n, QoreParseListNode* n_args,
464 const QoreClass* n_qc) : AbstractMethodCallNode(loc,
NT_SELF_CALL, n_args, n_qc), ns(n), is_copy(false) {
467 DLLLOCAL SelfFunctionCallNode(
const QoreProgramLocation* loc, NamedScope* n_ns, QoreParseListNode* n_args)
468 : AbstractMethodCallNode(loc,
NT_SELF_CALL, n_args, parse_get_class()), ns(n_ns), is_copy(false) {
471 DLLLOCAL SelfFunctionCallNode(
const SelfFunctionCallNode& old,
QoreListNode* n_args)
472 : AbstractMethodCallNode(old, n_args), ns(old.ns), is_copy(old.is_copy) {
475 DLLLOCAL
int parseInitCall(
QoreValue& val, QoreParseContext& parse_context);
477 DLLLOCAL
virtual ~SelfFunctionCallNode() {
480 DLLLOCAL
virtual const char* getTypeName()
const {
481 return "in-object method call";
484 DLLLOCAL
virtual const char* getName()
const {
488 using AbstractFunctionCallNode::evalImpl;
498 const qore_class_private* class_ctx =
nullptr;
500 bool is_abstract =
false;
502 DLLLOCAL
virtual int parseInitImpl(
QoreValue& val, QoreParseContext& parse_context);
512 using AbstractFunctionCallNode::evalImpl;
515 using AbstractFunctionCallNode::deref;
525 const qore_class_private* cls;
526 mutable bool deref_self =
true;
529class StaticMethodCallNode :
public AbstractFunctionCallNode {
531 NamedScope* scope =
nullptr;
534 using AbstractFunctionCallNode::evalImpl;
537 DLLLOCAL
virtual int parseInitImpl(
QoreValue& val, QoreParseContext& parse_context);
539 DLLLOCAL
virtual const QoreTypeInfo* getTypeInfo()
const;
542 DLLLOCAL StaticMethodCallNode(
const QoreProgramLocation* loc, NamedScope* n_scope, QoreParseListNode* args) : AbstractFunctionCallNode(loc,
NT_STATIC_METHOD_CALL, args), scope(n_scope) {
546 DLLLOCAL StaticMethodCallNode(
const StaticMethodCallNode& old,
QoreListNode* args) : AbstractFunctionCallNode(old, args), method(old.method) {
549 DLLLOCAL StaticMethodCallNode(
const QoreProgramLocation* loc,
const QoreMethod* m, QoreParseListNode* args) : AbstractFunctionCallNode(loc,
NT_STATIC_METHOD_CALL, args), method(m) {
552 DLLLOCAL
virtual ~StaticMethodCallNode() {
556 DLLLOCAL
const QoreMethod* getMethod()
const {
568 getAsString(*rv, foff, xsink);
572 DLLLOCAL
virtual const char* getName()
const {
577 DLLLOCAL
virtual const char* getTypeName()
const {
578 return getStaticTypeName();
583 DLLLOCAL
static const char* getStaticTypeName() {
584 return "static method call";
587 DLLLOCAL NamedScope* takeScope() {
588 NamedScope* rv = scope;
593 DLLLOCAL QoreParseListNode* takeParseArgs() {
594 QoreParseListNode* rv = parse_args;
595 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
virtual DLLEXPORT bool is_equal_hard(const AbstractQoreNode *v, ExceptionSink *xsink) const =0
tests for equality ("deep compare" including all contained values for container types) without type c...
virtual DLLEXPORT int getAsString(QoreString &str, int foff, ExceptionSink *xsink) const =0
concatenate the verbose string representation of the value (including all contained values for contai...
virtual DLLEXPORT AbstractQoreNode * realCopy() const =0
returns a copy of the object; the caller owns the reference count
virtual DLLEXPORT QoreValue evalImpl(bool &needs_deref, ExceptionSink *xsink) const =0
optionally evaluates the argument
DLLEXPORT void deref(ExceptionSink *xsink)
decrements the reference count and calls derefImpl() if there_can_be_only_one is false,...
virtual DLLEXPORT const char * getTypeName() const =0
returns the type name as a c string
virtual DLLEXPORT bool is_equal_soft(const AbstractQoreNode *v, ExceptionSink *xsink) const =0
tests for equality ("deep compare" including all contained values for container types) with possible ...
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:257
DLLEXPORT const QoreTypeInfo * getTypeInfo() const
returns the type information structure for this class
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
DLLEXPORT QoreListNode * listRefSelf() const
returns "this" with an incremented reference count
a method in a QoreClass
Definition: QoreClass.h:143
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:62
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:508
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:279