Единственный способ развеить скепсис — это попробовать.
Я решил попробовать макросы Nemerle в более-менее реальной задаче. Цель две.
1. Изучить собственно Nemerle и его макросы.
2. Продемонстрировать его возможности на этом форуме.
Я планирую несколько сообщений которые будут являться подсообщениями этого.
Так как многие из вас захотят попробовать приводимый мною код, то начнем пожалуй с подготовительного этапа. Конечно в реальных условиях многие из вас предпочту полноценную IDE и какую-нибудь утилиту сборки (make, Ant или MSBuild), но учитывая, что для данного случая скорее важна простота вхождения, я решил остановиться на Сцинтиле как редакторе и обычном бач-файле для сборки проекта. Ведь нам пока что достаточно компилировать два файла (сборку с макросами и целевую сборку).
Итак, для экспериментов вам понадобится:
1. .NET Framework 2.0 (и возможно SDK). Лучше конечно если на машине просто установлена VS 2005.
2. Компилятор Nemerle и сопутствующая ему байда. Все это можно взять на их сайте
http://nemerle.org. Так здесь
http://nemerle.org/download/msi/nemerle-0.9.2.msi лежит инсталлятор для Виндовс. А здесь
http://nemerle.org/download/ можно взять более свежую рабочую версию причем вместе с исходниками. Очень советую это сделать даже если вы выберете инсталляцию msi-я, так как поглядеть на исходники макросво и вообще на исподники созданные авторами языка очень полезно. Полноценной документации ведь пока нет, а исходники говорят о многом.
2. Сцинтила или другой редактор который упростить ввод и тестирование кода. Сцентилу можно взять здесь:
http://prdownloads.sourceforge.net/scintilla/wscite167.zip?use_mirror=heanet
Файлы для обеспечения подсветки синтаксиса Nemerle для Сцинтылы можно взять здесь:
http://nemerle.org/svn/nemerle/trunk/misc/scintilla/SciTEGlobal.properties
http://nemerle.org/svn/nemerle/trunk/misc/scintilla/nemerle.properties
их нужно скопировать в каталог где лежат другие properties-файлы Сцинтилы.
3. Для упрощения компиляции и запуска файлов я написал простенький cmd-файлик для ХРюши:
@echo off
SET FileName=%1
SET MacroOutFileName=%FileName%-macro.dll
SET MacroSourceFileName=%FileName%-macro.n
SET SourceFileName=%FileName%.n
SET OutFileName=%FileName%.exe
if exist %MacroSourceFileName% (
@echo --# Compiling Macro-assembly #---
@echo ---------------------------------
ncc.exe -no-color -debug+ -r Nemerle.Compiler.dll -t:dll %MacroSourceFileName% -out %MacroOutFileName%
if not errorlevel 1 (
@echo --- Compiling target assembly ---
@echo ---------------------------------
ncc.exe -no-color -debug+ -r %MacroOutFileName% -t exe %SourceFileName% -o %OutFileName%
rem -r System.Windows.Forms -r System.Data
if errorlevel 1 (
@echo -------------------------------------
@echo !!! Error detected in targer code !!!
) else (
@echo --------------- OK -----------------
@echo --Run: %OutFileName%
@echo .
%OutFileName%
)
) else (
@echo ------------------------------------
@echo !!! Error detected in macro-code !!!
)
) else (
@echo ----- No Macro-assembly found ------
@echo ------------------------------------
if not errorlevel 1 (
@echo --- Compiling target assembly ---
@echo ---------------------------------
ncc.exe -no-color -debug+ -t exe %SourceFileName% -o %OutFileName%
rem -r System.Windows.Forms -r System.Data
if errorlevel 1 (
@echo -------------------------------------
@echo !!! Error detected in targer code !!!
) else (
@echo --------------- OK -----------------
@echo --- Run: %OutFileName%
@echo .
%OutFileName%
)
) else (
@echo ------------------------------------
@echo --! Error detected in macro-code !--
)
)
Его нужно сохранить под именеме build-and-run.cmd в каталог где лежат бинарники Нэмерла (файл ncc.exe и т.п.).
Далее нужно отредактировать файл nemerle.properties добавив в него примерно такие строчки:
#Extra tool: Build With Macro and Run
#Build macro and target for console application"
command.name.6.*.n=Build With Macro and Run
command.6.*.n=build-and-run.cmd $(FileName)
command.6.subsystem.*.n=0
command.save.before.6.*.n=1
command.shortcut.6.*.n=F5
При этом, если что, нужно или изменить F5 на удобную для себя кнопку, или убрать/изменить аналогичный шорткат у имеющегся в nemerle.properties пункта.
Теперь открыв в Сцинтиле файл с расширением .n вы можете просто нажатием на F5 скомпилировать его и запустить на выполнение.
Если при этом рядом с компилируемым файлом будет лежать файл начальная часть имени которого совпадает с компилируемым, и оно оканчивается на «-macro», то сначала будет произведена компиляция этого файла. А потом, вслучае успеха будет откомплирован вайл без суффикса «–macro». Причем при его компиляции будет подключаться макросборка получившаяся на первом этапе. Например, если имеются файлы:
test-001.n
test-001-macro.n
если активизировать в Сцинтиле файл test-001.n и нажать F5, то будет сначала произвдена компиляция макросборки test-001-macro.dll (на базе файла test-001-macro.n), а потом будет произведена компиляция сборки test-001.exe (на базе файла test-001.n). Причем при компиляции test-001.exe будет использована макро-сборк полученная на первом этапе.
Если все скомпилируется, то будет произведен запуск test-001.exe. Иначе будет выданы сообщения об ошибке.
Для того, чтобы убедиться, что все работает создайте простенькую тестовую пару файлов:
Test-001.n – содержащий следующий код:
// abstract, and, array, as, base, catch, class, def, delegate, do, else, enum, event, extern, false, finally, for, foreach, fun, if, implements, in, interface, internal, lock, macro, match, module, mutable, namespace, new, null, out, override, params,
// WriteLine public private protected internal
TestMacro();
Примечание: Коментарии с лабудой нужны для того, чтобы можно было пользоваться недо-интелисенсом. Если в Сцинтиле написат первые буквы слова и нажать Ctrl+Enter, то она выдаст список слов начинающихся на эти буквы.
И файл test-001-macro.n содержащий следующий код:
using System.Console;
// abstract, and, array, as, base, catch, class, def, delegate, do, else, enum, event, extern, false, finally, for, foreach, fun, if, implements, in, interface, internal, lock, macro, match, module, mutable, namespace, new, null, out, override, params,
// WriteLine public private protected internal
macro TestMacro()
{
WriteLine("compile-time\n");
<[ WriteLine("run-time\n") ]>;
}
Теперь откройте Сцинтилой файл Test-001.n и нажмите F5.
Если в ответ вы увидите следующее:
>build-and-run.cmd test-001
--# Compiling Macro-assembly #---
---------------------------------
--- Compiling target assembly ---
---------------------------------
compile-time
--------------- OK -----------------
--Run: test-001.exe
.
run-time
>Exit code: 0
Значит вы все сделали верно и первый этап знакомства с Нэмерлом и его макросами пройдет.
Если вам сказали, что мол файл не найдет, то пропишите путь к каталогу с бинарниками Нэмерла в переменную PATH окружения.
Теперь прокомментирую, что вы видите на экране. Вывод:
---------------------------------
--- Compiling target assembly ---
---------------------------------
compile-time
Означает что началась компиляция основной сборки (сборки которую мы будем запускать на исполнение) и вызвался макрос. Который вывел информацию о себе на констоль. Надпись:
run-time
Ввел код сгенерированный макросом. Если вы теперь откроете полученный исполнимый файл Рефлектором, то увидите, что в функции Main() присутствует вызов:
Console.WriteLine("run-time\n");
а от макроса не осталось и следа. Это и есть чудесное действие макросов.
Продолжение следует.
... << RSDN@Home 1.2.0 alpha rev. 637>>
14.03.06 11:09: Перенесено из 'Философия программирования'
30.01.07 18:23: Перенесено модератором из 'Декларативное программирование' — IT