From d38ad5ba3ee3677c4d00213fc93497f9031cba08 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Fri, 19 May 2023 19:00:15 +0200 Subject: fix rss --- feed.xml | 76 ++++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 41 insertions(+), 35 deletions(-) (limited to 'feed.xml') diff --git a/feed.xml b/feed.xml index 9f20111..4cc1f28 100644 --- a/feed.xml +++ b/feed.xml @@ -3,14 +3,19 @@ Marc's Programming Notes https://marc.vertes.org/ + A blog about programming -Thu, 18 May 2023 19:05:48 +0200 +mvertes@free.fr (Marc Vertes) +Fri, 19 May 2023 18:59:21 +0200 +https://marc.vertes.org/yaegi-internals/ Yaegi Internals https://marc.vertes.org/yaegi-internals/ Design and implementation of a Go interpreter +mvertes@free.fr (Marc Vertes) Wed, 03 May 2023 12:00:00 +0200 -Yaegi internals + +Yaegi internals

Yaegi is an interpreter of the Go language written in Go. This project was started in Traefik-Labs initially to provide a simple and practical embedded @@ -36,7 +41,7 @@ overview.

Overview of architecture

Let’s see what happens inside yaegi when one executes the following line:

-
interp.Eval(`print("hello", 2+3)`)
+
interp.Eval(`print("hello", 2+3)`)

The following figure 1 displays the main steps of evaluation:

interpreter or other language tool, and the function to use it (extracted from here).

-
// node defines a node of a (abstract syntax) tree.
-type node struct {
-    // Node children
-    child []*node
-    // Node metadata
-    ...
-}
-
-// walk traverses AST n in depth first order, invoking in function
-// at node entry and out function at node exit.
-func (n *node) walk(in func(n *node) bool, out func(n *node)) {
-    if in != nil && !in(n) {
-        return
-    }
-    for _, child := range n.child {
-        child.Walk(in, out)
-    }
-    if out != nil {
-        out(n)
-    }
-}
+
// node defines a node of a (abstract syntax) tree.
+type node struct {
+    // Node children
+    child []*node
+    // Node metadata
+    ...
+}
+
+// walk traverses AST n in depth first order, invoking in function
+// at node entry and out function at node exit.
+func (n *node) walk(in func(n *node) bool, out func(n *node)) {
+    if in != nil && !in(n) {
+        return
+    }
+    for _, child := range n.child {
+        child.Walk(in, out)
+    }
+    if out != nil {
+        out(n)
+    }
+}

The above code is deceptively simple. As in many complex systems, an important part of the signification is carried by the relationships between the elements and the patterns they form. It’s easier to understand it by displaying the corresponding graph and consider the system as a whole. We can do that using a simple example:

-
a := 3
-if a > 2 {
-    print("ok")
-}
-print("bye")
+
a := 3
+if a > 2 {
+    print("ok")
+}
+print("bye")

The corresponding AST is:

figure 2: a raw AST @@ -202,11 +207,11 @@ step, a full interpretation can still be necessary on an expression sub-tree if this one serves to implement a global type definition. For example if an array size is computed by an expression as in the following valid Go declarations:

-
const (
-    prefix = "/usr"
-    path   = prefix + "/local/bin"
-)
-var a [len(prefix+path) + 2]int
+
const (
+    prefix = "/usr"
+    path   = prefix + "/local/bin"
+)
+var a [len(prefix+path) + 2]int

A paradox is that the compiler needs an interpreter to perform the type analysis! Indeed, in the example above, [16]int (because len(prefix+path) + 2 = 16) is a specific type in @@ -384,7 +389,8 @@ in a next article:

P.S. Thanks to @lejatorn for his feedback and suggestions on this post.

-]]> +
From: Marc Vertes, 03 may 2023]]> + -- cgit v1.2.3