Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion

is there a way to count classes?

edited May 24 in Questions Posts: 1,089

i'm wanting some project stats, and getting a list of all classes would be of great value. offhand i don't see how to do it. ideas? thanks!

Comments

  • dave1707dave1707 Mod
    Posts: 9,422

    @RonJeffries Would something like this help. If not I might have something else.

    viewer.mode=FULLSCREEN
    
    function setup()    
        project="Examples:Cargo-Bot"
        lst=listProjectTabs(project)
        for a,b in pairs(lst) do
            str=readProjectTab(project..":"..b)
        end 
        font("Courier")
        textMode(CORNER)
        dy=0
        tab={}   
        r=listProjectTabs(project)
        for a,b in pairs(r) do
            str=readProjectTab(project..":"..b)
            table.insert(tab,"\n")
            table.insert(tab,"\n")
            table.insert(tab,project.." : "..b)
            b1=1
            s=1
            comment=false
            startComment=false
            while true do
                s,e=string.find(str,"\n",s)
                if s==nil then
                    break
                end
                s=e+1                        
                str1=string.sub(str,b1,e)   
    
                sc1,ec1=string.find(str1,"%-%-%[%[")  
                if sc1 ~= nil then
                    startComment=true
                end            
                --sc2,ec21=string.find(str1,"%-%-%]%]")  
                sc2,ec21=string.find(str1,"%]%]")  
                if sc2 ~= nil then
                    startComment=false
                end  
    
                comment=false
                sc3,ec3=string.find(str1,"%-%-")            
                if sc3 ~= nil then
                    comment=true
                    sc4,ec4=string.find(str1,"class")
                    if sc4~=nil and sc4<sc3 then
                        comment=false
                    end
                    sc5,ec5=string.find(str1,"function")
                    if sc5~=nil and sc5<sc3 then
                        comment=false
                    end
                end  
    
                process=true
                if comment or startComment then
                    process=false
                end 
    
                if process then
                    s1,e1=string.find(str1,"class")
                    if s1~=nil then
                        s2,e2=string.find(str1,")")
                        if s2~= nil then
                            str1=removeSpaces(string.sub(str1,1,e2))                            
                            table.insert(tab,"    "..str1)
                            b1=e2+1
                        end
                        else
                        s2,e2=string.find(str1,"function ")
                        if s2~=nil then
                            s3,e3=string.find(str1,")")
                            if s3~= nil then
                                table.insert(tab,"        "..string.sub(str1,s2,e3))
                                b1=e3+1
                            end
                        end
                    end
                    if s==nil then
                        break
                    end
                end
                if e~=nil then
                    b1=e+1
                end
            end
        end
        table.insert(tab,"\n")
        table.insert(tab,"\n")
        table.insert(tab,"END of "..project)
    end
    
    function removeSpaces(s)
        for z=1,#s do
            if string.sub(s,z,z)~=" " then
                return(string.sub(s,z))
            end
        end
    end
    
    function draw()
        background(40, 40, 50)
        fill(255)
        for a,b in pairs(tab) do
            text(b,100,HEIGHT-a*20+dy)
        end
    end
    
    function touched(t)
        if t.state==BEGAN or t.state==MOVING then
            dy=dy+t.deltaY
            if dy<0 then
                dy=0
            end
        end
    end
    
  • edited May 24 Posts: 1,089

    that's quite nice!

    yes, i was thinking i can search for "class()", etc. was hoping for something less fragile, in runtime memory, but maybe source analysis is better. thanks!

  • Posts: 1,089

    you're right on find, i removed the discussion :smile:

  • Posts: 1,089

    @dave1707 at the top of that program there is a loop reading tabs. Is there a purpose for that, or is it a leftover? Thanks!

  • dave1707dave1707 Mod
    Posts: 9,422

    @RonJeffries The listProjectTab and readProjectTab code at the very beginning isn’t needed. Those are probably leftover from when I started.

  • Posts: 1,089

    yes, thought so. today's article is about your prog, check it out. let me know if i said anything bad.

  • dave1707dave1707 Mod
    Posts: 9,422

    @RonJeffries I like the article. Interesting to see how someone else would redo my code. Generally when I write something, I write something small to get it to work and then start expanding it until it does what I want. I never wrote any class code until I started playing with Codea. At work when I switched from C to C++, I was totally lost as to why anyone would want to use classes. I had newly hired programmers who learned C++ as their only language try to explain the purpose of classes to me, but for some reason it didn’t make sense. I now know the purpose, but still don’t use it that often.

    Here’s the companion program to the first one. It displays two columns on the screen. The left column shows “Classes defined within “. The right column shows “Instances created within ”. The titles are at the top of each column. Not sure if this is anymore useful or useless than the first. It was just something to write when I couldn’t think of anything else to do.

    -- find classes and instances of those classes
    
    function setup()
        parameter.action("list projects",listProj)
        parameter.text("project")
        parameter.action("search",srch)
        sTab={}
        dy=-80
        listProj()
    end
    
    function listProj()
        project=""
        sTab={}
        output.clear()
        tab=listProjects()
        for a,b in pairs(tab) do
            print(b)
        end
    end
    
    function srch()
        s,e=string.find(project,"\n")
        if s~=nil then
            project=string.sub(project,1,s-1)
        end
        textMode(CORNER)
        sTab={}
        iTab={}
        cls={}
        tab={}
        ins={}
        print("Find classes")
        findClasses()    
        for a,b in pairs(cls) do
            print("Find instances in "..b)
            findInstances("="..b.."(")
        end
        table.sort(sTab)
        viewer.mode=FULLSCREEN
        output.clear()
    end
    
    function draw()
        background(40, 40, 50)
        fill(255)
    
        if #sTab>0 then
            text("Classes defined within < tabs >",50,HEIGHT+50+dy)
            text("Instances created within < tabs >",WIDTH/2,HEIGHT+50+dy)
            text(project,300,HEIGHT+20+dy)
    
            cnt=0
            for _,a in pairs(sTab) do
                b=tab[a]
                cnt=cnt+1
                text("< "..a.." >",50,HEIGHT-cnt*20+dy)
                for c,d in pairs(b) do
                    cnt=cnt+1
                    text(d,50,HEIGHT-cnt*20+dy)
                end
                cnt=cnt+2
            end
    
            cnt=0
            for _,a in pairs(sTab) do
                b=iTab[a]
                if b~=nil and #iTab[a]>0 then
                    cnt=cnt+1
                    text("< "..a.." >",WIDTH/2,HEIGHT-cnt*20+dy)
                    for c,d in pairs(b) do
                        cnt=cnt+1
                        text(d,WIDTH/2+20,HEIGHT-cnt*20+dy)
                    end
                    cnt=cnt+2
                end
            end 
        end   
    end
    
    function touched(t)
        if t.state==BEGAN or t.state==MOVING then
            dy=dy+t.deltaY
            if dy<-80 then
                dy=-80
            end
        end
    end
    
    function findClasses()
        local r=listProjectTabs(project)
        for a,b in pairs(r) do
            local str=readProjectTab(project..":"..b)
            table.insert(tab,b)
            tab[b]={}
            table.insert(sTab,b)
            local b1=1
            local s,e=1,0
            while true do
                s,e=string.find(str,"\n",s)
                if s==nil then
                    break
                end
                local str1=leaveSpaces(0,string.sub(str,b1,e+1))
                local s1,e1=string.find(str1,"=class(",1,true)
                if s1~=nil then
                    table.insert(tab[b],"       "..string.sub(str,b1,e-1))
                    local s2,e2=string.find(str1,"=")
                    if s2~=nil then
                        table.insert(cls,string.sub(str1,1,e2-1))
                    end                
                end
                b1=e+1
                s=b1
            end
        end
    end
    
    function findInstances(class)
        local r=listProjectTabs(project)
        for a,b in pairs(r) do
            local str=readProjectTab(project..":"..b)
            if iTab[b]==nil then
                iTab[b]={}
            end
            local b1=1
            local s,e=1,0
            while true do
                s,e=string.find(str,"\n",s)
                if s==nil then
                    break
                end
                local str1=string.sub(str,b1,e+1)
                local str2=leaveSpaces(0,str1)
                local s1,e1=string.find(str2,class,1,true)
                if s1~=nil then 
                    local s2,e2=string.find(str1,"(",1,true)
                    table.insert(iTab[b],leaveSpaces(1,string.sub(str1,1,e2-1)))
                end
                b1=e+1
                s=b1
            end
        end
    end
    
    function leaveSpaces(nbr,str)   -- nbr spaces between words in str (0 or 1)
        local str1=""
        local sp=0
        for z=1,#str do
            local c=string.sub(str,z,z)
            if c~=" " then
                sp=0
                str1=str1..c
            elseif sp<nbr then
                sp=sp+1
                str1=str1..c
            end
        end
        return str1
    end
    
  • Posts: 1,089

    cool, i'll check it out right now!

  • edited May 25 Posts: 1,089

    interesting trick with leaveSpaces(0). Evil, but works. i'd have done that the hard way, i think.

  • dave1707dave1707 Mod
    edited May 26 Posts: 9,422

    @RonJeffries Enjoying your article. Nice having someone pointing out my sloppy coding which I do mostly by choice. I hate coming up with long variable names, hence my 1 or 2 character names. One thing I’d like you to mention in your writings so that everyone reading them don’t think that I’m such a terrible coder, is that I write all of my code while I’m watching TV. There’s no pre-planning for my programs and most of the time no planning in what I’m actually writing. That’s why you’ll sometimes find code that doesn’t need to be there. It was something I was trying and forgot to remove it. If it works, it goes in the code. A comment on TV will remind me of something or if I see someone make a comment on the forum, I’ll think that might be an interesting program and start writing. Anyways, I’m interested to see how well you’ll condense my code and make it more readable and understandable.

  • Posts: 1,089

    i'll do that. it's not bad code, as i've tried to say a couple of times. just not to my liking. :smile:

  • dave1707dave1707 Mod
    Posts: 9,422

    @RonJeffries I didn’t mean to say that you think my code is bad. Well, it is bad from a readability point of view. My meaningless variable names, and everything packed into large function. Half the time when I look a my code I don’t know what’s happening. It takes awhile to figure it out. We have different coding styles and I like yours better than mine. I write quick code, so I don’t plan it very well. I just write it to get the job done with no plans to expand on it at a later time. Interested to see how your version turns out.

  • dave1707dave1707 Mod
    Posts: 9,422

    @RonJeffries Liked your latest article. I also like the approach you did about removing the comments from the code before parsing thru it. The only problem is the multi line comment can take on various forms. See the example below. If there are nested multi line comments, a matching number of = can be placed between the beginning and ending square brackets. Not sure what the max number of = are. The line that would kill a normal multi line comment would be something like
    a=b[c[d]] . The = in [[ works to ignore that and other multi line comments.

    function setup()
        --[=[
        print("aaa")
        b={2,4,6,8}
        c={1,2,3}
        d=2
        --[[
        print("comment 1")
        print("comment 2")
        --]]
        a=b[c[d]]
        print("a",a)
        print("yy")    
        --]=]
    end
    
  • Posts: 1,089

    yes. i should have mentioned that i'm consciously ignoring some cases of the multi-line thing. i don't recall, does your original deal with those properly?

  • dave1707dave1707 Mod
    Posts: 9,422

    @RonJeffries My original code doesn’t deal with them. I never used the = sign with the multi line comment, so I didn’t look for it. My programs don’t usually cover all possibilities of problems, I just get them to work on normal things. A lot of my code is never seen except by me so I just code for what I need.

  • Posts: 1,089

    yes, i feel much the same, esp with tools like these

  • dave1707dave1707 Mod
    Posts: 9,422

    @RonJeffries Just finished reading your latest article. Two things I’d like to mention.

    The first is with the multi line comments with the = signs. I don’t know how many people will nest comments, but my immediate use is trying to comment out a function that contains a line of code similar to a = b[c[d]] or something that has ]] . The ]] will mess up the multi line comment. By using the = sign in the multi line comment, you can successfully comment out a function containing that line of code.

    The second has to do with my second program. When I list all the projects in the print area, if you tap on one of the project names, you’ll notice that it’s background will darken more. Then if you long press in the parameter Project text area, you’ll get a paste option. Tapping paste, that project name will be copied there. Then you’ll have to press backspace to get rid of the new line character so the project name is just one line. So you don’t have to type the name there.

    Just so you know, I have a bookmark to your articles. Every now and then I just pop in and read some of what you’re doing.

  • edited May 29 Posts: 1,089

    yes ... i haven't needed the nested comments but i am confident the program handles them correctly now. i hadn't thought of the copy paste but makes sense. i'm glad you check out the articles and hope you find them amusing if not valuable :wink:

Sign In or Register to comment.