Meta programming evaluator, pluggable components!

This file is almost completely rewritten, I involved some meta
programming to implement some DSL for just handling dynamically the
different operations.

And now I really diminished so many duplicated code, and the most
important thing is, it is now more elegant!

I involved these new functions:
  - CScriptEvaluator#handler
  - eval_error
  - newval
  - dispatch
And the `evaluate` is almost compltely rewritten also(actually all
functions in this module are rewritten).

First, I'll describe all function's function and its usage.

handler:
    A module-macro(opposite to class macro), defined in the module. The
    arguments are in three forms. (and with a block)
    First: more than one type to be handled.
    Second: an Array of operators that would be evaluated automatically
    Third: options
    While the first one is ncessary to indicate the handler and being
    done the matching work for eval types.

    The second and the third is optional, in default
    condition it will pass all the raw subnodes of the
    syntatic tree node, which means, you need only to pick them in
    the parameter of the block.

    The second argument of the function controls
    which evaluations of subnodes will be done by the `dispatcher`
    rather than user to do it manually. However, once you got the
    convience, you'll lose some flexibility. Just pass an array of
    numbers of indexes of the subnodes is okay.

    The thrid argument controls other options. for instance, if you need
    to get a raw tree rather than the subnodes, you gotta add
        `:raw => true`
    at the end of arguments, it will pass the whole tree without any
    process as argument to you.

eval_error:
    This function is used for report runtime error conveniently, if you
    got some wrong in user's code, such as refering to a undefined
    variables, you could raise an error easily by this function rather
    write a huge amout of code to raise yourself manually.

    Most easy way to use this is just pass some error message into the argument,
    and it will automatically get the runtime stack, the exception type
    (CScriptRuntimeError), and then raise it.

    For a little addvanced use, you can take an Exception class into the
    first argument, and then input your error message(this is required
    for this form).

    For both two forms of calls, you can also optionally pass a error stack as
    the last argument.

newval:
    Alias for CScriptValue.new

dispatch:
    This function will simply match the current tree's type and pass it
    to a matched handler. Also, it do automatically evaluation for needs.

    Do not call this function directly unless you know exactly what you
    are doing, just call `evaluate` instead.

evaluate:
    Just as before, but now all dispatching work is separated to the
    specific dispatcher. It would now only do some simple thing, like
    environment communicate management, status validating and such like.

    Call this as before just.

A sample handler:

    handler :MULTIPLY, [0, 1] do |op1, op2|
        if op1.type_is? :INTEGER and op2.type_is? :INTEGER then
            newval(op1.val * op2.val)
        elsif op1.type_is? :STRING and op2.type_is? :INTEGER then
            newval(op1.val * op2.val)
        else
            eval_error("Type Error")
        end
    end

I just got another whole night through today! Nice dream now!

Shou
Sun May 20 08:24:27 CST 2012