32 #ifndef _QORE_FUNCTIONCALLNODE_H
34 #define _QORE_FUNCTIONCALLNODE_H
37 #include "qore/intern/QoreParseListNode.h"
38 #include "qore/intern/FunctionList.h"
40 class 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, LocalVar* oflag,
int pflag, QoreFunction* func, qore_ns_private* ns,
const QoreTypeInfo*& returnTypeInfo);
73 DLLLOCAL
const AbstractQoreFunctionVariant* getVariant()
const {
78 class AbstractFunctionCallNode :
public ParseNode,
public FunctionCallBase {
82 bool tmp_args =
false;
86 DLLLOCAL
void doFlags(
int64 flags) {
87 if (flags & QCF_RET_VALUE_ONLY) {
89 set_effect_as_root(
false);
91 if (flags & QCF_CONSTANT) {
92 set_effect_as_root(
false);
97 DLLLOCAL AbstractFunctionCallNode(
const QoreProgramLocation* loc,
qore_type_t t, QoreParseListNode* n_args,
bool needs_eval =
true) : ParseNode(loc, t,
needs_eval), FunctionCallBase(n_args) {
100 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) {
103 DLLLOCAL AbstractFunctionCallNode(
const AbstractFunctionCallNode& old) : ParseNode(old), FunctionCallBase(old) {
106 DLLLOCAL AbstractFunctionCallNode(
const AbstractFunctionCallNode& old,
QoreListNode* n_args) : ParseNode(old), FunctionCallBase(old, n_args), tmp_args(true) {
109 DLLLOCAL
virtual ~AbstractFunctionCallNode() {
119 DLLLOCAL
int parseArgs(LocalVar* oflag,
int pflag, QoreFunction* func, qore_ns_private* ns,
const QoreTypeInfo*& returnTypeInfo) {
120 int lvids = parseArgsVariant(loc, oflag, pflag, func, ns, returnTypeInfo);
123 doFlags(variant->getFlags());
125 doFlags(func->parseGetUniqueFlags());
129 DLLLOCAL
virtual const char* getName()
const = 0;
132 class FunctionCallNode :
public AbstractFunctionCallNode {
134 DLLLOCAL FunctionCallNode(
const FunctionCallNode& old,
QoreListNode* args) : AbstractFunctionCallNode(old, args), fe(old.fe), pgm(old.pgm), finalized(old.finalized) {
137 DLLLOCAL FunctionCallNode(
const QoreProgramLocation* loc,
const FunctionEntry* f, QoreParseListNode* a) : AbstractFunctionCallNode(loc,
NT_FUNCTION_CALL, a), fe(f) {
140 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) {
144 DLLLOCAL FunctionCallNode(
const QoreProgramLocation* loc,
char* name, QoreParseListNode* a) : AbstractFunctionCallNode(loc,
NT_FUNCTION_CALL, a), c_str(name) {
147 DLLLOCAL
virtual ~FunctionCallNode() {
148 printd(5,
"FunctionCallNode::~FunctionCallNode(): fe: %p c_str: %p (%s) args: %p\n", fe, c_str, c_str ? c_str :
"n/a", args);
157 DLLLOCAL
virtual const char* getTypeName()
const {
158 return "function call";
165 DLLLOCAL
void parseInitCall(
QoreValue& val, LocalVar* oflag,
int pflag,
int& lvids,
const QoreTypeInfo*& typeInfo);
167 DLLLOCAL
void parseInitFinalizedCall(
QoreValue& val, LocalVar* oflag,
int pflag,
int& lvids,
const QoreTypeInfo*& typeInfo);
169 DLLLOCAL
virtual const char* getName()
const {
170 return fe ? fe->getName() : c_str;
173 DLLLOCAL
const QoreFunction* getFunction()
const {
174 return fe ? fe->getFunction() :
nullptr;
178 DLLLOCAL
char* takeName() {
185 DLLLOCAL QoreParseListNode* takeParseArgs() {
186 QoreParseListNode* rv = parse_args;
187 parse_args =
nullptr;
199 parse_error(*loc,
"argument given to call reference");
211 DLLLOCAL
bool isFinalized()
const {
215 DLLLOCAL
void setFinalized() {
220 const FunctionEntry* fe =
nullptr;
222 char* c_str =
nullptr;
224 bool finalized =
false;
226 using AbstractFunctionCallNode::evalImpl;
229 DLLLOCAL FunctionCallNode(
const QoreProgramLocation* loc,
char* name, QoreParseListNode* a,
qore_type_t n_type) : AbstractFunctionCallNode(loc, n_type, a), c_str(name), finalized(false) {
232 DLLLOCAL
virtual void parseInitImpl(
QoreValue& val, LocalVar* oflag,
int pflag,
int& lvids,
const QoreTypeInfo*& typeInfo);
234 DLLLOCAL
virtual const QoreTypeInfo* getTypeInfo()
const {
235 return variant ? variant->parseGetReturnTypeInfo() : (fe ? fe->getFunction()->parseGetUniqueReturnTypeInfo() :
nullptr);
239 class ProgramFunctionCallNode :
public FunctionCallNode {
241 DLLLOCAL ProgramFunctionCallNode(
const QoreProgramLocation* loc,
char* name, QoreParseListNode* a) : FunctionCallNode(loc, name, a,
NT_PROGRAM_FUNC_CALL) {
244 DLLLOCAL
virtual void parseInitImpl(
QoreValue& val, LocalVar* oflag,
int pflag,
int& lvids,
const QoreTypeInfo*& typeInfo) {
245 parseInitCall(val, oflag, pflag, lvids, typeInfo);
251 class AbstractMethodCallNode :
public AbstractFunctionCallNode {
259 DLLLOCAL
virtual void parseInitImpl(
QoreValue& val, LocalVar* oflag,
int pflag,
int& lvids,
const QoreTypeInfo*& typeInfo) = 0;
261 DLLLOCAL
virtual const QoreTypeInfo* getTypeInfo()
const;
264 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) {
267 DLLLOCAL AbstractMethodCallNode(
const AbstractMethodCallNode& old) : AbstractFunctionCallNode(old), qc(old.qc), method(old.method) {
270 DLLLOCAL AbstractMethodCallNode(
const AbstractMethodCallNode& old,
QoreListNode* n_args) : AbstractFunctionCallNode(old, n_args), qc(old.qc), method(old.method) {
275 DLLLOCAL
const QoreClass* getClass()
const {
279 DLLLOCAL
const QoreMethod* getMethod()
const {
284 class MethodCallNode :
public AbstractMethodCallNode {
287 const QoreTypeInfo* pseudoTypeInfo =
nullptr;
290 using AbstractFunctionCallNode::evalImpl;
297 DLLLOCAL
virtual void parseInitImpl(
QoreValue& val, LocalVar* oflag,
int pflag,
int& lvids,
const QoreTypeInfo*& typeInfo) {
299 lvids += parseArgs(oflag, pflag,
nullptr,
nullptr, typeInfo);
303 DLLLOCAL MethodCallNode(
const QoreProgramLocation* loc,
char* name, QoreParseListNode* n_args) : AbstractMethodCallNode(loc,
NT_METHOD_CALL, n_args), c_str(name) {
307 DLLLOCAL MethodCallNode(
const MethodCallNode &old,
QoreListNode* n_args) : AbstractMethodCallNode(old, n_args), c_str(old.c_str ? strdup(old.c_str) : nullptr), pseudo(old.pseudo) {
310 DLLLOCAL
virtual ~MethodCallNode() {
315 using AbstractMethodCallNode::exec;
320 DLLLOCAL
virtual const char* getName()
const {
321 return c_str ? c_str :
"copy";
324 DLLLOCAL
const char* getRawName()
const {
329 str.
sprintf(
"'%s' %smethod call (%p)", getName(), pseudo ?
"pseudo " :
"",
this);
336 getAsString(*rv, foff, xsink);
340 DLLLOCAL
char* takeName() {
347 DLLLOCAL
virtual const char* getTypeName()
const {
348 return getStaticTypeName();
351 DLLLOCAL
static const char* getStaticTypeName() {
352 return "method call";
364 DLLLOCAL
void setPseudo(
const QoreTypeInfo* pti) {
365 assert(!pseudo && !pseudoTypeInfo);
367 pseudoTypeInfo = pti;
370 DLLLOCAL
bool isPseudo()
const {
374 DLLLOCAL
const QoreTypeInfo* getPseudoTypeInfo()
const {
375 return pseudoTypeInfo;
379 class SelfFunctionCallNode :
public AbstractMethodCallNode {
382 const qore_class_private* class_ctx =
nullptr;
385 DLLLOCAL
virtual void parseInitImpl(
QoreValue& val, LocalVar* oflag,
int pflag,
int& lvids,
const QoreTypeInfo*& typeInfo);
388 DLLLOCAL SelfFunctionCallNode(
const QoreProgramLocation* loc,
char* n, QoreParseListNode* n_args) : AbstractMethodCallNode(loc,
NT_SELF_CALL, n_args, parse_get_class()), ns(n), is_copy(false) {
391 DLLLOCAL SelfFunctionCallNode(
const QoreProgramLocation* loc,
char* n, QoreParseListNode* n_args,
393 AbstractMethodCallNode(loc,
NT_SELF_CALL, n_args, n_qc, m), ns(n),
394 class_ctx(class_ctx), is_copy(false) {
397 DLLLOCAL SelfFunctionCallNode(
const QoreProgramLocation* loc,
char* n, QoreParseListNode* n_args,
const QoreClass* n_qc) : AbstractMethodCallNode(loc,
NT_SELF_CALL, n_args, n_qc), ns(n), is_copy(false) {
400 DLLLOCAL SelfFunctionCallNode(
const QoreProgramLocation* loc, NamedScope* n_ns, QoreParseListNode* n_args) : AbstractMethodCallNode(loc,
NT_SELF_CALL, n_args, parse_get_class()), ns(n_ns), is_copy(false) {
403 DLLLOCAL SelfFunctionCallNode(
const SelfFunctionCallNode& old,
QoreListNode* n_args) : AbstractMethodCallNode(old, n_args), ns(old.ns), is_copy(old.is_copy) {
406 DLLLOCAL
void parseInitCall(
QoreValue& val, LocalVar* oflag,
int pflag,
int& lvids,
const QoreTypeInfo*& returnTypeInfo);
408 DLLLOCAL
virtual ~SelfFunctionCallNode() {
411 DLLLOCAL
virtual const char* getTypeName()
const {
412 return "in-object method call";
415 DLLLOCAL
virtual const char* getName()
const {
419 using AbstractFunctionCallNode::evalImpl;
428 class StaticMethodCallNode :
public AbstractFunctionCallNode {
430 NamedScope* scope =
nullptr;
433 using AbstractFunctionCallNode::evalImpl;
436 DLLLOCAL
virtual void parseInitImpl(
QoreValue& val, LocalVar* oflag,
int pflag,
int& lvids,
const QoreTypeInfo*& typeInfo);
438 DLLLOCAL
virtual const QoreTypeInfo* getTypeInfo()
const;
441 DLLLOCAL StaticMethodCallNode(
const QoreProgramLocation* loc, NamedScope* n_scope, QoreParseListNode* args) : AbstractFunctionCallNode(loc,
NT_STATIC_METHOD_CALL, args), scope(n_scope) {
445 DLLLOCAL StaticMethodCallNode(
const StaticMethodCallNode& old,
QoreListNode* args) : AbstractFunctionCallNode(old, args), method(old.method) {
448 DLLLOCAL StaticMethodCallNode(
const QoreProgramLocation* loc,
const QoreMethod* m, QoreParseListNode* args) : AbstractFunctionCallNode(loc,
NT_STATIC_METHOD_CALL, args), method(m) {
451 DLLLOCAL
virtual ~StaticMethodCallNode() {
455 DLLLOCAL
const QoreMethod* getMethod()
const {
467 getAsString(*rv, foff, xsink);
471 DLLLOCAL
virtual const char* getName()
const {
476 DLLLOCAL
virtual const char* getTypeName()
const {
477 return getStaticTypeName();
482 DLLLOCAL
static const char* getStaticTypeName() {
483 return "static method call";
486 DLLLOCAL NamedScope* takeScope() {
487 NamedScope* rv = scope;
492 DLLLOCAL QoreParseListNode* takeParseArgs() {
493 QoreParseListNode* rv = parse_args;
494 parse_args =
nullptr;