
開発環境
- 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ではなく、関数を呼び出すとか))を少しずつ書き進めてめていくことに。
未実装だった cond 構文の else 節と、構文 let を(lambdaを使って導出された式として)実装完了。
参考書籍等
- 計算機プログラムの構造と解釈[第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)
cond.h
#pragma once
#include "data.h"
void cond_print(FILE *stream, data_s in);
extern const data_s cond_data;
extern const data_s else_data;
extern data_s else_sym;
void else_print(FILE *stream, data_s in);
void ev_cond();
cond.c
#include "cond.h"
const data_s cond_data = {.type = COND};
void cond_print(FILE *stream, data_s in) { fprintf(stream, "#<syntax cond>"); }
#include "evaluator.h"
#include "list_operations.h"
#include "undef.h"
#include "if.h"
#include "symbol.h"
#include "begin.h"
#include "environment.h"
#include "sequence.h"
const data_s else_data = {.type = ELSE};
data_s else_sym;
void else_print(FILE *stream, data_s in) { fprintf(stream, "#<else>"); }
static data_s expand_clauses(data_s in) {
if (in.type == EMPTY)
return undef_data;
data_s first = car(in);
data_s rest = cdr(in);
data_s t = cdr(first);
data_s e = car(first);
if (e.type == SYMBOL && e.data.symbol == else_sym.data.symbol &&
lookup_variable_value(e, env).type == ELSE)
return sequence2expr(cdr(first));
if (t.type == EMPTY)
return make_if(car(first), t, expand_clauses(rest));
if (cdr(t).type == EMPTY)
return make_if(car(first), car(t), expand_clauses(rest));
return make_if(car(first), cons(begin_data, t), expand_clauses(rest));
}
static data_s cond2if(data_s in) { return expand_clauses(cdr(in)); }
void ev_cond() {
expr = cond2if(expr);
eval_flag = 1;
}
let.h
#pragma once
#include "data.h"
void let_print(FILE *stream, data_s in);
extern const data_s let_data;
void ev_let();
let.c
#include "let.h"
void let_print(FILE *stream, data_s in) { fprintf(stream, "#<syntax let>"); }
#include "evaluator.h"
#include "list_operations.h"
#include "lambda.h"
#include "empty.h"
const data_s let_data = {.type = LET};
static data_s let2combination(data_s in) {
data_s body = cddr(in);
data_s vars = empty_data;
data_s exprs = empty_data;
data_s t = reverse(cadr(expr));
while (t.type != EMPTY) {
data_s var_expr = car(t);
vars = cons(car(var_expr), vars);
exprs = cons(cadr(var_expr), exprs);
t = cdr(t);
}
return cons(make_lambda(vars, body), exprs);
}
void ev_let() {
expr = let2combination(expr);
eval_flag = 1;
}
入出力結果(Terminal(kscm), REPL(Read, Eval, Print, Loop))
$ ./main kscm> cond #<syntax cond> kscm> (cond (#t 1) (else 2)) 1 kscm> (cond (#f 1) (else 2)) 2 kscm> let #<syntax let> kscm> (let ((a 5) (b 10)) (+ a b)) 15 kscm> (let ((a 5) (b 10)) (+ a b) (* a b)) 50 kscm> $
0 コメント:
コメントを投稿