Help us understand the problem. What is going on with this article?

PrologでLisp遊び

More than 1 year has passed since last update.

はじめに

Prologで書いたLispモドキです。O-Prologのテストを兼ねて書きました。S式の代わりにPrologのリストを使います。Prologで遊びつつLispの内部構造をお楽しみください。実用性はまったくありません。遊びです。

使い方

起動はreplです。終了は[quit]です。


| ?- repl.
> [defun,foo,[a,b],[*,a,b]].
t
> [foo,10,2].
20
> [setq,x,2].
t
> x.
2
> [quit].
t
yes
| 


拡張

四則演算しか実装していません。いろいろ追加して遊んでください。

コード

%Lisp in Prolog


repl :-
    repeat,
    write('> '),
    read(X),
    eval(X,Y,[]),
    write(Y),nl,
    (X=[quit]->true;fail).

eval(X,X,E) :-
    integer(X).
eval(X,X,E) :-
    float(X).
eval(X,Y,E) :-
    atom(X),
    assoc(X,E,Y).
eval(X,Y,E) :-
    atom(X),
    global(X,Y).
eval([quit],t,E).
eval([defun,F,A,B],t,E) :-
    assert(fun(F,A,B)).
eval([setq,X,Y],t,E) :-
    eval(Y,Z,E),
    assert(global(X,Z)).
eval(X,Y,E) :-
    funcall(X,Y,E).

funcall([F|A1],Z,E) :-
    fun(F,A,B),
    argument(A,A1,Y),
    append(Y,E,E1),
    eval(B,Z,E1).
funcall([+,X,Y],Z,E) :-
    eval(X,X1,E),
    eval(Y,Y1,E),
    Z is X1+Y1.
funcall([-,X,Y],Z,E) :-
    eval(X,X1,E),
    eval(Y,Y1,E),
    Z is X1-Y1.
funcall([*,X,Y],Z,E) :-
    eval(X,X1,E),
    eval(Y,Y1,E),
    Z is X1*Y1.
funcall([/,X,Y],Z,E) :-
    eval(X,X1,E),
    eval(Y,Y1,E),
    Z is X1/Y1.

assoc(X,[],Z) :- fail.
assoc(X,[[X|Y]|Ys],Y).
assoc(X,[_|Ys],Z) :-
    assoc(X,Ys,Z).



argument([X],[Y],[X|Y]).
argument([X|Xs],[Y|Ys],[[X|Y],Z]) :-
    argument(Xs,Ys,Z).


global(t,t).
global(nil,nil).

:- dynamic(fun/3).
fun(dummy,a,b).

sym_num
LALの笹川です。よろしくお願いします。
http://eisl.kan-be.com/
fukuokaex
エンジニア/企業向けにElixirプロダクト開発・SI案件開発を支援する福岡のコミュニティ
https://fukuokaex.fun/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away