2015年4月28日火曜日

開発環境

Schemeの処理系(解釈系、評価機、レジスタ計算機を翻訳した命令列中心のより、もう少しC言語の特性を使った書き方をしたもの(label, gotoではなく、関数を呼び出すとか))を少しずつ書き進めてめていくことに。

出力ファイルを開いたり閉じたりする基本手続きを実装。

参考書籍等

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 コメント:

コメントを投稿