- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我一直在根据 minilisp 中的编码编写一个 micro-mini-lisp , McCarthy paper (由 Roots of Lisp 修订),并使用基于 J Incunabulum 的(可能令人反感的)风格.并使用来自 here 的 PP_NARG
宏.我也被我之前的项目所激励,一个 codegolf'ed lambda calculus interpreter后来我发现它与 1999 ioccc Lisp interpreter 惊人地相似,特别是在使用游标而不是指针来引用内存地址时。
它似乎大部分都有效,包括阅读器代码。但是,尽管 eval(ATOM(QUOTE X))
正确地产生了 T
,并且 eval(ATOM(QUOTE(X Y Z)))
是正确的产生 NIL
,eval(QUOTE X)
产生 X
,而 eval(QUOTE(X Y Z))
产生 (X Y Z)
;奇怪的结果是 eval(QUOTE(ATOM(QUOTE X)))
产生 ATOM
,而不是完整的子表达式 ATOM(QUOTE X)
.
我想这是不可能的,而且我并没有让它变得简单,但是任何人都可以帮我弄清楚引用哪里出了问题吗?
顺便说一句,与我上面的描述不同,解释器仅限于单字符标记,所以 QUOTE
是 Q
而 ATOM
是A
。 ( github )
/*cf.
http://www.ioccc.org/1989/jar.2.c
http://leon.bottou.org/projects/minilisp
http://www.jsoftware.com/jwiki/Essays/Incunabulum
http://www-formal.stanford.edu/jmc/recursive/recursive.html
http://www.paulgraham.com/rootsoflisp.html
https://codegolf.stackexchange.com/questions/284/write-an-interpreter-for-the-untyped-lambda-calculus/3290#3290
*/
#include<assert.h>
#include<signal.h>
#include<stdarg.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include"ppnarg.h"
#define R return
int*m,*n,msz;
tag(x){R x&3;}
val(x){R x>>2;}
#define ALPHA 'T'
#define NIL (0)
#define T atom(ALPHA)
atom(x){R((x-ALPHA)<<2)|1;}
number(x){R(x<<2)|3;}
listp(x){R tag(x)==0;}
atomp(x){R tag(x)==1;}
objectp(x){R tag(x)==2;}
numberp(x){R tag(x)==3;}
consp(x){R x&&listp(x);}
car(x){R consp(x)?val(x)[m]:0;}
cdr(x){R consp(x)?val(x)[m+1]:0;}
caar(x){R car(car(x));}
cadr(x){R car(cdr(x));}
cadar(x){R car(cdr(car(x)));}
caddr(x){R car(cdr(cdr(x)));}
caddar(x){R car(cdr(cdr(car(x))));}
cons(x,y){int z;R z=n-m,*n++=x,*n++=y,z<<2;}
rplaca(x,y){R consp(x)?val(x)[m]=y:0;}
rplacd(x,y){R consp(x)?val(x)[m+1]=y:0;}
eq(x,y){R atomp(x)&&atomp(y)?x==y:0;}
ff(x){R atomp(x)?x:ff(car(x));}
subst(x,y,z){R atomp(z)?(eq(z,y)?x:z):
cons(subst(x,y,car(z)),subst(x,y,cdr(z)));}
equal(x,y){R(atomp(x)&&atomp(y)&&eq(x,y))
||(consp(x)&&consp(y)&&equal(car(x),car(y))&&equal(cdr(x),cdr(y)));}
null(x){R listp(x)&&(val(x)==0);}
lista(int c,int*a){int z=NIL;for(;c;)z=cons(a[--c],z);R z;}
listn(int c,...){va_list a;int*z=n;
va_start(a,c);for(;c--;)*n++=va_arg(a,int);va_end(a);
c=n-z;R lista(c,z);}
#define list(...) listn(PP_NARG(__VA_ARGS__),__VA_ARGS__)
append(x,y){R null(x)?y:cons(car(x),append(cdr(x),y));}
among(x,y){R !null(y)&&equal(x,car(y))||among(x,cdr(y));}
pair(x,y){R null(x)&&null(y)?NIL:
consp(x)&&consp(y)?cons(list(car(x),car(y)),pair(cdr(x),cdr(y))):0;}
assoc(x,y){R eq(caar(y),x)?cadar(y):assoc(x,cdr(y));}
sub2(x,z){R null(x)?z:eq(caar(x),z)?cadar(x):sub2(cdr(x),z);}
sublis(x,y){R atom(y)?sub2(x,y):cons(sublis(x,car(y)),sublis(x,cdr(y)));}
apply(f,args){R eval(cons(f,appq(args)),NIL);}
appq(m){R null(m)?NIL:cons(list(atom('Q'),car(m)),appq(cdr(m)));}
eval(e,a){R numberp(e)?e:
atomp(e)?assoc(e,a):
atomp(car(e))?(
/*QUOTE*/ eq(car(e),atom('Q'))?cadr(e):
/*ATOM*/ eq(car(e),atom('A'))?atomp(eval(cadr(e),a)):
/*EQ*/ eq(car(e),atom('E'))?eval(cadr(e),a)==eval(caddr(e),a):
/*COND*/ eq(car(e),atom('D'))?evcon(cdr(e),a):
/*CAR*/ eq(car(e),atom('H'))?car(eval(cadr(e),a)):
/*CDR*/ eq(car(e),atom('R'))?cdr(eval(cadr(e),a)):
/*CONS*/ eq(car(e),atom('C'))?cons(eval(cadr(e),a),eval(caddr(e),a)):
//eval(cons(assoc(car(e),a),evlis(cdr(e),a)),a) ):/*cf. Roots of Lisp*/
eval(cons(assoc(car(e),a),cdr(e)),a) ):
eq(caar(e),atom('M'))? /*LABEL*/
eval(cons(caddar(e),cdr(e)),cons(list(cadar(e),car(e)),a)):
eq(caar(e),atom('L'))? /*LAMBDA*/
eval(caddar(e),append(pair(cadar(e),evlis(cdr(e),a)),a)):0;}
evcon(c,a){R eval(caar(c),a)?eval(cadar(c),a):evcon(cdr(c),a);}
evlis(m,a){R null(m)?NIL:cons(eval(car(m),a),evlis(cdr(m),a));}
maplist(x,f){R null(x)?NIL:cons(apply(f,x),maplist(cdr(x),f));}
prn(x){atomp(x)?printf("'%c' ",val(x)+ALPHA):
numberp(x)?printf("%d ",val(x)):
objectp(x)?printf("OBJ %d ",val(x)):
consp(x)?printf("( "),prn(car(x)),prn(cdr(x)),printf(") "):
0//printf("NIL ")
;}
#define LPAR '('
#define RPAR ')'
rd(char **p){int t,u,v,z;
if(!(**p))R 0;
if(**p==' ')R ++(*p),rd(p);
if(**p==RPAR)R ++(*p),atom(RPAR);
if(**p==LPAR){++(*p);
z=NIL;u=rd(p);z=cons(u,z);
while(u=rd(p),!eq(u,atom(RPAR)))
//u=cons(u,NIL),
z=append(z,u);
R z;}
if(**p>='0'&&**p<='9')R ++(*p),number(*((*p)-1)-'0');
R ++(*p),atom(*((*p)-1));}
void fix(x){signal(SIGSEGV,fix);sbrk(msz);msz*=2;}
int main(){
assert((-1>>1)==-1); /*right-shift must be sign-preserving*/
n=m=sbrk(sizeof(int)*(msz=getpagesize()));*n++=0;*n++=0;
//signal(SIGSEGV,fix); /*might let it run longer, obscures problems*/
char *s="(Q (A (Q X)))";
char *p=s;
int a=rd(&p);
printf("%s\n",s);
int x,y;
x = a;
y = NIL;
prn(x);
x = eval(x,y);
printf("\nEVAL\n");
printf("x: %d\n", x);
printf("0: %o\n", x);
printf("0x: %x\n", x);
printf("tag(x): %d\n",tag(x));
printf("val(x): %d\n",val(x));
printf("car(x): %d\n",car(x));
printf("cdr(x): %d\n",cdr(x));
prn(x);
R 0;
}
下面是 indent
处理的相同代码。
/*cf.
http://www.ioccc.org/1989/jar.2.c
http://leon.bottou.org/projects/minilisp
http://www.jsoftware.com/jwiki/Essays/Incunabulum
http://www-formal.stanford.edu/jmc/recursive/recursive.html
http://www.paulgraham.com/rootsoflisp.html
*/
#include<assert.h>
#include<signal.h>
#include<stdarg.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include"ppnarg.h"
#define R return
int *m, *n, msz;
tag (x)
{
R x & 3;
}
val (x)
{
R x >> 2;
}
#define ALPHA 'T'
#define NIL (0)
#define T atom(ALPHA)
atom (x)
{
R ((x - ALPHA) << 2) | 1;
}
number (x)
{
R (x << 2) | 3;
}
listp (x)
{
R tag (x) == 0;
}
atomp (x)
{
R tag (x) == 1;
}
objectp (x)
{
R tag (x) == 2;
}
numberp (x)
{
R tag (x) == 3;
}
consp (x)
{
R x && listp (x);
}
car (x)
{
R consp (x) ? val (x)[m] : 0;
}
cdr (x)
{
R consp (x) ? val (x)[m + 1] : 0;
}
caar (x)
{
R car (car (x));
}
cadr (x)
{
R car (cdr (x));
}
cadar (x)
{
R car (cdr (car (x)));
}
caddr (x)
{
R car (cdr (cdr (x)));
}
caddar (x)
{
R car (cdr (cdr (car (x))));
}
cons (x, y)
{
int z;
R z = n - m, *n++ = x, *n++ = y, z << 2;
}
rplaca (x, y)
{
R consp (x) ? val (x)[m] = y : 0;
}
rplacd (x, y)
{
R consp (x) ? val (x)[m + 1] = y : 0;
}
eq (x, y)
{
R atomp (x) && atomp (y) ? x == y : 0;
}
ff (x)
{
R atomp (x) ? x : ff (car (x));
}
subst (x, y, z)
{
R atomp (z) ? (eq (z, y) ? x : z) :
cons (subst (x, y, car (z)), subst (x, y, cdr (z)));
}
equal (x, y)
{
R (atomp (x) && atomp (y) && eq (x, y))
|| (consp (x) && consp (y) && equal (car (x), car (y))
&& equal (cdr (x), cdr (y)));
}
null (x)
{
R listp (x) && (val (x) == 0);
}
lista (int c, int *a)
{
int z = NIL;
for (; c;)
z = cons (a[--c], z);
R z;
}
listn (int c, ...)
{
va_list a;
int *z = n;
va_start (a, c);
for (; c--;)
*n++ = va_arg (a, int);
va_end (a);
c = n - z;
R lista (c, z);
}
#define list(...) listn(PP_NARG(__VA_ARGS__),__VA_ARGS__)
append (x, y)
{
R null (x) ? y : cons (car (x), append (cdr (x), y));
}
among (x, y)
{
R ! null (y) && equal (x, car (y)) || among (x, cdr (y));
}
pair (x, y)
{
R null (x) && null (y) ? NIL :
consp (x)
&& consp (y) ? cons (list (car (x), car (y)),
pair (cdr (x), cdr (y))) : 0;
}
assoc (x, y)
{
R eq (caar (y), x) ? cadar (y) : assoc (x, cdr (y));
}
sub2 (x, z)
{
R null (x) ? z : eq (caar (x), z) ? cadar (x) : sub2 (cdr (x), z);
}
sublis (x, y)
{
R atom (y) ? sub2 (x, y) : cons (sublis (x, car (y)), sublis (x, cdr (y)));
}
apply (f, args)
{
R eval (cons (f, appq (args)), NIL);
}
appq (m)
{
R null (m) ? NIL : cons (list (atom ('Q'), car (m)), appq (cdr (m)));
}
eval (e, a)
{
R numberp (e) ? e :
atomp (e) ? assoc (e, a) :
atomp (car (e)) ? ( /*QUOTE*/ eq (car (e), atom ('Q')) ? cadr (e) :
/*ATOM*/ eq (car (e),
atom ('A')) ? atomp (eval (cadr (e),
a)) : /*EQ*/
eq (car (e), atom ('E')) ? eval (cadr (e),
a) == eval (caddr (e),
a) :
/*COND*/ eq (car (e), atom ('D')) ? evcon (cdr (e),
a) : /*CAR*/
eq (car (e),
atom ('H')) ? car (eval (cadr (e),
a)) : /*CDR*/ eq (car (e),
atom
('R')) ?
cdr (eval (cadr (e), a)) : /*CONS*/ eq (car (e),
atom ('C')) ?
cons (eval (cadr (e), a), eval (caddr (e), a)) :
//eval(cons(assoc(car(e),a),evlis(cdr(e),a)),a) ):/*cf. Roots of Lisp*/
eval (cons (assoc (car (e), a), cdr (e)), a)) :
eq (caar (e), atom ('M')) ? /*LABEL*/
eval (cons (caddar (e), cdr (e)), cons (list (cadar (e), car (e)), a)) :
eq (caar (e), atom ('L')) ? /*LAMBDA*/
eval (caddar (e), append (pair (cadar (e), evlis (cdr (e), a)), a)) : 0;
}
evcon (c, a)
{
R eval (caar (c), a) ? eval (cadar (c), a) : evcon (cdr (c), a);
}
evlis (m, a)
{
R null (m) ? NIL : cons (eval (car (m), a), evlis (cdr (m), a));
}
maplist (x, f)
{
R null (x) ? NIL : cons (apply (f, x), maplist (cdr (x), f));
}
prn (x)
{
atomp (x) ? printf ("'%c' ", val (x) + ALPHA) : numberp (x) ? printf ("%d ", val (x)) : objectp (x) ? printf ("OBJ %d ", val (x)) : consp (x) ? printf ("( "), prn (car (x)), prn (cdr (x)), printf (") ") : 0 //printf("NIL ")
;
}
#define LPAR '('
#define RPAR ')'
rd (char **p)
{
int t, u, v, z;
if (!(**p))
R 0;
if (**p == ' ')
R++ (*p), rd (p);
if (**p == RPAR)
R++ (*p), atom (RPAR);
if (**p == LPAR)
{
++(*p);
z = NIL;
u = rd (p);
z = cons (u, z);
while (u = rd (p), !eq (u, atom (RPAR)))
//u=cons(u,NIL),
z = append (z, u);
R z;
}
if (**p >= '0' && **p <= '9')
R++ (*p), number (*((*p) - 1) - '0');
R++ (*p), atom (*((*p) - 1));
}
void
fix (x)
{
signal (SIGSEGV, fix);
sbrk (msz);
msz *= 2;
}
int
main ()
{
assert ((-1 >> 1) == -1); /*right-shift must be sign-preserving */
n = m = sbrk (sizeof (int) * (msz = getpagesize ()));
*n++ = 0;
*n++ = 0;
//signal(SIGSEGV,fix); /*might let it run longer, obscures problems*/
char *s = "(Q (A (Q X)))";
char *p = s;
int a = rd (&p);
printf ("%s\n", s);
int x, y;
x = a;
y = NIL;
prn (x);
x = eval (x, y);
printf ("\nEVAL\n");
printf ("x: %d\n", x);
printf ("0: %o\n", x);
printf ("0x: %x\n", x);
printf ("tag(x): %d\n", tag (x));
printf ("val(x): %d\n", val (x));
printf ("car(x): %d\n", car (x));
printf ("cdr(x): %d\n", cdr (x));
prn (x);
R 0;
}
这又是main
的核心部分,测试部分。
char *s="(Q (A (Q X)))";
char *p=s;
int a=rd(&p);
printf("%s\n",s);
int x,y;
x = a;
y = NIL;
prn(x);
x = eval(x,y);
printf("\nEVAL\n");
printf("x: %d\n", x);
printf("0: %o\n", x);
printf("0x: %x\n", x);
printf("tag(x): %d\n",tag(x));
printf("val(x): %d\n",val(x));
printf("car(x): %d\n",car(x));
printf("cdr(x): %d\n",cdr(x));
prn(x);
我得到的输出是:
(Q (A (Q X)))
( 'Q' ( 'A' ( 'Q' 'X' ) ) )
EVAL
x: -75
0: 37777777665
0x: ffffffb5
tag(x): 1
val(x): -19
car(x): 0
cdr(x): 0
'A'
最佳答案
你的阅读器错了,你的打印机在骗你。
提示:尝试读取包含多个元素的列表,例如 (1 2 3 4 5)
。
问题是 rd
使用 element 调用 append
它只是作为第二个参数读取。 (修复已经存在,注释掉了。)在上面的测试用例中,它恰好是一个列表本身,所以 append
可以工作。但是您实际传递给 eval
的数据实际上是
(Q . (A . (Q . X)))
正确打印时,或者
(Q A Q . X)
使用标准列表缩写。
所以是的,eval
返回 A
,这是正确的答案,除非您想检查没有意外项。
打印机中的错误是,对于成对打印 cdr,就好像它是一个元素一样。您应该在汽车和 cdr 之间打印一个点,或者您应该编写一个辅助函数 prnlst
来打印缩写列表。
关于c - 为什么我的小口齿不清 QUOTE?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18096456/
在 Lisp 中,我如何找到一个列表有多少个不同的元素? 最佳答案 (length (remove-duplicates )) 最短的方法,但也可以一次性完成,如下所示: (defun count-d
(defun tictactoe3d () '( ((NIL NIL NIL) (NIL NIL NIL) (NIL NIL NIL)) ((NIL NIL NIL) (NIL NIL NIL)
我的作业有一些问题。我的目标是创建代表学生姓名、姓氏以及他们的入学编号(属性列表)的符号。我还为我创建的所有学生使用了一个全局变量。 我的代码是这样的: (defun student-create (
如何在 Common lisp 中实现这一点? (logselect (t nil t) (list1 list2 list3)) ---> (list1 list2) 我编写了以下函数,但我认为有更
我有如下代码。它返回列表为 (((1 . 2) (1 . 0)) ((1 . 2) (1 . 1)) ((1 . 2) (1 . 3)) ((1 . 2) (1 . 4)) ((1 . 2) (1 .
我希望我的程序请求一个表达式,将输入的字符串分配给变量“exp”,然后打印该表达式。 但是我遇到了一些麻烦。我首先尝试使用(阅读) (princ "Enter a expression to be e
我需要编写一个函数来计算列表中给定原子的所有出现次数。这是我的: (defun my-count (a L) (cond ((null L) nil) ((equal a (c
我正在复习旧考试,为自己的考试做准备,教授很友善,也为我们提供了解决方案,现在我想知道为什么一个函数会做它应该做的事情。 (defun sortulists (L) (mapcar (lambda
如果存在在 J2ME 上运行的 lisp,那么在移动设备(而不是移动设备)上编程似乎会更容易。 您知道任何(最好是开源的)lisp/smalltalk 应用程序吗?我在网上搜索,但找不到有效的 J2M
像错误调用函数的错误消息显示,例如: (message (file-attributes ".")) 产生消息: "eval: Wrong type argument: stringp, ("/hom
作为一个更大项目的一部分,我希望能够将每个子列表的每个第一个元素乘以 -1。我正在尝试像这样使用递归来做到这一点: (defun negative (secondpoly) (let ((t1
它比标题所暗示的要复杂一点,但我无法将其浓缩为一句话。 我正在使用 Clisp,目前有一个列表列表。外部列表是任意长的,而内部列表是 4 个整数长。这是我可能拥有的示例。 ((2 1 1 0) (1
有没有办法找出调用的函数是什么? 比方说,有一个处理程序函数可以监视对外部进程的请求。在处理请求之前,它会将它们打印到日志文件中以供日后检查。 这个函数能找出它被哪个函数调用了吗? 最佳答案 答案是否
我有 Mac OSX 10.8.4。我克隆了 gcl 的 git repo,并根据自述文件运行了 ./configure。 但是,我收到以下错误: configure: error: Cannot b
嘿伙计们,我刚刚开始在大学学习 Lisp,但是教授非常穷,而且他自己似乎也不懂这门语言,所以我向你们求助。我在 Java 方面非常有经验,但在将 Java 的条件与 Lisp 联系起来时遇到了困难。这
字节编译 emacs lisp 非常有用,因为它会生成编译器警告,尽管有时很隐晦,但总是指向错误或未完成的任务,例如缺少导入或未实现的函数。 但是,我找不到一种方法来生成与 *Compile-Log*
TL; 博士 customize 中是否有一些标准的回退处理? 系统,用于处理部分无效的复合定制 变量,例如一个条目不是缺点的列表? 长版 emacs 的自定义机制非常强大,使用 复合 Materia
我遇到的问题是,当我创建一个函数来打印列表的特定部分时,它会将其打印为 NIL 而不是实际元素。 例如: > (setf thelist '((a b) (c (d e f)) (g (h i)))
我正在尝试使用 butlast 但出于某种原因,我明白了错误:没有函数定义:BUTLAST。有什么想法吗? 最佳答案 butlast 在 AutoLisp 中不存在,所以错误说有这样的函数是正确的。
这个问题在这里已经有了答案: Test if array is inside a list in lisp (1 个回答) 关闭 7 年前。 我在使用这个字符串列表中删除字符串时遇到问题 (remo
我是一名优秀的程序员,十分优秀!