Search code examples
compiler-constructionnestedinterpreter

Is there any opensource interpreter implementation with static parents (static links)?


I'm interested in implementing my own language interpreter. According to chapter 10 in "Concepts of Programming Languages" by Sebesta, a new ARI (active record instance) is filled with a static parent when the programming language allows nested functions like this;

f(){
   int x;
   g() { int y = x+1; ..}        // definition of g

   k(t)  {                       // definition of k
           h(t) { t();..}        // definition of h... it calls g() via t()
           h(t);                 // this will call g();
   } 

   k(g);                         // this will call h() with g

}

In this simple example, when g is called, a new ARI for g is created, and the static link of this ARI is fed with f's ARI, previously existing in the runtime stack.

But it's hard for me to clearly understand how to determine static parents of ARIs "at runtime." The simplest approach is searching all over the runtime stack until we find the existing ARI of the static parent, but they say it's not an efficient way. So I'd like to try the better option, which is "navigating along caller's static ancestors." (The book says we can achieve this by following the static links from caller's static link.)

In above the example, when g() is invoked from h() via t(), we first go to caller h()'s static parent's ARI, and again go to the static parent of that ARI and so on, until we meet f()'s ARI. Thus we will follow the chains of h-k-f's ARIs in this example. (We would follow longer chains of ARI links for deeper nesting.)

So my questions are;

  • Is there any of actual interpreters and compilers for a commonly used language with nested functions, like JavaScript, which is using the static link for each ARI in above the (less simple) way?
  • If so, is there any way to check the source code of the interpreter/compiler to see how it works?

Thanks for any helps.


Solution

  • Here is a translation of your code to Lua:

    function f()
        local x = 0
        local function g () 
            local y = x+1
            -- etc
        end
        local function k (t)  
            local function h (t) 
                t()
                -- etc.
            end
            h(t)
        end
        k(g)
    end
    

    Here is another version that returns values so we can demonstrate that it runs:

    function f()
        local x = 0
        local function g () 
            local y = x+1
            return y
        end
        local function k (t)  
            local function h (t) 
                return t()
            end
            return h(t)
        end
        return k(g)
    end
    

    and a test:

    > =f()
    1
    > 
    

    See The Implementation of Lua 5.0 by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, and Waldemar Celes, especially section 5, Functions and Closures.

    You can see the Lua annotated source code for version 5.1.4, or canonical source code for Lua 5.3.x.