開発環境
- OS X Yosemite - Apple, Ubuntu (OS)
- Emacs (CUI)、BBEdit - Bare Bones Software, Inc. (GUI) (Text Editor)
- C (プログラミング言語)
- Clang/LLVM (コンパイラ, Xcode - Apple)
Schemeの処理系(解釈系、評価器、レジスタ計算機を翻訳した命令列中心のより、もう少しC言語の特性を使った書き方をしたもの(label, gotoではなく、関数を呼び出すとか))を少しずつ書き進めてめていくことに。
Land of Lisp で必要になった, 準クォート(quasiquote、バッククォートともいうのかも)、unquote 等を実装。
参考書籍等
- 計算機プログラムの構造と解釈[第2版]
- Structure and Interpretation of Computer Programs (原書)
- R7RSHomePage – Scheme Working Groups
- Head First C ―頭とからだで覚えるCの基本
- 21st Century C: C Tips from the New School
- プログラミング言語C 第2版 ANSI規格準拠
- プログラミング言語Cアンサー・ブック 第2版
- C実践プログラミング 第3版
kscheme
コード(BBEdit, Emacs)
quasiquote.c
#include "quasiquote.h"
#include "list_operations.h"
void quasiquote_print(FILE *stream, data_s in) {
fprintf(stream, "#<syntax quasiquote>");
}
const data_s quasiquote_data = {.type = QUASIQUOTE};
data_s quasiquote_sym;
#include "empty.h"
#include "symbol.h"
static data_s quasiquote2expr(data_s in) {
data_s out;
data_s quote_sym = data_s_new(SYMBOL, "quote");
data_s quasiquote_sym = data_s_new(SYMBOL, "quasiquote");
data_s unquote_sym = data_s_new(SYMBOL, "unquote");
data_s cons_sym = data_s_new(SYMBOL, "cons");
data_s t = cadr(in);
if (t.type == EMPTY)
out = list(2, quote_sym, empty_data);
else if (t.type != PAIR)
out = list(2, quote_sym, t);
else {
out = list(2, quote_sym, empty_data);
data_s reversed = reverse(t);
while (reversed.type != EMPTY) {
data_s elem = car(reversed);
if (elem.type == PAIR) {
data_s t = car(elem);
if (t.type == SYMBOL && symbol_is_eq(t, unquote_sym)) {
out = list(3, cons_sym, cadr(elem), out);
} else {
out = list(3, cons_sym,
quasiquote2expr(list(2, quasiquote_sym, elem)), out);
}
} else {
out = list(3, cons_sym, list(2, quote_sym, elem), out);
}
reversed = cdr(reversed);
}
}
return out;
}
#include "evaluator.h" // eval_flag
void ev_quasiquote() {
expr = quasiquote2expr(expr);
eval_flag = 1;
}
入出力結果(Terminal(kscm), REPL(Read, Eval, Print, Loop))
$ kscheme kscm> `() () kscm> `(1) (1) kscm> `(1 2) (1 2) kscm> `(1 (+ 2 3)) (1 (+ 2 3)) kscm> `(1 ,(+ 2 3)) (1 5) kscm> `(1 (+ 2 3) 4) (1 (+ 2 3) 4) kscm> `(1 ,(+ 2 3) 4) (1 5 4) kscm> `((1) 2) ((1) 2) kscm> `((+ 1 2) 3) ((+ 1 2) 3) kscm> `(,(+ 1 2) 3) (3 3) kscm> `(1 2 (3 ,(+ 4 5))) (1 2 (3 9)) kscm> `(1 2 (3 ,(+ 4 5) 6)) (1 2 (3 9 6)) kscm> `(1 2 (,(+ 4 5) 6)) (1 2 (9 6)) kscm> `(`(1 2)) ((quasiquote (1 2))) kscm> $
0 コメント:
コメントを投稿