Прям как в анекдоте:
— Мужики, я себе такой мобильник купил! тариф — все исходящие бесплатно!
— Да нуу, так не бывает. Должны быть какие-то минусы.
— Нет никаких минусов!
— Может, трубка тяжелая, с чемодан размером?
— Да нет. Обычная трубка. Записывайте номер: 8921677443865202957. Это код. Теперь номер…
А кнопка «показать» лучше помогает от опечатки?
Уверен, что немногие с первого же взгляда увидят, что ввели
Ytcecdtynfz{eqyz вместо Ytcecdtnyfz{eqyz.
Я так и вовсе понятия не имею, как мой пароль выглядит :)
Во, напомнили: еще один пример самоисполняемых данных.
Традиционные интерпретаторы выглядят как большущий switch в цикле: for (;;) {
switch (next_bytecode()) {
case CODE_0:
...
break;
case CODE_1:
...
break;
case CODE_N:
...
break;
}
}
А можно интерпретатор сделать проще и наглядней с самоисполняемым промежуточным представлением (IR). В моем случае это Control Flow Graph (CFG), вершинами которого служат экземпляры класса Instruction с виртуальным методом execute:
Кстати, когда-то давно я написал простенький парсер выражений на С++ (как раз для всякого рода конфигурационных файлов), постепенно он обрастал и усложнялся, пока не вырос в очень-похожий-на-ECMAscript язык с функциями, объектами, сборщиком мусора и всё такое :)
Так что могу поделиться и своим движком, если интересно. Пусть он и не полностью совместим с ECMA-262, зато по коду очень компактный и простой.
Значит, неудача :) А если серьезно, то ничего хитрого и для C++ нет: берется ECMAscript engine с открытым кодом на нужном Вам языке — en.wikipedia.org/wiki/List_of_ECMAscript_engines, с использованием его API создаются обёртки для объектов, которые будут «видны» из скрипта — и все, можно исполнять Javascript-подобные сценарии из Вашей программы.
Не, ну, если Вы дадите пользователям править php-конфиги, то будут у Вас и проблемы с безопасностью, и с непонятками формата. По мне так конфигурационные файлы в любом виде не для пользователей.
Даёшь пользователям пользовательский интерфейс! :)
Все верно: данные от кода надо отделять. Только для этого необязательно выдумывать отдельный язык описания данных, если многие современные объектно-ориентированные языки программирования и так предоставляют замечательные средства, чтобы изящно и понятно описывать самые разнообразные сущности. Благодаря инкапсуляции так и получается: в одном месте код: интерфейс и его программная реализация, а совершенно в другом — данные, описываемые с помощью классов.
Вспомните JSON — простое и гениальное, на мой взгляд, изобретение — как раз воплощение того, о чем я здесь писал. Да, были там проблемы и с безопасностью, но все эти трудности успешно разрешены, самоинтерпретируемая нотация широко и успешно применяется в настоящий момент.
Про файлы конфигурации см. комментарий выше.
Насчет «пэхапэшника» — не уверен, что Вы хотели этим сказать, но должен заметить, что концепция компиляции данных пришла именно из системного программирования. Видели, например, как выглядит back-end оптимизирующего JIT-компилятора Sun Java SE (C2)? Он в основном состоит из одного файла — описания архитектуры процессора, в каком-то смысле именно конфигурационного файла. При этом описание сущностей (например, peephole optimizations) носит именно императивный характер, т.е. в виде алгоритма, как это будет работать. Пример с компиляцией шрифта — тоже реальный случай из системного программирования, где он сыграл большую роль в ускорении рендеринга текста в ПО мобильного телефона.
Жаль, что из заметки был вынесен только такой смысл. На самом деле, целью было рассказать о концепции self-executable data. Конфигурационный файл был лишь одним примером из трех.
SFX-архивы, в таком случае, вообще несусветное зло: это ж какой изверг додумался все запихивать в один файл, а потом еще делать так, чтоб программа открывала сама себя как файл с данными!
В Джаве, как языке, не может быть ассемблерных инструкций. По возможности код, в том числе системных классов, пишется кросплатформенным образом. Однако для некоторых методов, особенно критичных к производительности, Just-in-Time компилятор может обходить (игнорировать) написанный Java-код, подменяя его асcемблерными инструкциями (так называемые Intrinsic methods). Например, так делается для всяких там String.indexOf, Integer.bitCount, System.arraycopy и т.п.
Очевидно, Long.highestOneBit не является критичным для типичных Java-приложений, и для него нет VM Intrinsics.
— Мужики, я себе такой мобильник купил! тариф — все исходящие бесплатно!
— Да нуу, так не бывает. Должны быть какие-то минусы.
— Нет никаких минусов!
— Может, трубка тяжелая, с чемодан размером?
— Да нет. Обычная трубка. Записывайте номер: 8921677443865202957. Это код. Теперь номер…
Уверен, что немногие с первого же взгляда увидят, что ввели
Ytcecdtynfz{eqyz вместо Ytcecdtnyfz{eqyz.
Я так и вовсе понятия не имею, как мой пароль выглядит :)
Традиционные интерпретаторы выглядят как большущий switch в цикле:
for (;;) {
switch (next_bytecode()) {
case CODE_0:
...
break;
case CODE_1:
...
break;
case CODE_N:
...
break;
}
}
А можно интерпретатор сделать проще и наглядней с самоисполняемым промежуточным представлением (IR). В моем случае это Control Flow Graph (CFG), вершинами которого служат экземпляры класса Instruction с виртуальным методом execute:
Instruction* instr = sequence();
while (instr != NULL) {
instr = instr->execute();
}
class Instruction {
protected:
Instruction* _next;
public:
virtual Instruction* execute() {
return _next;
}
};
class Branch : public Instruction {
protected:
Expression* _cond;
Instruction* _true_branch;
public:
virtual Instruction* execute() {
return _cond->evaluate()->as_boolean() ? _true_branch : _next;
}
};
и т.д.
Примеры уместного использования самоисполняемых структур можно придумывать бесконечно.
Так что могу поделиться и своим движком, если интересно. Пусть он и не полностью совместим с ECMA-262, зато по коду очень компактный и простой.
Даёшь пользователям пользовательский интерфейс! :)
Вспомните JSON — простое и гениальное, на мой взгляд, изобретение — как раз воплощение того, о чем я здесь писал. Да, были там проблемы и с безопасностью, но все эти трудности успешно разрешены, самоинтерпретируемая нотация широко и успешно применяется в настоящий момент.
Насчет «пэхапэшника» — не уверен, что Вы хотели этим сказать, но должен заметить, что концепция компиляции данных пришла именно из системного программирования. Видели, например, как выглядит back-end оптимизирующего JIT-компилятора Sun Java SE (C2)? Он в основном состоит из одного файла — описания архитектуры процессора, в каком-то смысле именно конфигурационного файла. При этом описание сущностей (например, peephole optimizations) носит именно императивный характер, т.е. в виде алгоритма, как это будет работать. Пример с компиляцией шрифта — тоже реальный случай из системного программирования, где он сыграл большую роль в ускорении рендеринга текста в ПО мобильного телефона.
Очевидно, Long.highestOneBit не является критичным для типичных Java-приложений, и для него нет VM Intrinsics.