为mit scheme添加for循环语句

Mit-Scheme不支持syntax-case, 只能用它的er-macro-transformer来编写。Mit-Scheme的宏系统比较低级,不支持模式匹配和literal。

使用pmatch能得到一个可用的模式匹配,为了简洁这里使用了pmatch,没有pmatch也可以编写同样的宏,但啰嗦一点。没有literal就导致代码里面满是反引号和逗号。完成的代码看起来很啰嗦,但编写时却比较简单,先写一个与使用syntax-case时相同的transformer,然后再重命名。

宏不会对参数求值。编写正确宏的一个要点就是搞清楚哪个参数在哪个时候求值。最初编写这个宏时就因为没注意参数求值的时机出了一个bug,下面的代码应该是合法的,但最初的版本却不能得到想要的结果。

(define i 1)
(for i from i to (* i 100)
  (if (> i 10) (break #f))
  (display i)
  (display " "))
from后面的i应该一开始就求值与for后面的i和for语句内第二行以后的i无关。

(define-syntax for
  (er-macro-transformer
   (lambda (x r c)
     (pmatch x
       (`(for ,i in ,l . ,body)
        (guard (identifier? i))
        `(,(r ‘call-with-current-continuation)
          (,(r ‘lambda) (break)
           (,(r ‘do) ((,(r ‘ns) ,l (,(r ‘cdr) ,(r ‘ns))))
            ((,(r  ‘null?) ,(r ‘ns)) #f)
            (,(r  ‘let) ((,i (,(r ‘car) ,(r ‘ns))))
             (,(r ‘call-with-current-continuation)
              (,(r ‘lambda) (continue)
               ,@body)))))))
       (`(for ,i from ,a to ,z . ,body)
        (guard (identifier? i))
        `(,(r ‘let) ((,(r ‘a) ,a)
                     (,(r ‘z) ,z))
          (,(r ‘call/cc)
           (,(r ‘lambda) (break)
            (,(r ‘do) ((,i ,(r ‘a) (+ ,i 1)))
             ((,(r ‘>) ,i ,(r ‘ z)) #f)
             (,(r ‘call/cc)
              (,(r ‘lambda) (continue)
               ,@body)))))))
       (`(for ,i from ,a ,b to ,z . ,body)
        (guard (identifier? i))
        `(,(r ‘let*) ((,(r ‘a) ,a)
                      (,(r ‘b) ,b)
                      (,(r ‘z) ,z)
                      (,(r ‘s) (,(r ‘-) ,(r ‘b) ,(r ‘a)))
                      (,(r ‘p) (,(r ‘if) (,(r ‘>) ,(r ‘b) ,(r ‘a))
                                ,(r ‘>) ,(r ‘<))))
          (,(r ‘call/cc)
           (,(r ‘lambda) (break)
            (,(r ‘do) ((,i ,(r ‘a) (,(r ‘+) ,i ,(r ‘s))))
             ((,(r ‘p) ,i ,(r ‘z)) #f)
             (,(r ‘call/cc)
              (,(r ‘lambda) (continue)
               ,@body)))))))
       (else (error ‘bad-syntax x))))))
时间: 2024-12-29 16:14:21

为mit scheme添加for循环语句的相关文章

为scheme添加for循环语句

有三个辅助关键字in, from和to能够 break和continue语法有三种(for n in '(1 2 3 4 5 6 7 8 9 10) (if (> n 8) (break #f)) (if (even? n) (continue #f)) (display n) (display " "))=> 1 3 5 7 #f(for n from 1 to 100 (if (> n 10) (break #f)) (display n) (display &q

Swift流程控制之循环语句和判断语句详解

Swift提供了所有c类语言的控制流结构.包括for和while循环来执行一个任务多次:if和switch语句来执行确定的条件下不同的分支的代码:break和continue关键字能将运行流程转到你代码的另一个点上. 除了C语言传统的for-condition-increment循环,Swift加入了for-in循环,能更加容易的遍历arrays, dictionaries, ranges, strings等其他序列类型. Swift的switch语句也比C语言的要强大很多. Swift中swi

slime for mit scheme

很多人写过 Scheme 开发环境的设置.但 Scheme 毕竟是一种 Lisp ,是 Lisp 就应该用 Slime. Chicken Scheme 有一个扩展叫 Chicken Slime, 安装非常简单,但功能极差.安装之后几乎没用. Slime本身带的,contrib目录下的swank-kawa.scm swank-larceny.scm swank-mit-scheme.scm 一个都不能用. 好在这位先生修复了对Mit Scheme的支持.照他指导安装就可以用了. 但他说 "也可以将

shell test 命令、循环语句

test 命令.循环语句 test命令格式: test condition 通常,在if-then-else语句中,用[]代替,即[ condition ].注意,方括号两边都要有空格. 常用命令: -a 两个条件同时成立,返回真值 -o   两个条件成立一个,就返回真值 -n ' '     后面跟字符串 -z 判断字符串是否为0,为空则返回真值 =            判断左边是否等于右边,若相等,返回true !=         判断左边是否等于右边,若相等,返回false -eq  

自动化运维工具Ansible之Playbooks循环语句

在使用ansible做自动化运维的时候,免不了的要重复执行某些操作,如:添加几个用户,创建几个MySQL用户并为之赋予权限,操作某个目录下所有文件等等.好在playbooks支持循环语句,可以使得某些需求很容易而且很规范的实现. with_items是playbooks中最基本也是最常用的循环语句. - name: add several users   user: name={{ item }} state=present groups=wheel   with_items:      - t

VBS基础篇 - 循环语句(3) - For...Next

VBS基础篇 - 循环语句(3) - For...Next 指定循环次数,使用计数器重复运行语句,语法结构如下: 1 2 3 4 5 For counter = start To end [Step step]     [statements]     [Exit For]     [statements] Next 主要参数:        counter:用做循环计数器的数值变量.这个变量不能是数组元素或用户自定义类型的元素.        start:counter的初值.        

Python基础篇【第四篇】:循环语句

循环语句包含:while和for语句 while循环 whil循环的表达式: while 判断条件: (这里统一四个空格)语句 一定要注意缩进和判断条件后面的冒号! 例如用while计算1-100的和: 1 #!/usr/bin/env python3 2 3 a = 100 4 b = 0 5 counter = 1 6 7 while counter <= a: 8 b = b + counter 9 counter += 1 10 print(b) 运算结果: 1 /Library/Fra

switch_case,&amp;&amp;,||,条件操作符和逗号操作符,循环语句

一.switch-case switch-case语句主要用在多分支条件的环境中,在这种环境中使用if语句会存在烦琐且效率不高的弊端. switch(expression) { case const expression1: .... case const expression2; ... default: ... } 在执行过程中,expression的值会与每个case的值比较,实现switch语句的功能.关键字case和它所关联的值被称作case标号.每个case标号的值都必须是一个整形常

shell学习之for循环语句【初学者】

前言:日常系统管理工作中有大量需要重复运行的指令,shell编程提供了for.while.until.select循环语句以实现特定指令的反复执行功能,在所有的循环语句中,变量必须要有初始值,每次运行命令序列前都需要对条件进行过滤,满足条件才会运行命令,否则不执行相关操作.下面介绍的就是for循环语句的两种语法格式. for 循环每次处理依次列表内信息,直至循环耗尽.相对于while.until的循环方式是必须符合某个条件的状态,for这种语法是已经知道要进行几次循环的状态. 语法格式1: fo