unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* progress on my NYACC javascript example complier
@ 2017-06-02 23:56 Matt Wette
  2017-06-03  1:52 ` Nala Ginrut
  0 siblings, 1 reply; 2+ messages in thread
From: Matt Wette @ 2017-06-02 23:56 UTC (permalink / raw)
  To: Guile User

I started working on NYACC documentation and that got me on cleaning up the example (but very incomplete) javascript example.  This example uses an architecture where syntax trees emitted from the parser are in SXML format.  From there I use foldts*-values (developed by Andy Wingo) to convert to Tree-IL and from there the Guile compiler tower takes over.  This effort is my sandbox for getting familiar with all tools and techniques.  I have no plan to implement everything.

foldts*-values allows me to trap new scope on the way down the tree: I push scope levels there and update the symbol table if needed.  On the way down I also pick off simple constructs (e.g., constants and identifiers).  Also, on the way down, I splice in javascript Blocks to track scope of new variables introduced by JavaScript variable declarations.  On the way up, the trees are converted to Tree-IL.

The top-level variables live in the default module scope, so I can call Guile procedures and Guile can make use of top-level functions defined in the Javascript.  The following is an example from “JavaScript, The Definitive Guide” in which a closure is used to provide a function that has a private var to generate incrementing numeric identifiers.  What you see below is
1) the javascript code
2) the output of running this in Guile
3) the SXML syntax tree emitted from the parser
4) the tree-il syntax tree emitted from the compiler

var uid = (function() { var id = 0; return function () { return id++; };})();
display(uid()); newline();
display(uid()); newline();
display(uid()); newline();
display(uid()); newline();

=> 

0
1
2
3
#<unspecified>

SXML:
(Program
  (SourceElements
    (VariableStatement
      (VariableDeclarationList
        (VariableDeclaration
          (Identifier "uid")
          (Initializer
            (CallExpression
              (FunctionExpression
                (FormalParameterList)
                (SourceElements
                  (VariableStatement
                    (VariableDeclarationList
                      (VariableDeclaration
                        (Identifier "id")
                        (Initializer
                          (PrimaryExpression (NumericLiteral "0"))))))
                  (ReturnStatement
                    (FunctionExpression
                      (FormalParameterList)
                      (SourceElements
                        (ReturnStatement
                          (post-inc
                            (PrimaryExpression (Identifier "id")))))))))
              (ArgumentList))))))
    (EmptyStatement)
    (ExpressionStatement
      (CallExpression
        (PrimaryExpression (Identifier "display"))
        (ArgumentList
          (CallExpression
            (PrimaryExpression (Identifier "uid"))
            (ArgumentList)))))
    (ExpressionStatement
      (CallExpression
        (PrimaryExpression (Identifier "newline"))
        (ArgumentList)))
    (EmptyStatement)
    (ExpressionStatement
      (CallExpression
        (PrimaryExpression (Identifier "display"))
        (ArgumentList
          (CallExpression
            (PrimaryExpression (Identifier "uid"))
            (ArgumentList)))))
    (ExpressionStatement
      (CallExpression
        (PrimaryExpression (Identifier "newline"))
        (ArgumentList)))
    (EmptyStatement)
    (ExpressionStatement
      (CallExpression
        (PrimaryExpression (Identifier "display"))
        (ArgumentList
          (CallExpression
            (PrimaryExpression (Identifier "uid"))
            (ArgumentList)))))
    (ExpressionStatement
      (CallExpression
        (PrimaryExpression (Identifier "newline"))
        (ArgumentList)))
    (EmptyStatement)
    (ExpressionStatement
      (CallExpression
        (PrimaryExpression (Identifier "display"))
        (ArgumentList
          (CallExpression
            (PrimaryExpression (Identifier "uid"))
            (ArgumentList)))))
    (ExpressionStatement
      (CallExpression
        (PrimaryExpression (Identifier "newline"))
        (ArgumentList)))
    (EmptyStatement)))


tree-il:
  (begin
    (begin
      (define uid
        (apply (lambda ()
                 (lambda-case
                   ((() #f @args #f () (JS~6715))
                    (prompt
                      (const return)
                      (begin
                        (let (id)
                          (JS~6716)
                          ((const 0))
                          (begin
                            (lambda ()
                              (lambda-case
                                ((() #f @args #f () (JS~6718))
                                 (prompt
                                   (const return)
                                   (begin
                                     (let (~ref)
                                       (JS~6719)
                                       ((lexical id JS~6716))
                                       (begin
                                         (set! (lexical id JS~6716)
                                           (apply (@@ (nyacc lang javascript jslib)
                                                      js:+)
                                                  (const 1)
                                                  (lexical ~ref JS~6719)))
                                         (lexical ~ref JS~6719))))
                                   (lambda-case
                                     (((tag val) #f #f #f () (JS~6720 JS~6721))
                                      (lexical val JS~6721))))))))))
                      (lambda-case
                        (((tag val) #f #f #f () (JS~6722 JS~6723))
                         (lexical val JS~6723))))))))))
    (apply (@@ (guile-user) display)
           (apply (toplevel uid)))
    (apply (@@ (guile-user) newline))
    (apply (@@ (guile-user) display)
           (apply (toplevel uid)))
    (apply (@@ (guile-user) newline))
    (apply (@@ (guile-user) display)
           (apply (toplevel uid)))
    (apply (@@ (guile-user) newline))
    (apply (@@ (guile-user) display)
           (apply (toplevel uid)))
    (apply (@@ (guile-user) newline)))



^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: progress on my NYACC javascript example complier
  2017-06-02 23:56 progress on my NYACC javascript example complier Matt Wette
@ 2017-06-03  1:52 ` Nala Ginrut
  0 siblings, 0 replies; 2+ messages in thread
