2015年4月26日日曜日

開発環境

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

テキストポート型(入出力)、出力手続き(write, display, newline)を実装。

参考書籍等

kscheme

コード(BBEdit, Emacs)

port_input_text.h

#pragma once
#include "data.h"

data_s port_input_text_new(char *in);

void port_input_text_free(data_s in);

void port_input_text_print(FILE *stream, data_s in);

port_input_text.c

#include "port_input_text.h"
#include <string.h>
#include <stdlib.h>

data_s port_input_text_new(char *in) {
  data_s out = {
      .type = PORT_INPUT_TEXT,
      .data.input_port = {.port = fopen(in, "r"), .path_name = strdup(in)}};
  return out;
}

void port_input_text_free(data_s in) {
  free(in.data.input_port.port);
  free(in.data.input_port.path_name);
}

void port_input_text_print(FILE *stream, data_s in) {
  fprintf(stream, "#<input-por \"%st\">", in.data.input_port.path_name);
}

port_output_text.h

#pragma once
#include "data.h"

data_s port_output_text_new(char *in);

void port_output_text_free(data_s in);

void port_output_text_print(FILE *stream, 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_free(data_s in) {
  free(in.data.output_port.port);
  free(in.data.output_port.path_name);
}

void port_output_text_print(FILE *stream, data_s in) {
  fprintf(stream, "#<output-por \"%st\">", in.data.output_port.path_name);
}

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);

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, car(in));
  } 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;
}

入出力結果(Terminal(kscm), REPL(Read, Eval, Print, Loop))

$ ./main
kscm> write
#<primitive-procedure write>
kscm> display
#<primitive-procedure display>
kscm> newline
#<primitive-procedure newline>
kscm> (write "scheme")
"scheme"#<undefined>
kscm> (display "scheme")
scheme#<undefined>
kscm> (newline)

#<undefined>
kscm> (begin (display "Hello, World!") (newline))
Hello, World!
#<undefined>
kscm> $

0 コメント:

コメントを投稿