Last active
February 27, 2018 20:49
-
-
Save Liutos/3792922 to your computer and use it in GitHub Desktop.
我所捏造出来的语言的样子\( ̄▽ ̄)/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;;; Code Examples but the language wasn't implemented yet. | |
;;; 定义函数factorial | |
defun factorial (n) ;; 注释以两个分号开始,至一行的末尾结束。 | |
if 0 = n ;; 表示两个对象之间的关系的函数用中缀形式表示 | |
1 | |
n * factorial(n - 1) ;; if的alternate部分的表达式比起consequence的部分向左移动一个空格,但是其实并非像Python那样用缩进决定语法结构。 | |
;;; 尾递归版本的factorial,使用了内部的辅助函数。 | |
;;; 可以这样表达的内部函数需要语言支持词法作用域,并且defun也应该是这样的,而不是像CL那样定义全局函数。 | |
defun factorial (n) | |
{ ;; defun的函数体只能接受一个表达式,因此对于多个表达式的情况必须使用花括号将表达式括住。 | |
defun aux (acc, n) ;; 因为lexical scope所以函数aux是仅在factorial内部可见的,利用这个特性可以方便地定义辅助函数。 | |
if 0 = n | |
acc | |
aux(acc * n, n - 1) | |
;;; 这里有个要求,就是if必须有三个参数,就如Haskell中的那样。在这个语言中,所有的函数的参数应该都是固定的。 | |
aux(1, n) ;; 花括号的最后一条表达式的值就是整个括号表达式的值 | |
} | |
;;; 这里需要的是明确函数调用的形式,即究竟需不需要括号?如果可以不要,那么就写成aux 1 n这样的形式;如果要,那么就写成aux(1, n)这样的形式。也就是说,一种需要分隔符和定界符,另一种不需要。 | |
;;; 如果写成需要的,那么何以解释诸如defun这样的宏的调用可以不需要括号呢?一个解释是宏可以不需要,那么这样怎么实现cond这样的宏呢?答案是规定要用花括号包围多条语句,得到代码块。 | |
defun square (x) | |
{ | |
"Demo of docstring." ;; 当函数体的第一条表达式为字符串时,这个字符串将成为docstring而不是函数体被执行时的表达式。 | |
x * x | |
} | |
defun addn (n) | |
{ | |
"Return a closure." | |
lambda (x) ;; lambda函数和defun的作用类似,只是它所定义的函数没有名字。 | |
x + n | |
} | |
;;; 定义宏,开单引号阻止表达式被求值,逗号,启动求值,和Common Lisp中的一样。 | |
defmacro push (obj, place) | |
`{ ,place <- ,obj :: ,place} | |
defmacro incf (place, &optional (delta 1)) | |
`{ ,place <- ,place + ,delta} ;; 赋值操作符<-的返回值是操作符右边的表达式的计算结果 | |
defmacro when (test, &body forms) | |
`{ if ,test {,@forms} nil} ;; ,@的功能和CL中的一样,不过只能够应用在{}或者函数参数列表中。 | |
>> when(1 > 2, | |
print('impossible), | |
[]) | |
<=> if 1 > 2 { print('impossible) []} ;; 中缀表达式的运算优先级最高因此1和2首先和大于号>结合为单独的表达式1 > 2 | |
nil | |
defun make-cf (n) ;; 标识符中间可以使用连字符 | |
{ | |
a <- 0 ;; 绑定局部变量 | |
b <- 1 | |
cf-list <- [] | |
defun update () | |
{ | |
m <- truncate(sqrt(n) + a, b) | |
push(m, cf-list) | |
psetf(a, m * b - a, | |
b, (n - (m * b - a) ^ 2) / b) | |
values(a, b, m) | |
} | |
defun to-cf () | |
reduce((lambda (acc, x) | |
x + 1 / acc), | |
tail(cf-list), | |
:initial-value head(cf-list)) | |
defun cf-list () | |
cf-list | |
lambda (msg) | |
case(msg, ;; 这里的case是一个比较奇怪的宏,因为对于1以及偶数位置上的参数都会被求值。 | |
'update, update(), | |
'to-cf, to-cf(), | |
'cf-list, cf-list()) | |
} | |
>> (lambda (x) x + 1)(1) ;; 匿名函数调用 | |
2 | |
>> (macro (&rest widgets) ;; 匿名宏调用 | |
`{,@mapcar(lambda (w) `(::)(l1, []), widgets)})(l1, l2, l3) | |
{ (::)(l1, []) (::)(l2, []) (::)(l3, [])} | |
>> cond( | |
1 = random(1), 'one | |
t, 'zero) | |
<=> if 1 = random(1) 'one if t 'zero | |
;; return ONE or ZERO | |
;;; 用宏实现cond | |
defmacro cond (&rest clauses) | |
{ | |
if clauses is null ;; is是一个中缀形式的函数 | |
nil | |
{ | |
p <- caar(clauses) | |
e <- cdar(clauses) | |
`{ if ,p ,e cond(,@cdr(clauses))} | |
} | |
} |
Nice body ≖‿≖✧
哦,原来还有别人来评论啊,我心血来潮回来看看的,好自豪=。=
似乎没看出差别,和lisp比起来.
还是有差别的啊, C结合了lisp, 又有点点ML的感觉..楼主喜欢"<-"作为赋值吗? 我个人好反感>o<
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
忽然间觉得弄一套这样的语法貌似没啥意义啊,怎么也没有逃出Lisp的手掌心T_T