Wednesday, November 25, 2009

Анонс

Последние полгода я занимался изучением того, что принято называть "Modern C++" изучая код Boost.Spirit (Classic). Фактически, то чем я занимался можно разделить на 2 части:
1. Изучение функциональности и основных идей Spirit.
2. Реализация своего варианта.

Особенно интересен второй пункт. Он состоит из двух подпунктов:
а. Язык C++ во всём своём великолепии. Можно охарактеризовать так: шаблонное метапрограммирование.
б. Проектирование и принятие решений.

Работа, в основном, состояла в (преднамеренных) бессчётных попытках изобрести велосипед. Я заставлял себя принимать аргументированные Решения. Я пытался слушать свою интуицию в надежде сделать лучше, чем оригинал Джоела Де Гузмана. Уходили недели на то, чтобы убедиться, что мои решения заводят весь проект в тупик и ничего с этим не сделаешь.
Кроме того, что за время работы мне удалось неплохо улучшить свои знания в C++, также удалось скорректировать своё понимание того, как нужно писать код и как его писать не нужно.

Надеюсь закончить полное описание этой работы через пару месяцев.

Monday, November 23, 2009

Тизер.


Фибоначчи:
a = b = 1;
i = 0;
while(i < 10) {
c = a + b;
?(c);
a = b;
b = c;
i = i + 1;
}

Результат:
PRINT: 2
PRINT: 3
PRINT: 5
PRINT: 8
PRINT: 13
PRINT: 21
PRINT: 34
PRINT: 55
PRINT: 89
PRINT: 144
CONTEXT:
'a' is 89
'b' is 144
'c' is 144
'i' is 10

P.S. Вот и кончился отпуск.

Thursday, November 19, 2009

3*(2+1)

Один из нескольких способов вычислить 3*(2+1) на C++.

#include <iostream>

//
struct empty_t {};

template<class Value, class Children = empty_t>
struct Node
{
typedef Value value;
typedef Children children;
};

template<class TA, class TB = empty_t>
struct Tree
{
typedef TA ta;
typedef TB tb;
};
//

//
struct Add
{
template<int A, int B>
struct Do { enum { value = A + B }; };
};

struct Mul
{
template<int A, int B>
struct Do { enum { value = A * B }; };
};

template<int X>
struct Val
{
enum { val = X };
};
//

//
template<class NodeT>
struct compute;

// если узел - это число
template<class ValueT>
struct compute<Node<ValueT, empty_t> >
{
enum { value = ValueT::val };
};

// если узел - это операция
template<class ValueT, class ChildrenT>
struct compute<Node<ValueT, ChildrenT> >
{
enum
{
A = compute<typename ChildrenT::ta>::value,
B = compute<typename ChildrenT::tb>::value,
value = ValueT::template Do<A, B>::value
};
};

int main()
{
// 3*(2+1)
typedef Node<
Mul,
Tree<
Node<Val<3> >,
Node<
Add,
Tree<
Node<Val<2> >,
Node<Val<1> >
>
>
>
> expr;

std::cout << compute<expr>::value << std::endl; // 9
}

По-моему, неплохой способ свести кого-нибудь с ума. Вообще не об этом. О том, что с помощью шаблонов можно забавно описывать статические древовидные структуры.

Saturday, November 7, 2009

Тизер.


...
int main()
{
char const* str = "myvalue=2*(yourvalue=1);myvalue=myvalue+1;";

typedef AstParseInfo<char const*> parse_info_t;
parse_info_t tpi =
ast_parse(str, str+strlen(str), MyGrammar(), *ch_p(' '));

typedef std::map<std::string, int> context_t;
context_t context;
int v = evaluate(tpi.nodes[0], context);

std::cout << "CONTEXT: " << std::endl;
typedef context_t::const_iterator context_iter_t;
for(context_iter_t it = context.begin(); it != context.end(); ++it)
{
std::cout
<< " '"
<< (*it).first
<< "' is "
<< (*it).second
<< std::endl;
}
}
...


debug: set 'yourvalue' to 1
debug: set 'myvalue' to 2
debug: set 'myvalue' to 3
CONTEXT:
'myvalue' is 3
'yourvalue' is 1
Press [Enter] to close the terminal ...

P.S. Наконец-то отпуск.