Ejemplo n.º 1
0
void addScopeToScopeStack(DbgRsScope& stack, exec_list *scope, void* mem_ctx)
{
	if (!scope)
		return;
 	foreach_in_list(scope_item, sc_item, scope)
 		addToScope(stack, sc_item, mem_ctx);
}
Ejemplo n.º 2
0
/** Declare a symbol in a scope.
	@param scope The scope to add the symbol to.
	@param key The symbol.
	@param data The data to be associated with the symbol.
	@return A boolean that indicates whether the @a declare action was
		successful.

	The difference from the @a addToScope function is that @a declare checks
	that the symbol does not already exist in the @a scope, while @a addToScope
	blindly adds the symbol.

	If memory for the new data item cannot be allocated, the function will not
	return.
*/
bool declare(Scope *scope, const char *key, void *data) {
    if (lookup(scope, key))
        return false;

    addToScope(scope, key, data);
    return true;
}
Ejemplo n.º 3
0
/* Impl format:
 * "impl" [<type_bounds>] <qualified_ident>[<type_bounds>] ["for" <qualified_ident>[<type_bounds>]] "{" [<body>] "}"
 */
static void parseImpl (lexerState *lexer, vString *scope, int parent_kind)
{
	unsigned long line;
	fpos_t pos;
	vString *name;

	advanceToken(lexer, TRUE);

	line = lexer->line;
	pos = lexer->pos;

	skipTypeBlock(lexer);

	name = vStringNew();

	parseQualifiedType(lexer, name);

	if (lexer->cur_token == TOKEN_IDENT && strcmp(lexer->token_str->buffer, "for") == 0)
	{
		advanceToken(lexer, TRUE);
		parseQualifiedType(lexer, name);
	}

	addTag(name, NULL, K_IMPL, line, pos, scope, parent_kind);
	addToScope(scope, name);

	parseBlock(lexer, TRUE, K_IMPL, scope);

	vStringDelete(name);
}
Ejemplo n.º 4
0
bool ast_debugvar_traverser_visitor::enter(class ast_declaration* node)
{
	ShVariable* var = findShVariable(node->debug_id);
	assert(var);

	VPRINT(3, "%c%sdeclaration of %s <%i>%c%s\n", ESC_CHAR, ESC_BOLD,
			node->identifier, var->uniqueId, ESC_CHAR, ESC_RESET);

	// Add variable to the global list of all seen variables
	addShVariableCtx(vl, var, var->builtin, shader);

	if (node->initializer) {
		node->initializer->accept(this);
		exec_list* scope = &node->initializer->scope;
		(void)scope;
		/*
		 * Actually do not add declared variable to the list here, because
		 * Code Generation would access the data before it is declared. This should
		 * not be needed anyway, since the data would be uninitialized
		 *
		 // Dont forget to check for double ids
		 scopeList::iterator e = find(sl->begin(), sl->end(), v->getUniqueId());

		 // Finally at it to the list
		 if (e == sl->end()) {
		 sl->push_back(v->getUniqueId());
		 }
		 */
	}

	// Now add the list to the actual scope and proceed
	addToScope(var);
	dumpScope();
	return false;
}
Ejemplo n.º 5
0
void setDbgScope(DbgRsScope& scope, exec_list *s, void* mem_ctx)
{
	assert(s || !"no scopeList");
	VPRINT(3, "SET GLOBAL SCOPE LIST: ");

	foreach_in_list(scope_item, item, s) {
		addToScope(scope, item, mem_ctx);
		VPRINT(3, "<%i,%s> ", item->id, item->name);
	}
Ejemplo n.º 6
0
ast_debugvar_traverser_visitor::ast_debugvar_traverser_visitor(AstShader* _sh,
		ShVariableList* _vl) :
		vl(_vl), shader(_sh)
{
	for(int i = 0; i < _sh->globals.numVariables; ++i) {
		ShVariable* var = _sh->globals.variables[i];
		addShVariableCtx(vl, var, var->builtin, _sh);
		addToScope(var);
	}
}
Ejemplo n.º 7
0
/* Mod format:
 * "mod" <ident> "{" [<body>] "}"
 * "mod" <ident> ";"*/
static void parseMod (lexerState *lexer, vString *scope, int parent_kind)
{
	advanceToken(lexer, TRUE);
	if (lexer->cur_token != TOKEN_IDENT)
		return;

	addTag(lexer->token_str, NULL, K_MOD, lexer->line, lexer->pos, scope, parent_kind);
	addToScope(scope, lexer->token_str);

	advanceToken(lexer, TRUE);

	parseBlock(lexer, TRUE, K_MOD, scope);
}
Ejemplo n.º 8
0
bool ast_debugvar_traverser_visitor::enter(class ast_parameter_declarator* node)
{
	// No variable when void
	if (node->is_void)
		return false;

	ShVariable* var = findShVariable(node->debug_id);
	assert(var);

	VPRINT(3, "%c%sparameter %s <%i> %c%s\n", ESC_CHAR, ESC_BOLD,
			node->identifier, var->uniqueId, ESC_CHAR, ESC_RESET);
	addShVariableCtx(vl, var, var->builtin, shader);
	addToScope(var);
	dumpScope();
	return false;
}
Ejemplo n.º 9
0
static void parseFunction (tokenInfo *const token)
{
	tokenInfo *const name = newToken ();
	vString *const signature = vStringNew ();
	boolean is_class = FALSE;

	/*
	 * This deals with these formats
	 *	   function validFunctionTwo(a,b) {}
	 */

	readToken (name);
	if (!isType (name, TOKEN_IDENTIFIER))
		goto cleanUp;

	/* Add scope in case this is an INNER function */
	addToScope(name, token->scope);

	readToken (token);
	while (isType (token, TOKEN_PERIOD))
	{
		readToken (token);
		if ( isKeyword(token, KEYWORD_NONE) )
		{
			addContext (name, token);
			readToken (token);
		}
	}

	if ( isType (token, TOKEN_OPEN_PAREN) )
		skipArgumentList(token, FALSE, signature);

	if ( isType (token, TOKEN_OPEN_CURLY) )
	{
		is_class = parseBlock (token, name);
		if ( is_class )
			makeClassTag (name, signature);
		else
			makeFunctionTag (name, signature);
	}

	findCmdTerm (token, FALSE, FALSE);

 cleanUp:
	vStringDelete (signature);
	deleteToken (name);
}
Ejemplo n.º 10
0
/* Trait format:
 * "trait" <ident> [<type_bounds>] "{" [<body>] "}"
 */
static void parseTrait (lexerState *lexer, vString *scope, int parent_kind)
{
	int goal_tokens[] = {'{'};

	advanceToken(lexer, TRUE);
	if (lexer->cur_token != TOKEN_IDENT)
		return;

	addTag(lexer->token_str, NULL, K_TRAIT, lexer->line, lexer->pos, scope, parent_kind);
	addToScope(scope, lexer->token_str);

	advanceToken(lexer, TRUE);

	skipUntil(lexer, goal_tokens, 1);

	parseBlock(lexer, TRUE, K_TRAIT, scope);
}
Ejemplo n.º 11
0
static void enterScope (tokenInfo *const parentToken,
						const vString *const extraScope,
						const int parentKind)
{
	tokenInfo *token = newToken ();
	int origParentKind = parentToken->parentKind;

	copyToken (token, parentToken, true);

	if (extraScope)
	{
		addToScope (token, extraScope);
		token->parentKind = parentKind;
	}

	readToken (token);
	while (token->type != TOKEN_EOF &&
		   token->type != TOKEN_CLOSE_CURLY)
	{
		bool readNext = true;

		switch (token->type)
		{
			case TOKEN_OPEN_CURLY:
				enterScope (token, NULL, -1);
				break;

			case TOKEN_KEYWORD:
				readNext = parseFunction (token);
				break;

			case TOKEN_VARIABLE:
				readNext = parseVariable (token);
				break;

			default: break;
		}

		if (readNext)
			readToken (token);
	}

	copyToken (parentToken, token, false);
	parentToken->parentKind = origParentKind;
	deleteToken (token);
}
Ejemplo n.º 12
0
static boolean parseBlock (tokenInfo *const token, tokenInfo *const parent)
{
	boolean is_class = FALSE;
	boolean read_next_token = TRUE;
	vString * saveScope = vStringNew ();

	token->nestLevel++;
	/*
	 * Make this routine a bit more forgiving.
	 * If called on an open_curly advance it
	 */
	if ( isType (token, TOKEN_OPEN_CURLY) &&
			isKeyword(token, KEYWORD_NONE) )
		readToken(token);

	if (! isType (token, TOKEN_CLOSE_CURLY))
	{
		/*
		 * Read until we find the closing brace,
		 * any nested braces will be handled within
		 */
		do
		{
			read_next_token = TRUE;
			if (isKeyword (token, KEYWORD_this))
			{
				/*
				 * Means we are inside a class and have found
				 * a class, not a function
				 */
				is_class = TRUE;
				vStringCopy(saveScope, token->scope);
				addToScope (token, parent->string);

				/*
				 * Ignore the remainder of the line
				 * findCmdTerm(token);
				 */
				parseLine (token, is_class);

				vStringCopy(token->scope, saveScope);
			}
			else if (isKeyword (token, KEYWORD_var))
			{
				/*
				 * Potentially we have found an inner function.
				 * Set something to indicate the scope
				 */
				vStringCopy(saveScope, token->scope);
				addToScope (token, parent->string);
				parseLine (token, is_class);
				vStringCopy(token->scope, saveScope);
			}
			else if (isKeyword (token, KEYWORD_function))
			{
				vStringCopy(saveScope, token->scope);
				addToScope (token, parent->string);
				parseFunction (token);
				vStringCopy(token->scope, saveScope);
			}
			else if (isType (token, TOKEN_OPEN_CURLY))
			{
				/* Handle nested blocks */
				parseBlock (token, parent);
			}
			else
			{
				/*
				 * It is possible for a line to have no terminator
				 * if the following line is a closing brace.
				 * parseLine will detect this case and indicate
				 * whether we should read an additional token.
				 */
				read_next_token = parseLine (token, is_class);
			}

			/*
			 * Always read a new token unless we find a statement without
			 * a ending terminator
			 */
			if( read_next_token )
				readToken(token);

			/*
			 * If we find a statement without a terminator consider the
			 * block finished, otherwise the stack will be off by one.
			 */
		} while (! isType (token, TOKEN_CLOSE_CURLY) && read_next_token );
	}

	vStringDelete(saveScope);
	token->nestLevel--;

	return is_class;
}
Ejemplo n.º 13
0
/* Structs and enums are very similar syntax-wise.
 * It is possible to parse variants a bit more cleverly (e.g. make tuple variants functions and
 * struct variants structs) but it'd be too clever and the signature wouldn't make too much sense without
 * the enum's definition (e.g. for the type bounds)
 *
 * Struct/Enum format:
 * "struct/enum" <ident>[<type_bounds>] "{" [<ident>,]+ "}"
 * "struct/enum" <ident>[<type_bounds>] ";"
 * */
static void parseStructOrEnum (lexerState *lexer, vString *scope, int parent_kind, boolean is_struct)
{
	int kind = is_struct ? K_STRUCT : K_ENUM;
	int field_kind = is_struct ? K_FIELD : K_VARIANT;
	int goal_tokens1[] = {';', '{'};

	advanceToken(lexer, TRUE);
	if (lexer->cur_token != TOKEN_IDENT)
		return;

	addTag(lexer->token_str, NULL, kind, lexer->line, lexer->pos, scope, parent_kind);
	addToScope(scope, lexer->token_str);

	skipUntil(lexer, goal_tokens1, 2);

	if (lexer->cur_token == '{')
	{
		vString *field_name = vStringNew();
		while (lexer->cur_token != TOKEN_EOF)
		{
			int goal_tokens2[] = {'}', ','};
			/* Skip attributes. Format:
			 * #[..] or #![..]
			 * */
			if (lexer->cur_token == '#')
			{
				advanceToken(lexer, TRUE);
				if (lexer->cur_token == '!')
					advanceToken(lexer, TRUE);
				if (lexer->cur_token == '[')
				{
					/* It's an attribute, skip it. */
					skipUntil(lexer, NULL, 0);
				}
				else
				{
					/* Something's up with this field, skip to the next one */
					skipUntil(lexer, goal_tokens2, 2);
					continue;
				}
			}
			if (lexer->cur_token == TOKEN_IDENT)
			{
				if (strcmp(lexer->token_str->buffer, "priv") == 0
				    || strcmp(lexer->token_str->buffer, "pub") == 0)
				{
					advanceToken(lexer, TRUE);
					if (lexer->cur_token != TOKEN_IDENT)
					{
						/* Something's up with this field, skip to the next one */
						skipUntil(lexer, goal_tokens2, 2);
						continue;
					}
				}

				vStringClear(field_name);
				vStringCat(field_name, lexer->token_str);
				addTag(field_name, NULL, field_kind, lexer->line, lexer->pos, scope, kind);
				skipUntil(lexer, goal_tokens2, 2);
			}
			if (lexer->cur_token == '}')
			{
				advanceToken(lexer, TRUE);
				break;
			}
			advanceToken(lexer, TRUE);
		}
		vStringDelete(field_name);
	}
}
Ejemplo n.º 14
0
/* Function format:
 * "fn" <ident>[<type_bounds>] "(" [<args>] ")" ["->" <ret_type>] "{" [<body>] "}"*/
static void parseFn (lexerState *lexer, vString *scope, int parent_kind)
{
	int kind = (parent_kind == K_TRAIT || parent_kind == K_IMPL) ? K_METHOD : K_FN;
	vString *name;
	vString *arg_list;
	unsigned long line;
	fpos_t pos;
	int paren_level = 0;
	boolean found_paren = FALSE;
	boolean valid_signature = TRUE;

	advanceToken(lexer, TRUE);
	if (lexer->cur_token != TOKEN_IDENT)
		return;

	name = vStringNewCopy(lexer->token_str);
	arg_list = vStringNew();

	line = lexer->line;
	pos = lexer->pos;

	advanceToken(lexer, TRUE);

	/* HACK: This is a bit coarse as far as what tag entry means by
	 * 'arglist'... */
	while (lexer->cur_token != '{' && lexer->cur_token != ';')
	{
		if (lexer->cur_token == '}')
		{
			valid_signature = FALSE;
			break;
		}
		else if (lexer->cur_token == '(')
		{
			found_paren = TRUE;
			paren_level++;
		}
		else if (lexer->cur_token == ')')
		{
			paren_level--;
			if (paren_level < 0)
			{
				valid_signature = FALSE;
				break;
			}
		}
		else if (lexer->cur_token == TOKEN_EOF)
		{
			valid_signature = FALSE;
			break;
		}
		writeCurTokenToStr(lexer, arg_list);
		advanceToken(lexer, FALSE);
	}
	if (!found_paren || paren_level != 0)
		valid_signature = FALSE;

	if (valid_signature)
	{
		vStringStripTrailing(arg_list);
		addTag(name, arg_list->buffer, kind, line, pos, scope, parent_kind);
		addToScope(scope, name);
		parseBlock(lexer, TRUE, kind, scope);
	}

	vStringDelete(name);
	vStringDelete(arg_list);
}
Ejemplo n.º 15
0
static void enterScope (tokenInfo *const parentToken,
						const vString *const extraScope,
						const int parentKind)
{
	tokenInfo *token = newToken ();
	int origParentKind = parentToken->parentKind;

	copyToken (token, parentToken, TRUE);

	if (extraScope)
	{
		token->parentKind = parentKind;
		addToScope (token, extraScope, origParentKind);
	}

	readToken (token);
	while (token->type != TOKEN_EOF &&
		   token->type != TOKEN_CLOSE_CURLY)
	{
		boolean readNext = TRUE;

		switch (token->type)
		{
			case TOKEN_OPEN_CURLY:
				enterScope (token, NULL, -1);
				break;

			case TOKEN_KEYWORD:
				switch (token->keyword)
				{
					/* handle anonymous classes */
					case KEYWORD_new:
						readToken (token);
						if (token->keyword != KEYWORD_class)
							readNext = FALSE;
						else
						{
							char buf[32];
							tokenInfo *name = newToken ();

							copyToken (name, token, TRUE);
							snprintf (buf, sizeof buf, "AnonymousClass%u", ++AnonymousID);
							vStringCopyS (name->string, buf);
							readNext = parseClassOrIface (token, K_CLASS, name);
							deleteToken (name);
						}
						break;

					case KEYWORD_class:		readNext = parseClassOrIface (token, K_CLASS, NULL);		break;
					case KEYWORD_interface:	readNext = parseClassOrIface (token, K_INTERFACE, NULL);	break;
					case KEYWORD_trait:		readNext = parseTrait (token);								break;
					case KEYWORD_function:	readNext = parseFunction (token, NULL);						break;
					case KEYWORD_const:		readNext = parseConstant (token);							break;
					case KEYWORD_define:	readNext = parseDefine (token);								break;

					case KEYWORD_namespace:	readNext = parseNamespace (token);	break;

					case KEYWORD_private:	CurrentStatement.access = ACCESS_PRIVATE;	break;
					case KEYWORD_protected:	CurrentStatement.access = ACCESS_PROTECTED;	break;
					case KEYWORD_public:	CurrentStatement.access = ACCESS_PUBLIC;	break;
					case KEYWORD_var:		CurrentStatement.access = ACCESS_PUBLIC;	break;

					case KEYWORD_abstract:	CurrentStatement.impl = IMPL_ABSTRACT;		break;

					default: break;
				}
				break;

			case TOKEN_VARIABLE:
				readNext = parseVariable (token);
				break;

			default: break;
		}

		if (readNext)
			readToken (token);
	}

	copyToken (parentToken, token, FALSE);
	parentToken->parentKind = origParentKind;
	deleteToken (token);
}