Git Product home page Git Product logo

cry's Introduction

Cry

A CommonLisp CLOS-like parse tree library for Ruby… read (and write) it and weep.

For example, you could create a parse tree like so:

parse_tree = Cry::ParseTree.new(:+, 1, 3)

… then evaluate it:

parse_tree.evaluate # => 4

… You can also create and evaluate more complex parse trees:

Cry::ParseTree.new( :+, Cry::ParseTree.new( :+, 1, Cry::ParseTree.new(:*, 2, 2) ), Cry::ParseTree.new(:+, 1, 3) ).evaluate # => 9

Lineage

Cry::ParseTree just inherits from Array, so you can use all of Array’s convenient methods for manipulating your ParseTrees too.

Parameter order

The first parameter is the method as a String or Symbol, this never changes. The second parameter is the object that the method will be called on. This can either be a normal object, or an unevaluated Cry::ParseTree for delayed recursive evaluation. Any subsequent parameters can either be normal objects, or Cry::ParseTrees, and will be passed as arguments to the method call.

Usage

require 'cry'

Cry::ParseTree.new(:*, Cry::ParseTree.new(:+, 1, 3), 23).evaluate # => 92

This is similar to the following Lisp:

(* (+ 1 3) 23) # => 92 Take note that ParseTree’s second parameter is always your object (be it a class or not).

The method specified will be called on the object, similar to CLOS. To distinguish Cry::ParseTree objects from Arrays when using inspect, they are denoted by parentheses:

Cry::ParseTree.new(:<<, [1], 2).inspect # => "(:<<, [1], 2)"

Realize that you have access to all of Ruby, so you can do crazy things like this:

Cry::ParseTree.new(:instance_variable_set, self, ‘@parse_tree’, ‘Cry::ParseTree.new(:*, Cry::ParseTree.new(:+, 1, 3), 23).evaluate’).evaluate Cry::ParseTree.new(:eval, Kernel, @parse_tree).evaluate # => 92

Manipulation

The nice thing is that the parse trees are lazily evaluated. This means you can change them around before evaluations.

parse_tree = Cry::ParseTree.new(:+, 1, 3)

parse_tree.node_method # => :+
parse_tree.node_object # => 1
parse_tree.node_arguments # => [3]

parse_tree.node_method = :*
parse_tree.node_object = 2
parse_tree.node_arguments = [4]

parse_tree.evaluate # => 8

Also note that evaluate is not a destructive method.

parse_tree.evaluate # => 8
parse_tree.node_object = 3
parse_tree.evaluate # => 12

Blocks

To use methods that accept a block, just use a Proc for your last argument:

Cry::ParseTree.new(:inject, [1, 2, 3], 0, lambda{|sum, i| sum + i }).evaluate # => 6

Author

Author

Larry Diehl (larrytheliquid)

Website

larrytheliquid.com/2008/06/05/learn-to-cry-by-writing-parse-trees-in-ruby

cry's People

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.