開発環境
- 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ではなく、関数を呼び出すとか))を少しずつ書き進めてめていくことに。
出力ファイルを開いたり閉じたりする基本手続きを実装。
参考書籍等
- 計算機プログラムの構造と解釈[第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)
port_output_text.h
#pragma once
#include "data.h"
data_s port_output_text_new(char *in);
void port_output_text_print(FILE *stream, data_s in);
data_s port_output_text_close(data_s in);
port_output_text.c
#include "port_output_text.h"
#include <string.h>
#include <stdlib.h>
data_s port_output_text_new(char *in) {
data_s out = {
.type = PORT_OUTPUT_TEXT,
.data.output_port = {.port = fopen(in, "w"), .path_name = strdup(in)}};
return out;
}
void port_output_text_print(FILE *stream, data_s in) {
fprintf(stream, "#<output-port \"%s\">", in.data.output_port.path_name);
}
#include "none.h"
data_s port_output_text_close(data_s in) {
fclose(in.data.output_port.port);
free(in.data.output_port.path_name);
return none_data;
}
prim_io_procedures.c
#pragma once
#include "data.h"
data_s prim_io_write(data_s in);
data_s prim_io_display(data_s in);
data_s prim_io_newline(data_s in);
data_s prim_io_close_port(data_s in);
data_s prim_io_open_input_file(data_s in);
data_s prim_io_open_output_file(data_s in);
data_s prim_io_close_output_port(data_s in);
prim_io_procedures.c
#include "prim_io_procedures.h"
#include "list_operations.h"
#include "empty.h"
#include "undef.h"
data_s prim_io_write(data_s in) {
if (cdr(in).type == EMPTY)
data_s_print(stdout, car(in));
else
data_s_print(cadr(in).data.output_port.port, car(in));
return undef_data;
}
data_s prim_io_display(data_s in) {
data_s t = car(in);
if (cdr(in).type == EMPTY) {
if (t.type == STRING)
fprintf(stdout, "%s", t.data.str);
else
data_s_print(stdout, t);
} else {
if (t.type == STRING)
fprintf(cadr(in).data.output_port.port, "%s", t.data.str);
else
data_s_print(cadr(in).data.output_port.port, t);
}
return undef_data;
}
data_s prim_io_newline(data_s in) {
if (in.type == EMPTY)
fprintf(stdout, "\n");
else
fprintf(car(in).data.output_port.port, "\n");
return undef_data;
}
data_s prim_io_open_input_file(data_s in) {
return data_s_new(PORT_INPUT_TEXT, car(in).data.str);
}
data_s prim_io_open_output_file(data_s in) {
return data_s_new(PORT_OUTPUT_TEXT, car(in).data.str);
}
#include "port_output_text.h"
#include "none.h"
data_s prim_io_close_port(data_s in) {
data_s t = car(in);
if (t.type == PORT_INPUT_TEXT) {
return port_output_text_close(t);
}
return none_data;
}
data_s prim_io_close_output_port(data_s in) {
data_s t = car(in);
if (t.type == PORT_INPUT_TEXT) {
return port_output_text_close(t);
}
return none_data;
}
入出力結果(Terminal(kscm), REPL(Read, Eval, Print, Loop))
$ ./main kscm> open-output-file #<primitive-procedure open-output-file> kscm> close-output-port #<primitive-procedure close-output-port> kscm> (define file (open-output-file "text.txt")) kscm> (display "Hello, World! " file) #<undefined> kscm> (close-output-port file) kscm> (define file (open-output-file "text1.txt")) kscm> (close-port file) kscm> close-port #<primitive-procedure close-port> kscm> $ cat text.txt Hello, World! $ cat text1.txt $
0 コメント:
コメントを投稿