From: Nala Ginrut @ 2017-06-03  1:52 UTC (permalink / raw)
  To: Matt Wette; +Cc: Guile User

Hi Matt!
Thanks for working on that. It's really cool!

IMO, translate AST to tree-il simply is not enough to implement
spec-compatible front-end for most of real languages. They just looks like
JS/Lua/Python, but not them at all. This conclusion is from my experience
on developing guile-lua-rebirth.

The real implementation needs to do far more than simple translator. But
provide spec-compatible AST is relative easier, then let anyone who
interested in compiler hacking try their luck.

Another common concern is that Guile IR may not suitable for non-FP
languages. But IMO, the CPS is general enough for any turing-complete
language. People may thought SSA is required for imperitive languages, but
I don't think so, actually Appel had a paper to prove SSA is kind of FP
language too. And all these intermediate representations: SSA, CPS, ANF,
sequent-caculus ... are equivalent. The difference is the expressiveness.
Just like the difference between functional and imperitive language.

People may concern that GuileVM is not general enough for any languages.
But it is improvable if we can figure out what is missing in the current VM
implementation. No mention Guile is going for native code generating in the
future.




2017年6月3日 上午7:57,"Matt Wette" <matt.wette@gmail.com>写道:

> I started working on NYACC documentation and that got me on cleaning up
> the example (but very incomplete) javascript example.  This example uses an
> architecture where syntax trees emitted from the parser are in SXML
> format.  From there I use foldts*-values (developed by Andy Wingo) to
> convert to Tree-IL and from there the Guile compiler tower takes over.
> This effort is my sandbox for getting familiar with all tools and
> techniques.  I have no plan to implement everything.
>
> foldts*-values allows me to trap new scope on the way down the tree: I
> push scope levels there and update the symbol table if needed.  On the way
> down I also pick off simple constructs (e.g., constants and identifiers).
> Also, on the way down, I splice in javascript Blocks to track scope of new
> variables introduced by JavaScript variable declarations.  On the way up,
> the trees are converted to Tree-IL.
>
> The top-level variables live in the default module scope, so I can call
> Guile procedures and Guile can make use of top-level functions defined in
> the Javascript.  The following is an example from “JavaScript, The
> Definitive Guide” in which a closure is used to provide a function that has
> a private var to generate incrementing numeric identifiers.  What you see
> below is
> 1) the javascript code
> 2) the output of running this in Guile
> 3) the SXML syntax tree emitted from the parser
> 4) the tree-il syntax tree emitted from the compiler
>
> var uid = (function() { var id = 0; return function () { return id++;
> };})();
> display(uid()); newline();
> display(uid()); newline();
> display(uid()); newline();
> display(uid()); newline();
>
> =>
>
> 0
> 1
> 2
> 3
> #<unspecified>
>
> SXML:
> (Program
>   (SourceElements
>     (VariableStatement
>       (VariableDeclarationList
>         (VariableDeclaration
>           (Identifier "uid")
>           (Initializer
>             (CallExpression
>               (FunctionExpression
>                 (FormalParameterList)
>                 (SourceElements
>                   (VariableStatement
>                     (VariableDeclarationList
>                       (VariableDeclaration
>                         (Identifier "id")
>                         (Initializer
>                           (PrimaryExpression (NumericLiteral "0"))))))
>                   (ReturnStatement
>                     (FunctionExpression
>                       (FormalParameterList)
>                       (SourceElements
>                         (ReturnStatement
>                           (post-inc
>                             (PrimaryExpression (Identifier "id")))))))))
>               (ArgumentList))))))
>     (EmptyStatement)
>     (ExpressionStatement
>       (CallExpression
>         (PrimaryExpression (Identifier "display"))
>         (ArgumentList
>           (CallExpression
>             (PrimaryExpression (Identifier "uid"))
>             (ArgumentList)))))
>     (ExpressionStatement
>       (CallExpression
>         (PrimaryExpression (Identifier "newline"))
>         (ArgumentList)))
>     (EmptyStatement)
>     (ExpressionStatement
>       (CallExpression
>         (PrimaryExpression (Identifier "display"))
>         (ArgumentList
>           (CallExpression
>             (PrimaryExpression (Identifier "uid"))
>             (ArgumentList)))))
>     (ExpressionStatement
>       (CallExpression
>         (PrimaryExpression (Identifier "newline"))
>         (ArgumentList)))
>     (EmptyStatement)
>     (ExpressionStatement
>       (CallExpression
>         (PrimaryExpression (Identifier "display"))
>         (ArgumentList
>           (CallExpression
>             (PrimaryExpression (Identifier "uid"))
>             (ArgumentList)))))
>     (ExpressionStatement
>       (CallExpression
>         (PrimaryExpression (Identifier "newline"))
>         (ArgumentList)))
>     (EmptyStatement)
>     (ExpressionStatement
>       (CallExpression
>         (PrimaryExpression (Identifier "display"))
>         (ArgumentList
>           (CallExpression
>             (PrimaryExpression (Identifier "uid"))
>             (ArgumentList)))))
>     (ExpressionStatement
>       (CallExpression
>         (PrimaryExpression (Identifier "newline"))
>         (ArgumentList)))
>     (EmptyStatement)))
>
>
> tree-il:
>   (begin
>     (begin
>       (define uid
>         (apply (lambda ()
>                  (lambda-case
>                    ((() #f @args #f () (JS~6715))
>                     (prompt
>                       (const return)
>                       (begin
>                         (let (id)
>                           (JS~6716)
>                           ((const 0))
>                           (begin
>                             (lambda ()
>                               (lambda-case
>                                 ((() #f @args #f () (JS~6718))
>                                  (prompt
>                                    (const return)
>                                    (begin
>                                      (let (~ref)
>                                        (JS~6719)
>                                        ((lexical id JS~6716))
>                                        (begin
>                                          (set! (lexical id JS~6716)
>                                            (apply (@@ (nyacc lang
> javascript jslib)
>                                                       js:+)
>                                                   (const 1)
>                                                   (lexical ~ref JS~6719)))
>                                          (lexical ~ref JS~6719))))
>                                    (lambda-case
>                                      (((tag val) #f #f #f () (JS~6720
> JS~6721))
>                                       (lexical val JS~6721))))))))))
>                       (lambda-case
>                         (((tag val) #f #f #f () (JS~6722 JS~6723))
>                          (lexical val JS~6723))))))))))
>     (apply (@@ (guile-user) display)
>            (apply (toplevel uid)))
>     (apply (@@ (guile-user) newline))
>     (apply (@@ (guile-user) display)
>            (apply (toplevel uid)))
>     (apply (@@ (guile-user) newline))
>     (apply (@@ (guile-user) display)
>            (apply (toplevel uid)))
>     (apply (@@ (guile-user) newline))
>     (apply (@@ (guile-user) display)
>            (apply (toplevel uid)))
>     (apply (@@ (guile-user) newline)))
>
>


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2017-06-03  1:52 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-02 23:56 progress on my NYACC javascript example complier Matt Wette
2017-06-03  1:52 ` Nala Ginrut

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).