heol
Heol
Heol is a Lisp system for the Uxn virtual machine. Heol is a 16-bit Lisp designed to fit comfortably inside Uxn with Varvara bindings. Heol 是一个为 Uxn 虚拟机设计的 Lisp 系统。它是一个 16 位的 Lisp,旨在通过 Varvara 绑定,舒适地运行在 Uxn 环境中。
Execution consists of reducing expressions, atoms return their value, lists are treated as function applications where the first element is a function name and the rest, arguments. Arguments are evaluated before being passed to the function. 执行过程由归约表达式组成:原子(atoms)返回其自身的值;列表被视为函数调用,其中第一个元素是函数名,其余为参数。参数在传递给函数之前会被求值。
Lists
列表
The (cons value list) procedure constructs pairs, the (car list) procedure extracts the first elements of the list, and the (cdr list) procedure extracts the rest.
(cons value list) 过程用于构造序对,(car list) 过程用于提取列表的第一个元素,而 (cdr list) 过程用于提取剩余部分。
(cons 'a '(b c)) ; (a b c)
(car '(a b c)) ; a
(cdr '(a b c)) ; (b c)
Logic
逻辑
The (eq? a b) procedure results in a flag either #t or () provided that the values of the expressions being compared are both atoms, and either they are both the same number, or they are both the same symbol:
(eq? a b) 过程返回一个标志(#t 或 ())。前提是参与比较的两个表达式值均为原子,且它们要么是相同的数字,要么是相同的符号:
(eq? 'a 'a) ; #t
(eq? 'a 'b) ; ()
Given three expressions, the (if flag when-true else) returns the value of the second if the value of the expression flag is #t, otherwise returns the value of the third.
给定三个表达式,(if flag when-true else) 会在 flag 为 #t 时返回第二个表达式的值,否则返回第三个表达式的值。
(if #t 123 456)
Arithmetic
算术
Arithmetic operators apply on all the items of a list and follow the prefix notation: 算术运算符应用于列表中的所有项,并遵循前缀表示法:
(* (+ 1 3 5) 19) ; 171
Procedures
过程
A (lambda args exp) expression evaluates to a procedure. The environment which is in effect when a lambda expression is evaluated is enclosed in the newly created procedure, this is referred to as a closure. Given an expression, the (quote exp) procedure returns that expression as a value.
(lambda args exp) 表达式会求值为一个过程。当 lambda 表达式被求值时,当前生效的环境会被封装在新创建的过程内,这被称为闭包(closure)。给定一个表达式,(quote exp) 过程会将该表达式作为值返回。
((lambda (x) (* x x)) 3) ; 9
The (define name exp) expression binds an expression to a name, making it possible to utilize that reference throughout the code.
(define name exp) 表达式将一个表达式绑定到一个名称上,从而可以在代码中引用该名称。
(define double (lambda (x) (+ x x)))
(double 5) ; 10
Sequencing operations
序列操作
Heol does not have an explicit way of sequencing reduction (progn, begin, etc..) instead it uses (and x1 x2 … xk). One difference to be mindful of, is that and will not evaluate any argument after the first nil value. This can still be an efficient way, for example, of printing a value and returning another.
Heol 没有显式的归约序列化方法(如 progn, begin 等),而是使用 (and x1 x2 ... xk)。需要注意的一个区别是,and 不会求值第一个 nil 值之后的任何参数。这仍然是一种高效的方法,例如,用于打印一个值并返回另一个值。
(and (print 'hello) 42) ; Prints "Hello", but returns 42
Loops
循环
We now have the parts needed to make a loop and print the state of each step. 现在我们有了构建循环并打印每一步状态所需的所有组件。
(define count-down (lambda (n) (if (< n 0) n (and (print n) (count-down (- n 1))))))
(count-down 9)
9876543210
Programs
程序
If we put it all together now: 现在让我们把它们整合在一起:
(define fac (lambda (n) (if (< n 2) 1 (* n (fac (- n 1))))))
(print (fac 5)) ; 120
Summary
总结
- (eval x) return evaluated x (such as when x was quoted)
- (eval x) 返回求值后的 x(例如当 x 被 quote 时)
- (quote x) special form, returns x unevaluated “as is”
- (quote x) 特殊形式,返回未求值的 x(原样返回)
- (cons x y) construct pair (x . y)
- (cons x y) 构造序对 (x . y)
- (car p) car of pair p
- (car p) 获取序对 p 的 car
- (cdr p) cdr of pair p
- (cdr p) 获取序对 p 的 cdr
- (if x y z) if x is non-() then y else z
- (if x y z) 如果 x 非 () 则返回 y,否则返回 z
- (let* (v1 x1) (v2 x2) … y) binds each variable vi to xi to evaluate y
- (let* (v1 x1) (v2 x2) … y) 将每个变量 vi 绑定到 xi 以求值 y
- (lambda v x) construct a closure
- (lambda v x) 构造一个闭包
- (define v x) define a named value globally
- (define v x) 全局定义一个命名值
- (+ n1 n2 … nk) sum of n1 to nk
- (+ n1 n2 … nk) n1 到 nk 的和
- (- n1 n2 … nk) difference of n1 to nk
- (- n1 n2 … nk) n1 到 nk 的差
- (* n1 n2 … nk) product of n1 to nk
- (* n1 n2 … nk) n1 到 nk 的积
- (/ n1 n2 … nk) quotient of n1 to nk
- (/ n1 n2 … nk) n1 到 nk 的商
- (% n1 n2 … nk) remainder of n1 to nk
- (% n1 n2 … nk) n1 到 nk 的余数
- (< n1 n2) #t if n1<n2, otherwise ()
- (< n1 n2) 若 n1<n2 返回 #t,否则返回 ()
- (eq? x y) #t if x equals y, otherwise ()
- (eq? x y) 若 x 等于 y 返回 #t,否则返回 ()
- (pair? x) #t if x is a non-empty list, a cons cell or closure
- (pair? x) 若 x 是非空列表、cons 单元或闭包,返回 #t
- (or x1 x2 … xk) first x that is not (), otherwise ()
- (or x1 x2 … xk) 返回第一个非 () 的 x,否则返回 ()
- (and x1 x2 … xk) last x if all x are not (), otherwise ()
- (and x1 x2 … xk) 若所有 x 均非 (),返回最后一个 x,否则返回 ()
- (not x) #t if x is (), otherwise ()
- (not x) 若 x 为 () 返回 #t,否则返回 ()
- (dotimes (i x) fn) run fn for x times
- (dotimes (i x) fn) 执行 fn 共 x 次
- (print x) print value of x, returns x
- (print x) 打印 x 的值,并返回 x
- (deo port x) send x to a Varvara port
- (deo port x) 将 x 发送到 Varvara 端口