Beispiel #1
0
/*
 * Register the built-in constants defined above.
 */
JX9_PRIVATE void jx9RegisterBuiltInConstant(jx9_vm *pVm)
{
	sxu32 n;
	/* 
	 * Note that all built-in constants have access to the jx9 virtual machine
	 * that trigger the constant invocation as their private data.
	 */
	for( n = 0 ; n < SX_ARRAYSIZE(aBuiltIn) ; ++n ){
		jx9_create_constant(&(*pVm), aBuiltIn[n].zName, aBuiltIn[n].xExpand, &(*pVm));
	}
}
Beispiel #2
0
/*
 * Register all the UnQLite foreign functions defined above.
 */
UNQLITE_PRIVATE int unqliteRegisterJx9Functions(unqlite_vm *pVm)
{
	static const jx9_builtin_func aBuiltin[] = {
		{ "db_version" , unqliteBuiltin_db_version },
		{ "db_copyright", unqliteBuiltin_db_credits },
		{ "db_credits" , unqliteBuiltin_db_credits },
		{ "db_sig" ,     unqliteBuiltin_db_sig     },
		{ "db_errlog",   unqliteBuiltin_db_errlog  },
		{ "collection_exists", unqliteBuiltin_collection_exists },
		{ "db_exists",         unqliteBuiltin_collection_exists }, 
		{ "collection_create", unqliteBuiltin_collection_create },
		{ "db_create",         unqliteBuiltin_collection_create },
		{ "db_fetch",          unqliteBuiltin_db_fetch_next     },
		{ "db_get",            unqliteBuiltin_db_fetch_next     },
		{ "db_fetch_by_id",    unqliteBuiltin_db_fetch_by_id    },
		{ "db_get_by_id",      unqliteBuiltin_db_fetch_by_id    },
		{ "db_fetch_all",      unqliteBuiltin_db_fetch_all      },
		{ "db_get_all",        unqliteBuiltin_db_fetch_all      },
		{ "db_last_record_id", unqliteBuiltin_db_last_record_id },
		{ "db_current_record_id", unqliteBuiltin_db_current_record_id },
		{ "db_reset_record_cursor", unqliteBuiltin_db_reset_record_cursor },
		{ "db_total_records",  unqliteBuiltin_db_total_records  },
		{ "db_creation_date",  unqliteBuiltin_db_creation_date  },
		{ "db_store",          unqliteBuiltin_db_store          },
		{ "db_put",            unqliteBuiltin_db_store          },
		{ "db_drop_collection", unqliteBuiltin_db_drop_col      },
		{ "collection_delete", unqliteBuiltin_db_drop_col       },
		{ "db_drop_record",    unqliteBuiltin_db_drop_record    },
		{ "db_update_record",  unqliteBuiltin_db_update_record  },
		{ "db_set_schema",     unqliteBuiltin_db_set_schema     },
		{ "db_get_schema",     unqliteBuiltin_db_get_schema     },
		{ "db_begin",          unqliteBuiltin_db_begin          },
		{ "db_commit",         unqliteBuiltin_db_commit         },
		{ "db_rollback",       unqliteBuiltin_db_rollback       },
	};
	int rc = UNQLITE_OK;
	sxu32 n;
	/* Register the unQLite functions defined above in the Jx9 call table */
	for( n = 0 ; n < SX_ARRAYSIZE(aBuiltin) ; ++n ){
		rc = jx9_create_function(pVm->pJx9Vm,aBuiltin[n].zName,aBuiltin[n].xFunc,pVm);
	}
	return rc;
}
Beispiel #3
0
/*
 * Check if the given token is a potential operator or not.
 * This function is called by the lexer each time it extract a token that may 
 * look like an operator.
 * Return a structure [i.e: jx9_expr_op instnace ] that describe the operator on success.
 * Otherwise NULL.
 * Note that the function take care of handling ambiguity [i.e: whether we are dealing with
 * a binary minus or unary minus.]
 */
JX9_PRIVATE const jx9_expr_op *  jx9ExprExtractOperator(SyString *pStr, SyToken *pLast)
{
	sxu32 n = 0;
	sxi32 rc;
	/* Do a linear lookup on the operators table */
	for(;;){
		if( n >= SX_ARRAYSIZE(aOpTable) ){
			break;
		}
		rc = SyStringCmp(pStr, &aOpTable[n].sOp, SyMemcmp);		
		if( rc == 0 ){
			if( aOpTable[n].sOp.nByte != sizeof(char) || (aOpTable[n].iOp != EXPR_OP_UMINUS && aOpTable[n].iOp != EXPR_OP_UPLUS) || pLast == 0 ){
				if( aOpTable[n].iOp == EXPR_OP_SUBSCRIPT && (pLast == 0 || (pLast->nType & (JX9_TK_ID|JX9_TK_CSB/*]*/|JX9_TK_RPAREN/*)*/)) == 0) ){
					/* JSON Array not subscripting, return NULL  */
					return 0;
				}
				/* There is no ambiguity here, simply return the first operator seen */
				return &aOpTable[n];
			}
			/* Handle ambiguity */
			if( pLast->nType & (JX9_TK_LPAREN/*'('*/|JX9_TK_OCB/*'{'*/|JX9_TK_OSB/*'['*/|JX9_TK_COLON/*:*/|JX9_TK_COMMA/*, '*/) ){
				/* Unary opertors have prcedence here over binary operators */
				return &aOpTable[n];
			}
			if( pLast->nType & JX9_TK_OP ){
				const jx9_expr_op *pOp = (const jx9_expr_op *)pLast->pUserData;
				/* Ticket 1433-31: Handle the '++', '--' operators case */
				if( pOp->iOp != EXPR_OP_INCR && pOp->iOp != EXPR_OP_DECR ){
					/* Unary opertors have prcedence here over binary operators */
					return &aOpTable[n];
				}
			
			}
		}
		++n; /* Next operator in the table */
	}
	/* No such operator */
	return 0;
}
Beispiel #4
0
/*
 * Make sure we are dealing with a valid expression tree.
 * This function check for balanced parenthesis, braces, brackets and so on.
 * When errors, JX9 take care of generating the appropriate error message.
 * Return SXRET_OK on success. Any other return value indicates syntax error.
 */
