Permalink
Browse files

Create gh-pages branch via GitHub

  • Loading branch information...
1 parent dc48def commit 6c01812a7d64751c12c0d80cf10ccdcd1aa2af3d @chriswailes committed Mar 25, 2014
View
BIN images/body-bg.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN images/highlight-bg.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN images/hr.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN images/octocat-icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN images/tar-gz-icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN images/zip-icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
826 index.html
430 additions, 396 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
1 javascripts/main.js
@@ -0,0 +1 @@
+console.log('This would be the main JS file.');
View
2 params.json
@@ -1 +1 @@
-{"name":"The Ruby Language Toolkit","tagline":"Everything you need to build a programming language in Ruby","body":"# Welcome to the Ruby Language Toolkit\r\n\r\nRLTK is a collection of classes and methods designed to help programmers work with languages in an easy to use and straightforward manner. This toolkit provides the following features:\r\n\r\n* Lexer generator\r\n* Parser generator\r\n* AST node baseclass\r\n* Class for representing context free grammars\r\n* [Low Level Virtual Machine](http://llvm.org) (LLVM) bindings for code generation\r\n\r\nIn addition, RLTK includes several ready-made lexers and parsers and a Turing-complete language called Kazoo for use in your code and as examples for how to use the toolkit.\r\n\r\n## Why Use RLTK\r\n\r\nHere are some reasons to use RLTK to build your lexers, parsers, and abstract syntax trees, as well as generating LLVM IR and native object files:\r\n\r\n* **Lexer and Parser Definitions in Ruby** - Many tools require you to write your lexer/parser definitions in their own format, which is then processed and used to generate Ruby code. RLTK lexers/parsers are written entirely in Ruby and use syntax you are already familiar with.\r\n\r\n* **Re-entrant Code** - The lexers and parsers generated by RLTK are fully re-entrant.\r\n\r\n* **Multiple Lexers and Parsers** - You can define as many lexers and parses as you want, and instantiate as many of them as you need.\r\n\r\n* **Token Positions** - Detailed information about a token's position is available in the parser.\r\n\r\n* **Feature Rich Lexing and Parsing** - Often, lexer and parser generators will try and force you to do everything their way. RLTK gives you more flexibility with features such as states and flags for lexers, and argument arrays for parsers. What's more, these features actually work (I'm looking at you REX).\r\n\r\n* **LALR(1)/GLR Parsing** - RLTK parsers use the LALR(1)/GLR parsing algorithms, which means you get both speed and the ability to handle **any** context-free grammar.\r\n\r\n* **Parser Serialization** - RLTK parsers can be serialized and saved after they are generated for faster loading the next time they are required.\r\n\r\n* **Error Productions** - RLKT parsers can use error productions to recover from, and report on, errors.\r\n\r\n* **Fast Prototyping** - If you need to change your lexer/parser you don't have to re-run the lexer and parser generation tools, simply make the changes and be on your way.\r\n\r\n* **Parse Tree Graphs** - RLTK parsers can print parse trees (in the DOT language) of accepted strings.\r\n\r\n* **Comprehensive LLVM Bindings** - RLTK provides bindings to all of the C LLVM bindings as well as some functionality that isn't present in the C LLVM bindings.\r\n\r\n* **The Contractor** - LLVM's method of building instructions is a bit cumbersome, and is very imperative in style. RLTK provides the Contractor class to make things easier.\r\n\r\n* **Documentation** - We have it!\r\n\r\n* **I Eat My Own Dog Food** - I'm using RLTK for my own projects so if there is a bug I'll most likely be the first one to know.\r\n\r\n## Lexers\r\n\r\nTo create your own lexer using RLTK you simply need to subclass the {RLTK::Lexer} class and define the *rules* that will be used for matching text and generating tokens. Here we see a simple lexer for a calculator:\r\n\r\n\tclass Calculator < RLTK::Lexer\r\n\t\trule(/\\+/)\t{ :PLS }\r\n\t\trule(/-/)\t{ :SUB }\r\n\t\trule(/\\*/)\t{ :MUL }\r\n\t\trule(/\\//)\t{ :DIV }\r\n\r\n\t\trule(/\\(/)\t{ :LPAREN }\r\n\t\trule(/\\)/)\t{ :RPAREN }\r\n\r\n\t\trule(/[0-9]+/)\t{ |t| [:NUM, t.to_i] }\r\n\r\n\t\trule(/\\s/)\r\n\tend\r\n\r\nThe {RLTK::Lexer.rule} method's first argument is the regular expression used for matching text. The block passed to the function is the action that executes when a substring is matched by the rule. These blocks must return the *type* of the token (which must be in ALL CAPS; see the Parsers section), and optionally a *value*. In the latter case you must return an array containing the *type* and *value*, which you can see an example of in the Calculator lexer shown above. The values returned by the proc object are used to build a {RLTK::Token} object that includes the *type* and *value* information, as well as information about the line number the token was found on, the offset from the beginning of the line to the start of the token, and the length of the token's text. If the *type* value returned by the proc is `nil` the input is discarded and no token is produced.\r\n\r\nThe {RLTK::Lexer} class provides both {RLTK::Lexer.lex} and {RLTK::Lexer.lex_file}. The {RLTK::Lexer.lex} method takes a string as its argument and returns an array of tokens, with an *end of stream* token automatically added to the result. The {RLTK::Lexer.lex_file} method takes the name of a file as input, and lexes the contents of the specified file.\r\n\r\n### The Lexing Environment\r\n\r\nThe proc objects passed to the {RLTK::Lexer.rule} methods are evaluated inside an instance of the {RLTK::Lexer::Environment} class. This gives you access to methods for manipulating the lexer's state and flags (see bellow). You can also subclass the environment inside your lexer to provide additional functionality to your rule blocks. When doing so you need to ensure that you name your new class Environment like in the following example:\r\n\r\n\tclass MyLexer < RLTK::Lexer\r\n\t\t...\r\n\t\t\r\n\t\tclass Environment < Environment\r\n\t\t\tdef helper_function\r\n\t\t\t\t...\r\n\t\t\tend\r\n\t\t\t\r\n\t\t\t...\r\n\t\tend\r\n\tend\r\n\r\n### Using States\r\n\r\nThe lexing environment may be used to keep track of state inside your lexer. When rules are defined they are defined inside a given state, which is specified by the second parameter to {RLTK::Lexer.rule}. The default state is cleverly named `:default`. When the lexer is scanning the input string for matching rules, it only considers the rules for the given state.\r\n\r\nThe methods used to manipulate state are:\r\n\r\n* **RLTK::Lexer::Environment.push_state** - Pushes a new state onto the stack.\r\n* **RLTK::Lexer::Environment.pop_state** - Pops a state off of the stack.\r\n* **RLTK::Lexer::Environment.set_state** - Sets the state at the top of the stack.\r\n* **RLTK::Lexer::Environment.state** - Returns the current state.\r\n\r\nStates may be used to easily support nested comments.\r\n\r\n\tclass StateLexer < RLTK::Lexer\r\n\t\trule(/a/)\t\t{ :A }\r\n\t\trule(/\\s/)\r\n\t\t\r\n\t\trule(/\\(\\*/)\t{ push_state(:comment) }\r\n\t\t\r\n\t\trule(/\\(\\*/, :comment)\t{ push_state(:comment) }\r\n\t\trule(/\\*\\)/, :comment)\t{ pop_state }\r\n\t\trule(/./, :comment)\r\n\tend\r\n\r\nBy default the lexer will start in the `:default` state. To change this, you may use the {RLTK::Lexer.start} method.\r\n\r\n### Using Flags\r\n\r\nThe lexing environment also maintains a set of *flags*. This set is manipulated using the following methods:\r\n\r\n* **RLTK::Lexer::Environment.set_flag** - Adds the specified flag to the set of flags.\r\n* **RLTK::Lexer::Environment.unset_flag** - Removes the specified flag from the set of flags.\r\n* **RLTK::Lexer::Environment.clear_flags** - Unsets all flags.\r\n\r\nWhen *rules* are defined they may use a third parameter to specify a list of flags that must be set before the rule is considered when matching substrings. An example of this usage follows:\r\n\r\n\tclass FlagLexer < RLTK::Lexer\r\n\t\trule(/a/)\t\t{ set_flag(:a); :A }\r\n\t\t\r\n\t\trule(/\\s/)\r\n\t\t\r\n\t\trule(/b/, :default, [:a]) { set_flag(:b); :B }\r\n\t\trule(/c/, :default, [:a, :b]) { :C }\r\n\tend\r\n\r\n### Instantiating Lexers\r\n\r\nIn addition to using the {RLTK::Lexer.lex} class method you may also instantiate lexer objects. The only difference then is that the lexing environment used between subsequent calls to {RLTK::Lexer#lex} is the same object, and therefor allows you to keep persistent state.\r\n\r\n### First and Longest Match\r\n\r\nA RLTK::Lexer may be told to select either the first substring that is found to match a rule or the longest substring to match any rule. The default behavior is to match the longest substring possible, but you can change this by using the {RLTK::Lexer.match_first} method inside your class definition as follows:\r\n\r\n\tclass MyLexer < RLTK::Lexer\r\n\t\tmatch_first\r\n\t\t\r\n\t\t...\r\n\tend\r\n\r\n### Match Data\r\n\r\nBecause it isn't RLTK's job to tell you how to write lexers and parsers, the MatchData object from a pattern match is available inside the Lexer::Environment object via the `match` accessor.\r\n\r\n## Parsers\r\n\r\nTo create a parser using RLTK simply subclass RLTK::Parser, define the productions of the grammar you wish to parse, and call `finalize`. During finalization RLTK will build an LALR(1) parsing table, which may contain conflicts that can't be resolved with LALR(1) lookahead sets or precedence/associativity information. Traditionally, when parser generators such as **YACC** encounter conflicts during parsing table generation they will resolve shift/reduce conflicts in favor of shifts and reduce/reduce conflicts in favor of the production that was defined first. This means that the generated parsers can't handle ambiguous grammars.\r\n\r\nRLTK parsers, on the other hand, can handle *all* context-free grammars by forking the parse stack when shift/reduce or reduce/reduce conflicts are encountered. This method is called the GLR parsing algorithm and allows the parser to explore multiple different possible derivations, discarding the ones that don't produce valid parse trees. GLR parsing is more expensive, in both time and space requirements, but these penalties are only payed when a parser for an ambiguous grammar is given an input with multiple parse trees, and as such most parsing should proceed using the faster LALR(1) base algorithm.\r\n\r\n### Defining a Grammar\r\n\r\nLet us look at the simple prefix calculator included with RLTK:\r\n\r\n\tclass PrefixCalc < RLTK::Parser\r\n\t\tproduction(:e) do\r\n\t\t\tclause('NUM') {|n| n}\r\n\t\t\t\r\n\t\t\tclause('PLS e e') { |_, e0, e1| e0 + e1 }\r\n\t\t\tclause('SUB e e') { |_, e0, e1| e0 - e1 }\r\n\t\t\tclause('MUL e e') { |_, e0, e1| e0 * e1 }\r\n\t\t\tclause('DIV e e') { |_, e0, e1| e0 / e1 }\r\n\t\tend\r\n\t\t\r\n\t\tfinalize\r\n\tend\r\n\r\nThe parser uses the same method for defining productions as the {RLTK::CFG} class. In fact, the parser forwards the {RLTK::Parser.production} and {RLTK::Parser.clause} method invocations to an internal {RLTK::CFG} object after removing the parser specific information. To see a detailed description of grammar definitions please read the Context-Free Grammars section bellow.\r\n\r\nIt is important to note that the proc objects associated with productions should evaluate to the value you wish the left-hand side of the production to take.\r\n\r\nThe default starting symbol of the grammar is the left-hand side of the first production defined (in this case, _e_). This can be changed using the {RLTK::Parser.start} function when defining your parser.\r\n\r\n**Make sure you call `finalize` at the end of your parser definition, and only call it once.**\r\n\r\n### Shortcuts\r\n\r\nRLTK provides several shortcuts for common grammar constructs. Right now these shortcuts include the {RLTK::Parser.empty_list} and {RLTK::Parser.nonempty_list} methods. An empty list is a list that may contain 0, 1, or more elements, with an optional token or tokens seperating each element. A non-empty list contains **at least** 1 element. An empty list with only a single list element and an empty separator is equivelent to the Kleene star. Simillarly, a nonempty list with only a single list element and an empty separator is equivelent to the Kleene plus.\r\n\r\nThis example shows how these shortcuts may be used to define a list of integers separated by a `:COMMA` token:\r\n\r\n\tclass ListParser < RLTK::Parser\r\n\t\tnonempty_list(:int_list, :INT, :COMMA)\r\n\t\t\r\n\t\tfinalize\r\n\tend\r\n\r\nIf you wanted to define a list of floats or integers you could define your parser like this:\r\n\r\n\tclass ListParser < RLTK::Parser\r\n\t\tnonempty_list(:mixed_list, [:INT, :FLOAT], :COMMA)\r\n\t\t\r\n\t\tfinalize\r\n\tend\r\n\r\nIf you don't want to require a separator you can do this:\r\n\r\n\tclass ListParser < RLTK::Parser\r\n\t\tnonempty_list(:mixed_nonsep_list, [:INT, :FLOAT])\r\n\t\t\r\n\t\tfinalize\r\n\tend\r\n\r\nYou can also use separators that are made up of multiple tokens:\r\n\r\n\tclass ListParser < RLTK::Parser\r\n\t\tnonempty_list(:mixed_nonsep_list, [:INT, :FLOAT], 'COMMA NEWLINE?')\r\n\t\t\r\n\t\tfinalize\r\n\tend\r\n\r\nA list may also contain multiple tokens between the separator:\r\n\r\n\tclass ListParser < RLTK::Parser\r\n\t\tnonempty_list(:foo_bar_list, 'FOO BAR', :COMMA)\r\n\t\t\r\n\t\tfinalize\r\n\tend\r\n\r\nLastly, you can mix all of these features together:\r\n\r\n\tclass ListParser < RLTK::Parser\r\n\t\tnonempty_list(:foo_list, ['FOO BAR', 'FOO BAZ+'], :COMMA)\r\n\t\t\r\n\t\tfinalize\r\n\tend\r\n\r\nThe productions generated by these shortcuts will always evaluate to an array. In the first two examples above the productions will produce a 1-D array containing the values of the `INT` or `FLOAT` tokens. In the last two examples the productions `foo_bar_list` and `foo_list` will produce 2-D arrays where the top level array is composed of tuples coresponding to the values of `FOO`, and `BAR` or one or more `BAZ`s.\r\n\r\n### Precedence and Associativity\r\n\r\nTo help you remove ambiguity from your grammars RLTK lets you assign precedence and associativity information to terminal symbols. Productions then get assigned precedence and associativity based on either the last terminal symbol on the right-hand side of the production, or an optional parameter to the {RLTK::Parser.production} or {RLTK::Parser.clause} methods. When an {RLTK::Parser} encounters a shift/reduce error it will attempt to resolve it using the following rules:\r\n\r\n1. If there is precedence and associativity information present for all reduce actions involved and for the input token we attempt to resolve the conflict using the following rule. If not, no resolution is possible and the parser generator moves on. This conflict will later be reported to the programmer.\r\n\r\n2. The precedence of the actions involved in the conflict are compared (a shift action's precedence is based on the input token), and the action with the highest precedence is selected. If two actions have the same precedence the associativity of the input symbol is used: left associativity means we select the reduce action, right associativity means we select the shift action, and non-associativity means that we have encountered an error.\r\n\r\nTo assign precedence to terminal symbols you can use the {RLTK::Parser.left}, {RLTK::Parser.right}, and {RLTK::Parser.nonassoc} methods inside your parser class definition. Later declarations of associativity have higher levels of precedence than earlier declarations of the same associativity.\r\n\r\nLet's look at the infix calculator example now:\r\n\r\n\tclass InfixCalc < Parser\r\n\t\t\r\n\t\tleft :PLS, :SUB\r\n\t\tright :MUL, :DIV\r\n\t\t\r\n\t\tproduction(:e) do\r\n\t\t\tclause('NUM') { |n| n }\r\n\t\t\t\r\n\t\t\tclause('LPAREN e RPAREN') { |_, e, _| e }\r\n\t\t\t\r\n\t\t\tclause('e PLS e') { |e0, _, e1| e0 + e1 }\r\n\t\t\tclause('e SUB e') { |e0, _, e1| e0 - e1 }\r\n\t\t\tclause('e MUL e') { |e0, _, e1| e0 * e1 }\r\n\t\t\tclause('e DIV e') { |e0, _, e1| e0 / e1 }\r\n\t\tend\r\n\t\t\r\n\t\tfinalize\r\n\tend\r\n\r\nHere we use associativity information to properly deal with the different precedence of the addition, subtraction, multiplication, and division operators. The PLS and SUB terminals are given left associativity with precedence of 1 (by default all terminals and productions have precedence of zero, which is to say no precedence), and the MUL and DIV terminals are given right associativity with precedence of 1.\r\n\r\n### Argument Passing for Actions\r\n\r\nBy default the proc objects associated with productions are passed one argument for each symbol on the right-hand side of the production. This can lead to long, unwieldy argument lists. To change this behaviour you can use the {RLTK::Parser.default_arg_type} method, which accepts the `:splat` (default) and `:array` arguments. Any production actions that are defined after a call to {RLTK::Parser.default_arg_type} will use the argument passing method currently set as the default. You can switch between the different argument passing methods by calling {RLTK::Parser.default_arg_type repeatedly.\r\n\r\nIndividual productions may specify the argument type used by their action via the `arg_type` parameter. If the {RLTK::Parser.production} method is passed an argument type and a block, any clauses defined inside the block will use the argument type specified by the `arg_type` parameter.\r\n\r\n### The Parsing Environment\r\n\r\nThe parsing environment is the context in which the proc objects associated with productions are evaluated, and can be used to provide helper functions and to keep state while parsing. To define a custom environment simply subclass {RLTK::Parser::Environment} inside your parser definition as follows:\r\n\r\n\tclass MyParser < RLTK::Parser\r\n\t\t...\r\n\t\t\r\n\t\tfinalize\r\n\t\t\r\n\t\tclass Environment < Environment\r\n\t\t\tdef helper_function\r\n\t\t\t\t...\r\n\t\t\tend\r\n\t\t\t\r\n\t\t\t...\r\n\t\tend\r\n\tend\r\n\r\n(The definition of the Environment class may occur anywhere inside the MyParser class definition.)\r\n\r\n### Instantiating Parsers\r\n\r\nIn addition to using the {RLTK::Parser.parse} class method you may also instantiate parser objects. The only difference then is that the parsing environment used between subsequent calls to {RLTK::Parser#parse} is the same object, and therefor allows you to keep persistent state.\r\n\r\n### Finalization Options\r\n\r\nThe {RLTK::Parser.finalize} method has several options that you should be aware of:\r\n\r\n* **explain** - Value should be `true`, `false`, an `IO` object, or a file name. Default value is `false`. If a non `false` (or `nil`) value is specified `finalize` will print an explanation of the parser to $stdout, the provided `IO` object, or the specified file. This explanation will include all of the productions defined, all of the terminal symbols used in the grammar definition, and the states present in the parsing table along with their items, actions, and conflicts.\r\n\r\n* **lookahead** - Either `true` or `false`. Default value is `true`. Specifies whether the parser generator should build an LALR(1) or LR(0) parsing table. The LALR(1) table may have the same actions as the LR(0) table or fewer reduce actions if it is possible to resolve conflicts using lookahead sets.\r\n\r\n* **precedence** - Either `true` or `false`. Default value is `true`. Specifies whether the parser generator should use precedence and associativity information to solve conflicts.\r\n\r\n* **use** - Value should be `false`, the name of a file, or a file object. If the file exists and hasn't been modified since the parser definition was RLTK will load the parser definition from the file, saving a bunch of time. If the file doesn't exist or the parser has been modified since it was last used RLTK will save the parser's data structures to this file.\r\n\r\n### Parsing Options\r\n\r\nThe {RLTK::Parser.parse} and {RLTK::Parser#parse} methods also have several options that you should be aware of:\r\n\r\n* **accept** - Either `:first` or `:all`. Default value is `:first`. This option tells the parser to accept the first successful parse-tree found, or all parse-trees that enter the accept state. It only affects the behavior of the parser if the defined grammar is ambiguous.\r\n\r\n* **env** - This option specifies the environment in which the productions' proc objects are evaluated. The RLTK::Parser::parse class function will create a new RLTK::Parser::Environment on each call unless one is specified. RLTK::Parser objects have an internal, per-instance, RLTK::Parser::Environment that is the default value for this option when calling RLTK::Parser.parse\r\n\r\n* **parse_tree** - Value should be `true`, `false`, an `IO` object, or a file name. Default value is `false`. If a non `false` (or `nil`) value is specified a DOT language description of all accepted parse trees will be printed out to $stdout, the provided `IO` object, or the specified file.\r\n\r\n* **verbose** - Value should be `true`, `false`, an `IO` object, or a file name. Default value is `false`. If a non `false` (or `nil`) value is specified a detailed description of the actions of the parser are printed to $stdout, the provided `IO` object, or the specified file as it parses the input.\r\n\r\n### Parse Trees\r\n\r\nThe above section briefly mentions the *parse_tree* option. So that this neat feature doesn't get lost in the rest of the documentation here is the tree generated by the Kazoo parser from Chapter 7 of the tutorial when it parses the line `def fib(a) if a < 2 then 1 else fib(a-1) + fib(a-2);`:\r\n\r\n![Kazoo parse tree.](https://github.com/chriswailes/RLTK/raw/master/resources/simple_tree.png)\r\n\r\n### Parsing Exceptions\r\n\r\nCalls to {RLTK::Parser.parse} may raise one of four exceptions:\r\n\r\n* **RLTK::BadToken** - This exception is raised when a token is observed in the input stream that wasn't used in the language's definition.\r\n* **RLTK::HandledError** - This exception is raised whenever an error production is encountered. The input stream is not actually in the langauge, but we were able to handle the encountered errors in a way that makes it appear that it is.\r\n* **RLTK::InternalParserError** - This exception tells you that something REALLY went wrong. Users should never receive this exception.\r\n* **RLTK::NotInLanguage** - This exception indicates that the input token stream is not in the parser's language.\r\n\r\n### Error Productions\r\n\r\n**Warning: this is the lest tested feature of RLTK. If you encounter any problems while using it, please let me know so I can fix any bugs as soon as possible.**\r\n\r\nWhen an RLTK parser encounters a token for which there are no more valid actions (and it is on the last parse stack / possible parse-tree path) it will enter error handling mode. In this mode the parser pops states and input off of the parse stack (the parser is a pushdown automaton after all) until it finds a state that has a shift action for the `ERROR` terminal. A dummy `ERROR` terminal is then placed onto the parse stack and the shift action is taken. This error token will have the position information of the token that caused the parser to enter error handling mode. Additional tokens may have been discarded after this token.\r\n\r\nIf the input (including the `ERROR` token) can be reduced immediately the associated error handling proc is evaluated and we continue parsing. If no shift or reduce action is available the parser will being shifting tokens off of the input stack until a token appears with a valid action in the current state, in which case parsing resumes as normal.\r\n\r\nThe value of an `ERROR` non-terminal will be an array containing all of the tokens that were discarded while the parser was searching for a valid action.\r\n\r\nThe example below, based on one of the unit tests, shows a very basic usage of error productions:\r\n\r\n\tclass ErrorCalc < RLTK::Parser\r\n\t\tleft :ERROR\r\n\t\tright :PLS, :SUB, :MUL, :DIV, :NUM\r\n\t\t\r\n\t\tproduction(:e) do\r\n\t\t\tclause('NUM') {|n| n}\r\n\t\t\r\n\t\t\tclause('e PLS e') { |e0, _, e1| e0 + e1 }\r\n\t\t\tclause('e SUB e') { |e0, _, e1| e0 - e1 }\r\n\t\t\tclause('e MUL e') { |e0, _, e1| e0 * e1 }\r\n\t\t\tclause('e DIV e') { |e0, _, e1| e0 / e1 }\r\n\t\t\r\n\t\t\tclause('e PLS ERROR e') { |e0, _, err, e1| error(\"#{err.len} tokens skipped.\"); e0 + e1 }\r\n\t\tend\r\n\t\r\n\t\tfinalize\r\n\tend\r\n\r\n## A Note on Token Naming\r\n\r\nIn the world of RLTK both terminal and non-terminal symbols may contain only alphanumeric characters and underscores. The differences between terminal and non-terminal symbols is that terminals are **ALL\\_UPPER\\_CASE** and non-terminals are **all\\_lower\\_case**.\r\n\r\n## ASTNode\r\n\r\nThe {RLTK::ASTNode} base class is meant to be a good starting point for implementing your own abstract syntax tree nodes. By subclassing {RLTK::ASTNode} you automagically get features such as tree comparison, notes, value accessors with type checking, child node accessors and `each` and `map` methods (with type checking), and the ability to retrieve the root of a tree from any member node.\r\n\r\nTo create your own AST node classes you subclass the {RLTK::ASTNode} class and then use the {RLTK::ASTNode.child} and {RLTK::ASTNode.value} methods. By declaring the children and values of a node the class will define the appropriate accessors with type checking, know how to pack and unpack a node's children, and know how to handle constructor arguments.\r\n\r\nHere we can see the definition of several AST node classes that might be used to implement binary operations for a language:\r\n\t\r\n\tclass Expression < RLTK::ASTNode; end\r\n\t\r\n\tclass Number < Expression\r\n\t\tvalue :value, Fixnum\r\n\tend\r\n\t\r\n\tclass BinOp < Expression\r\n\t\tvalue :op, String\r\n\t\t\r\n\t\tchild :left, Expression\r\n\t\tchild :right, Expression\r\n\tend\r\n\r\nThe assignment functions that are generated for the children and values perform type checking to make sure that the AST is well-formed. The type of a child must be a subclass of the {RLTK::ASTNode} class, whereas the type of a value must **NOT** be a subclass of the {RLTK::ASTNode} class. While child and value objects are stored as instance variables it is unsafe to assign to these variables directly, and it is strongly recommended to always use the accessor functions.\r\n\r\nWhen instantiating a subclass of {RLTK::ASTNode} the arguments to the constructor should be the node's values (in order of definition) followed by the node's children (in order of definition). If a constructor is given fewer arguments then the number of values and children the remaining arguments are assumed to be `nil`. Example:\r\n\r\n\tclass Foo < RLTK::ASTNode\r\n\t\tvalue :a, Fixnum\r\n\t\tchild :b, Bar\r\n\t\tvalue :c, String\r\n\t\tchild :d, Bar\r\n\tend\r\n\t\r\n\tclass Bar < RLTK::ASTNode\r\n\t\tvalue :a, String\r\n\tend\r\n\t\r\n\tFoo.new(1, 'baz', Bar.new)\r\n\r\nLastly, the type of a child or value can be defined as an array of objects of a specific type as follows:\r\n\r\n\tclass Foo < RLTK::ASTNode\r\n\t\tvalue :strings, [String]\r\n\tend\r\n\r\n### Tree Iteration and Mapping\r\n\r\nRLTK Abstract Syntax Trees may be [traversed](http://en.wikipedia.org/wiki/Tree_traversal) in three different ways:\r\n\r\n* Pre-order\r\n* Post-order\r\n* Level-order\r\n\r\nThe order you wish to traverse the tree can be specified by passing the appropriate symbol to {RLTK::ASTNode#each}: `:pre`, `:post`, or `:level`.\r\n\r\nYou can also map one tree to another tree using the {RLTK::ASTNode#map} and {RLTK::ASTNode#map!} methods. In the former case a new tree is created and returned; in the latter case the current tree is transformed and the result of calling the provided block on the root node is returned. These methods will always visit nodes in *post-order*, so that all children of a node are visited before the node itself.\r\n\r\n## Code Generation\r\n\r\nRLTK supports the generation of native code and LLVM IR, as well as JIT compilation and execution, through the {RLTK::CG} module. This module is built on top of bindings to [LLVM](http://llvm.org) and provides much, though not all, of the functionality of the LLVM libraries.\r\n\r\nA small amount of the functionality of the RLTK::CG module requires the [LLVM Extended C Bindings](https://github.com/chriswailes/llvm-ecb) library. If this library is missing the rest of the module should behave properly, but this functionality will be missing. The features that require this library are:\r\n\r\n* **Shared Library Loading** - Load shared libraries into the process so that their exported symbols are visible to LLVM via the {RLTK::CG::Support.load\\_library} method.\r\n* **ASM Printer and Parser Initialization** - Available through the {RLTK::CG::LLVM.init\\_asm\\_parser} and {RLTK::CG::LLVM.init\\_asm\\_printer} methods.\r\n* **LLVM IR Loading** - LLVM IR files can be loaded into RLTK via the {RLTK::CG::Module.read\\_ir\\_file} method.\r\n* **Value Printing** - Print any value's LLVM IR to a given file descriptor using {RLTK::CG::Value#print}.\r\n* **Targets, Target Data, and Target Machines** - Manipulate LLVM structures that contain data about the target environment.\r\n* **Object File Generation** - LLVM Modules can be compiled to object files via the {RLTK::CG::Module#compile} method.\r\n\r\n### Acknowledgments and Discussion\r\n\r\nBefore we get started with the details, I would like to thank [Jeremy Voorhis](https://github.com/jvoorhis/). The bindings present in RLTK are really a fork of the great work that he did on [ruby-llvm](https://github.com/jvoorhis/ruby-llvm).\r\n\r\nWhy did I fork ruby-llvm, and why might you want to use the RLTK bindings over ruby-llvm? There are a couple of reasons:\r\n\r\n* **Cleaner Codebase** - The RLTK bindings present a cleaner interface to the LLVM library by conforming to more standard Ruby programming practices, providing better abstractions and cleaner inheritance hierarchies, overloading constructors and other methods properly, and performing type checking on objects to better aid in debugging.\r\n* **Documentation** - RLTK's bindings provide better documentation.\r\n* **Completeness** - The RLTK bindings provide several features that are missing from the ruby-llvm project. These include the ability to initialize LLVM for architectures besides x86 (RLTK supports all architectures supported by LLVM), the presence of all of LLVM's optimization passes, the ability to print the LLVM IR representation of modules and values to files and load modules *from* files, easy initialization of native architectures, initialization for ASM printers and parsers, and compiling modules to object files.\r\n* **Ease of Use** - Several features have been added to make generating code easier such as automatic management of memory resources used by LLVM.\r\n* **Speed** - The RLTK bindings are ever so slightly faster due to avoiding unnecessary FFI calls.\r\n\r\nBefore you dive into generating code, here are some resources you might want to look over to build up some background knowledge on how LLVM works:\r\n\r\n* [Static Single Assignment Form](http://en.wikipedia.org/wiki/Static_single_assignment_form)\r\n* [LLVM Intermediate Representation](http://llvm.org/docs/LangRef.html)\r\n\r\n### LLVM\r\n\r\nSince RLTK's code generation functionality is built on top of LLVM the first step in generating code is to inform LLVM of the target architecture. This is accomplished via the {RLTK::CG::LLVM.init} method, which is used like this: `RLTK::CG::LLVM.init(:PPC)`. The {RLTK::CG::Bindings::ARCHS} constant provides a list of supported architectures. This call must appear before any other calls to the RLTK::CG module.\r\n\r\nIf you would like to see what version of LLVM is targeted by your version of RLTK you can either call the {RLTK::CG::LLVM.version} method or looking at the {RLTK::LLVM\\_TARGET\\_VERSION} constant.\r\n\r\n### Modules\r\n\r\nModules are one of the core building blocks of the code generation module. Functions, constants, and global variables all exist inside a particular module and, if you use the JIT compiler, a module provides the context for your executing code. New modules can be created using the {RLTK::CG::Module#initialize RLTK::CG::Module.new} method. While this method is overloaded you, as a library user, will always pass it a string as its first argument. This allows you to name your modules for easier debugging later.\r\n\r\nOnce you have created you can serialize the code inside of it into *bitcode* via the {RLTK::CG::Module#write\\_bitcode} method. This allows you to save partially generated code and then use it later. To load a module from *bitcode* you use the {RLTK::CG::Module.read\\_bitcode} method.\r\n\r\n### Types\r\n\r\nTypes are an important part of generating code using LLVM. Functions, operations, and other constructs use types to make sure that the generated code is sane. All types in RLTK are subclasses of the {RLTK::CG::Type} class, and have class names that end in \"Type\". Types can be grouped into to categories: fundamental and composite.\r\n\r\nFundamental types are those like {RLTK::CG::Int32Type} and {RLTK::CG::FloatType} that don't take any arguments when they are created. Indeed, these types are represented using a Singleton class, and so the `new` method is disabled. Instead you can use the `instance` method to get an instantiated type, or simply pass in the class itself whenever you need to reference the type. In this last case, the method you pass the class to will instantiate the type for you.\r\n\r\nComposite types are constructed from other types. These include the {RLTK::CG::ArrayType}, {RLTK::CG::FunctionType}, and other classes. These types you must instantiate directly before they can be used, and you may not simply pass the type class as the type argument to functions inside the RLTK::CG module.\r\n\r\nFor convenience, the native integer type of the host platform is made available via {RLTK::CG::NativeIntType}.\r\n\r\n### Values\r\n\r\nThe {RLTK::CG::Value} class is the common ancestor of many classes inside the RLTK::CG module. The main way in which you, the library user, will interact with them is when creating constant values. Here is a list of some of value classes you might use:\r\n\r\n* {RLTK::CG::Int1}\r\n* {RLTK::CG::Int8}\r\n* {RLTK::CG::Int16}\r\n* {RLTK::CG::Int32}\r\n* {RLTK::CG::Int64}\r\n* {RLTK::CG::Float}\r\n* {RLTK::CG::Double}\r\n* {RLTK::CG::ConstantArray}\r\n* {RLTK::CG::ConstantStruct}\r\n\r\nAgain, for convenience, the native integer class of the host platform is made available via {RLTK::CG::NativeInt}.\r\n\r\n### Functions\r\n\r\nFunctions in LLVM are much like C functions; they have a return type, argument types, and a body. Functions may be created in several ways, though they all require a module in which to place the function.\r\n\r\nThe first way to create functions is via a module's function collection:\r\n\r\n\tmod.functions.add('my function', RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType])\r\n\r\nHere we have defined a function named 'my function' in the `mod` module. It takes two native integers as arguments and returns a native integer. It is also possible to define the type of a function ahead of time and pass it to this method:\r\n\r\n\ttype = RLTK::CG::FunctionType.new(RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType])\r\n\tmod.functions.add('my function', type)\r\n\r\nFunctions may also be created directly via the {RLTK::CG::Function#initialize RLTK::CG::Function.new} method, though a reference to a module is still necessary:\r\n\r\n\tmod = Module.new('my module')\r\n\tfun = Function.new(mod, 'my function', RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType])\r\n\r\nor\r\n\t\r\n\tmod = Module.new('my module')\r\n\ttype = RLTK::CG::FunctionType.new(RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType])\r\n\tfun = Function.new(mod, 'my function', type)\r\n\r\nLastly, whenever you use one of these methods to create a function you may give it a block to be executed inside the context of the function object. This allows for easier building of functions:\r\n\r\n\tmod.functions.add('my function', RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType]) do\r\n\t\tbb = blocks.append('entry)'\r\n\t\t...\r\n\tend\r\n\r\n### Basic Blocks\r\n\r\nOnce a function has been added to a module you will need to add {RLTK::CG::BasicBlock BasicBlocks} to the function. This can be done easily:\r\n\r\n\tbb = fun.blocks.append('entry')\r\n\r\nWe now have a basic block that we can use to add instructions to our function and get it to actually do something. You can also instantiate basic blocks directly:\r\n\r\n\tbb = RLTK::CG::BasicBlock.new(fun, 'entry')\r\n\r\n### The Builder\r\n\r\nNow that you have a basic block you need to add instructions to it. This is accomplished using a {RLTK::CG::Builder builder}, either directly or indirectly.\r\n\r\nTo add instructions using a builder directly (this is most similar to how it is done using C/C++) you create the builder, position it where you want to add instructions, and then build them:\r\n\r\n\tfun = mod.functions.add('add', RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType])\r\n\tbb = fun.blocks.append('entry')\r\n\t\r\n\tbuilder = RLTK::CG::Builder.new\r\n\t\r\n\tbuilder.position_at_end(bb)\r\n\t\r\n\t# Generate an add instruction.\r\n\tinst0 = builder.add(fun.params[0], fun.params[1])\r\n\t\r\n\t# Generate a return instruction.\r\n\tbuilder.ret(inst0)\r\n\r\nYou can get rid of some of those references to the builder by using the {RLTK::CG::Builder#build} method:\r\n\r\n\tfun = mod.functions.add('add', RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType])\r\n\tbb = fun.blocks.append('entry')\r\n\t\r\n\tbuilder = RLTK::CG::Builder.new\r\n\t\r\n\tbuilder.build(bb) do\r\n\t\tret add(fun.params[0], fun.params[1])\r\n\tend\r\n\r\nTo get rid of more code:\r\n\r\n\tfun = mod.functions.add('add', RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType])\r\n\tbb = fun.blocks.append('entry')\r\n\t\r\n\tRLTK::CG::Builder.new(bb) do\r\n\t\tret add(fun.params[0], fun.params[1])\r\n\tend\r\n\r\nOr:\r\n\r\n\tfun = mod.functions.add('add', RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType])\r\n\tfun.blocks.append('entry') do\r\n\t\tret add(fun.params[0], fun.params[1])\r\n\tend\r\n\r\nOr even:\r\n\r\n\tmod.functions.add('add', RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType]) do\r\n\t\tblocks.append('entry') do |fun|\r\n\t\t\tret add(fun.params[0], fun.params[1])\r\n\t\tend\r\n\tend\r\n\r\nIn the last two examples a new builder object is created for the block. It is possible to specify the builder to be used:\r\n\r\n\tbuilder = RLTK::CG::Builder.new\r\n\t\r\n\tmod.functions.add('add', RLTK:CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType]) do\r\n\t\tblocks.append('entry', builder) do |fun|\r\n\t\t\tret add(fun.params[0], fun.params[1])\r\n\t\tend\r\n\tend\r\n\r\nFor an example of where this is useful, see the Kazoo tutorial.\r\n\r\n### The Contractor\r\n\r\nAn alternative to using the {RLTK::CG::Builder} class is to use the {RLTK::CG::Contractor} class, which is a subclass of the Builder and includes the {RLTK::Visitor} module. (Get it? It's a visiting builder!) By subclassing the Contractor you can define blocks of code for handling various types of AST nodes and leave the selection of the correct code up to the {RLTK::CG::Contractor#visit} method. In addition, the `:at` and `:rcb` options to the *visit* method make it much easier to manage the positioning of the Builder.\r\n\r\nHere we can see how easy it is to define a block that builds the instructions for binary operations:\r\n\t\r\n\ton Binary do |node|\r\n\t\tleft = visit node.left\r\n\t\tright = visit node.right\r\n\t\r\n\t\tcase node\r\n\t\twhen Add then fadd(left, right, 'addtmp')\r\n\t\twhen Sub then fsub(left, right, 'subtmp')\r\n\t\twhen Mul then fmul(left, right, 'multmp')\r\n\t\twhen Div then fdiv(left, right, 'divtmp')\r\n\t\twhen LT then ui2fp(fcmp(:ult, left, right, 'cmptmp'), RLTK::CG::DoubleType, 'booltmp')\r\n\t\tend\r\n\tend\r\n\r\nAST nodes whos translation requires the generation of control flow will require the creation of new BasicBlocks and the repositioning of the builder. This can be easily managed:\r\n\r\n\ton If do |node|\r\n\t\tcond_val = visit node.cond\r\n\t\tfcmp :one, cond_val, ZERO, 'ifcond'\r\n\t\t\r\n\t\tstart_bb = current_block\r\n\t\tfun = start_bb.parent\r\n\t\t\r\n\t\tthen_bb = fun.blocks.append('then')\r\n\t\tthen_val, new_then_bb = visit node.then, at: then_bb, rcb: true\r\n\t\t\r\n\t\telse_bb = fun.blocks.append('else')\r\n\t\telse_val, new_else_bb = visit node.else, at: else_bb, rcb: true\r\n\t\t\r\n\t\tmerge_bb = fun.blocks.append('merge', self)\r\n\t\tphi_inst = build(merge_bb) { phi RLTK::CG::DoubleType, {new_then_bb => then_val, new_else_bb => else_val}, 'iftmp' }\r\n\t\t\r\n\t\tbuild(start_bb) { cond cond_val, then_bb, else_bb }\r\n\t\t\r\n\t\tbuild(new_then_bb) { br merge_bb }\r\n\t\tbuild(new_else_bb) { br merge_bb }\r\n\t\t\r\n\t\treturning(phi_inst) { target merge_bb }\r\n\tend\r\n\r\nMore extensive examples of how to use the Contractor class can be found in the Kazoo tutorial cchapters.\r\n\r\n### Execution Engines\r\n\r\nOnce you have generated your code you may want to run it. RLTK provides bindings to both the LLVM interpreter and JIT compiler to help you do just that. Creating a JIT compiler is pretty simple.\r\n\r\n\tmod = RLTK::CG::Module.new('my module')\r\n\tjit = RLTK::CG::JITCompiler(mod)\r\n\t\r\n\tmod.functions.add('add', RLTK:CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType]) do\r\n\t\tblocks.append('entry', nil, nil, self) do |fun|\r\n\t\t\tret add(fun.params[0], fun.params[1])\r\n\t\tend\r\n\tend\r\n\r\nNow you can run your 'add' function like this:\r\n\r\n\tjit.run(fun, 1, 2)\r\n\r\nThe result will be a {RLTK::CG::GenericValue} object, and you will want to use its {RLTK::CG::GenericValue#to\\_i #to\\_i} and {RLTK::CG::GenericValue#to\\_f #to\\_f} methods to get the Ruby value result.\r\n\r\n## Context-Free Grammars\r\n\r\nThe {RLTK::CFG} class provides an abstraction for context-free grammars. For the purpose of this class terminal symbols appear in **ALL CAPS**, and non-terminal symbols appear in **all lowercase**. Once a grammar is defined the {RLTK::CFG#first_set} and {RLTK::CFG#follow_set} methods can be used to find *first* and *follow* sets.\r\n\r\n### Defining Grammars\r\n\r\nA grammar is defined by first instantiating the {RLTK::CFG} class. The {RLTK::CFG#production} and {RLTK::CFG#clause} methods may then be used to define the productions of the grammar. The `production` method can take a Symbol denoting the left-hand side of the production and a string describing the right-hand side of the production, or the left-hand side symbol and a block. In the first usage a single production is created. In the second usage the block may contain repeated calls to the `clause` method, each call producing a new production with the same left-hand side but different right-hand sides. {RLTK::CFG#clause} may not be called outside of {RLTK::CFG#production}. Bellow we see a grammar definition that uses both methods:\r\n\r\n\tgrammar = RLTK::CFG.new\r\n\t\r\n\tgrammar.production(:s) do\r\n\t\tclause('A G D')\r\n\t\tclause('A a C')\r\n\t\tclause('B a D')\r\n\t\tclause('B G C')\r\n\tend\r\n\t\r\n\tgrammar.production(:a, 'b')\r\n\tgrammar.production(:b, 'G')\r\n\r\n### Extended Backus–Naur Form\r\n\r\nThe RLTK::CFG class understands grammars written in the extended Backus–Naur form. This allows you to use the \\*, \\+, and ? operators in your grammar definitions. When each of these operators are encountered additional productions are generated. For example, if the right-hand side of a production contained 'NUM*' a production of the form 'num_star -> | NUM num_star' is added to the grammar. As such, your grammar should not contain productions with similar left-hand sides (e.g. foo_star, bar_question, or baz_plus).\r\n\r\nAs these additional productions are added internally to the grammar a callback functionality is provided to let you know when such an event occurs. The callback proc object can either be specified when the CFG object is created, or by using the {RLTK::CFG#callback} method. The callback will receive three arguments: the production generated, the operator that triggered the generation, and a symbol (:first or :second) specifying which clause of the production this callback is for.\r\n\r\n### Helper Functions\r\n\r\nOnce a grammar has been defined you can use the following functions to obtain information about it:\r\n\r\n* {RLTK::CFG#first_set} - Returns the *first set* for the provided symbol or sentence.\r\n* {RLTK::CFG#follow_set} - Returns the *follow set* for the provided symbol.\r\n* {RLTK::CFG#nonterms} - Returns a list of the non-terminal symbols used in the grammar's definition.\r\n* {RLTK::CFG#productions} - Provides either a hash or array of the grammar's productions.\r\n* {RLTK::CFG#symbols} - Returns a list of all symbols used in the grammar's definition.\r\n* {RLTK::CFG#terms} - Returns a list of the terminal symbols used in the grammar's definition.\r\n\r\n## Tutorial\r\n\r\nWhat follows is an in-depth example of how to use the Ruby Language Toolkit. This tutorial will show you how to use RLTK to build a lexer, parser, AST nodes, and compiler to create a toy language called Kazoo. The tutorial is based on the LLVM [Kaleidoscope](http://llvm.org/docs/tutorial/) tutorial, but has been modified to:\r\n\r\n* a) be done in Ruby\r\n* 2) use a lexer and parser generator and\r\n* III) use a language that I call Kazoo, which is really just a cleaned up and simplified version of the Kaleidoscope language used in the LLVM tutorial (as opposed to the [Kaleidoscope language](http://en.wikipedia.org/wiki/Kaleidoscope_%28programming_language%29) from the 90′s).\r\n\r\nThe Kazoo toy language is a procedural language that allows you to define functions, use conditionals, and perform basic mathematical operations. Over the course of the tutorial we’ll extend Kazoo to support the if/then/else construct, for loops, JIT compilation, and a simple command line interface to the JIT.\r\n\r\nBecause we want to keep things simple the only datatype in Kazoo is a 64-bit floating point type (a C double or a Ruby float). As such, all values are implicitly double precision and the language doesn’t require type declarations. This gives the language a very nice and simple syntax. For example, the following example computes Fibonacci numbers:\r\n\r\n\tdef fib(x)\r\n\t\tif x < 3 then\r\n\t\t\t1\r\n\t\telse\r\n\t\t\tfib(x-1) + fib(x-2)\r\n\r\nThe tutorial is organized as follows:\r\n\r\n * [Chapter 1: The Lexer](file.Chapter1.html)\r\n * [Chapter 2: The AST Nodes](file.Chapter2.html)\r\n * [Chapter 3: The Parser](file.Chapter3.html)\r\n * [Chapter 4: AST Translation](file.Chapter4.html)\r\n * [Chapter 5: JIT Compilation](file.Chapter5.html)\r\n * [Chapter 6: Adding Control Flow](file.Chapter6.html)\r\n * [Chapter 7: Playtime](file.Chapter7.html)\r\n * [Chapter 8: Mutable Variables](file.Chapter8.html)\r\n\r\nBefore starting this tutorial you should know about regular expressions, the basic ideas behind lexing and parsing, and be able to read context-free grammar (CFG) definitions. By the end of this tutorial we will have written 372 lines of source code and have a JIT compiler for a Turing complete language.\r\n\r\n## Provided Lexers and Parsers\r\n\r\nThe following lexer and parser classes are included as part of RLTK:\r\n\r\n* {RLTK::Lexers::Calculator}\r\n* {RLTK::Lexers::EBNF}\r\n* {RLTK::Parsers::PrefixCalc}\r\n* {RLTK::Parsers::InfixCalc}\r\n* {RLTK::Parsers::PostfixCalc}\r\n\r\n## Contributing\r\n\r\nIf you are interested in contributing to RLTK you can:\r\n\r\n* Help provide unit tests. Not all of RLTK is tested as well as it could be. Specifically, more tests for the RLTK::CFG and RLTK::Parser classes would be appreciated.\r\n* Write lexers or parsers that you think others might want to use. Possibilities include HTML, JSON/YAML, Javascript, and Ruby.\r\n* Write a class for dealing with regular languages.\r\n* Extend the RLTK::CFG class with additional functionality.\r\n* Let me know if you found any part of this documentation unclear or incomplete.\r\n","google":"","note":"Don't delete this file! It's used internally to help with page regeneration."}
+{"name":"The Ruby Language Toolkit","tagline":"Everything you need to build a programming language in Ruby","body":"# Welcome to the Ruby Language Toolkit\r\n\r\nRLTK is a collection of classes and methods designed to help programmers work with languages in an easy to use and straightforward manner. This toolkit provides the following features:\r\n\r\n* Lexer generator\r\n* Parser generator\r\n* AST node baseclass\r\n* Class for representing context free grammars\r\n* [Low Level Virtual Machine](http://llvm.org) (LLVM) bindings for code generation\r\n\r\nIn addition, RLTK includes several ready-made lexers and parsers and a Turing-complete language called Kazoo for use in your code and as examples for how to use the toolkit.\r\n\r\n## Why Use RLTK\r\n\r\nHere are some reasons to use RLTK to build your lexers, parsers, and abstract syntax trees, as well as generating LLVM IR and native object files:\r\n\r\n* **Lexer and Parser Definitions in Ruby** - Many tools require you to write your lexer/parser definitions in their own format, which is then processed and used to generate Ruby code. RLTK lexers/parsers are written entirely in Ruby and use syntax you are already familiar with.\r\n\r\n* **Re-entrant Code** - The lexers and parsers generated by RLTK are fully re-entrant.\r\n\r\n* **Multiple Lexers and Parsers** - You can define as many lexers and parses as you want, and instantiate as many of them as you need.\r\n\r\n* **Token Positions** - Detailed information about a token's position is available in the parser.\r\n\r\n* **Feature Rich Lexing and Parsing** - Often, lexer and parser generators will try and force you to do everything their way. RLTK gives you more flexibility with features such as states and flags for lexers, and argument arrays for parsers. What's more, these features actually work (I'm looking at you REX).\r\n\r\n* **LALR(1)/GLR Parsing** - RLTK parsers use the LALR(1)/GLR parsing algorithms, which means you get both speed and the ability to handle **any** context-free grammar.\r\n\r\n* **Parser Serialization** - RLTK parsers can be serialized and saved after they are generated for faster loading the next time they are required.\r\n\r\n* **Error Productions** - RLKT parsers can use error productions to recover from, and report on, errors.\r\n\r\n* **Fast Prototyping** - If you need to change your lexer/parser you don't have to re-run the lexer and parser generation tools, simply make the changes and be on your way.\r\n\r\n* **Parse Tree Graphs** - RLTK parsers can print parse trees (in the DOT language) of accepted strings.\r\n\r\n* **LLVM Bindings** - RLTK provides wrappers for most of the C LLVM bindings.\r\n\r\n* **The Contractor** - LLVM's method of building instructions is a bit cumbersome, and is very imperative in style. RLTK provides the Contractor class to make things easier.\r\n\r\n* **Documentation** - We have it!\r\n\r\n* **I Eat My Own Dog Food** - I'm using RLTK for my own projects so if there is a bug I'll most likely be the first one to know.\r\n\r\n## Lexers\r\n\r\nTo create your own lexer using RLTK you simply need to subclass the {RLTK::Lexer} class and define the *rules* that will be used for matching text and generating tokens. Here we see a simple lexer for a calculator:\r\n\r\n```Ruby\r\nclass Calculator < RLTK::Lexer\r\n rule(/\\+/) { :PLS }\r\n rule(/-/) { :SUB }\r\n rule(/\\*/) { :MUL }\r\n rule(/\\//) { :DIV }\r\n\r\n rule(/\\(/) { :LPAREN }\r\n rule(/\\)/) { :RPAREN }\r\n\r\n rule(/[0-9]+/) { |t| [:NUM, t.to_i] }\r\n\r\n rule(/\\s/)\r\nend\r\n```\r\n\r\nThe {RLTK::Lexer.rule} method's first argument is the regular expression used for matching text. The block passed to the function is the action that executes when a substring is matched by the rule. These blocks must return the *type* of the token (which must be in ALL CAPS; see the Parsers section), and optionally a *value*. In the latter case you must return an array containing the *type* and *value*, which you can see an example of in the Calculator lexer shown above. The values returned by the proc object are used to build a {RLTK::Token} object that includes the *type* and *value* information, as well as information about the line number the token was found on, the offset from the beginning of the line to the start of the token, and the length of the token's text. If the *type* value returned by the proc is `nil` the input is discarded and no token is produced.\r\n\r\nThe {RLTK::Lexer} class provides both {RLTK::Lexer.lex} and {RLTK::Lexer.lex_file}. The {RLTK::Lexer.lex} method takes a string as its argument and returns an array of tokens, with an *end of stream* token automatically added to the result. The {RLTK::Lexer.lex_file} method takes the name of a file as input, and lexes the contents of the specified file.\r\n\r\n### The Lexing Environment\r\n\r\nThe proc objects passed to the {RLTK::Lexer.rule} methods are evaluated inside an instance of the {RLTK::Lexer::Environment} class. This gives you access to methods for manipulating the lexer's state and flags (see bellow). You can also subclass the environment inside your lexer to provide additional functionality to your rule blocks. When doing so you need to ensure that you name your new class Environment like in the following example:\r\n\r\n```Ruby\r\nclass MyLexer < RLTK::Lexer\r\n ...\r\n\r\n class Environment < Environment\r\n def helper_function\r\n ...\r\n end\r\n\r\n ...\r\n end\r\nend\r\n```\r\n\r\n### Using States\r\n\r\nThe lexing environment may be used to keep track of state inside your lexer. When rules are defined they are defined inside a given state, which is specified by the second parameter to {RLTK::Lexer.rule}. The default state is cleverly named `:default`. When the lexer is scanning the input string for matching rules, it only considers the rules for the given state.\r\n\r\nThe methods used to manipulate state are:\r\n\r\n* **RLTK::Lexer::Environment.push_state** - Pushes a new state onto the stack.\r\n* **RLTK::Lexer::Environment.pop_state** - Pops a state off of the stack.\r\n* **RLTK::Lexer::Environment.set_state** - Sets the state at the top of the stack.\r\n* **RLTK::Lexer::Environment.state** - Returns the current state.\r\n\r\nStates may be used to easily support nested comments.\r\n\r\n```Ruby\r\nclass StateLexer < RLTK::Lexer\r\n rule(/a/) { :A }\r\n rule(/\\s/)\r\n\r\n rule(/\\(\\*/) { push_state(:comment) }\r\n\r\n rule(/\\(\\*/, :comment) { push_state(:comment) }\r\n rule(/\\*\\)/, :comment) { pop_state }\r\n rule(/./, :comment)\r\nend\r\n```\r\n\r\nBy default the lexer will start in the `:default` state. To change this, you may use the {RLTK::Lexer.start} method.\r\n\r\n### Using Flags\r\n\r\nThe lexing environment also maintains a set of *flags*. This set is manipulated using the following methods:\r\n\r\n* **RLTK::Lexer::Environment.set_flag** - Adds the specified flag to the set of flags.\r\n* **RLTK::Lexer::Environment.unset_flag** - Removes the specified flag from the set of flags.\r\n* **RLTK::Lexer::Environment.clear_flags** - Unsets all flags.\r\n\r\nWhen *rules* are defined they may use a third parameter to specify a list of flags that must be set before the rule is considered when matching substrings. An example of this usage follows:\r\n\r\n```Ruby\r\nclass FlagLexer < RLTK::Lexer\r\n rule(/a/) { set_flag(:a); :A }\r\n\r\n rule(/\\s/)\r\n\r\n rule(/b/, :default, [:a]) { set_flag(:b); :B }\r\n rule(/c/, :default, [:a, :b]) { :C }\r\nend\r\n```\r\n\r\n### Instantiating Lexers\r\n\r\nIn addition to using the {RLTK::Lexer.lex} class method you may also instantiate lexer objects. The only difference then is that the lexing environment used between subsequent calls to {RLTK::Lexer#lex} is the same object, and therefor allows you to keep persistent state.\r\n\r\n### First and Longest Match\r\n\r\nA RLTK::Lexer may be told to select either the first substring that is found to match a rule or the longest substring to match any rule. The default behavior is to match the longest substring possible, but you can change this by using the {RLTK::Lexer.match_first} method inside your class definition as follows:\r\n\r\n```Ruby\r\nclass MyLexer < RLTK::Lexer\r\n match_first\r\n\r\n ...\r\nend\r\n```\r\n\r\n### Match Data\r\n\r\nBecause it isn't RLTK's job to tell you how to write lexers and parsers, the MatchData object from a pattern match is available inside the Lexer::Environment object via the `match` accessor.\r\n\r\n## Context-Free Grammars\r\n\r\nThe {RLTK::CFG} class provides an abstraction for context-free grammars. For the purpose of this class terminal symbols appear in **ALL CAPS**, and non-terminal symbols appear in **all lowercase**. Once a grammar is defined the {RLTK::CFG#first_set} and {RLTK::CFG#follow_set} methods can be used to find *first* and *follow* sets.\r\n\r\n### Defining Grammars\r\n\r\nA grammar is defined by first instantiating the {RLTK::CFG} class. The {RLTK::CFG#production} and {RLTK::CFG#clause} methods may then be used to define the productions of the grammar. The `production` method can take a Symbol denoting the left-hand side of the production and a string describing the right-hand side of the production, or the left-hand side symbol and a block. In the first usage a single production is created. In the second usage the block may contain repeated calls to the `clause` method, each call producing a new production with the same left-hand side but different right-hand sides. {RLTK::CFG#clause} may not be called outside of {RLTK::CFG#production}. Bellow we see a grammar definition that uses both methods:\r\n\r\n```Ruby\r\ngrammar = RLTK::CFG.new\r\n\r\ngrammar.production(:s) do\r\n clause('A G D')\r\n clause('A a C')\r\n clause('B a D')\r\n clause('B G C')\r\nend\r\n\r\ngrammar.production(:a, 'b')\r\ngrammar.production(:b, 'G')\r\n```\r\n\r\n### Extended Backus–Naur Form\r\n\r\nThe RLTK::CFG class understands grammars written in the extended Backus–Naur form. This allows you to use the \\*, \\+, and ? operators in your grammar definitions. When each of these operators are encountered additional productions are generated. For example, if the right-hand side of a production contained `NUM*` a production of the form `num_star -> | NUM num_star` is added to the grammar. As such, your grammar should not contain productions with similar left-hand sides (e.g. foo_star, bar_question, or baz_plus).\r\n\r\nAs these additional productions are added internally to the grammar a callback functionality is provided to let you know when such an event occurs. The callback proc object can either be specified when the CFG object is created, or by using the {RLTK::CFG#callback} method. The callback will receive three arguments: the production generated, the operator that triggered the generation, and a symbol (:first or :second) specifying which clause of the production this callback is for.\r\n\r\n### Helper Functions\r\n\r\nOnce a grammar has been defined you can use the following functions to obtain information about it:\r\n\r\n* {RLTK::CFG#first_set} - Returns the *first set* for the provided symbol or sentence.\r\n* {RLTK::CFG#follow_set} - Returns the *follow set* for the provided symbol.\r\n* {RLTK::CFG#nonterms} - Returns a list of the non-terminal symbols used in the grammar's definition.\r\n* {RLTK::CFG#productions} - Provides either a hash or array of the grammar's productions.\r\n* {RLTK::CFG#symbols} - Returns a list of all symbols used in the grammar's definition.\r\n* {RLTK::CFG#terms} - Returns a list of the terminal symbols used in the grammar's definition.\r\n\r\n## Parsers\r\n\r\nTo create a parser using RLTK simply subclass RLTK::Parser, define the productions of the grammar you wish to parse, and call `finalize`. During finalization RLTK will build an LALR(1) parsing table, which may contain conflicts that can't be resolved with LALR(1) lookahead sets or precedence/associativity information. Traditionally, when parser generators such as **YACC** encounter conflicts during parsing table generation they will resolve shift/reduce conflicts in favor of shifts and reduce/reduce conflicts in favor of the production that was defined first. This means that the generated parsers can't handle ambiguous grammars.\r\n\r\nRLTK parsers, on the other hand, can handle *all* context-free grammars by forking the parse stack when shift/reduce or reduce/reduce conflicts are encountered. This method is called the GLR parsing algorithm and allows the parser to explore multiple different possible derivations, discarding the ones that don't produce valid parse trees. GLR parsing is more expensive, in both time and space requirements, but these penalties are only payed when a parser for an ambiguous grammar is given an input with multiple parse trees, and as such most parsing should proceed using the faster LALR(1) base algorithm.\r\n\r\n### Defining a Grammar\r\n\r\nLet us look at the simple prefix calculator included with RLTK:\r\n\r\n```Ruby\r\nclass PrefixCalc < RLTK::Parser\r\n production(:e) do\r\n clause('NUM') {|n| n}\r\n\r\n clause('PLS e e') { |_, e0, e1| e0 + e1 }\r\n clause('SUB e e') { |_, e0, e1| e0 - e1 }\r\n clause('MUL e e') { |_, e0, e1| e0 * e1 }\r\n clause('DIV e e') { |_, e0, e1| e0 / e1 }\r\n end\r\n\r\n finalize\r\nend\r\n```\r\n\r\nThe parser uses the same method for defining productions as the {RLTK::CFG} class. In fact, the parser forwards the {RLTK::Parser.production} and {RLTK::Parser.clause} method invocations to an internal {RLTK::CFG} object after removing the parser specific information. To see a detailed description of grammar definitions please read the Context-Free Grammars section bellow.\r\n\r\nIt is important to note that the proc objects associated with productions should evaluate to the value you wish the left-hand side of the production to take.\r\n\r\nThe default starting symbol of the grammar is the left-hand side of the first production defined (in this case, _e_). This can be changed using the {RLTK::Parser.start} function when defining your parser.\r\n\r\n**Make sure you call `finalize` at the end of your parser definition, and only call it once.**\r\n\r\n### Shortcuts\r\n\r\nRLTK provides several shortcuts for common grammar constructs. Right now these shortcuts include the {RLTK::Parser.empty_list} and {RLTK::Parser.nonempty_list} methods. An empty list is a list that may contain 0, 1, or more elements, with an optional token or tokens seperating each element. A non-empty list contains **at least** 1 element. An empty list with only a single list element and an empty separator is equivelent to the Kleene star. Simillarly, a nonempty list with only a single list element and an empty separator is equivelent to the Kleene plus.\r\n\r\nThis example shows how these shortcuts may be used to define a list of integers separated by a `:COMMA` token:\r\n\r\n```Ruby\r\nclass ListParser < RLTK::Parser\r\n nonempty_list(:int_list, :INT, :COMMA)\r\n\r\n finalize\r\nend\r\n```\r\n\r\nIf you wanted to define a list of floats or integers you could define your parser like this:\r\n\r\n```Ruby\r\nclass ListParser < RLTK::Parser\r\n nonempty_list(:mixed_list, [:INT, :FLOAT], :COMMA)\r\n\r\n finalize\r\nend\r\n```\r\n\r\nIf you don't want to require a separator you can do this:\r\n\r\n```Ruby\r\nclass ListParser < RLTK::Parser\r\n nonempty_list(:mixed_nonsep_list, [:INT, :FLOAT])\r\n\r\n finalize\r\nend\r\n```\r\n\r\nYou can also use separators that are made up of multiple tokens:\r\n\r\n```Ruby\r\nclass ListParser < RLTK::Parser\r\n nonempty_list(:mixed_nonsep_list, [:INT, :FLOAT], 'COMMA NEWLINE?')\r\n\r\n finalize\r\nend\r\n```\r\n\r\nA list may also contain multiple tokens between the separator:\r\n\r\n```Ruby\r\nclass ListParser < RLTK::Parser\r\n nonempty_list(:foo_bar_list, 'FOO BAR', :COMMA)\r\n\r\n finalize\r\nend\r\n```\r\n\r\nLastly, you can mix all of these features together:\r\n\r\n```Ruby\r\nclass ListParser < RLTK::Parser\r\n nonempty_list(:foo_list, ['FOO BAR', 'FOO BAZ+'], :COMMA)\r\n\r\n finalize\r\nend\r\n```\r\n\r\nThe productions generated by these shortcuts will always evaluate to an array. In the first two examples above the productions will produce a 1-D array containing the values of the `INT` or `FLOAT` tokens. In the last two examples the productions `foo_bar_list` and `foo_list` will produce 2-D arrays where the top level array is composed of tuples coresponding to the values of `FOO`, and `BAR` or one or more `BAZ`s.\r\n\r\n### Precedence and Associativity\r\n\r\nTo help you remove ambiguity from your grammars RLTK lets you assign precedence and associativity information to terminal symbols. Productions then get assigned precedence and associativity based on either the last terminal symbol on the right-hand side of the production, or an optional parameter to the {RLTK::Parser.production} or {RLTK::Parser.clause} methods. When an {RLTK::Parser} encounters a shift/reduce error it will attempt to resolve it using the following rules:\r\n\r\n1. If there is precedence and associativity information present for all reduce actions involved and for the input token we attempt to resolve the conflict using the following rule. If not, no resolution is possible and the parser generator moves on. This conflict will later be reported to the programmer.\r\n\r\n2. The precedence of the actions involved in the conflict are compared (a shift action's precedence is based on the input token), and the action with the highest precedence is selected. If two actions have the same precedence the associativity of the input symbol is used: left associativity means we select the reduce action, right associativity means we select the shift action, and non-associativity means that we have encountered an error.\r\n\r\nTo assign precedence to terminal symbols you can use the {RLTK::Parser.left}, {RLTK::Parser.right}, and {RLTK::Parser.nonassoc} methods inside your parser class definition. Later declarations of associativity have higher levels of precedence than earlier declarations of the same associativity.\r\n\r\nLet's look at the infix calculator example now:\r\n\r\n```Ruby\r\nclass InfixCalc < Parser\r\n\r\n left :PLS, :SUB\r\n right :MUL, :DIV\r\n\r\n production(:e) do\r\n clause('NUM') { |n| n }\r\n\r\n clause('LPAREN e RPAREN') { |_, e, _| e }\r\n\r\n clause('e PLS e') { |e0, _, e1| e0 + e1 }\r\n clause('e SUB e') { |e0, _, e1| e0 - e1 }\r\n clause('e MUL e') { |e0, _, e1| e0 * e1 }\r\n clause('e DIV e') { |e0, _, e1| e0 / e1 }\r\n end\r\n\r\n finalize\r\nend\r\n```\r\n\r\nThe standard order of mathematical operations tells us that the correct way to group the operations in the expression `2 + 3 * 4` is `2 + (3 * 4)`. However, our grammar tells us that `(2 + 3) * 5` is also a valid way to parse the expression, leading to a shift/reduce error in the parser. To get rid of the shift/reduce error we need some way to tell the parser how to distinguish between these two parse trees. This is where associativity comes in. If the parser has already read `NUM PLS NUM` and the current symbol is a `MUL` symbol we want to tell the parser to shift the new `MUL` symbol onto the stack and continue on. We do this by making the `MUL` symbol right associative. When the parser generator encounters a shift/reduce error it looks at the token currently being read. If it has no associativity information, the error can't be resolved; if the token is left associative, it will remove the shift action from the parser (leaving only the reduce action); if the token is right associative, it will remove the reduce action from the parser (leaving only the shift action).\r\n\r\nNow, let us consider the expression `3 - 2 - 1`. Here, the correct way to parse the expression is `(3 - 2) - 2`. To ensure that this case is selected over `3 - (2 - 1)` we can make the `SUB` token left associative. This will cause the symbols `NUM SUB NUM` to be reduced before the second `SUB` symbol is shifted onto the parse stack.\r\n\r\nNot that, to resolve a shift/reduce or reduce/reduce conflict, precedence and associativty information must be present for all actions involved in the conflict. As such, it isn't enough to simply make the `MUL` and `DIV` tokens right associative; we must also make the `PLS` and `SUB` tokens left associative.\r\n\r\n### Argument Passing for Actions\r\n\r\nBy default the proc objects associated with productions are passed one argument for each symbol on the right-hand side of the production. This can lead to long, unwieldy argument lists. To change this behaviour you can use the {RLTK::Parser.default_arg_type} method, which accepts the `:splat` (default) and `:array` arguments. Any production actions that are defined after a call to {RLTK::Parser.default_arg_type} will use the argument passing method currently set as the default. You can switch between the different argument passing methods by calling {RLTK::Parser.default_arg_type} repeatedly.\r\n\r\nIndividual productions may specify the argument type used by their action via the `arg_type` parameter. If the {RLTK::Parser.production} method is passed an argument type and a block, any clauses defined inside the block will use the argument type specified by the `arg_type` parameter.\r\n\r\n### The Parsing Environment\r\n\r\nThe parsing environment is the context in which the proc objects associated with productions are evaluated, and can be used to provide helper functions and to keep state while parsing. To define a custom environment simply subclass {RLTK::Parser::Environment} inside your parser definition as follows:\r\n\r\n```Ruby\r\nclass MyParser < RLTK::Parser\r\n ...\r\n\r\n class Environment < Environment\r\n def helper_function\r\n ...\r\n end\r\n\r\n ...\r\n end\r\n\r\n finalize\r\nend\r\n```\r\n\r\n(The definition of the Environment class may occur anywhere inside the MyParser class definition.)\r\n\r\n### Instantiating Parsers\r\n\r\nIn addition to using the {RLTK::Parser.parse} class method you may also instantiate parser objects. The only difference then is that the parsing environment used between subsequent calls to {RLTK::Parser#parse} is the same object, and therefor allows you to keep persistent state.\r\n\r\n### Finalization Options\r\n\r\nThe {RLTK::Parser.finalize} method has several options that you should be aware of:\r\n\r\n* **explain** - Value should be `true`, `false`, an `IO` object, or a file name. Default value is `false`. If a non `false` (or `nil`) value is specified `finalize` will print an explanation of the parser to $stdout, the provided `IO` object, or the specified file. This explanation will include all of the productions defined, all of the terminal symbols used in the grammar definition, and the states present in the parsing table along with their items, actions, and conflicts.\r\n\r\n* **lookahead** - Either `true` or `false`. Default value is `true`. Specifies whether the parser generator should build an LALR(1) or LR(0) parsing table. The LALR(1) table may have the same actions as the LR(0) table or fewer reduce actions if it is possible to resolve conflicts using lookahead sets.\r\n\r\n* **precedence** - Either `true` or `false`. Default value is `true`. Specifies whether the parser generator should use precedence and associativity information to solve conflicts.\r\n\r\n* **use** - Value should be `false`, the name of a file, or a file object. If the file exists and hasn't been modified since the parser definition was RLTK will load the parser definition from the file, saving a bunch of time. If the file doesn't exist or the parser has been modified since it was last used RLTK will save the parser's data structures to this file.\r\n\r\n### Parsing Options\r\n\r\nThe {RLTK::Parser.parse} and {RLTK::Parser#parse} methods also have several options that you should be aware of:\r\n\r\n* **accept** - Either `:first` or `:all`. Default value is `:first`. This option tells the parser to accept the first successful parse-tree found, or all parse-trees that enter the accept state. It only affects the behavior of the parser if the defined grammar is ambiguous.\r\n\r\n* **env** - This option specifies the environment in which the productions' proc objects are evaluated. The RLTK::Parser::parse class function will create a new RLTK::Parser::Environment on each call unless one is specified. RLTK::Parser objects have an internal, per-instance, RLTK::Parser::Environment that is the default value for this option when calling RLTK::Parser.parse\r\n\r\n* **parse_tree** - Value should be `true`, `false`, an `IO` object, or a file name. Default value is `false`. If a non `false` (or `nil`) value is specified a DOT language description of all accepted parse trees will be printed out to $stdout, the provided `IO` object, or the specified file.\r\n\r\n* **verbose** - Value should be `true`, `false`, an `IO` object, or a file name. Default value is `false`. If a non `false` (or `nil`) value is specified a detailed description of the actions of the parser are printed to $stdout, the provided `IO` object, or the specified file as it parses the input.\r\n\r\n### Parse Trees\r\n\r\nThe above section briefly mentions the *parse_tree* option. So that this neat feature doesn't get lost in the rest of the documentation here is the tree generated by the Kazoo parser from Chapter 7 of the tutorial when it parses the line `def fib(a) if a < 2 then 1 else fib(a-1) + fib(a-2);`:\r\n\r\n![Kazoo parse tree.](https://github.com/chriswailes/RLTK/raw/master/resources/simple_tree.png)\r\n\r\n### Parsing Exceptions\r\n\r\nCalls to {RLTK::Parser.parse} may raise one of four exceptions:\r\n\r\n* **RLTK::BadToken** - This exception is raised when a token is observed in the input stream that wasn't used in the language's definition.\r\n* **RLTK::HandledError** - This exception is raised whenever an error production is encountered. The input stream is not actually in the langauge, but we were able to handle the encountered errors in a way that makes it appear that it is.\r\n* **RLTK::InternalParserError** - This exception tells you that something REALLY went wrong. Users should never receive this exception.\r\n* **RLTK::NotInLanguage** - This exception indicates that the input token stream is not in the parser's language.\r\n\r\n### Error Productions\r\n\r\n**Warning: this is the lest tested feature of RLTK. If you encounter any problems while using it, please let me know so I can fix any bugs as soon as possible.**\r\n\r\nWhen an RLTK parser encounters a token for which there are no more valid actions (and it is on the last parse stack / possible parse-tree path) it will enter error handling mode. In this mode the parser pops states and input off of the parse stack (the parser is a pushdown automaton after all) until it finds a state that has a shift action for the `ERROR` terminal. A dummy `ERROR` terminal is then placed onto the parse stack and the shift action is taken. This error token will have the position information of the token that caused the parser to enter error handling mode. Additional tokens may have been discarded after this token.\r\n\r\nIf the input (including the `ERROR` token) can be reduced immediately the associated error handling proc is evaluated and we continue parsing. If no shift or reduce action is available the parser will being shifting tokens off of the input stack until a token appears with a valid action in the current state, in which case parsing resumes as normal.\r\n\r\nThe value of an `ERROR` non-terminal will be an array containing all of the tokens that were discarded while the parser was searching for a valid action.\r\n\r\nThe example below, based on one of the unit tests, shows a very basic usage of error productions:\r\n\r\n```Ruby\r\nclass ErrorCalc < RLTK::Parser\r\n left :ERROR\r\n right :PLS, :SUB, :MUL, :DIV, :NUM\r\n\r\n production(:e) do\r\n clause('NUM') {|n| n}\r\n\r\n clause('e PLS e') { |e0, _, e1| e0 + e1 }\r\n clause('e SUB e') { |e0, _, e1| e0 - e1 }\r\n clause('e MUL e') { |e0, _, e1| e0 * e1 }\r\n clause('e DIV e') { |e0, _, e1| e0 / e1 }\r\n\r\n clause('e PLS ERROR e') { |e0, _, err, e1| error(\"#{err.len} tokens skipped.\"); e0 + e1 }\r\n end\r\n\r\n finalize\r\nend\r\n```\r\n\r\n## A Note on Token Naming\r\n\r\nIn the world of RLTK both terminal and non-terminal symbols may contain only alphanumeric characters and underscores. The differences between terminal and non-terminal symbols is that terminals are **ALL\\_UPPER\\_CASE** and non-terminals are **all\\_lower\\_case**.\r\n\r\n## ASTNode\r\n\r\nThe {RLTK::ASTNode} base class is meant to be a good starting point for implementing your own abstract syntax tree nodes. By subclassing {RLTK::ASTNode} you automagically get features such as tree comparison, notes, value accessors with type checking, child node accessors and `each` and `map` methods (with type checking), and the ability to retrieve the root of a tree from any member node.\r\n\r\nTo create your own AST node classes you subclass the {RLTK::ASTNode} class and then use the {RLTK::ASTNode.child} and {RLTK::ASTNode.value} methods. By declaring the children and values of a node the class will define the appropriate accessors with type checking, know how to pack and unpack a node's children, and know how to handle constructor arguments.\r\n\r\nHere we can see the definition of several AST node classes that might be used to implement binary operations for a language:\r\n\r\n```Ruby\r\nclass Expression < RLTK::ASTNode; end\r\n\r\nclass Number < Expression\r\n value :value, Fixnum\r\nend\r\n\r\nclass BinOp < Expression\r\n value :op, String\r\n\r\n child :left, Expression\r\n child :right, Expression\r\nend\r\n```\r\n\r\nThe assignment functions that are generated for the children and values perform type checking to make sure that the AST is well-formed. The type of a child must be a subclass of the {RLTK::ASTNode} class, whereas the type of a value must **NOT** be a subclass of the {RLTK::ASTNode} class. While child and value objects are stored as instance variables it is unsafe to assign to these variables directly, and it is strongly recommended to always use the accessor functions.\r\n\r\nWhen instantiating a subclass of {RLTK::ASTNode} the arguments to the constructor should be the node's values (in order of definition) followed by the node's children (in order of definition). If a constructor is given fewer arguments then the number of values and children the remaining arguments are assumed to be `nil`. Example:\r\n\r\n```Ruby\r\nclass Foo < RLTK::ASTNode\r\n value :a, Fixnum\r\n child :b, Bar\r\n value :c, String\r\n child :d, Bar\r\nend\r\n\r\nclass Bar < RLTK::ASTNode\r\n value :a, String\r\nend\r\n\r\nFoo.new(1, 'baz', Bar.new)\r\n```\r\n\r\nLastly, the type of a child or value can be defined as an array of objects of a specific type as follows:\r\n\r\n```Ruby\r\nclass Foo < RLTK::ASTNode\r\n value :strings, [String]\r\nend\r\n```\r\n\r\n### Tree Iteration and Mapping\r\n\r\nRLTK Abstract Syntax Trees may be [traversed](http://en.wikipedia.org/wiki/Tree_traversal) in three different ways:\r\n\r\n* Pre-order\r\n* Post-order\r\n* Level-order\r\n\r\nThe order you wish to traverse the tree can be specified by passing the appropriate symbol to {RLTK::ASTNode#each}: `:pre`, `:post`, or `:level`.\r\n\r\nYou can also map one tree to another tree using the {RLTK::ASTNode#map} and {RLTK::ASTNode#map!} methods. In the former case a new tree is created and returned; in the latter case the current tree is transformed and the result of calling the provided block on the root node is returned. These methods will always visit nodes in *post-order*, so that all children of a node are visited before the node itself.\r\n\r\n## Code Generation\r\n\r\nRLTK supports the generation of native code and LLVM IR, as well as JIT compilation and execution, through the {RLTK::CG} module. This module is built on top of bindings to [LLVM](http://llvm.org) and provides much, though not all, of the functionality of the LLVM libraries.\r\n\r\n### Acknowledgments and Discussion\r\n\r\nBefore we get started with the details, I would like to thank [Jeremy Voorhis](https://github.com/jvoorhis/). The bindings present in RLTK are really a fork of the great work that he did on [ruby-llvm](https://github.com/jvoorhis/ruby-llvm).\r\n\r\nWhy did I fork ruby-llvm, and why might you want to use the RLTK bindings over ruby-llvm? There are a couple of reasons:\r\n\r\n* **Cleaner Codebase** - The RLTK bindings present a cleaner interface to the LLVM library by conforming to more standard Ruby programming practices, providing better abstractions and cleaner inheritance hierarchies, overloading constructors and other methods properly, and performing type checking on objects to better aid in debugging.\r\n* **Documentation** - RLTK's bindings provide better documentation.\r\n* **Completeness** - The RLTK bindings provide several features that are missing from the ruby-llvm project. These include the ability to initialize LLVM for architectures besides x86 (RLTK supports all architectures supported by LLVM), the presence of all of LLVM's optimization passes, the ability to print the LLVM IR representation of modules and values to files and load modules *from* files, easy initialization of native architectures, initialization for ASM printers and parsers, and compiling modules to object files.\r\n* **Ease of Use** - Several features have been added to make generating code easier such as automatic management of memory resources used by LLVM.\r\n* **Speed** - The RLTK bindings are ever so slightly faster due to avoiding unnecessary FFI calls.\r\n\r\nBefore you dive into generating code, here are some resources you might want to look over to build up some background knowledge on how LLVM works:\r\n\r\n* [Static Single Assignment Form](http://en.wikipedia.org/wiki/Static_single_assignment_form)\r\n* [LLVM Intermediate Representation](http://llvm.org/docs/LangRef.html)\r\n\r\n### LLVM\r\n\r\nSince RLTK's code generation functionality is built on top of LLVM the first step in generating code is to inform LLVM of the target architecture. This is accomplished via the {RLTK::CG::LLVM.init} method, which is used like this: `RLTK::CG::LLVM.init(:PPC)`. The {RLTK::CG::Bindings::ARCHS} constant provides a list of supported architectures. This call must appear before any other calls to the RLTK::CG module.\r\n\r\nIf you would like to see what version of LLVM is targeted by your version of RLTK you can either call the {RLTK::CG::LLVM.version} method or looking at the {RLTK::LLVM\\_TARGET\\_VERSION} constant.\r\n\r\n### Modules\r\n\r\nModules are one of the core building blocks of the code generation module. Functions, constants, and global variables all exist inside a particular module and, if you use the JIT compiler, a module provides the context for your executing code. New modules can be created using the {RLTK::CG::Module#initialize RLTK::CG::Module.new} method. While this method is overloaded you, as a library user, will always pass it a string as its first argument. This allows you to name your modules for easier debugging later.\r\n\r\nOnce you have created you can serialize the code inside of it into *bitcode* via the {RLTK::CG::Module#write\\_bitcode} method. This allows you to save partially generated code and then use it later. To load a module from *bitcode* you use the {RLTK::CG::Module.read\\_bitcode} method.\r\n\r\n### Types\r\n\r\nTypes are an important part of generating code using LLVM. Functions, operations, and other constructs use types to make sure that the generated code is sane. All types in RLTK are subclasses of the {RLTK::CG::Type} class, and have class names that end in \"Type\". Types can be grouped into to categories: fundamental and composite.\r\n\r\nFundamental types are those like {RLTK::CG::Int32Type} and {RLTK::CG::FloatType} that don't take any arguments when they are created. Indeed, these types are represented using a Singleton class, and so the `new` method is disabled. Instead you can use the `instance` method to get an instantiated type, or simply pass in the class itself whenever you need to reference the type. In this last case, the method you pass the class to will instantiate the type for you.\r\n\r\nComposite types are constructed from other types. These include the {RLTK::CG::ArrayType}, {RLTK::CG::FunctionType}, and other classes. These types you must instantiate directly before they can be used, and you may not simply pass the type class as the type argument to functions inside the RLTK::CG module.\r\n\r\nFor convenience, the native integer type of the host platform is made available via {RLTK::CG::NativeIntType}.\r\n\r\n### Values\r\n\r\nThe {RLTK::CG::Value} class is the common ancestor of many classes inside the RLTK::CG module. The main way in which you, the library user, will interact with them is when creating constant values. Here is a list of some of value classes you might use:\r\n\r\n* {RLTK::CG::Int1}\r\n* {RLTK::CG::Int8}\r\n* {RLTK::CG::Int16}\r\n* {RLTK::CG::Int32}\r\n* {RLTK::CG::Int64}\r\n* {RLTK::CG::Float}\r\n* {RLTK::CG::Double}\r\n* {RLTK::CG::ConstantArray}\r\n* {RLTK::CG::ConstantStruct}\r\n\r\nAgain, for convenience, the native integer class of the host platform is made available via {RLTK::CG::NativeInt}.\r\n\r\n### Functions\r\n\r\nFunctions in LLVM are much like C functions; they have a return type, argument types, and a body. Functions may be created in several ways, though they all require a module in which to place the function.\r\n\r\nThe first way to create functions is via a module's function collection:\r\n\r\n```Ruby\r\nmod.functions.add('my function', RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType])\r\n```\r\n\r\nHere we have defined a function named 'my function' in the `mod` module. It takes two native integers as arguments and returns a native integer. It is also possible to define the type of a function ahead of time and pass it to this method:\r\n\r\n```Ruby\r\ntype = RLTK::CG::FunctionType.new(RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType])\r\nmod.functions.add('my function', type)\r\n```\r\n\r\nFunctions may also be created directly via the {RLTK::CG::Function#initialize RLTK::CG::Function.new} method, though a reference to a module is still necessary:\r\n\r\n```Ruby\r\nmod = Module.new('my module')\r\nfun = Function.new(mod, 'my function', RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType])\r\n```\r\n\r\nor\r\n\r\n```Ruby\r\nmod = Module.new('my module')\r\ntype = RLTK::CG::FunctionType.new(RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType])\r\nfun = Function.new(mod, 'my function', type)\r\n```\r\n\r\nLastly, whenever you use one of these methods to create a function you may give it a block to be executed inside the context of the function object. This allows for easier building of functions:\r\n\r\n```Ruby\r\nmod.functions.add('my function', RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType]) do\r\n bb = blocks.append('entry)'\r\n ...\r\nend\r\n```\r\n\r\n### Basic Blocks\r\n\r\nOnce a function has been added to a module you will need to add {RLTK::CG::BasicBlock BasicBlocks} to the function. This can be done easily:\r\n\r\n```Ruby\r\nbb = fun.blocks.append('entry')\r\n```\r\n\r\nWe now have a basic block that we can use to add instructions to our function and get it to actually do something. You can also instantiate basic blocks directly:\r\n\r\n```Ruby\r\nbb = RLTK::CG::BasicBlock.new(fun, 'entry')\r\n```\r\n\r\n### The Builder\r\n\r\nNow that you have a basic block you need to add instructions to it. This is accomplished using a {RLTK::CG::Builder builder}, either directly or indirectly.\r\n\r\nTo add instructions using a builder directly (this is most similar to how it is done using C/C++) you create the builder, position it where you want to add instructions, and then build them:\r\n\r\n```Ruby\r\nfun = mod.functions.add('add', RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType])\r\nbb = fun.blocks.append('entry')\r\n\r\nbuilder = RLTK::CG::Builder.new\r\n\r\nbuilder.position_at_end(bb)\r\n\r\n# Generate an add instruction.\r\ninst0 = builder.add(fun.params[0], fun.params[1])\r\n\r\n# Generate a return instruction.\r\nbuilder.ret(inst0)\r\n```\r\n\r\nYou can get rid of some of those references to the builder by using the {RLTK::CG::Builder#build} method:\r\n\r\n```Ruby\r\nfun = mod.functions.add('add', RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType])\r\nbb = fun.blocks.append('entry')\r\n\r\nbuilder = RLTK::CG::Builder.new\r\n\r\nbuilder.build(bb) do\r\n ret add(fun.params[0], fun.params[1])\r\nend\r\n```\r\n\r\nTo get rid of more code:\r\n\r\n```Ruby\r\nfun = mod.functions.add('add', RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType])\r\nbb = fun.blocks.append('entry')\r\n\r\nRLTK::CG::Builder.new(bb) do\r\n ret add(fun.params[0], fun.params[1])\r\nend\r\n```\r\n\r\nor\r\n\r\n```Ruby\r\nfun = mod.functions.add('add', RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType])\r\nfun.blocks.append('entry') do\r\n ret add(fun.params[0], fun.params[1])\r\nend\r\n```\r\n\r\nor even\r\n\r\n```Ruby\r\nmod.functions.add('add', RLTK::CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType]) do\r\n blocks.append('entry') do |fun|\r\n ret add(fun.params[0], fun.params[1])\r\n end\r\nend\r\n```\r\n\r\nIn the last two examples a new builder object is created for the block. It is possible to specify the builder to be used:\r\n\r\n```Ruby\r\nbuilder = RLTK::CG::Builder.new\r\n\r\nmod.functions.add('add', RLTK:CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType]) do\r\n blocks.append('entry', builder) do |fun|\r\n ret add(fun.params[0], fun.params[1])\r\n end\r\nend\r\n```\r\n\r\nFor an example of where this is useful, see the Kazoo tutorial.\r\n\r\n### The Contractor\r\n\r\nAn alternative to using the {RLTK::CG::Builder} class is to use the {RLTK::CG::Contractor} class, which is a subclass of the Builder and includes the Filigree::Visitor module. (Get it? It's a visiting builder!) By subclassing the Contractor you can define blocks of code for handling various types of AST nodes and leave the selection of the correct code up to the {RLTK::CG::Contractor#visit} method. In addition, the `:at` and `:rcb` options to the *visit* method make it much easier to manage the positioning of the Builder.\r\n\r\nHere we can see how easy it is to define a block that builds the instructions for binary operations:\r\n\r\n```Ruby\r\non Binary do |node|\r\n left = visit node.left\r\n right = visit node.right\r\n\r\n case node\r\n when Add then fadd(left, right, 'addtmp')\r\n when Sub then fsub(left, right, 'subtmp')\r\n when Mul then fmul(left, right, 'multmp')\r\n when Div then fdiv(left, right, 'divtmp')\r\n when LT then ui2fp(fcmp(:ult, left, right, 'cmptmp'), RLTK::CG::DoubleType, 'booltmp')\r\n end\r\nend\r\n```\r\n\r\nAST nodes whos translation requires the generation of control flow will require the creation of new BasicBlocks and the repositioning of the builder. This can be easily managed:\r\n\r\n```Ruby\r\non If do |node|\r\n cond_val = visit node.cond\r\n fcmp :one, cond_val, ZERO, 'ifcond'\r\n\r\n start_bb = current_block\r\n fun = start_bb.parent\r\n\r\n then_bb = fun.blocks.append('then')\r\n then_val, new_then_bb = visit node.then, at: then_bb, rcb: true\r\n\r\n else_bb = fun.blocks.append('else')\r\n else_val, new_else_bb = visit node.else, at: else_bb, rcb: true\r\n\r\n merge_bb = fun.blocks.append('merge', self)\r\n phi_inst = build(merge_bb) { phi RLTK::CG::DoubleType, {new_then_bb => then_val, new_else_bb => else_val}, 'iftmp' }\r\n\r\n build(start_bb) { cond cond_val, then_bb, else_bb }\r\n\r\n build(new_then_bb) { br merge_bb }\r\n build(new_else_bb) { br merge_bb }\r\n\r\n returning(phi_inst) { target merge_bb }\r\nend\r\n```\r\n\r\nMore extensive examples of how to use the Contractor class can be found in the Kazoo tutorial chapters.\r\n\r\n### Execution Engines\r\n\r\nOnce you have generated your code you may want to run it. RLTK provides bindings to both the LLVM interpreter and JIT compiler to help you do just that. Creating a JIT compiler is pretty simple.\r\n\r\n```Ruby\r\nmod = RLTK::CG::Module.new('my module')\r\njit = RLTK::CG::JITCompiler(mod)\r\n\r\nmod.functions.add('add', RLTK:CG::NativeIntType, [RLTK::CG::NativeIntType, RLTK::CG::NativeIntType]) do\r\n blocks.append('entry', nil, nil, self) do |fun|\r\n ret add(fun.params[0], fun.params[1])\r\n end\r\nend\r\n```\r\n\r\nNow you can run your 'add' function like this:\r\n\r\n```Ruby\r\njit.run(fun, 1, 2)\r\n```\r\n\r\nThe result will be a {RLTK::CG::GenericValue} object, and you will want to use its {RLTK::CG::GenericValue#to\\_i #to\\_i} and {RLTK::CG::GenericValue#to\\_f #to\\_f} methods to get the Ruby value result.\r\n\r\n## Tutorial\r\n\r\nWhat follows is an in-depth example of how to use the Ruby Language Toolkit. This tutorial will show you how to use RLTK to build a lexer, parser, AST nodes, and compiler to create a toy language called Kazoo. The tutorial is based on the LLVM [Kaleidoscope](http://llvm.org/docs/tutorial/) tutorial, but has been modified to:\r\n\r\n* a) be done in Ruby\r\n* 2) use a lexer and parser generator and\r\n* III) use a language that I call Kazoo, which is really just a cleaned up and simplified version of the Kaleidoscope language used in the LLVM tutorial (as opposed to the [Kaleidoscope language](http://en.wikipedia.org/wiki/Kaleidoscope_%28programming_language%29) from the 90′s).\r\n\r\nThe Kazoo toy language is a procedural language that allows you to define functions, use conditionals, and perform basic mathematical operations. Over the course of the tutorial we’ll extend Kazoo to support the if/then/else construct, for loops, JIT compilation, and a simple command line interface to the JIT.\r\n\r\nBecause we want to keep things simple the only datatype in Kazoo is a 64-bit floating point type (a C double or a Ruby float). As such, all values are implicitly double precision and the language doesn’t require type declarations. This gives the language a very nice and simple syntax. For example, the following example computes Fibonacci numbers:\r\n\r\n```\r\ndef fib(x)\r\n if x < 3 then\r\n 1\r\n else\r\n fib(x-1) + fib(x-2)\r\n```\r\n\r\nThe tutorial is organized as follows:\r\n\r\n * [Chapter 1: The Lexer](https://github.com/chriswailes/RLTK/blob/master/examples/kazoo/chapter%201/Chapter1.md)\r\n * [Chapter 2: The AST Nodes](https://github.com/chriswailes/RLTK/blob/master/examples/kazoo/chapter%202/Chapter2.md)\r\n * [Chapter 3: The Parser](https://github.com/chriswailes/RLTK/blob/master/examples/kazoo/chapter%203/Chapter3.md)\r\n * [Chapter 4: AST Translation](https://github.com/chriswailes/RLTK/blob/master/examples/kazoo/chapter%204/Chapter4.md)\r\n * [Chapter 5: JIT Compilation](https://github.com/chriswailes/RLTK/blob/master/examples/kazoo/chapter%205/Chapter5.md)\r\n * [Chapter 6: Adding Control Flow](https://github.com/chriswailes/RLTK/blob/master/examples/kazoo/chapter%206/Chapter6.md)\r\n * [Chapter 7: Playtime](https://github.com/chriswailes/RLTK/blob/master/examples/kazoo/chapter%207/Chapter7.md)\r\n * [Chapter 8: Mutable Variables](https://github.com/chriswailes/RLTK/blob/master/examples/kazoo/chapter%208/Chapter8.md)\r\n\r\nBefore starting this tutorial you should know about regular expressions, the basic ideas behind lexing and parsing, and be able to read context-free grammar (CFG) definitions. By the end of this tutorial we will have written 372 lines of source code and have a JIT compiler for a Turing complete language.\r\n\r\n## Provided Lexers and Parsers\r\n\r\nThe following lexer and parser classes are included as part of RLTK:\r\n\r\n* {RLTK::Lexers::Calculator}\r\n* {RLTK::Lexers::EBNF}\r\n* {RLTK::Parsers::PrefixCalc}\r\n* {RLTK::Parsers::InfixCalc}\r\n* {RLTK::Parsers::PostfixCalc}\r\n\r\n## Contributing\r\n\r\nIf you are interested in contributing to RLTK there are many aspects of the library that you can work on. A detailed TODO list can be found [here](https://github.com/chriswailes/RLTK/blob/master/TODO.md). If you are looking for smaller units of work feel free to:\r\n\r\n* Help provide unit tests. Not all of RLTK is tested as well as it could be. Specifically, more tests for the RLTK::CFG and RLTK::Parser classes would be appreciated.\r\n* Write lexers or parsers that you think others might want to use. Possibilities include HTML, JSON/YAML, Javascript, and Ruby.\r\n* Extend the RLTK::CFG class with additional functionality.\r\n\r\nLastly, I love hearing back from users. If you find any part of the documentation unclear or incomplete let me know. It is also helpful to me to know how people are using the library, so if you are using RLTK in your project send me an email. This lets me know what features are being used and where I should focus my development efforts.\r\n\r\n## News\r\n\r\nAaaaand we're back. Development of RLTK has been on hold for a while as I worked on other projects. If you want to see what I've been up to, you can check out [Clang's](http://llvm.org/clang) new `-Wconsumed` flag and the [Filigree](http://github.com/chriswailes/filigree) gem.\r\n\r\nThe next version of RLTK is going to be updated to require Ruby 2.0 as well as LLVM 3.4. Previous versions of RLTK required my LLVM-ECB libarary to expose extra LLVM features through the C bindings; this is no longer necessary as this functionality has been moved into LLVM proper. If anyone has any requests for new or improved features for RLTK version 3.0, let me know.\r\n","google":"","note":"Don't delete this file! It's used internally to help with page regeneration."}
View
226 stylesheets/print.css
@@ -0,0 +1,226 @@
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed,
+figure, figcaption, footer, header, hgroup,
+menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ vertical-align: baseline;
+}
+/* HTML5 display-role reset for older browsers */
+article, aside, details, figcaption, figure,
+footer, header, hgroup, menu, nav, section {
+ display: block;
+}
+body {
+ line-height: 1;
+}
+ol, ul {
+ list-style: none;
+}
+blockquote, q {
+ quotes: none;
+}
+blockquote:before, blockquote:after,
+q:before, q:after {
+ content: '';
+ content: none;
+}
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+body {
+ font-size: 13px;
+ line-height: 1.5;
+ font-family: 'Helvetica Neue', Helvetica, Arial, serif;
+ color: #000;
+}
+
+a {
+ color: #d5000d;
+ font-weight: bold;
+}
+
+header {
+ padding-top: 35px;
+ padding-bottom: 10px;
+}
+
+header h1 {
+ font-weight: bold;
+ letter-spacing: -1px;
+ font-size: 48px;
+ color: #303030;
+ line-height: 1.2;
+}
+
+header h2 {
+ letter-spacing: -1px;
+ font-size: 24px;
+ color: #aaa;
+ font-weight: normal;
+ line-height: 1.3;
+}
+#downloads {
+ display: none;
+}
+#main_content {
+ padding-top: 20px;
+}
+
+code, pre {
+ font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal;
+ color: #222;
+ margin-bottom: 30px;
+ font-size: 12px;
+}
+
+code {
+ padding: 0 3px;
+}
+
+pre {
+ border: solid 1px #ddd;
+ padding: 20px;
+ overflow: auto;
+}
+pre code {
+ padding: 0;
+}
+
+ul, ol, dl {
+ margin-bottom: 20px;
+}
+
+
+/* COMMON STYLES */
+
+table {
+ width: 100%;
+ border: 1px solid #ebebeb;
+}
+
+th {
+ font-weight: 500;
+}
+
+td {
+ border: 1px solid #ebebeb;
+ text-align: center;
+ font-weight: 300;
+}
+
+form {
+ background: #f2f2f2;
+ padding: 20px;
+
+}
+
+
+/* GENERAL ELEMENT TYPE STYLES */
+
+h1 {
+ font-size: 2.8em;
+}
+
+h2 {
+ font-size: 22px;
+ font-weight: bold;
+ color: #303030;
+ margin-bottom: 8px;
+}
+
+h3 {
+ color: #d5000d;
+ font-size: 18px;
+ font-weight: bold;
+ margin-bottom: 8px;
+}
+
+h4 {
+ font-size: 16px;
+ color: #303030;
+ font-weight: bold;
+}
+
+h5 {
+ font-size: 1em;
+ color: #303030;
+}
+
+h6 {
+ font-size: .8em;
+ color: #303030;
+}
+
+p {
+ font-weight: 300;
+ margin-bottom: 20px;
+}
+
+a {
+ text-decoration: none;
+}
+
+p a {
+ font-weight: 400;
+}
+
+blockquote {
+ font-size: 1.6em;
+ border-left: 10px solid #e9e9e9;
+ margin-bottom: 20px;
+ padding: 0 0 0 30px;
+}
+
+ul li {
+ list-style: disc inside;
+ padding-left: 20px;
+}
+
+ol li {
+ list-style: decimal inside;
+ padding-left: 3px;
+}
+
+dl dd {
+ font-style: italic;
+ font-weight: 100;
+}
+
+footer {
+ margin-top: 40px;
+ padding-top: 20px;
+ padding-bottom: 30px;
+ font-size: 13px;
+ color: #aaa;
+}
+
+footer a {
+ color: #666;
+}
+
+/* MISC */
+.clearfix:after {
+ clear: both;
+ content: '.';
+ display: block;
+ visibility: hidden;
+ height: 0;
+}
+
+.clearfix {display: inline-block;}
+* html .clearfix {height: 1%;}
+.clearfix {display: block;}
View
137 stylesheets/pygment_trac.css
@@ -1,70 +1,69 @@
-.highlight .hll { background-color: #404040 }
-.highlight { color: #d0d0d0 }
-.highlight .c { color: #999999; font-style: italic } /* Comment */
+.highlight { background: #ffffff; }
+.highlight .c { color: #999988; font-style: italic } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
-.highlight .g { color: #d0d0d0 } /* Generic */
-.highlight .k { color: #6ab825; font-weight: normal } /* Keyword */
-.highlight .l { color: #d0d0d0 } /* Literal */
-.highlight .n { color: #d0d0d0 } /* Name */
-.highlight .o { color: #d0d0d0 } /* Operator */
-.highlight .x { color: #d0d0d0 } /* Other */
-.highlight .p { color: #d0d0d0 } /* Punctuation */
-.highlight .cm { color: #999999; font-style: italic } /* Comment.Multiline */
-.highlight .cp { color: #cd2828; font-weight: normal } /* Comment.Preproc */
-.highlight .c1 { color: #999999; font-style: italic } /* Comment.Single */
-.highlight .cs { color: #e50808; font-weight: normal; background-color: #520000 } /* Comment.Special */
-.highlight .gd { color: #d22323 } /* Generic.Deleted */
-.highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */
-.highlight .gr { color: #d22323 } /* Generic.Error */
-.highlight .gh { color: #ffffff; font-weight: normal } /* Generic.Heading */
-.highlight .gi { color: #589819 } /* Generic.Inserted */
-.highlight .go { color: #cccccc } /* Generic.Output */
-.highlight .gp { color: #aaaaaa } /* Generic.Prompt */
-.highlight .gs { color: #d0d0d0; font-weight: normal } /* Generic.Strong */
-.highlight .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */
-.highlight .gt { color: #d22323 } /* Generic.Traceback */
-.highlight .kc { color: #6ab825; font-weight: normal } /* Keyword.Constant */
-.highlight .kd { color: #6ab825; font-weight: normal } /* Keyword.Declaration */
-.highlight .kn { color: #6ab825; font-weight: normal } /* Keyword.Namespace */
-.highlight .kp { color: #6ab825 } /* Keyword.Pseudo */
-.highlight .kr { color: #6ab825; font-weight: normal } /* Keyword.Reserved */
-.highlight .kt { color: #6ab825; font-weight: normal } /* Keyword.Type */
-.highlight .ld { color: #d0d0d0 } /* Literal.Date */
-.highlight .m { color: #3677a9 } /* Literal.Number */
-.highlight .s { color: #9dd5f1 } /* Literal.String */
-.highlight .na { color: #bbbbbb } /* Name.Attribute */
-.highlight .nb { color: #24909d } /* Name.Builtin */
-.highlight .nc { color: #447fcf; text-decoration: underline } /* Name.Class */
-.highlight .no { color: #40ffff } /* Name.Constant */
-.highlight .nd { color: #ffa500 } /* Name.Decorator */
-.highlight .ni { color: #d0d0d0 } /* Name.Entity */
-.highlight .ne { color: #bbbbbb } /* Name.Exception */
-.highlight .nf { color: #447fcf } /* Name.Function */
-.highlight .nl { color: #d0d0d0 } /* Name.Label */
-.highlight .nn { color: #447fcf; text-decoration: underline } /* Name.Namespace */
-.highlight .nx { color: #d0d0d0 } /* Name.Other */
-.highlight .py { color: #d0d0d0 } /* Name.Property */
-.highlight .nt { color: #6ab825;} /* Name.Tag */
-.highlight .nv { color: #40ffff } /* Name.Variable */
-.highlight .ow { color: #6ab825; font-weight: normal } /* Operator.Word */
-.highlight .w { color: #666666 } /* Text.Whitespace */
-.highlight .mf { color: #3677a9 } /* Literal.Number.Float */
-.highlight .mh { color: #3677a9 } /* Literal.Number.Hex */
-.highlight .mi { color: #3677a9 } /* Literal.Number.Integer */
-.highlight .mo { color: #3677a9 } /* Literal.Number.Oct */
-.highlight .sb { color: #9dd5f1 } /* Literal.String.Backtick */
-.highlight .sc { color: #9dd5f1 } /* Literal.String.Char */
-.highlight .sd { color: #9dd5f1 } /* Literal.String.Doc */
-.highlight .s2 { color: #9dd5f1 } /* Literal.String.Double */
-.highlight .se { color: #9dd5f1 } /* Literal.String.Escape */
-.highlight .sh { color: #9dd5f1 } /* Literal.String.Heredoc */
-.highlight .si { color: #9dd5f1 } /* Literal.String.Interpol */
-.highlight .sx { color: #ffa500 } /* Literal.String.Other */
-.highlight .sr { color: #9dd5f1 } /* Literal.String.Regex */
-.highlight .s1 { color: #9dd5f1 } /* Literal.String.Single */
-.highlight .ss { color: #9dd5f1 } /* Literal.String.Symbol */
-.highlight .bp { color: #24909d } /* Name.Builtin.Pseudo */
-.highlight .vc { color: #40ffff } /* Name.Variable.Class */
-.highlight .vg { color: #40ffff } /* Name.Variable.Global */
-.highlight .vi { color: #40ffff } /* Name.Variable.Instance */
-.highlight .il { color: #3677a9 } /* Literal.Number.Integer.Long */
+.highlight .k { font-weight: bold } /* Keyword */
+.highlight .o { font-weight: bold } /* Operator */
+.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
+.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
+.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
+.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
+.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
+.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
+.highlight .ge { font-style: italic } /* Generic.Emph */
+.highlight .gr { color: #aa0000 } /* Generic.Error */
+.highlight .gh { color: #999999 } /* Generic.Heading */
+.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
+.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
+.highlight .go { color: #888888 } /* Generic.Output */
+.highlight .gp { color: #555555 } /* Generic.Prompt */
+.highlight .gs { font-weight: bold } /* Generic.Strong */
+.highlight .gu { color: #800080; font-weight: bold; } /* Generic.Subheading */
+.highlight .gt { color: #aa0000 } /* Generic.Traceback */
+.highlight .kc { font-weight: bold } /* Keyword.Constant */
+.highlight .kd { font-weight: bold } /* Keyword.Declaration */
+.highlight .kn { font-weight: bold } /* Keyword.Namespace */
+.highlight .kp { font-weight: bold } /* Keyword.Pseudo */
+.highlight .kr { font-weight: bold } /* Keyword.Reserved */
+.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
+.highlight .m { color: #009999 } /* Literal.Number */
+.highlight .s { color: #d14 } /* Literal.String */
+.highlight .na { color: #008080 } /* Name.Attribute */
+.highlight .nb { color: #0086B3 } /* Name.Builtin */
+.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
+.highlight .no { color: #008080 } /* Name.Constant */
+.highlight .ni { color: #800080 } /* Name.Entity */
+.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
+.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
+.highlight .nn { color: #555555 } /* Name.Namespace */
+.highlight .nt { color: #000080 } /* Name.Tag */
+.highlight .nv { color: #008080 } /* Name.Variable */
+.highlight .ow { font-weight: bold } /* Operator.Word */
+.highlight .w { color: #bbbbbb } /* Text.Whitespace */
+.highlight .mf { color: #009999 } /* Literal.Number.Float */
+.highlight .mh { color: #009999 } /* Literal.Number.Hex */
+.highlight .mi { color: #009999 } /* Literal.Number.Integer */
+.highlight .mo { color: #009999 } /* Literal.Number.Oct */
+.highlight .sb { color: #d14 } /* Literal.String.Backtick */
+.highlight .sc { color: #d14 } /* Literal.String.Char */
+.highlight .sd { color: #d14 } /* Literal.String.Doc */
+.highlight .s2 { color: #d14 } /* Literal.String.Double */
+.highlight .se { color: #d14 } /* Literal.String.Escape */
+.highlight .sh { color: #d14 } /* Literal.String.Heredoc */
+.highlight .si { color: #d14 } /* Literal.String.Interpol */
+.highlight .sx { color: #d14 } /* Literal.String.Other */
+.highlight .sr { color: #009926 } /* Literal.String.Regex */
+.highlight .s1 { color: #d14 } /* Literal.String.Single */
+.highlight .ss { color: #990073 } /* Literal.String.Symbol */
+.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
+.highlight .vc { color: #008080 } /* Name.Variable.Class */
+.highlight .vg { color: #008080 } /* Name.Variable.Global */
+.highlight .vi { color: #008080 } /* Name.Variable.Instance */
+.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
+
+.type-csharp .highlight .k { color: #0000FF }
+.type-csharp .highlight .kt { color: #0000FF }
+.type-csharp .highlight .nf { color: #000000; font-weight: normal }
+.type-csharp .highlight .nc { color: #2B91AF }
+.type-csharp .highlight .nn { color: #000000 }
+.type-csharp .highlight .s { color: #A31515 }
+.type-csharp .highlight .sc { color: #A31515 }
View
371 stylesheets/stylesheet.css
@@ -0,0 +1,371 @@
+/* http://meyerweb.com/eric/tools/css/reset/
+ v2.0 | 20110126
+ License: none (public domain)
+*/
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed,
+figure, figcaption, footer, header, hgroup,
+menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ vertical-align: baseline;
+}
+/* HTML5 display-role reset for older browsers */
+article, aside, details, figcaption, figure,
+footer, header, hgroup, menu, nav, section {
+ display: block;
+}
+body {
+ line-height: 1;
+}
+ol, ul {
+ list-style: none;
+}
+blockquote, q {
+ quotes: none;
+}
+blockquote:before, blockquote:after,
+q:before, q:after {
+ content: '';
+ content: none;
+}
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+/* LAYOUT STYLES */
+body {
+ font-size: 1em;
+ line-height: 1.5;
+ background: #e7e7e7 url(../images/body-bg.png) 0 0 repeat;
+ font-family: 'Helvetica Neue', Helvetica, Arial, serif;
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.8);
+ color: #6d6d6d;
+}
+
+a {
+ color: #d5000d;
+}
+a:hover {
+ color: #c5000c;
+}
+
+header {
+ padding-top: 35px;
+ padding-bottom: 25px;
+}
+
+header h1 {
+ font-family: 'Chivo', 'Helvetica Neue', Helvetica, Arial, serif; font-weight: 900;
+ letter-spacing: -1px;
+ font-size: 48px;
+ color: #303030;
+ line-height: 1.2;
+}
+
+header h2 {
+ letter-spacing: -1px;
+ font-size: 24px;
+ color: #aaa;
+ font-weight: normal;
+ line-height: 1.3;
+}
+
+#container {
+ background: transparent url(../images/highlight-bg.jpg) 50% 0 no-repeat;
+ min-height: 595px;
+}
+
+.inner {
+ width: 620px;
+ margin: 0 auto;
+}
+
+#container .inner img {
+ max-width: 100%;
+}
+
+#downloads {
+ margin-bottom: 40px;
+}
+
+a.button {
+ -moz-border-radius: 30px;
+ -webkit-border-radius: 30px;
+ border-radius: 30px;
+ border-top: solid 1px #cbcbcb;
+ border-left: solid 1px #b7b7b7;
+ border-right: solid 1px #b7b7b7;
+ border-bottom: solid 1px #b3b3b3;
+ color: #303030;
+ line-height: 25px;
+ font-weight: bold;
+ font-size: 15px;
+ padding: 12px 8px 12px 8px;
+ display: block;
+ float: left;
+ width: 179px;
+ margin-right: 14px;
+ background: #fdfdfd; /* Old browsers */
+ background: -moz-linear-gradient(top, #fdfdfd 0%, #f2f2f2 100%); /* FF3.6+ */
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#fdfdfd), color-stop(100%,#f2f2f2)); /* Chrome,Safari4+ */
+ background: -webkit-linear-gradient(top, #fdfdfd 0%,#f2f2f2 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #fdfdfd 0%,#f2f2f2 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #fdfdfd 0%,#f2f2f2 100%); /* IE10+ */
+ background: linear-gradient(top, #fdfdfd 0%,#f2f2f2 100%); /* W3C */
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fdfdfd', endColorstr='#f2f2f2',GradientType=0 ); /* IE6-9 */
+ -webkit-box-shadow: 10px 10px 5px #888;
+ -moz-box-shadow: 10px 10px 5px #888;
+ box-shadow: 0px 1px 5px #e8e8e8;
+}
+a.button:hover {
+ border-top: solid 1px #b7b7b7;
+ border-left: solid 1px #b3b3b3;
+ border-right: solid 1px #b3b3b3;
+ border-bottom: solid 1px #b3b3b3;
+ background: #fafafa; /* Old browsers */
+ background: -moz-linear-gradient(top, #fdfdfd 0%, #f6f6f6 100%); /* FF3.6+ */
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#fdfdfd), color-stop(100%,#f6f6f6)); /* Chrome,Safari4+ */
+ background: -webkit-linear-gradient(top, #fdfdfd 0%,#f6f6f6 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #fdfdfd 0%,#f6f6f6 100%); /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #fdfdfd 0%,#f6f6f6 100%); /* IE10+ */
+ background: linear-gradient(top, #fdfdfd 0%,#f6f6f6, 100%); /* W3C */
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fdfdfd', endColorstr='#f6f6f6',GradientType=0 ); /* IE6-9 */
+}
+
+a.button span {
+ padding-left: 50px;
+ display: block;
+ height: 23px;
+}
+
+#download-zip span {
+ background: transparent url(../images/zip-icon.png) 12px 50% no-repeat;
+}
+#download-tar-gz span {
+ background: transparent url(../images/tar-gz-icon.png) 12px 50% no-repeat;
+}
+#view-on-github span {
+ background: transparent url(../images/octocat-icon.png) 12px 50% no-repeat;
+}
+#view-on-github {
+ margin-right: 0;
+}
+
+code, pre {
+ font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal;
+ color: #222;
+ margin-bottom: 30px;
+ font-size: 14px;
+}
+
+code {
+ background-color: #f2f2f2;
+ border: solid 1px #ddd;
+ padding: 0 3px;
+}
+
+pre {
+ padding: 20px;
+ background: #303030;
+ color: #f2f2f2;
+ text-shadow: none;
+ overflow: auto;
+}
+pre code {
+ color: #f2f2f2;
+ background-color: #303030;
+ border: none;
+ padding: 0;
+}
+
+ul, ol, dl {
+ margin-bottom: 20px;
+}
+
+
+/* COMMON STYLES */
+
+hr {
+ height: 1px;
+ line-height: 1px;
+ margin-top: 1em;
+ padding-bottom: 1em;
+ border: none;
+ background: transparent url('../images/hr.png') 50% 0 no-repeat;
+}
+
+strong {
+ font-weight: bold;
+}
+
+em {
+ font-style: italic;
+}
+
+table {
+ width: 100%;
+ border: 1px solid #ebebeb;
+}
+
+th {
+ font-weight: 500;
+}
+
+td {
+ border: 1px solid #ebebeb;
+ text-align: center;
+ font-weight: 300;
+}
+
+form {
+ background: #f2f2f2;
+ padding: 20px;
+
+}
+
+
+/* GENERAL ELEMENT TYPE STYLES */
+
+h1 {
+ font-size: 32px;
+}
+
+h2 {
+ font-size: 22px;
+ font-weight: bold;
+ color: #303030;
+ margin-bottom: 8px;
+}
+
+h3 {
+ color: #d5000d;
+ font-size: 18px;
+ font-weight: bold;
+ margin-bottom: 8px;
+}
+
+h4 {
+ font-size: 16px;
+ color: #303030;
+ font-weight: bold;
+}
+
+h5 {
+ font-size: 1em;
+ color: #303030;
+}
+
+h6 {
+ font-size: .8em;
+ color: #303030;
+}
+
+p {
+ font-weight: 300;
+ margin-bottom: 20px;
+}
+
+a {
+ text-decoration: none;
+}
+
+p a {
+ font-weight: 400;
+}
+
+blockquote {
+ font-size: 1.6em;
+ border-left: 10px solid #e9e9e9;
+ margin-bottom: 20px;
+ padding: 0 0 0 30px;
+}
+
+ul li {
+ list-style: disc inside;
+ padding-left: 20px;
+}
+
+ol li {
+ list-style: decimal inside;
+ padding-left: 3px;
+}
+
+dl dt {
+ color: #303030;
+}
+
+footer {
+ background: transparent url('../images/hr.png') 0 0 no-repeat;
+ margin-top: 40px;
+ padding-top: 20px;
+ padding-bottom: 30px;
+ font-size: 13px;
+ color: #aaa;
+}
+
+footer a {
+ color: #666;
+}
+footer a:hover {
+ color: #444;
+}
+
+/* MISC */
+.clearfix:after {
+ clear: both;
+ content: '.';
+ display: block;
+ visibility: hidden;
+ height: 0;
+}
+
+.clearfix {display: inline-block;}
+* html .clearfix {height: 1%;}
+.clearfix {display: block;}
+
+/* #Media Queries
+================================================== */
+
+/* Smaller than standard 960 (devices and browsers) */
+@media only screen and (max-width: 959px) {}
+
+/* Tablet Portrait size to standard 960 (devices and browsers) */
+@media only screen and (min-width: 768px) and (max-width: 959px) {}
+
+/* All Mobile Sizes (devices and browser) */
+@media only screen and (max-width: 767px) {
+ header {
+ padding-top: 10px;
+ padding-bottom: 10px;
+ }
+ #downloads {
+ margin-bottom: 25px;
+ }
+ #download-zip, #download-tar-gz {
+ display: none;
+ }
+ .inner {
+ width: 94%;
+ margin: 0 auto;
+ }
+}
+
+/* Mobile Landscape Size to Tablet Portrait (devices and browsers) */
+@media only screen and (min-width: 480px) and (max-width: 767px) {}
+
+/* Mobile Portrait Size to Mobile Landscape Size (devices and browsers) */
+@media only screen and (max-width: 479px) {}

0 comments on commit 6c01812

Please sign in to comment.