extern ASPROP *asprop;
-/* ã\82¢ã\82»ã\83³ã\83\96ã\83©å\91½ä»¤ã\81¨ã\83\9eã\82¯ã\83å\91½ä»¤ã\82\92表ã\81\99ç\95ªå\8f· */
+/* アセンブラ命令を表す番号 */
typedef enum {
START = 01,
END = 02,
DS = 03,
DC = 04,
+} ASCMDID;
+
+/* アセンブラ命令を表す配列 */
+typedef struct {
+ ASCMDID cmdid;
+ int opdc_min;
+ int opdc_max;
+ char *cmd;
+} ASCMD;
+
+/* マクロ命令を表す番号 */
+typedef enum {
IN = 011,
OUT = 012,
RPUSH = 013,
RPOP = 014,
-} CASLCMD;
+} MACROCMDID;
-/* ã\82¢ã\82»ã\83³ã\83\96ã\83©å\91½ä»¤ã\81¨ã\83\9eã\82¯ã\83å\91½ä»¤ã\82\92表ã\81\99é\85\8då\88\97 */
+/* マクロ命令を表す配列 */
typedef struct {
- CASLCMD cmdid;
+ MACROCMDID cmdid;
int opdc_min;
int opdc_max;
char *cmd;
-} CMDARRAY;
+} MACROCMD;
/* ラベル配列 */
typedef struct {
/* アセンブラ命令DCをメモリに書込 */
void writeDC(const char *str, PASS pass);
-/* 命令がアセンブラ命令の場合は処理を実行する。
- 実行に成功した場合TRUE、それ以外の場合はFALSEを返す */
+/* 命令がアセンブラ命令の場合は処理を実行する。 */
+/* 実行に成功した場合TRUE、それ以外の場合はFALSEを返す */
bool assemblecmd(const CMDLINE *cmdl, PASS pass);
/* 命令のコードを返す
命令が無効な場合は0xFFFF */
WORD getcmd(CMDTYPE type, const char *cmd);
-/* 命令が機械語命令の場合は処理を実行
- 実行に成功した場合TRUE、それ以外の場合はFALSEを返す */
+/* 命令が機械語命令の場合は処理を実行 */
+/* 実行に成功した場合TRUE、それ以外の場合はFALSEを返す */
bool cometcmd(const CMDLINE *cmdl, PASS pass);
/* 1行のアセンブル */
/* エラーを出力して終了 */
void *malloc_chk(size_t size, char *tag);
+/* malloc_chkを実行してメモリを確保してから、 */
+/* コピーした文字列を返す */
+char *strdup_chk(const char *s, char *tag);
+
/* エラーの構造体 */
typedef struct {
int num; /* エラー番号 */
WORD r;
/* 「GR[0-7]」以外の文字列では、0xFFFFを返して終了 */
if(!(strlen(str) == 3 && strncmp(str, "GR", 2) == 0 &&
- (*(str+2) >= '0' && *(str+2) <= '0' + GRSIZE)))
+ (*(str+2) >= '0' && *(str+2) <= '0' + (GRSIZE - 1))))
{
return 0xFFFF;
}
bool assemblecmd(const CMDLINE *cmdl, PASS pass)
{
int i = 0;
- CASLCMD cmd = 0;
+ ASCMDID cmdid = 0;
bool status = false;
- CMDARRAY ascmd[] = {
+ ASCMD ascmd[] = {
{ START, 0, 1, "START" },
{ END, 0, 0, "END" },
{ DC, 1, OPDSIZE, "DC" },
setcerr(106, NULL); /* operand count mismatch */
return false;
}
- cmd = ascmd[i].cmdid;
+ cmdid = ascmd[i].cmdid;
break;
}
} while(ascmd[++i].cmdid != 0);
/* アセンブラ命令 */
- switch(cmd)
+ switch(cmdid)
{
case START:
if(cmdl->label == NULL) {
return false;
}
/* プログラム名の設定 */
- asprop->prog = strdup(cmdl->label);
+ asprop->prog = strdup_chk(cmdl->label, "asprop.prog");
/* オペランドがある場合、実行開始番地を設定 */
if(pass == SECOND && cmdl->opd->opdc == 1) {
if((progprop->start = getlabel(asprop->prog, cmdl->opd->opdv[0])) == 0xFFFF) {
bool macrocmd(const CMDLINE *cmdl, PASS pass)
{
int i = 0;
- CASLCMD cmd;
+ MACROCMDID cmdid;
bool status = false;
- CMDARRAY macrocmd[] = {
+ MACROCMD macrocmd[] = {
{ IN, 2, 2, "IN" },
{ OUT, 2, 2, "OUT" },
{ RPUSH, 0, 0, "RPUSH" },
do {
if(strcmp(cmdl->cmd, macrocmd[i].cmd) == 0) {
- if(cmdl->opd->opdc < macrocmd[i].opdc_min || cmdl->opd->opdc > macrocmd[i].opdc_max) {
+ if(cmdl->opd->opdc < macrocmd[i].opdc_min ||
+ cmdl->opd->opdc > macrocmd[i].opdc_max)
+ {
setcerr(106, NULL); /* operand count mismatch */
return false;
}
- cmd = macrocmd[i].cmdid;
+ cmdid = macrocmd[i].cmdid;
break;
}
} while(macrocmd[++i].cmdid != 0);
- switch(cmd)
+ switch(cmdid)
{
case IN:
status = writeIN(cmdl->opd->opdv[0], cmdl->opd->opdv[1], pass);
/* casl2コマンドのオプション */
static struct option longopts[] = {
- {"source", no_argument, NULL, 's'},
- {"label", no_argument, NULL, 'l'},
- {"labelonly", no_argument, NULL, 'L'},
- {"assembledetail", no_argument, NULL, 'a'},
- {"assembledetailonly", no_argument, NULL, 'A'},
- {"assembleout", optional_argument, NULL, 'o'},
- {"assembleoutonly", optional_argument, NULL, 'O'},
- {"trace", no_argument, NULL, 't'},
- {"tracearithmetic", no_argument, NULL, 't'},
- {"tracelogical", no_argument, NULL, 'T'},
- {"dump", no_argument, NULL, 'd'},
- {"memorysize", required_argument, NULL, 'M'},
- {"clocks", required_argument, NULL, 'C'},
- {"help", no_argument, NULL, 'h'},
- {0, 0, 0, 0},
+ { "source", no_argument, NULL, 's' },
+ { "label", no_argument, NULL, 'l' },
+ { "labelonly", no_argument, NULL, 'L' },
+ { "assembledetail", no_argument, NULL, 'a' },
+ { "assembledetailonly", no_argument, NULL, 'A' },
+ { "assembleout", optional_argument, NULL, 'o' },
+ { "assembleoutonly", optional_argument, NULL, 'O' },
+ { "trace", no_argument, NULL, 't' },
+ { "tracearithmetic", no_argument, NULL, 't' },
+ { "tracelogical", no_argument, NULL, 'T' },
+ { "dump", no_argument, NULL, 'd' },
+ { "memorysize", required_argument, NULL, 'M' },
+ { "clocks", required_argument, NULL, 'C' },
+ { "help", no_argument, NULL, 'h' },
+ { 0, 0, 0, 0 },
};
/* casl2のエラー定義 */
/* 指定されたファイルにアセンブル結果を書込 */
void outassemble(const char *file) {
FILE *fp;
+
if((fp = fopen(file, "w")) == NULL) {
perror(file);
exit(-1);
const char *objfile_name(const char *str)
{
const char *default_name = "a.o";
-
- if(str == NULL) {
- return default_name;
- } else {
- return str;
- }
+ return (str == NULL) ? default_name : str;
}
/* casl2コマンドのメイン */
int main(int argc, char *argv[])
{
- int opt, i, retval = 0;
+ int opt, i, status = 0;
PASS pass;
- bool status = false;
+ bool res = false;
WORD beginptr[argc];
char *objfile = NULL;
const char *usage =
asmode.onlyassemble = true;
break;
case 'o':
- objfile = strdup(objfile_name(optarg));
+ objfile = strdup_chk(objfile_name(optarg), "objfile");
break;
case 'O':
asmode.onlyassemble = true;
- objfile = strdup(objfile_name(optarg));
+ objfile = strdup_chk(objfile_name(optarg), "objfile");
break;
case 't':
execmode.trace = true;
{
fprintf(stdout, "\nAssemble %s (%d)\n", argv[i], pass);
}
- if((status = assemble(argv[i], pass)) == false) {
+ if((res = assemble(argv[i], pass)) == false) {
exit(-1);
}
}
freelabel(); /* ラベルハッシュ表を解放 */
}
}
- if(status == true) {
+ if(res == true) {
if(objfile != NULL) {
outassemble(objfile);
}
if(asmode.onlyassemble == false) {
create_code_type(); /* 命令と命令タイプがキーのハッシュ表を作成 */
- status = exec(); /* プログラム実行 */
+ res = exec(); /* プログラム実行 */
free_code_type(); /* 命令と命令タイプがキーのハッシュ表を解放 */
}
}
/* COMET II仮想マシンのシャットダウン */
shutdown();
if(cerr->num > 0) {
- retval = -1;
+ status = -1;
}
/* エラーの解放 */
freecerr();
- return retval;
+ return status;
}
return p;
}
+/* malloc_chkを実行してメモリを確保してから、 */
+/* コピーした文字列を返す */
+char *strdup_chk(const char *s, char *tag)
+{
+ assert(s != NULL);
+ char *t;
+
+ t = malloc_chk(strlen(s) + 1, tag);
+ strcpy(t, s);
+ return t;
+}
+
/* 現在のエラー */
CERR *cerr;
/* 命令をセット */
keys[0] = malloc_chk(sizeof(HKEY), "hash_cmdtype.key");
keys[0]->type = CHARS;
- keys[0]->val.s = strdup(cmd);
+ keys[0]->val.s = strdup_chk(cmd, "keys[0].val");
/* 命令タイプをセット */
keys[1] = malloc_chk(sizeof(HKEY), "hash_cmdtype.key");
keys[1]->type = INT;
/* comet2コマンド */
int main(int argc, char *argv[])
{
- int opt, retval = 0;
+ int opt, status = 0;
const char *usage = "Usage: %s [-tTdh] [-M <MEMORYSIZE>] [-C <CLOCKS>] FILE\n";
/* エラーの初期化 */
/* COMET II仮想マシンのシャットダウン */
shutdown();
if(cerr->num > 0) {
- retval = -1;
+ status = -1;
}
/* エラーの解放 */
freecerr();
- return retval;
+ return status;
}
#include <getopt.h>
static struct option longopts[] = {
- {"arithmetic", no_argument, NULL, 'a'},
- {"logical", no_argument, NULL, 'l'},
- {"help", no_argument, NULL, 'h'},
- {0, 0, 0, 0},
+ { "arithmetic", no_argument, NULL, 'a' },
+ { "logical", no_argument, NULL, 'l' },
+ { "help", no_argument, NULL, 'h' },
+ { 0, 0, 0, 0 },
};
int main(int argc, char *argv[])
clock_t clock_begin, clock_end;
addcerrlist_exec();
- if(execmode.trace) {
+ if(execmode.trace == true) {
fprintf(stdout, "\nExecuting machine codes\n");
}
- /* レジスタの初期化 */
+ /* フラグレジスタの初期値設定 */
+ cpu->fr = 0x0;
cpu->sp = memsize;
cpu->pr = progprop->start;
/* 機械語の実行 */
case 0x8100: /* RET */
assert(cpu->sp > progprop->end && cpu->sp <= memsize);
if(cpu->sp == memsize) {
- return false;
+ return true;
} else {
cpu->pr = memory[(cpu->sp)++];
break;
{
HKEY *keys[2];
int i = 0;
+
if(prog != NULL) {
- keys[i] = malloc_chk(sizeof(HKEY), "labelhash.key");
+ keys[i] = malloc_chk(sizeof(HKEY), "labelhash.key[]");
keys[i]->type = CHARS;
- keys[i++]->val.s = strdup(prog);
+ keys[i]->val.s = strdup_chk(prog, "labelhash.key[].val");
}
- keys[i] = malloc_chk(sizeof(HKEY), "labelhash.key");
+ keys[i] = malloc_chk(sizeof(HKEY), "labelhash.key[]");
keys[i]->type = CHARS;
- keys[i]->val.s = strdup(label);
+ keys[i]->val.s = strdup_chk(label, "labelhash.key[].val");
/* ハッシュ値を返す */
return hash(i+1, keys, LABELTABSIZE);
}
{
assert(label != NULL);
LABELTAB *np;
+
for(np = labels[labelhash(prog, label)]; np != NULL; np = np->next) {
if((prog == NULL || (np->prog != NULL && strcmp(prog, np->prog) == 0)) &&
strcmp(label, np->label) == 0)
return false;
}
/* メモリを確保 */
- if((np = malloc_chk(sizeof(LABELTAB), "addlabel.np")) == NULL) {
- goto cerr102;
- }
+ np = malloc_chk(sizeof(LABELTAB), "labels.next");
/* プログラム名を設定 */
if(prog == NULL) {
np->prog = NULL;
} else {
- if((np->prog = strdup(prog)) == NULL) {
- goto cerr102;
- }
+ np->prog = strdup_chk(prog, "labels.prog");
}
/* ラベルを設定 */
- if((np->label = strdup(label)) == NULL) {
- goto cerr102;
- }
+ np->label = strdup_chk(label, "labels.label");
/* アドレスを設定 */
np->adr = adr;
/* ラベル数を設定 */
np->next = labels[hashval];
labels[hashval] = np;
return true;
-cerr102:
- setcerr(102, NULL); /* label table is full */
- return false;
}
int compare_adr(const void *a, const void *b)
for(i = 0; i < LABELTABSIZE; i++) {
for(np = labels[i]; np != NULL; np = np->next) {
assert(np->label != NULL);
- ar[asize] = malloc_chk(sizeof(LABELARRAY), "ar[asize]");
- ar[asize]->prog = (np->prog == NULL ? NULL : strdup(np->prog));
- ar[asize]->label = strdup(np->label);
+ ar[asize] = malloc_chk(sizeof(LABELARRAY), "ar[]");
+ if(np->prog == NULL) {
+ ar[asize]->prog = NULL;
+ } else {
+ ar[asize]->prog = strdup_chk(np->prog, "ar[].prog");
+ }
+ ar[asize]->label = strdup_chk(np->label, "ar[].label");
ar[asize++]->adr = np->adr;
}
}
{
int i;
LABELTAB *np, *nq;
+
for(i = 0; i < LABELTABSIZE; i++) {
for(np = labels[i]; np != NULL; np = nq) {
nq = np->next;
void reset()
{
int i;
+
/* メモリの初期化 */
memory = malloc_chk(memsize * sizeof(WORD), "memory");
for(i = 0; i < memsize; i++) {
/* COMET II仮想マシンのシャットダウン */
void shutdown()
{
+ free(progprop);
free(cpu);
free(memory);
}
if(str == NULL) {
return opd;
}
- p = q = strdup(str);
+ p = q = strdup_chk(str, "opdtopk.p");
do {
/* オペランド数が多すぎる場合はエラー */
if(opd->opdc >= OPDSIZE) {
setcerr(118, NULL); /* operand length is too long */
break;
}
- opd->opdv[(++opd->opdc)-1] = strdup(p);
+ opd->opdv[(++opd->opdc)-1] = strdup_chk(p, "opd.opdv[]");
p = q = sepp + 1;
qcnt = 0;
}
if(line == NULL || strlen(line) == 0) {
return NULL;
}
- tokens = strdup(line);
+ tokens = strdup_chk(line, "tokens");
/* コメントを削除 */
for(p = tokens; *p != '\0'; p++) {
/* 「'」で囲まれた文字列の処理。「''」は無視 */
if(strlen(p) > LABELSIZE) {
setcerr(104, p); /* label length is too long */
}
- cmdl->label = strdup(p);
+ cmdl->label = strdup_chk(p, "cmdl.label");
p = sepp + 1;
}
while(*p == ' ' || *p == '\t') {
/* 命令を取得 */
sepp = p + strcspn(p, " \t\n");
*sepp = '\0';
- cmdl->cmd = strdup(p);
+ cmdl->cmd = strdup_chk(p, "cmdl.cmd");
p = sepp + 1;
while(*p == ' ' || *p == '\t') {
p++;
}
/* オペランドを取得 */
- cmdl->opd = malloc_chk(sizeof(OPD), "cmdl->opd");
+ cmdl->opd = malloc_chk(sizeof(OPD), "cmdl.opd");
/* 改行かタブまでの文字列を取得。
「'」で囲まれた文字列に含まれる場合があるため、空白は無視 */
if((sepp = p + strcspn(p, "\t\n")) > p) {