现在的位置: 首页 > 综合 > 正文

2008 October 17th Friday (十月 十七日 金曜日)

2013年04月22日 ⁄ 综合 ⁄ 共 6300字 ⁄ 字号 评论关闭
   Lua is a powerful embedding script.  It has many features similar to scheme.  However, it is so simple.

  In lua, the upvalue is an interesting type.  It accutally means the value from the up level.  It is used to
make a "C closure" conveniencely.

  Nowadays, lua is prevailling among thousand game players.  So, game is a power.

dynamic_cast<Type *>(pt)

  The purpose of this operator is to allow upcasts within a class hierarchy (such type casts being safe because
of the is-a relationship) and to disallow other casts.

  To converts the pointer pt to a pointer of type Type * if the pointed-to object (*pt) is of type Type or else
derived directly or indirectly from type Type. Otherwise, the expression evaluates to 0, the null pointer.

  The typeid operator returns a reference to a type_info object, where type_info is a class defined in the
typeinfo header file (formerly typeinfo.h). The type_info class overloads the == and != operators so that you
can use these operators to compare types. For example, the expression

typeid(Magnificent) == typeid(*pg)

evaluates to the bool value true if pg points to a Magnificent object and to false otherwise. If pg happens to
be a null pointer, the program will throw a bad_typeid exception. This exception type is derived from the exception
class and is declared in the typeinfo header file.

  The implementation of the type_info class will vary among vendors, but it will include a name() member that
returns an implementation-dependent string that typically would be the name of the class.

const_cast < type-name > (expression)

  The result making such a cast is an error if any other aspect of the type is altered. That is, type_name and
expression must be of the same type except they can differ in the presence or absence of const or volatile.

High bar;
const High * pbar;
    ...
High * pb = const_cast<High *> (pbar);    // valid

static_cast < type-name > (expression)

  It's valid only if type_name can be converted implicitly to the same type expression has, or vice versa. Otherwise,
the cast is an error. Suppose High is a base class to Low and that Pond is an unrelated class. Then conversions from
High to Low and Low to High are valid, but a conversion from Low to Pond is disallowed:

High bar;
Low blow;
...
High * pb = static_cast<High *> (&blow);     // valid upcast
Low * pl = static_cast<Low *> (&bar);        // valid downcast
Pond * pmer = static_cast<Pond *> (&blow);   // invalid, Pond unrelated

  The first conversion is valid because an upcast can be done explicitly. The second conversion, from a base-class
pointer to a derived-class pointer can't be done without an explicit type conversion. But because the type cast in
the other direction can be made without a type cast, it's valid to use a static_cast for a downcast.

  Similarly, because an enumeration value can be converted to an integral type without a type cast, an integral type
can be converted to an enumeration value with static_cast. Similarly, you can use static_cast to convert double to int,
float to long, and the various other numeric conversions.

reinterpret_cast < type-name > (expression)

  The reinterpret_cast operator is for inherently risky type-casts. It won't let you cast away const, but it will do
other unsavory things. Sometimes a programmer has to do implementation-dependent, unsavory things, and using the reinterpret_cast
operator makes it simpler to keep track of such acts.

  Typically, such casts would be used for low-level, implementation-dependent programming and would not be portable.

Namespace in mzscheme

  For expansion purposes, a namespace maps each symbol in each phase level to one of three possible bindings:

*a particular module binding from a particular module

*a top-level transformer binding named by the symbol

*a top-level variable named by the symbol

  A namespace is purely a top-level entity, not to be confused with an environment. In particular, a namespace does not encapsulate
the full environment of an expression inside local-binding forms.

  If an identifier is bound to syntax or to an import, then defining the identifier as a variable shadows the syntax or import in
future uses of the environment. Similarly, if an identifier is bound to a top-level variable, then binding the identifier to syntax
or an import shadows the variable; the variable’s value remains unchanged, however, and may be accessible through previously evaluated
expressions.

  After a namespace is created, module instances from existing namespaces can be attached to the new namespace. In terms of the evaluation
model, top-level variables from different namespaces essentially correspond to definitions with different prefixes. Furthermore, the first
step in evaluating any compiled expression is to link its top-level variable and module-level variable references to specific variables in
the namespace.

  At all times during evaluation, some namespace is designated as the current namespace. The current namespace has no particular relationship,
however, with the namespace that was used to expand the code that is executing, or with the namespace that was used to link the compiled form
of the currently evaluating code. In particular, changing the current namespace during evaluation does not change the variables to which executing
expressions refer. The current namespace only determines the behavior of reflective operations to expand code and to start evaluating expanded/compiled
code.

  There is reverse a list in prolog.

reverse([], R, R).
reverse([H|T], TMP, R) :- reverse(T, [H|TMP], R).

?- reverse([ants, mice, zebras], [], X).
X = [zebras, mice, ants]

Definite clause grammars

  Definite clause grammars are a useful notation to express grammar rules. However the ISO reference does not include them, so they should be considered
as a system dependent feature. Definite clause grammars are an extension of context-free grammars. A grammar rule is of the form:

  head --> body.
--> is a predefined infix operator.

  Here are some features of definite clause grammars:
*a non-terminal symbol may be any callable term.

*a terminal symbol may be any Prolog term and is written as a list. The empty list represents an empty sequence of terminals.

*a sequence is expressed using the Prolog conjunction operator ((',')/2).

The head of a grammar rule consists of a non-terminal optionally followed by a sequence of terminals (i.e. a Prolog list). The body of a grammar rule consists
of a sequence of non-terminals, terminals, predicate call, disjunction (using ;/2), if-then (using (->)/2) or cut (using !).

  A predicate call must be enclosed in curly brackets (using {}/1). This makes it possible to express an extra condition.
A grammar rule is nothing but a “syntactic sugar” for a Prolog clause. Each grammar rule accepts as input a list of terminals (tokens), parses a prefix of
this list and gives as output the rest of this list (possibly enlarged). This rest is generally parsed later. So, each a grammar rule is translated into a Prolog
clause that explicitly the manages the list.

  It is possible to include a call to a prolog predicate enclosing it in curly brackets({}) (to distinguish them from non-terminals):
assign(X,Y) --> left(X), [:=], right(Y0), {Y is Y0 }, [;].

is translated into:

assign(X,Y,Start,End) :-
        left(X, Start, A),
        A=[:=|B],
        right(Y0, B, C),
        Y is Y0,
        C=[;|End].
  Cut, disjunction and if-then(-else) are translated literally (and do not need to be enclosed in curly brackets).

抱歉!评论已关闭.