static sxi32 ExprVerifyNodes(jx9_gen_state *pGen, jx9_expr_node **apNode, sxi32 nNode)
{
	sxi32 iParen, iSquare, iBraces;
	sxi32 i, rc;

	if( nNode > 0 && apNode[0]->pOp && (apNode[0]->pOp->iOp == EXPR_OP_ADD || apNode[0]->pOp->iOp == EXPR_OP_SUB) ){
		/* Fix and mark as an unary not binary plus/minus operator */
		apNode[0]->pOp = jx9ExprExtractOperator(&apNode[0]->pStart->sData, 0);
		apNode[0]->pStart->pUserData = (void *)apNode[0]->pOp;
	}
	iParen = iSquare = iBraces = 0;
	for( i = 0 ; i < nNode ; ++i ){
		if( apNode[i]->pStart->nType & JX9_TK_LPAREN /*'('*/){
			if( i > 0 && ( apNode[i-1]->xCode == jx9CompileVariable || apNode[i-1]->xCode == jx9CompileLiteral ||
				(apNode[i - 1]->pStart->nType & (JX9_TK_ID|JX9_TK_KEYWORD|JX9_TK_SSTR|JX9_TK_DSTR|JX9_TK_RPAREN/*')'*/|JX9_TK_CSB/*]*/))) ){
					/* Ticket 1433-033: Take care to ignore alpha-stream [i.e: or, xor] operators followed by an opening parenthesis */
					if( (apNode[i - 1]->pStart->nType & JX9_TK_OP) == 0 ){
						/* We are dealing with a postfix [i.e: function call]  operator
						 * not a simple left parenthesis. Mark the node.
						 */
						apNode[i]->pStart->nType |= JX9_TK_OP;
						apNode[i]->pStart->pUserData = (void *)&sFCallOp; /* Function call operator */
						apNode[i]->pOp = &sFCallOp;
					}
			}
			iParen++;
		}else if( apNode[i]->pStart->nType & JX9_TK_RPAREN/*')*/){
			if( iParen <= 0 ){
				rc = jx9GenCompileError(&(*pGen), E_ERROR, apNode[i]->pStart->nLine, "Syntax error: Unexpected token ')'");
				if( rc != SXERR_ABORT ){
					rc = SXERR_SYNTAX;
				}
				return rc;
			}
			iParen--;
		}else if( apNode[i]->pStart->nType & JX9_TK_OSB /*'['*/ && apNode[i]->xCode == 0 ){
			iSquare++;
		}else if (apNode[i]->pStart->nType & JX9_TK_CSB /*']'*/){
			if( iSquare <= 0 ){
				rc = jx9GenCompileError(&(*pGen), E_ERROR, apNode[i]->pStart->nLine, "Syntax error: Unexpected token ']'");
				if( rc != SXERR_ABORT ){
					rc = SXERR_SYNTAX;
				}
				return rc;
			}
			iSquare--;
		}else if( apNode[i]->pStart->nType & JX9_TK_OCB /*'{'*/ && apNode[i]->xCode == 0 ){
			iBraces++;
		}else if (apNode[i]->pStart->nType & JX9_TK_CCB /*'}'*/){
			if( iBraces <= 0 ){
				rc = jx9GenCompileError(&(*pGen), E_ERROR, apNode[i]->pStart->nLine, "Syntax error: Unexpected token '}'");
				if( rc != SXERR_ABORT ){
					rc = SXERR_SYNTAX;
				}
				return rc;
			}
			iBraces--;
		}else if( apNode[i]->pStart->nType & JX9_TK_OP ){
			const jx9_expr_op *pOp = (const jx9_expr_op *)apNode[i]->pOp;
			if( i > 0 && (pOp->iOp == EXPR_OP_UMINUS || pOp->iOp == EXPR_OP_UPLUS)){
				if( apNode[i-1]->xCode == jx9CompileVariable || apNode[i-1]->xCode == jx9CompileLiteral ){
					sxi32 iExprOp = EXPR_OP_SUB; /* Binary minus */
					sxu32 n = 0;
					if( pOp->iOp == EXPR_OP_UPLUS ){
						iExprOp = EXPR_OP_ADD; /* Binary plus */
					}
					/*
					 * TICKET 1433-013: This is a fix around an obscure bug when the user uses
					 * a variable name which is an alpha-stream operator [i.e: $and, $xor, $eq..].
					 */
					while( n < SX_ARRAYSIZE(aOpTable) && aOpTable[n].iOp != iExprOp ){
						++n;
					}
					pOp = &aOpTable[n];
					/* Mark as binary '+' or '-', not an unary */
					apNode[i]->pOp = pOp;
					apNode[i]->pStart->pUserData = (void *)pOp;
				}
			}
		}
	}
	if( iParen != 0 || iSquare != 0 || iBraces != 0){
		rc = jx9GenCompileError(&(*pGen), E_ERROR, apNode[0]->pStart->nLine, "Syntax error, mismatched '(', '[' or '{'");
		if( rc != SXERR_ABORT ){
			rc = SXERR_SYNTAX;
		}
		return rc;
	}
	return SXRET_OK;
}