diff --git a/Ahuacatl/ahuacatl-ast-node.c b/Ahuacatl/ahuacatl-ast-node.c index cf141e0c2a..87c79ff6d7 100644 --- a/Ahuacatl/ahuacatl-ast-node.c +++ b/Ahuacatl/ahuacatl-ast-node.c @@ -30,6 +30,7 @@ #include "Ahuacatl/ahuacatl-functions.h" #include "Ahuacatl/ahuacatl-parser-functions.h" #include "Ahuacatl/ahuacatl-scope.h" +#include "Ahuacatl/ahuacatl-variable.h" // ----------------------------------------------------------------------------- // --SECTION-- private macros @@ -233,7 +234,7 @@ TRI_aql_node_t* TRI_CreateNodeForAql (TRI_aql_context_t* const context, } { - TRI_aql_node_t* variable = TRI_CreateNodeVariableAql(context, name); + TRI_aql_node_t* variable = TRI_CreateNodeVariableAql(context, name, node); ADD_MEMBER(variable) ADD_MEMBER(expression) } @@ -260,7 +261,7 @@ TRI_aql_node_t* TRI_CreateNodeLetAql (TRI_aql_context_t* const context, } { - TRI_aql_node_t* variable = TRI_CreateNodeVariableAql(context, name); + TRI_aql_node_t* variable = TRI_CreateNodeVariableAql(context, name, node); ADD_MEMBER(variable) ADD_MEMBER(expression) } @@ -305,7 +306,7 @@ TRI_aql_node_t* TRI_CreateNodeCollectAql (TRI_aql_context_t* const context, ADD_MEMBER(list) if (name) { - TRI_aql_node_t* variable = TRI_CreateNodeVariableAql(context, name); + TRI_aql_node_t* variable = TRI_CreateNodeVariableAql(context, name, node); ADD_MEMBER(variable) } @@ -365,7 +366,7 @@ TRI_aql_node_t* TRI_CreateNodeAssignAql (TRI_aql_context_t* const context, CREATE_NODE(AQL_NODE_ASSIGN) { - TRI_aql_node_t* variable = TRI_CreateNodeVariableAql(context, name); + TRI_aql_node_t* variable = TRI_CreateNodeVariableAql(context, name, node); ADD_MEMBER(variable) ADD_MEMBER(expression) } @@ -378,14 +379,15 @@ TRI_aql_node_t* TRI_CreateNodeAssignAql (TRI_aql_context_t* const context, //////////////////////////////////////////////////////////////////////////////// TRI_aql_node_t* TRI_CreateNodeVariableAql (TRI_aql_context_t* const context, - const char* const name) { + const char* const name, + TRI_aql_node_t* const definingNode) { CREATE_NODE(AQL_NODE_VARIABLE) if (!name) { ABORT_OOM } - if (!TRI_AddVariableScopeAql(context, name)) { + if (!TRI_AddVariableScopeAql(context, name, definingNode)) { // duplicate variable name TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_VARIABLE_REDECLARED, name); return NULL; @@ -412,9 +414,12 @@ TRI_aql_node_t* TRI_CreateNodeCollectionAql (TRI_aql_context_t* const context, TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_COLLECTION_NOT_FOUND, name); return NULL; } - - TRI_AQL_NODE_STRING(node) = (char*) name; + { + TRI_aql_node_t* nameNode = TRI_CreateNodeValueStringAql(context, name); + ADD_MEMBER(nameNode) + } + if (!TRI_AddCollectionAql(context, name)) { return NULL; } @@ -752,7 +757,7 @@ TRI_aql_node_t* TRI_CreateNodeSubqueryAql (TRI_aql_context_t* const context, { // add the temporary variable - TRI_aql_node_t* variable = TRI_CreateNodeVariableAql(context, TRI_GetNameParseAql(context)); + TRI_aql_node_t* variable = TRI_CreateNodeVariableAql(context, TRI_GetNameParseAql(context), node); ADD_MEMBER(variable) } @@ -811,8 +816,9 @@ TRI_aql_node_t* TRI_CreateNodeExpandAql (TRI_aql_context_t* const context, } { - TRI_aql_node_t* variable1 = TRI_CreateNodeVariableAql(context, varname); - TRI_aql_node_t* variable2 = TRI_CreateNodeVariableAql(context, TRI_GetNameParseAql(context)); + // TODO: check if 3rd parameters' values are correct for these + TRI_aql_node_t* variable1 = TRI_CreateNodeVariableAql(context, varname, node); + TRI_aql_node_t* variable2 = TRI_CreateNodeVariableAql(context, TRI_GetNameParseAql(context), node); ADD_MEMBER(variable1) ADD_MEMBER(variable2) diff --git a/Ahuacatl/ahuacatl-ast-node.h b/Ahuacatl/ahuacatl-ast-node.h index 053987ba12..0f9cbc065e 100644 --- a/Ahuacatl/ahuacatl-ast-node.h +++ b/Ahuacatl/ahuacatl-ast-node.h @@ -337,7 +337,8 @@ TRI_aql_node_t* TRI_CreateNodeParameterAql (TRI_aql_context_t* const, //////////////////////////////////////////////////////////////////////////////// TRI_aql_node_t* TRI_CreateNodeVariableAql (TRI_aql_context_t* const, - const char* const); + const char* const, + TRI_aql_node_t* const); //////////////////////////////////////////////////////////////////////////////// /// @brief create an AST collection node diff --git a/Ahuacatl/ahuacatl-codegen.c b/Ahuacatl/ahuacatl-codegen.c index 08b94cd505..b841940198 100644 --- a/Ahuacatl/ahuacatl-codegen.c +++ b/Ahuacatl/ahuacatl-codegen.c @@ -1168,7 +1168,9 @@ static void ProcessArgList (TRI_aql_codegen_js_t* const generator, if (parameter->_type == AQL_NODE_COLLECTION && TRI_ConvertParameterFunctionAql(function, i)) { // collection arguments will be created as string argument => e.g. "users" - ScopeOutputQuoted(generator, TRI_AQL_NODE_STRING(parameter)); + TRI_aql_node_t* nameNode = TRI_AQL_NODE_MEMBER(parameter, 0); + + ScopeOutputQuoted(generator, TRI_AQL_NODE_STRING(nameNode)); } else { // anything else will be created as is @@ -1226,9 +1228,9 @@ static void ProcessIndexed (TRI_aql_codegen_js_t* const generator, static void ProcessCollection (TRI_aql_codegen_js_t* const generator, const TRI_aql_node_t* const node) { - ScopeOutput(generator, "AHUACATL_GET_DOCUMENTS('"); - ScopeOutput(generator, TRI_AQL_NODE_STRING(node)); - ScopeOutput(generator, "')"); + ScopeOutput(generator, "AHUACATL_GET_DOCUMENTS("); + ProcessNode(generator, TRI_AQL_NODE_MEMBER(node, 0)); + ScopeOutput(generator, ")"); } //////////////////////////////////////////////////////////////////////////////// @@ -1253,7 +1255,7 @@ static void ProcessHintedCollection (TRI_aql_codegen_js_t* const generator, variableName = TRI_AQL_NODE_STRING(nameNode); assert(variableName); - collectionName = TRI_AQL_NODE_STRING(collectionNode); + collectionName = TRI_AQL_NODE_STRING((TRI_AQL_NODE_MEMBER(collectionNode, 0))); assert(collectionName); collection = TRI_GetCollectionAql(generator->_context, collectionName); diff --git a/Ahuacatl/ahuacatl-context.c b/Ahuacatl/ahuacatl-context.c index d3e425ff73..d3a0aeac9f 100644 --- a/Ahuacatl/ahuacatl-context.c +++ b/Ahuacatl/ahuacatl-context.c @@ -34,6 +34,7 @@ #include "Ahuacatl/ahuacatl-parser-functions.h" #include "Ahuacatl/ahuacatl-scope.h" #include "Ahuacatl/ahuacatl-tree-dump.h" +#include "Ahuacatl/ahuacatl-variable.h" // ----------------------------------------------------------------------------- // --SECTION-- private macros diff --git a/Ahuacatl/ahuacatl-context.h b/Ahuacatl/ahuacatl-context.h index 551fec298b..a856994f94 100644 --- a/Ahuacatl/ahuacatl-context.h +++ b/Ahuacatl/ahuacatl-context.h @@ -40,7 +40,6 @@ #include "Ahuacatl/ahuacatl-error.h" #include "Ahuacatl/ahuacatl-parser.h" -#include "Ahuacatl/ahuacatl-variable.h" #ifdef __cplusplus extern "C" { diff --git a/Ahuacatl/ahuacatl-optimiser.c b/Ahuacatl/ahuacatl-optimiser.c index a14bb56b4a..a55bfb1d17 100644 --- a/Ahuacatl/ahuacatl-optimiser.c +++ b/Ahuacatl/ahuacatl-optimiser.c @@ -538,6 +538,18 @@ TRY_LOOP: return node; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief optimise a reference expression +//////////////////////////////////////////////////////////////////////////////// + +static TRI_aql_node_t* OptimiseReference (TRI_aql_context_t* const context, + TRI_aql_node_t* node) { + // TODO: find variable in current symbol table + // follow references until variable declaration is found + // if variable value at source is constant, copy the constant into here as well + return node; +} + //////////////////////////////////////////////////////////////////////////////// /// @brief optimise an arithmetic operation with one operand //////////////////////////////////////////////////////////////////////////////// @@ -915,6 +927,8 @@ static TRI_aql_node_t* OptimiseNode (TRI_aql_context_t* const context, return OptimiseFilter(context, node); case AQL_NODE_FCALL: return OptimiseFcall(context, node); + case AQL_NODE_REFERENCE: + return OptimiseReference(context, node); default: break; } diff --git a/Ahuacatl/ahuacatl-scope.c b/Ahuacatl/ahuacatl-scope.c index 618979ad27..d04e3681c0 100644 --- a/Ahuacatl/ahuacatl-scope.c +++ b/Ahuacatl/ahuacatl-scope.c @@ -26,6 +26,7 @@ //////////////////////////////////////////////////////////////////////////////// #include "Ahuacatl/ahuacatl-scope.h" +#include "Ahuacatl/ahuacatl-variable.h" // ----------------------------------------------------------------------------- // --SECTION-- private functions @@ -314,7 +315,9 @@ bool TRI_VariableExistsScopeAql (TRI_aql_context_t* const context, /// @brief push a variable into the current scope's symbol table //////////////////////////////////////////////////////////////////////////////// -bool TRI_AddVariableScopeAql (TRI_aql_context_t* const context, const char* name) { +bool TRI_AddVariableScopeAql (TRI_aql_context_t* const context, + const char* name, + TRI_aql_node_t* const definingNode) { TRI_aql_variable_t* variable; TRI_aql_scope_t* scope; @@ -325,7 +328,7 @@ bool TRI_AddVariableScopeAql (TRI_aql_context_t* const context, const char* name return false; } - variable = TRI_CreateVariableAql(name); + variable = TRI_CreateVariableAql(name, definingNode); if (variable == NULL) { return false; } diff --git a/Ahuacatl/ahuacatl-scope.h b/Ahuacatl/ahuacatl-scope.h index 87adc0bbb4..5277220693 100644 --- a/Ahuacatl/ahuacatl-scope.h +++ b/Ahuacatl/ahuacatl-scope.h @@ -30,6 +30,7 @@ #include +#include "Ahuacatl/ahuacatl-ast-node.h" #include "Ahuacatl/ahuacatl-context.h" #include "Ahuacatl/ahuacatl-log.h" @@ -123,7 +124,9 @@ bool TRI_VariableExistsScopeAql (TRI_aql_context_t* const, const char* const); /// @brief push a variable into the current scope's symbol table //////////////////////////////////////////////////////////////////////////////// -bool TRI_AddVariableScopeAql (TRI_aql_context_t* const, const char*); +bool TRI_AddVariableScopeAql (TRI_aql_context_t* const, + const char*, + TRI_aql_node_t* const); //////////////////////////////////////////////////////////////////////////////// /// @} diff --git a/Ahuacatl/ahuacatl-tree-dump.c b/Ahuacatl/ahuacatl-tree-dump.c index 75b1f2179c..4fb4e8df09 100644 --- a/Ahuacatl/ahuacatl-tree-dump.c +++ b/Ahuacatl/ahuacatl-tree-dump.c @@ -138,7 +138,6 @@ static void DumpNode (void* data, const TRI_aql_node_t* const node) { case AQL_NODE_VARIABLE: case AQL_NODE_ATTRIBUTE: - case AQL_NODE_COLLECTION: case AQL_NODE_REFERENCE: case AQL_NODE_PARAMETER: case AQL_NODE_ARRAY_ELEMENT: diff --git a/Ahuacatl/ahuacatl-variable.c b/Ahuacatl/ahuacatl-variable.c index 22533be717..e1396b391a 100644 --- a/Ahuacatl/ahuacatl-variable.c +++ b/Ahuacatl/ahuacatl-variable.c @@ -40,7 +40,8 @@ /// @brief register a new variable //////////////////////////////////////////////////////////////////////////////// -TRI_aql_variable_t* TRI_CreateVariableAql (const char* const name) { +TRI_aql_variable_t* TRI_CreateVariableAql (const char* const name, + TRI_aql_node_t* const definingNode) { TRI_aql_variable_t* variable; variable = (TRI_aql_variable_t*) TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_aql_variable_t), false); @@ -57,6 +58,9 @@ TRI_aql_variable_t* TRI_CreateVariableAql (const char* const name) { } variable->_refCount = 0; + variable->_definingNode = definingNode; + + assert(definingNode); return variable; } diff --git a/Ahuacatl/ahuacatl-variable.h b/Ahuacatl/ahuacatl-variable.h index d04354e586..e5be1b77a5 100644 --- a/Ahuacatl/ahuacatl-variable.h +++ b/Ahuacatl/ahuacatl-variable.h @@ -34,6 +34,8 @@ #include #include +#include "Ahuacatl/ahuacatl-ast-node.h" + #ifdef __cplusplus extern "C" { #endif @@ -54,6 +56,7 @@ extern "C" { typedef struct TRI_aql_variable_s { char* _name; uint32_t _refCount; + TRI_aql_node_t* _definingNode; } TRI_aql_variable_t; @@ -74,7 +77,8 @@ TRI_aql_variable_t; /// @brief register a new variable //////////////////////////////////////////////////////////////////////////////// -TRI_aql_variable_t* TRI_CreateVariableAql (const char* const); +TRI_aql_variable_t* TRI_CreateVariableAql (const char* const, + TRI_aql_node_t* const); //////////////////////////////////////////////////////////////////////////////// /// @brief free an existing variable