2013-11-29 3 views
4

Я пытаюсь научиться писать простой язык сценариев поверх DLR, играя с очень старым примером DLR, называемым ToyScript. Однако ToyScript не кажется, поддерживают следующую структуру сценария, который я хотел бы использовать в своей реализации:Изучение DLR (как реализовать язык поверх него)

print b() 
def b() { 
    return 1 
} 

Это вызывает исключение, точно так, как в большинстве статически скомпилированных языках.

Если сценарий следует "статические языки парадигмы":

def b() { 
    return 1 
} 
print b() 

ToyScript работает без проблем.

Мой вопрос: как это сделать в DLR?

[Очевидно, что я ищу описание решения, а не для решения сам по себе :)]

+0

Что касается «как в большинстве статический скомпилированных языках»: Я не знаю, но я знаю, что вы получите сообщение об ошибке выполнения первого блока во многом * динамическом * языки (JavaScript, Python и Ruby, просто чтобы назвать несколько). – rsenna

+0

Я только что просмотрел [IronPython] (http://ironpython.codeplex.com/SourceControl/latest#IronPython_Main/), но, похоже, он много работает для его реализации. Возможно, вам захочется посмотреть, как они это сделали и пройти пробную версию. – Measuring

+4

Вам нужно будет сделать гораздо более умный интерпретатор. Он должен сделать * два * прохода через этот код. Первый проход должен содержать определения, второй проход выполняет код. Как это делают статические компиляторы :) –

ответ

1

Есть несколько возможных реализаций. Во-первых, требуется выполнение для создания функции. Таким образом, вы не можете вызывать функцию перед созданием функции с выполнением. Второй способ - создать все функции при анализе кода и выполнении глобальных скриптов. Таким образом, объявление функции может появляться в любом месте кода, потому что функции уже созданы до любого выполнения. Обратный вывод состоит в том, что вам нужно создать все функции независимо от того, вы их вызываете или нет. Тогда есть промежуточный способ; при синтаксическом анализе кода в первый раз вы храните абстрактное синтаксическое дерево (AST) функций в таблице функций. Затем, когда вы хотите вызвать функцию, найдите объявление функции в таблице функций, а затем выполните компиляцию или интерпретацию из AST. Сравните следующие два фрагмента кода JavaScript, и у вас будет хорошая идея.

console.log(b()); 
function b() { 
    return 1; 
} 

и

console.log(b()); 
var b = function() { 
    return 1; 
} 
+0

Большое спасибо за sugestion, но я чувствую, что должно быть более простое решение, доступное :). Рассмотрим ключевое слово «dynamic» в C#. Вы можете вызывать unkown членов на объекте, и правильное связывание выполняется во время выполнения. Хотя я вообще не эксперт по компилятору, я предполагаю, что что-то логически похожее можно было бы использовать для достижения моих целей здесь :). – user3050324