Thread: Does this look alright?(Representing variable scope on a stack)

  1. #1
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657

    Does this look alright?(Representing variable scope on a stack)

    HAI
    I HAS A QUESTION

    I'm trying to write a small && simple interpreter..of a lisp like language (Almost complete!)..and the following is what I'd build variable and symbol scopes on.
    Any noticeable problem ?
    Code:
    namespace mm
    {
        template<typename T>
        class scope
        {
            std::vector< std::map<std::string,T> > data;
        public:
            T* find(std::string s)
            {
                for(auto m=data.rbegin();m!=data.rend();m++)
                {
                    auto p = (*m).find(s);
                    if(p!=(*m).end())return &((*p).second);                
                }
                return nullptr;
            };
            void new_local(std::map<std::string,T> sm){data.push_back(sm);};
            void exit_scope(){data.pop_back();};
        };
    }
    Can the pointer returning be avoided ?
    (Other than exceptions...since it'd complicate the error handling too much..Most running code will already be within some try `s)

    PS: The following demonstrates my goal (It seems achieved..for now)
    Code:
    int main()
    {
        mm::scope<int> s;
        std::map<std::string,int> s1 = {{"Hey",42},{"Foo",84}};
        std::map<std::string,int> s2 = {{"Buddy",43},{"Bar",85}};
        s.new_local(s1);s.new_local(s2);
        std::cout<<*s.find("Foo");
        return 0;
    }



    KTHXBYE

  2. #2
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Firstly, how about you stop using the horrible (*p). syntax and go with the much cleaner p-> syntax?

    You can also remove the extra semicolons after the function bodies.

    Pass containers and strings that you don't need to modify by const-reference, not by value.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  3. #3
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by iMalc View Post
    Firstly, how about you stop using the horrible (*p). syntax and go with the much cleaner p-> syntax?

    You can also remove the extra semicolons after the function bodies.

    Pass containers and strings that you don't need to modify by const-reference, not by value.
    Oh.. I didn't know iterators overloaded -> too. Thanks for pointing that out.
    Ok.
    Forgot to do so.

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You can avoid returning pointers by returning an iterator. That is how the standard library does it.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by Elysia View Post
    You can avoid returning pointers by returning an iterator. That is how the standard library does it.
    Good idea.. didn't think of doing that.

  6. #6
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by Elysia View Post
    You can avoid returning pointers by returning an iterator.
    I wouldn't do that in this case. Returning a map iterator leaks some information about the internals of this class, i.e. the fact that it uses a map internally.

    It also means that if you change how things are stored inside this class then you are probably going to break the code that uses it because you're changing the interface. However, I guess he's already passing in a map so it's unlikely to change structure internally.

    Lastly, it's very difficult to do this correctly by returning an iterator unless you throw an exception when the item is not found. This is because the first step after calling find and getting back an iterator would be to compare the iterator against the end() of something. It has to be compared against the end() from the correct internal map that the data came from because you can't compare iterators from different containers. So unless your find function also passes out the end of the correct map (e.g. as a std::pair), then you're stuck with what to compare it to.
    Basically don't try to do this if the iterator being returned could be from more than one possible container.
    Last edited by iMalc; 11-23-2011 at 12:08 AM.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  7. #7
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by iMalc View Post
    I wouldn't do that in this case. Returning a map iterator leaks some information about the internals of this class, i.e. the fact that it uses a map internally.

    It also means that if you change how things are stored inside this class then you are probably going to break the code that uses it because you're changing the interface. However, I guess he's already passing in a map so it's unlikely to change structure internally.

    Lastly, it's very difficult to do this correctly by returning an iterator unless you throw an exception when the item is not found. This is because the first step after calling find and getting back an iterator would be to compare the iterator against the end() of something. It has to be compared against the end() from the correct internal map that the data came from because you can't compare iterators from different containers. So unless your find function also passes out the end of the correct map (e.g. as a std:air), then you're stuck with what to compare it to.
    Basically don't try to do this if the iterator being returned could be from more than one possible container.
    I think you're going off the wrong tangent here.
    Returning some map's iterator isn't a good idea, sure....but making this class' own iterator probably is.
    I did something like that for a linked list a week ago... and it worked nicely.
    (Here the iterator would traverse the various pair `s is the correct order ...and return a reference to 'second' )
    Last edited by manasij7479; 11-23-2011 at 02:45 AM.

  8. #8
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by manasij7479 View Post
    I think you're going off the wrong tangent here.
    Returning some map's iterator isn't a good idea, sure....but making this class' own iterator probably is.
    I did something like that for a linked list a week ago... and it worked nicely.
    (Here the iterator would traverse the various pair `s is the correct order ...and return a reference to 'second' )
    I simply don't know what you'd want to do that for. When really are you ever going to want to iterate over anything it returns, given what this is meant for? Anything that needs to iterate over the contents of that vector and its internal maps should probably belong to that class.
    It seems to me that you'd just add overhead and complexity for something that ultimately wan't useful.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  9. #9
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    > When really are you ever going to want to iterate over anything it returns, given what this is meant for?
    Maybe...Suppose I need to find a global variable that shares the same name with a local one..
    Making methods sounding like find_last_of_if_exists() ...will be much more complicated that a iteration from begin() to before end()

    >It seems to me that you'd just add overhead and complexity for something that ultimately wan't useful
    I'd just stick with pointers then..
    Last edited by manasij7479; 11-23-2011 at 12:49 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 8
    Last Post: 02-14-2010, 04:14 PM
  2. variable scope
    By happyclown in forum C Programming
    Replies: 4
    Last Post: 03-02-2009, 06:48 AM
  3. Variable Scope
    By Matty_Alan in forum C Programming
    Replies: 3
    Last Post: 11-23-2008, 03:28 PM
  4. Variable scope
    By Axel in forum C Programming
    Replies: 2
    Last Post: 09-19-2005, 08:41 PM
  5. Variable Scope
    By tinkerbell20 in forum C++ Programming
    Replies: 5
    Last Post: 06-22-2005, 10:31 PM