LINUX.ORG.RU

Как устроены компиляторы лиспа?

 , , , ,


0

3

Являются ли они вообще компиляторами в машинный код?Если да,то как работает такой код?

(defun print-value (a) (format t "~a~%" a))
(mapcar (read) (list 1 2 3 4))

=> print-value
1 2 3 4

=>

Там что `if +`,`if print-value`,`if etc` на (read) стоит?
------------------------------
Еще интересно почему сlojure нелисп

Многие из них являются компиляторами в нативный (читай, машинный) код. Как устроены, можно взять любой опенсорсный компилятор (SBCL, CCL), да и посмотреть

dave ★★★★★ ()

Да, в CL есть функция дизассемблирования. Можно ее вызвать и тоже посмотреть, какие будут машинные инструкции

dave ★★★★★ ()
* (defun test (x) (1+ x))

TEST
* (disassemble #'test)

; disassembly for TEST
; Size: 42 bytes. Origin: #x1002E2E16C
; 6C:       488B0C2558081020 MOV RCX, [#x20100858]            ; no-arg-parsing entry point
; 74:       48894DF8         MOV [RBP-8], RCX
; 78:       BF02000000       MOV EDI, 2
; 7D:       488BD3           MOV RDX, RBX
; 80:       41BBD0010020     MOV R11D, 536871376              ; GENERIC-+
; 86:       41FFD3           CALL R11
; 89:       488B5DF0         MOV RBX, [RBP-16]
; 8D:       488BE5           MOV RSP, RBP
; 90:       F8               CLC
; 91:       5D               POP RBP
; 92:       C3               RET
; 93:       0F0B10           BREAK 16                         ; Invalid argument count trap
NIL
dave ★★★★★ ()
Ответ на: комментарий от linuhs_user

Меня эта штука когда-то завораживала)

Ею можно смотреть и стандартные функции (теперь это LispWorks, а до этого был SBCL):

CL-USER 5 > (disassemble #'list)
20031C92:
       0:      33DB             xor   ebx, ebx
       2:      E861080F00       call  201224FA         ; #<Function RUNTIME:FIX-REST-ARGS-NSC 201224FA>
       7:      FD               std   
       8:      C3               ret   
       9:      90               nop   
NIL
dave ★★★★★ ()
Ответ на: комментарий от dave

Я уже разобрался,функция с (read) ссылается на read..И надо ее было смотреть,как я понял там таблица с именами или типо того.

linuhs_user ()
Ответ на: комментарий от linuhs_user

Там вызываются более низко-уровневые функции, на которых строится read. Вообще, лучше взять SBCL или ClozureCL и там посмотреть исходный код на лиспе.

В том же LispWorks:

CL-USER 7 > (disassemble #'read)
201AFCC2:
       0:      BB00040000       move  ebx, 400
       5:      E8E690E5FF       call  20008DB2         ; #<Function RUNTIME:FIX-OPTIONAL-ARGS-NSC 20008DB2>
      10:      81E100FF0000     and   ecx, FF00
      16:      8B7C2410         move  edi, [esp+10]
      20:      8B5C240C         move  ebx, [esp+C]
      24:      8B442408         move  eax, [esp+8]
      28:      8B542404         move  edx, [esp+4]
      32:      80FD00           cmpb  ch, 0
      35:      7623             jbe   L2
      37:      80FD01           cmpb  ch, 1
      40:      7637             jbe   L3
L1:   42:      C74424106BFC1A20 move  [esp+10], 201AFC6B  ; SYSTEM::IN-READ
      50:      897C240C         move  [esp+C], edi
      54:      895C2408         move  [esp+8], ebx
      58:      89442404         move  [esp+4], eax
      62:      B505             moveb ch, 5
      64:      89D0             move  eax, edx
      66:      FF257CEF1A20     jmp   [201AEF7C]       ; SYSTEM::CALL-READER-FUNCTION
L2:   72:      89E7             move  edi, esp
      74:      81CFFCFF0F00     or    edi, FFFFC
      80:      8B7FC4           move  edi, [edi-3C]
      83:      8B7F04           move  edi, [edi+4]
      86:      83FFF6           cmp   edi, -A
      89:      7506             jne   L3
      91:      8B3D7CC61120     move  edi, [2011C67C]  ; *STANDARD-INPUT*
L3:   97:      BB03400020       move  ebx, 20004003    ; T
     102:      EBC2             jmp   L1
     104:      90               nop   
     105:      90               nop   
NIL
dave ★★★★★ ()

Еще интересно почему сlojure нелисп

Кто тебе такое сказал?

no-such-file ★★★★★ ()

Это зависит от реализации лиспа и от настроек. Например, SBCL по умолчанию всё компилирует, но для простых команд из REPL это невыгодно. Тогда можно подкрутить настройки и по умолчанию в REPL будет интерпретатор, а компиляция - по запросу. В Lispworks ЕМНИП по умолчанию интерпретация в REPL.

read запускает лексер-парсер, к-рый возвращает дерево. таблица с именами называется пакет (ещё она иногда называется «пространство имён»). Оно не внутри read, а само по себе, read к нему только обращается, когда видит во входном потоке нечто, похожее на идентификатор (символ). Если read не находит символ, она его создаёт и помещает в пространство имён (в первом приближении).

den73 ★★★★★ ()
Ответ на: комментарий от dave

ОМГ! Ты заплатил 800 евро за сомнительное удовольствие хлебать борщ?

anonymous ()

Думаю, это будет замечательный тред

anonymous ()
Ответ на: комментарий от anonymous

LispWorks можно скачать бесплатно, чтобы попробовать. Ну, вот, фактически о лиспе так мало знают

dave ★★★★★ ()
Последнее исправление: dave (всего исправлений: 2)
Ответ на: комментарий от den73

Спасибо,ну так а парсер-лексер это типо интерпретатора в бинарнике?

linuhs_user ()
Ответ на: комментарий от anonymous

Тех.вопросы же,замечательным его бы сделал заголовок Common Lisp vs Rust.На обоих есть ОС,но в коммон лиспе os запускается Qu2

linuhs_user ()
Ответ на: комментарий от linuhs_user

Это часть интерпретатора. Парсер-лексер - это READ, Собственно интерпретатор - это Eval, а print - это напечатать. Отсюда Read-Eval-Print-Loop = REPL.

den73 ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.