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),
51 DLLLOCAL FunctionCallBase(
const FunctionCallBase& old) :
52 parse_args(old.parse_args ? old.parse_args->listRefSelf() : nullptr),
53 args(old.args ? old.args->listRefSelf() : nullptr),
54 variant(old.variant) {
57 DLLLOCAL FunctionCallBase(
const FunctionCallBase& old,
QoreListNode* n_args) : args(n_args),
58 variant(old.variant) {
61 DLLLOCAL ~FunctionCallBase() {
68 DLLLOCAL
const QoreParseListNode* getParseArgs()
const {
return parse_args; }
70 DLLLOCAL
const QoreListNode* getArgs()
const {
return args; }
73 DLLLOCAL
int parseArgsVariant(
const QoreProgramLocation* loc, QoreParseContext& parse_context, QoreFunction* func,
76 DLLLOCAL
const AbstractQoreFunctionVariant* getVariant()
const {
81class AbstractFunctionCallNode :
public ParseNode,
public FunctionCallBase {
85 bool tmp_args =
false;
89 DLLLOCAL
void doFlags(
int64 flags) {
90 if (flags & QCF_RET_VALUE_ONLY) {
92 set_effect_as_root(
false);
94 if (flags & QCF_CONSTANT) {
95 set_effect_as_root(
false);
100 DLLLOCAL AbstractFunctionCallNode(
const QoreProgramLocation* loc,
qore_type_t t, QoreParseListNode* n_args,
104 DLLLOCAL AbstractFunctionCallNode(
const QoreProgramLocation* loc,
qore_type_t t, QoreParseListNode* parse_args,
109 DLLLOCAL AbstractFunctionCallNode(
const AbstractFunctionCallNode& old) : ParseNode(old), FunctionCallBase(old) {
112 DLLLOCAL AbstractFunctionCallNode(
const AbstractFunctionCallNode& old,
QoreListNode* n_args) : ParseNode(old),
113 FunctionCallBase(old, n_args), tmp_args(true) {
116 DLLLOCAL
virtual ~AbstractFunctionCallNode() {
126 DLLLOCAL
int parseArgs(QoreParseContext& parse_context, QoreFunction* func, qore_ns_private* ns) {
127 int err = parseArgsVariant(loc, parse_context, func, ns);
130 doFlags(variant->getFlags());
132 doFlags(func->parseGetUniqueFlags());
137 DLLLOCAL
virtual const char* getName()
const = 0;
157 return new QoreStringMaker(
"new object for class '%s'", qc->
getName());
160 DLLEXPORT
virtual const char*
getTypeName()
const {
164 DLLLOCAL
virtual int parseInitImpl(
QoreValue& val, QoreParseContext& parse_context) {
169 DLLLOCAL
virtual const QoreTypeInfo* getTypeInfo()
const {
173 DLLLOCAL
virtual const char* getName()
const {
178 return new NewObjectCallNode(qc, args ? args->
listRefSelf() : nullptr);
190class FunctionCallNode :
public AbstractFunctionCallNode {
192 DLLLOCAL FunctionCallNode(
const FunctionCallNode& old,
QoreListNode* args) : AbstractFunctionCallNode(old, args),
193 fe(old.fe), pgm(old.pgm), finalized(old.finalized) {
196 DLLLOCAL FunctionCallNode(
const QoreProgramLocation* loc,
const FunctionEntry* f, QoreParseListNode* a)
200 DLLLOCAL FunctionCallNode(
const QoreProgramLocation* loc,
const FunctionEntry* f,
QoreListNode* a,
205 DLLLOCAL FunctionCallNode(
const QoreProgramLocation* loc,
char* name, QoreParseListNode* a)
209 DLLLOCAL
virtual ~FunctionCallNode() {
210 printd(5,
"FunctionCallNode::~FunctionCallNode(): fe: %p c_str: %p (%s) args: %p\n", fe, c_str,
211 c_str ? c_str :
"n/a", args);
220 DLLLOCAL
virtual const char* getTypeName()
const {
221 return "function call";
228 DLLLOCAL
int parseInitCall(
QoreValue& val, QoreParseContext& parse_context);
230 DLLLOCAL
int parseInitFinalizedCall(
QoreValue& val, QoreParseContext& parse_context);
232 DLLLOCAL
virtual const char* getName()
const {
233 return fe ? fe->getName() : c_str;
236 DLLLOCAL
const QoreFunction* getFunction()
const {
237 return fe ? fe->getFunction() :
nullptr;
241 DLLLOCAL
char* takeName() {
248 DLLLOCAL QoreParseListNode* takeParseArgs() {
249 QoreParseListNode* rv = parse_args;
250 parse_args =
nullptr;
262 parse_error(*loc,
"argument given to call reference");
274 DLLLOCAL
bool isFinalized()
const {
278 DLLLOCAL
void setFinalized() {
283 const FunctionEntry* fe =
nullptr;
285 char* c_str =
nullptr;
287 bool finalized =
false;
289 using AbstractFunctionCallNode::evalImpl;
292 DLLLOCAL FunctionCallNode(
const QoreProgramLocation* loc,
char* name, QoreParseListNode* a,
qore_type_t n_type)
293 : AbstractFunctionCallNode(loc, n_type, a), c_str(name), finalized(false) {
296 DLLLOCAL
virtual int parseInitImpl(
QoreValue& val, QoreParseContext& parse_context);
298 DLLLOCAL
virtual const QoreTypeInfo* getTypeInfo()
const {
300 ? variant->parseGetReturnTypeInfo()
301 : (fe ? fe->getFunction()->parseGetUniqueReturnTypeInfo() :
nullptr);
305class ProgramFunctionCallNode :
public FunctionCallNode {
307 DLLLOCAL ProgramFunctionCallNode(
const QoreProgramLocation* loc,
char* name, QoreParseListNode* a)
311 DLLLOCAL
virtual int parseInitImpl(
QoreValue& val, QoreParseContext& parse_context) {
312 return parseInitCall(val, parse_context);
318class AbstractMethodCallNode :
public AbstractFunctionCallNode {
326 DLLLOCAL
virtual int parseInitImpl(
QoreValue& val, QoreParseContext& parse_context) = 0;
328 DLLLOCAL
virtual const QoreTypeInfo* getTypeInfo()
const;
331 DLLLOCAL AbstractMethodCallNode(
const QoreProgramLocation* loc,
qore_type_t t, QoreParseListNode* n_args,
333 : AbstractFunctionCallNode(loc, t, n_args), qc(n_qc), method(m) {
336 DLLLOCAL AbstractMethodCallNode(
const AbstractMethodCallNode& old) : AbstractFunctionCallNode(old), qc(old.qc),
340 DLLLOCAL AbstractMethodCallNode(
const AbstractMethodCallNode& old,
QoreListNode* n_args)
341 : AbstractFunctionCallNode(old, n_args), qc(old.qc), method(old.method) {
347 DLLLOCAL
const QoreClass* getClass()
const {
351 DLLLOCAL
const QoreMethod* getMethod()
const {
356class MethodCallNode :
public AbstractMethodCallNode {
358 DLLLOCAL MethodCallNode(
const QoreProgramLocation* loc,
char* name, QoreParseListNode* n_args)
359 : AbstractMethodCallNode(loc,
NT_METHOD_CALL, n_args), c_str(name) {
364 DLLLOCAL MethodCallNode(
const MethodCallNode& old,
QoreListNode* n_args)
365 : AbstractMethodCallNode(old, n_args), c_str(old.c_str ? strdup(old.c_str) : nullptr),
369 DLLLOCAL
virtual ~MethodCallNode() {
374 using AbstractMethodCallNode::exec;
379 DLLLOCAL
virtual const char* getName()
const {
380 return c_str ? c_str :
"copy";
383 DLLLOCAL
const char* getRawName()
const {
388 str.
sprintf(
"'%s' %smethod call (%p)", getName(), pseudo ?
"pseudo " :
"", this);
395 getAsString(*rv, foff, xsink);
399 DLLLOCAL
char* takeName() {
406 DLLLOCAL
virtual const char* getTypeName()
const {
407 return getStaticTypeName();
410 DLLLOCAL
static const char* getStaticTypeName() {
411 return "method call";
423 DLLLOCAL
void setPseudo(
const QoreTypeInfo* pti) {
424 assert(!pseudo && !pseudoTypeInfo);
426 pseudoTypeInfo = pti;
429 DLLLOCAL
bool isPseudo()
const {
433 DLLLOCAL
const QoreTypeInfo* getPseudoTypeInfo()
const {
434 return pseudoTypeInfo;
439 const QoreTypeInfo* pseudoTypeInfo =
nullptr;
442 using AbstractFunctionCallNode::evalImpl;
449 DLLLOCAL
virtual int parseInitImpl(
QoreValue& val, QoreParseContext& parse_context) {
450 parse_context.typeInfo =
nullptr;
451 return parseArgs(parse_context,
nullptr,
nullptr);
455class SelfFunctionCallNode :
public AbstractMethodCallNode {
457 DLLLOCAL SelfFunctionCallNode(
const QoreProgramLocation* loc,
char* n, QoreParseListNode* n_args)
458 : AbstractMethodCallNode(loc,
NT_SELF_CALL, n_args, parse_get_class()), ns(n), is_copy(false) {
461 DLLLOCAL SelfFunctionCallNode(
const QoreProgramLocation* loc,
char* n, QoreParseListNode* n_args,
463 AbstractMethodCallNode(loc,
NT_SELF_CALL, n_args, n_qc, m), ns(n),
464 class_ctx(class_ctx), is_copy(false) {
467 DLLLOCAL SelfFunctionCallNode(
const QoreProgramLocation* loc,
char* n, QoreParseListNode* n_args,
468 const QoreClass* n_qc) : AbstractMethodCallNode(loc,
NT_SELF_CALL, n_args, n_qc), ns(n), is_copy(false) {
471 DLLLOCAL SelfFunctionCallNode(
const QoreProgramLocation* loc, NamedScope* n_ns, QoreParseListNode* n_args)
472 : AbstractMethodCallNode(loc,
NT_SELF_CALL, n_args, parse_get_class()), ns(n_ns), is_copy(false) {
475 DLLLOCAL SelfFunctionCallNode(
const SelfFunctionCallNode& old,
QoreListNode* n_args)
476 : AbstractMethodCallNode(old, n_args), ns(old.ns), is_copy(old.is_copy) {
479 DLLLOCAL
int parseInitCall(
QoreValue& val, QoreParseContext& parse_context);
481 DLLLOCAL
virtual ~SelfFunctionCallNode() {
484 DLLLOCAL
virtual const char* getTypeName()
const {
485 return "in-object method call";
488 DLLLOCAL
virtual const char* getName()
const {
492 using AbstractFunctionCallNode::evalImpl;
502 const qore_class_private* class_ctx =
nullptr;
504 bool is_abstract =
false;
506 DLLLOCAL
virtual int parseInitImpl(
QoreValue& val, QoreParseContext& parse_context);
516 using AbstractFunctionCallNode::evalImpl;
519 using AbstractFunctionCallNode::deref;
529 const qore_class_private* cls;
530 mutable bool deref_self =
true;
533class StaticMethodCallNode :
public AbstractFunctionCallNode {
535 NamedScope* scope =
nullptr;
538 using AbstractFunctionCallNode::evalImpl;
541 DLLLOCAL
virtual int parseInitImpl(
QoreValue& val, QoreParseContext& parse_context);
543 DLLLOCAL
virtual const QoreTypeInfo* getTypeInfo()
const;
546 DLLLOCAL StaticMethodCallNode(
const QoreProgramLocation* loc, NamedScope* n_scope, QoreParseListNode* args)
551 DLLLOCAL StaticMethodCallNode(
const StaticMethodCallNode& old,
QoreListNode* args)
552 : AbstractFunctionCallNode(old, args), method(old.method) {
555 DLLLOCAL StaticMethodCallNode(
const QoreProgramLocation* loc,
const QoreMethod* m, QoreParseListNode* args)
559 DLLLOCAL
virtual ~StaticMethodCallNode() {
563 DLLLOCAL
const QoreMethod* getMethod()
const {
575 getAsString(*rv, foff, xsink);
579 DLLLOCAL
virtual const char* getName()
const {
584 DLLLOCAL
virtual const char* getTypeName()
const {
585 return getStaticTypeName();
590 DLLLOCAL
static const char* getStaticTypeName() {
591 return "static method call";
594 DLLLOCAL NamedScope* takeScope() {
595 NamedScope* rv = scope;
600 DLLLOCAL QoreParseListNode* takeParseArgs() {
601 QoreParseListNode* rv = parse_args;
602 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:512
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