Thanks to visit codestin.com
Credit goes to github.com

Skip to content

How are scopes chained in nullc ? #30

@mingodad

Description

@mingodad

I'm trying to add a compiler warning for shadowed variables but I'm having trouble understand scopes in nullc, I started by copying and changing Report(ExpressionContext &ctx, SynBase *source, const char *msg, ...) then changed bool CheckVariableConflict(ExpressionContext &ctx, SynBase *source, InplaceStr name) to issue the warning then I'm getting this warnings when running nullc:

WARNING: name 'x' is already taken for a variable in outer scope
WARNING: name 'y' is already taken for a variable in outer scope
WARNING: name 'x' is already taken for a variable in outer scope
WARNING: name 'y' is already taken for a variable in outer scope
WARNING: name 'z' is already taken for a variable in outer scope
WARNING: name 'x' is already taken for a variable in outer scope
WARNING: name 'y' is already taken for a variable in outer scope
WARNING: name 'z' is already taken for a variable in outer scope
WARNING: name 'w' is already taken for a variable in outer scope
WARNING: name 'node' is already taken for a variable in outer scope
WARNING: name 'node' is already taken for a variable in outer scope
WARNING: name 'node' is already taken for a variable in outer scope
WARNING: name 'node' is already taken for a variable in outer scope
WARNING: name 'node' is already taken for a variable in outer scope
WARNING: name 'node' is already taken for a variable in outer scope

I understand that I need to search for the symbol name in outer scopes to decide to show the warning.

How are scopes chained in nullc ?

	NULLC_PRINT_FORMAT_CHECK(3, 4) void Warning(ExpressionContext &ctx, SynBase *source, const char *msg, ...)
	{
		va_list args;
		va_start(args, msg);

                vprintf(msg, args);
                //ReportAt(ctx, source, source->pos.begin, msg, args);

		va_end(args);
	}
	bool CheckVariableConflict(ExpressionContext &ctx, SynBase *source, InplaceStr name)
	{
		if(LookupTypeByName(ctx, name.hash()))
		{
			Report(ctx, source, "ERROR: name '%.*s' is already taken for a type", FMT_ISTR(name));
			return true;
		}

		if(IdentifierLookupResult *lookup = LookupObjectByName(ctx, name.hash()))
		{
			if(lookup->variable)
			{
                            if(lookup->variable->scope == ctx.scope) {
				Report(ctx, source, "ERROR: name '%.*s' is already taken for a variable in current scope", FMT_ISTR(name));
				return true;
                            }
                            else {
				Warning(ctx, source, "WARNING: name '%.*s' is already taken for a variable in outer scope\n", FMT_ISTR(name));
                            }
			}

			if(lookup->function && lookup->function->scope == ctx.scope)
			{
				Report(ctx, source, "ERROR: name '%.*s' is already taken for a function", FMT_ISTR(name));
			}
		}

		if(FindNamespaceInCurrentScope(ctx, name))
		{
			Report(ctx, source, "ERROR: name '%.*s' is already taken for a namespace", FMT_ISTR(name));
			return true;
		}

		return false;
	}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions