Giter VIP home page Giter VIP logo

ast's People

Contributors

abargnesi avatar adesnmi avatar akimd avatar alexdowad avatar gogainda avatar iliabylich avatar jethrodaniel avatar juanitofatas avatar leoarnold avatar marcandre avatar mbj avatar pocke avatar rattrayalex avatar tas50 avatar teliosdev avatar walf443 avatar whitequark avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ast's Issues

Local properties are not propagated

Hi,
There's a pattern that the library does not seem to support well: processors that label some nodes with properties. Indeed, when a parent node is updated with children equal in value, but different in properties, then we still use the original parent node instead of building it again with the new children. As a consequence we drop the property from the children and go back to the original node. That's the behavior of Node#updated

if @type == new_type &&

which relies on @children == new_children, which does not take the properties into account.

The following toy example demonstrates the problem.

require 'ast'

class ArithmeticsProcessor
  include AST::Processor::Mixin
  def on_integer(node)
    node.updated(nil, nil, {line: 42})
  end

  def on_add(node)
    node.updated(nil, process_all(node))
  end
end

include AST::Sexp
expr = s(:add, s(:integer, 2), s(:integer, 2))
res = ArithmeticsProcessor.new.process(expr)
p res.children[0].instance_variables

When run, we get [:@children, :@type, :@hash], i.e., the line property of the integer was dropped.

Is this the intended behavior?

Adding/ removing child nodes in existing AST

For a project I need some code duplication for a ruby file as described below. I'm using the parser project where it's using code from this repo. I seem to run into an issue with appending to an existing children array/ list.
Perhaps someone can help me clarify how the AST::Node function updated works. Because I cannot seem to get the children list appended.

def some_function
  @a = "a"
end
def here_s_another_one
  @b = "b"
end
# result of duplicating child (what I want to achieve):
def some_function
  @a = "a"
end
def here_s_another_one
  @b = "b"
end
def some_function
  @a = "a"
end

I have found the AST::Node def updated() on line 121, but when I try to insert a copy of the example module A, It is not appended/ concatenated. Code snippet below:

file_contents = File.read(filename)
p = Parser::CurrentRuby.parse(file_contents)
src = p.children[0]
p.concat(src)
file_contents = Unparser.unparse(p)
File.write(filename, file_contents)

However, when I remove the children.to_a.freeze in the AST::Node def initialize() found here, I'm able to mutate the children list directly. Like shown below, without the modification it prints an error: can't modify frozen Array.

file_contents = File.read(filename)
p = Parser::CurrentRuby.parse(file_contents)
src = p.children[0]
p.children << src
file_contents = Unparser.unparse(p)
File.write(filename, file_contents)

PS. Without the freeze, the tests for AST seem to run perfectly (apart from should be frozen). So I wonder why you've decided to implement it like this.

How to get the parent of a node?

Hi,

I am using the AST class together with the Parser gem. I am looking for a way to traverse up the AST from a given node, i.e., given a node, I want to access its parent. Any suggestions on how I can do this?

Thank you,
LN

each and first

I seem to be writing a lot of node.to_a.each
would you accept an each on node?

Similarly, the multi-assignment works well for multiples . Often i have just a single value, so the choice seems to be node.to_a.first or (slightly more expressive) node.children.first
Both of which seem long, so i already have a first function on node, do you want that ?

How do you handle node references?

Some processing, such as typing, are easier to deal with when you install references from uses to definitions. Typically, I first traverse my tree, paying attention to scopes, and binding local variable uses to their corresponding variable definition. This is super handy in later traversals, as you can very easily recover any meta-data left on the variable definition wherever you have a variable use.

However, since this library enforces an immutable approach, this pattern is very fragile: if I merely add an annotation to some variable definition, I'll get a completely different object, and all my bindings will be incorrectly pointing to the old version.

Is there a recommended pattern to handle such cross-node references? I'm used to imperative style ASTs (where this is straightforward), and I feel kind of stupid here :-(

#inspect should return valid Ruby code

Instead of this:

(str "hello")

The method AST::Node#inspect should return the following instead:

s(:str, "hello")

This makes it possible to directly copy-paste the output and run it (assuming the #s() method is defined).

process context

So, i am moving on to processing the ast with the Processor.
Alas, in my current compiler, i use a context that is passed to the transformation, for side effects.

Basically whatever i pass to the process method as a second parameter, ie

process(node , context)

i would need to be passed through to the on_xx as the second parameter, eg

on_xxx(node , context)

The process function could have the context = nil default and if nil, the nil would not be passed on
to the on_xx. That way existing code wouldn't break.

Also, i think one arg will be the extent of the change, as one can always use a hash or something if one actually needs more.

Any chance you would accept a pull for this, or shall i just stick with my own processor.

debug inspect

great stuff , thanks.

This just reduced my 10 (hand coded ast-) classes to nothing. Great :-)

In doing that i was obviously using the handy s() function. But also i wrote a modified Node.inspect
that gets included with the s() and prints out the node in the exact same way as the code needs it.

The effect being that one can copy paste the failed test output as an expected result (it's ruby code, yeah)

I found that very handy and could make a pull request. Code is here https://github.com/dancinglightning/ast/commit/fdb4d8cb7a36601d76750dab658893e30e85c8c9

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.