Class Models for Lua

# Conditional Compiler

## `loop.compiler.Conditional`

Class of objects that executes selected pieces of a chunk of Lua code. This class is useful for generating optimized functions that avoids condition tests or other constructions when such actions can be previously identified as unecessary. Since the execution of the selected pieces of the code chunk may be relatively slow, this approach is preferable for creation of optmized function that are generated rarely but are evaluated constantly.

Each object contains a list of pairs that contain a chunk of Lua code and a Lua expression that defines whether the chunk should be executed or not, e.g. used in the generation of a customized function. When the conditional code is executed, a table is provided containing the options used to select the appropriate pieces of the chunk.

## Behavior

### Fields

`name` [optional]
  Name of the compiled conditional code that is used in error messages (this name is used in the call of function `loadstring` that compiles the conditional code).

### Methods

`source(options)`
  Generate the source containing only selected pieces of the chunk that are identified by the evaluation of each associated conditional expressions with the values provided by `options`.
`execute(options, ...)`
  Compiles and executes the selected pieces of the chunk that are identified by the evaluation of each associated conditional expressions with the values provided by `options`. The aditional parameters are passed to the conditional code being executed. All the values returned by the conditional code is retured by this function.

## Remarks

- The creation of customized functions implies in compilation and evaluation of each conditional expression as well as chunk concatenation, compilation and execution, therefore it results in a very expensive operation.

## Examples

### Classes with `__index` meta-method.

    local oo          = require "loop.base"
    local Conditional = require "loop.compiler.Conditional"

    local indexer = Conditional{
      { [[local class = ...                     ]]                            },
      { [[local index = class.__index           ]], "indextype ~= 'nil'"      },
      { [[local super = select(2, ...)          ]], "supercount > 0"          },
      { [[return function(self, field)          ]]                            },
      { [[  local value                         ]]                            },
      { [[    = index[field]                    ]], "indextype == 'table'"    },
      { [[    = index(self, field)              ]], "indextype == 'function'" },
      { [[  if value == nil then                ]], "indextype ~= 'nil'"      },
      { [[    value = class[field]              ]]                            },
      { [[    if value == nil then              ]], "supercount > 0"          },
      { [[      value = super[field]            ]], "supercount == 1"         },
      { [[      for _, super in ipairs(super) do]], "supercount > 1"          },
      { [[        value = super[field]          ]], "supercount > 1"          },
      { [[        if value ~= nil then break end]], "supercount > 1"          },
      { [[      end                             ]], "supercount > 1"          },
      { [[    end                               ]], "supercount > 0"          },
      { [[  end                                 ]], "indextype ~= 'nil'"      },
      { [[  return value                        ]]                            },
      { [[end                                   ]]                            },
    }

    function class(class, ...)
      local options = {
        supercount = select("#", ...),
        indextype = type(class.__index),
      }
      local super
      if options.supercount <= 1
        then super =   ...
        else super = { ... }
      end
      class.__index = indexer:execute(options, class, super)
      return oo.class(class)
    end

    Class = class(
      -- class fields
      {
        classfield = "classfield",
        __index = function(_, field)
          if field == "dynamicfield" then
            return field
          end
        end,
      },
      -- superclasses
      { inherited1 = "inherited1" },
      { inherited2 = "inherited2" }
    )

    Object = Class{ objectfield = "objectfield" }

    print("Object.objectfield  = "..Object.objectfield )
    print("Object.classfield   = "..Object.classfield  )
    print("Object.dynamicfield = "..Object.dynamicfield)
    print("Object.inherited1   = "..Object.inherited1  )
    print("Object.inherited2   = "..Object.inherited2  )

Copyright (C) 2004-2008 Tecgraf, PUC-Rio

This project is currently being maintained by Tecgraf at PUC-Rio.