1
0
Fork 0

Merge branch 'master' of github.com:triAGENS/AvocadoDB

This commit is contained in:
Frank Celler 2012-04-23 16:27:05 +02:00
commit 71ea4eb957
3 changed files with 101 additions and 20 deletions

View File

@ -25,6 +25,8 @@
/// @author Copyright 2012, triagens GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#include <BasicsC/logging.h>
#include "Ahuacatl/ast-codegen-js.h"
// -----------------------------------------------------------------------------
@ -36,7 +38,21 @@
/// @{
////////////////////////////////////////////////////////////////////////////////
static char* GetIndexedFunctionName (const size_t funcIndex) {
////////////////////////////////////////////////////////////////////////////////
/// @brief register a function name for later disposal
////////////////////////////////////////////////////////////////////////////////
static bool RegisterString (TRI_aql_codegen_t* const generator,
const char* const name) {
assert(generator);
TRI_PushBackVectorPointer(&generator->_strings, (char*) name);
return true;
}
static char* GetIndexedFunctionName (TRI_aql_codegen_t* const generator,
const size_t funcIndex) {
char* numberString;
char* functionName;
@ -45,7 +61,10 @@ static char* GetIndexedFunctionName (const size_t funcIndex) {
return NULL;
}
functionName = TRI_Concatenate2String("f", numberString);
functionName = TRI_Concatenate2String("f", numberString);
if (functionName) {
RegisterString(generator, functionName);
}
TRI_Free(numberString);
@ -57,7 +76,7 @@ static char* GetNextFunctionName (TRI_aql_codegen_t* const generator) {
assert(generator);
functionName = GetIndexedFunctionName(++generator->_funcIndex);
functionName = GetIndexedFunctionName(generator, ++generator->_funcIndex);
return functionName;
}
@ -65,9 +84,7 @@ static char* GetNextFunctionName (TRI_aql_codegen_t* const generator) {
static void FreeScope (TRI_aql_codegen_scope_t* const scope) {
assert(scope);
if (scope->_funcName) {
TRI_Free(scope->_funcName);
}
// note: scope->_funcName is freed globally
if (scope->_buffer) {
TRI_FreeStringBuffer(scope->_buffer);
@ -76,7 +93,9 @@ static void FreeScope (TRI_aql_codegen_scope_t* const scope) {
TRI_Free(scope);
}
static TRI_aql_codegen_scope_t* CreateScope (const char* const funcName, const TRI_aql_scope_type_e type) {
static TRI_aql_codegen_scope_t* CreateScope (TRI_aql_codegen_t* const generator,
const char* const funcName,
const TRI_aql_scope_type_e type) {
TRI_aql_codegen_scope_t* scope = (TRI_aql_codegen_scope_t*) TRI_Allocate(sizeof(TRI_aql_codegen_scope_t));
if (!scope) {
@ -84,13 +103,19 @@ static TRI_aql_codegen_scope_t* CreateScope (const char* const funcName, const T
}
scope->_funcName = TRI_DuplicateString(funcName);
if (!scope->_funcName) {
FreeScope(scope);
return NULL;
}
RegisterString(generator, scope->_funcName);
scope->_variablePrefix = NULL;
scope->_indent = 0;
scope->_forLoops = 0;
scope->_type = type;
scope->_buffer = TRI_CreateStringBuffer();
if (!scope->_funcName || !scope->_buffer) {
if (!scope->_buffer) {
FreeScope(scope);
return NULL;
}
@ -104,7 +129,7 @@ static bool StartScope (TRI_aql_codegen_t* const generator, const TRI_aql_scope_
assert(generator);
assert(funcName);
scope = CreateScope(funcName, type);
scope = CreateScope(generator, funcName, type);
if (!scope) {
return false;
@ -236,7 +261,7 @@ static char* EndScope (TRI_aql_codegen_t* const generator) {
assert(scope);
funcName = TRI_DuplicateString(scope->_funcName);
funcName = scope->_funcName;
body = TRI_CreateStringBuffer();
if (!body) {
@ -638,7 +663,6 @@ static void GenerateCode (TRI_aql_codegen_t* const generator,
AppendCode(generator, "(");
GenerateCode(generator, ((TRI_aql_node_expand_t*) node)->_expanded);
AppendCode(generator, ")");
TRI_Free(funcName);
break;
}
case AQL_NODE_ASSIGN:
@ -661,7 +685,6 @@ static void GenerateCode (TRI_aql_codegen_t* const generator,
AppendCode(generator, funcName);
AppendCode(generator, "($)");
TRI_Free(funcName);
break;
}
case AQL_NODE_FILTER:
@ -686,14 +709,27 @@ static void GenerateCode (TRI_aql_codegen_t* const generator,
break;
case AQL_NODE_LIMIT: {
char* previousFunction;
char* value;
AppendIndent(generator);
AppendCode(generator, "result.push($);\n");
CloseForLoops(generator);
AppendCode(generator, " result = AHUACATL_LIMIT(result, ");
AppendCode(generator, TRI_StringInt64(((TRI_aql_node_limit_t*) node)->_offset)); // todo: oom
value = TRI_StringInt64(((TRI_aql_node_limit_t*) node)->_offset);
if (!value) {
return; // todo: OOM
}
RegisterString(generator, value);
AppendCode(generator, value);
AppendCode(generator, ", ");
AppendCode(generator, TRI_StringInt64(((TRI_aql_node_limit_t*) node)->_count)); // todo: oom
value = TRI_StringInt64(((TRI_aql_node_limit_t*) node)->_count);
if (!value) {
return; // todo: OOM
}
RegisterString(generator, value);
AppendCode(generator, value);
AppendCode(generator, ");\n");
previousFunction = EndScope(generator);
@ -718,7 +754,7 @@ static void GenerateCode (TRI_aql_codegen_t* const generator,
size_t i;
size_t n;
previousFunction = TRI_DuplicateString(scope->_funcName);
previousFunction = scope->_funcName;
// todo: OOM
sortFuncName = GetNextFunctionName(generator);
@ -1005,13 +1041,15 @@ TRI_aql_codegen_t* TRI_CreateCodegenAql (void) {
generator->_funcName = NULL;
TRI_InitStringBuffer(&generator->_buffer);
TRI_InitVectorPointer(&generator->_strings);
TRI_InitVectorPointer(&generator->_scopes);
if (!StartScope(generator, AQL_SCOPE_RESULT, GetNextFunctionName(generator))) {
TRI_FreeCodegenAql(generator);
return NULL;
}
return generator;
}
@ -1020,11 +1058,23 @@ TRI_aql_codegen_t* TRI_CreateCodegenAql (void) {
////////////////////////////////////////////////////////////////////////////////
void TRI_FreeCodegenAql (TRI_aql_codegen_t* const generator) {
size_t i;
assert(generator);
TRI_DestroyStringBuffer(&generator->_buffer);
TRI_DestroyVectorPointer(&generator->_scopes);
// free strings
i = generator->_strings._length;
while (i--) {
void* string = generator->_strings._buffer[i];
if (string) {
TRI_Free(string);
}
}
TRI_DestroyVectorPointer(&generator->_strings);
TRI_Free(generator);
}
@ -1065,7 +1115,7 @@ char* TRI_GenerateCodeAql (const void* const data) {
TRI_AppendStringStringBuffer(&generator->_buffer, "})();\n");
code = TRI_DuplicateString(generator->_buffer._buffer);
printf("CODE IS:\n%s\n\n",code);
LOG_TRACE("generated code:\n%s\n",code);
}
TRI_FreeCodegenAql(generator);

View File

@ -73,6 +73,7 @@ typedef struct TRI_aql_codegen_s {
size_t _funcIndex;
bool _error;
char* _funcName;
TRI_vector_pointer_t _strings;
}
TRI_aql_codegen_t;

View File

@ -143,27 +143,57 @@ TRI_aql_parse_context_t* TRI_CreateParseContextAql (const char* const query) {
////////////////////////////////////////////////////////////////////////////////
void TRI_FreeParseContextAql (TRI_aql_parse_context_t* const context) {
size_t i;
assert(context);
// free all remaining scopes
while (context->_scopes._length) {
TRI_EndScopeParseContextAql(context);
}
// TODO: Free nodes
TRI_DestroyVectorPointer(&context->_scopes);
TRI_DestroyVectorPointer(&context->_nodes);
// free all strings registered
i = context->_strings._length;
while (i--) {
void* string = context->_strings._buffer[i];
if (string) {
TRI_Free(context->_strings._buffer[i]);
}
}
TRI_DestroyVectorPointer(&context->_strings);
// free all nodes registered
i = context->_nodes._length;
while (i--) {
TRI_aql_node_t* node = (TRI_aql_node_t*) context->_nodes._buffer[i];
if (node) {
if (node->free) {
// call node's specific free function
node->free(node);
}
// free node itself
TRI_Free(node);
}
}
TRI_DestroyVectorPointer(&context->_nodes);
// free the stack
TRI_DestroyVectorPointer(&context->_stack);
// free query string
if (context->_query) {
TRI_Free(context->_query);
}
// free lexer
if (context->_parser) {
Ahuacatllex_destroy(context->_parser->_scanner);
TRI_Free(context->_parser);
}
// free error struct
TRI_DestroyErrorAql(&context->_error);
TRI_Free(context);