2013-04-14 3 views
0

Я даю язык на Схеме.Как извлечь список из программы Scheme?

(define-datatype statement statement? 
    (add1 (V symbol?)) 
    (sub1 (V symbol?)) 
    (skip (V symbol?)) 
    (if-goto (V symbol?) 
      (l symbol?))) 

(define-datatype instruction instruction? 
    (labeled (l symbol?) 
      (i statement?)) 
    (unlabeled (i statement?))) 

(define-datatype program program? 
    (a-program (l (list-of instruction?)))) 

Я пытаюсь создать новую функцию, которая сможет конвертировать программу в список инструкций. Как мне это сделать?

Вот то, что я до сих пор:

(define pgm->list 
    (lambda (pgm) 
    ;what goes here 
+1

'define-datatype' не является частью Схемы. Можете ли вы описать это или опустить тег 'schem'? – GoZoner

+0

Поиск в 'docs.racket-lang.org', кажется, что' define-datatype' является частью модулей 'lang/htdp-advanced' и' eopl'. OP должен указать, какую книгу они используют. –

+0

Если мы предположим, что 'pgm' является' программой', а 'program' содержит список инструкций, возникает вопрос, как получить доступ к полям структуры данных программы? Или вас интересует, как написать компилятор? – soegaard

ответ

1

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

(define-datatype program program? 
    (a-program (l (list-of instruction?)))) 

что такое список-оф? я должен представить здесь, что вы хотите объявить некоторые варианты программ. a-program будет определяться как список инструкций ... ok. если list-of возвращает lambda, который является правильным предикатом (который возвращает true только при действии в списке инструкций), то это работает?

(define pgm->list 
    (lambda (pgm) 
    (cases program pgm 
     (a-program (l) l)))) 

Edit: Так как определить тип данных, было неизвестно большинству из нас, кроме ОП, я добавляю некоторые документы:

[синтаксис] (определить-тип данных TYPENAME [PREDICATE] VARIANT .. .)

Определяет тип записи с именем TYPENAME, где VARIANT ... определяет один или несколько конструкторов для экземпляров этого типа. ВАРИАНТ должен иметь вид

ВАРИАНТ = (КОНСТРУКТОРСКИМИ (FIELDNAME FIELDPRED) ...)

КОНСТРУКТОР это имя процедуры конструктора, который будет определен с как много аргументов, которые заданы поля. (FIELDNAME FIELDPRED) ... укажите имя для каждого поля и процедуру для одного из них, который должен возвращать истинное значение для значений поля .

Необязательный PREDICATE должен быть именем процедуры, которая будет определена, и , которая возвращает #t при применении к экземпляру этой записи варианта.

[синтаксис] (случаи TYPENAME EXP ОГОВОРКА ...)

Средство для согласования и деконструируя экземпляр EXP варианта записи с именем TypeName. Каждый ПУНКТА определяет конструктор полевых имен и тело, чтобы выполнить, когда конструктор соответствует записи экземпляра:

= (ПУНКТ КОНСТРУКТОР (FIELDNAME ...) ТЕЛО ...) | (еще BODY ...)

ура!

+0

Полезное спасибо! Теперь скажите, что я хочу отправить полученный список в другую функцию, как бы я это сделал? Когда я пытаюсь изменить последнюю строку на что-то вроде: (other-func (a-program (l) l))))) Я получаю сообщение о том, что первый l теперь является несвязанным идентификатором – Stephen

+0

hmmm, возможно, я не понимаю вопрос здесь. если other-func ожидает список (инструкций), созданный из «программы», тогда это не будет (other-func (pgm-> list program))? что кажется тривиальным, так что, пожалуйста, можете ли вы дать нам рабочий пример, чтобы запустить его и понять? :) спасибо, dood !. – ramrunner

+0

Хмм я видел вещь о «последней строке». если вы хотите изменить последнюю строку кода pgm-> list, это не сработает. вы видите, что «случаи» лямбда распаковывают структуру программы на основе типа, указанного ниже. вы должны использовать целое, если это как одно закрытие. возможно, вы могли бы создать другую лямбду, которая использует весь «pgm-> list», чтобы получить список, а затем отправить его другой функции, как показано в предыдущем комментарии? – ramrunner

Смежные вопросы