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:310
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:61
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:76
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:266
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