/**
* エラーリストを作成・追加する
*/
-bool addcerrlist(int cerrc, CERR cerrv[]);
+void addcerrlist(int cerrc, CERR cerrv[]);
/**
* エラーリストを表示する
#define ARRAYSIZE(array) (sizeof(array)/sizeof(array[0]))
#endif
+/**
+ * メモリを解放
+ */
+#ifndef FREE
+#define FREE(ptr) {free(ptr); ptr = NULL;}
+#endif
+
/**
* mallocを実行し、0で初期化
* メモリを確保できない場合はエラーを出力して終了
*/
char *strdup_chk(const char *s, char *tag);
-/**
- * メモリを解放
- */
-void free_chk(void *ptr, char *tag);
#endif
/**
* 実行エラーをエラーリストに追加
*/
-bool addcerrlist_exec();
+void addcerrlist_exec();
+
+/**
+ * アセンブル結果読み込みエラーをエラーリストに追加
+ */
+void addcerrlist_load();
/**
* 指定されたファイルからアセンブル結果を読み込む
/**
* wordのエラーをエラーリストに追加
*/
-bool addcerrlist_word();
+void addcerrlist_word();
/**
* 10進数または16進数の文字列をWORD値に変換
else if(pass == SECOND) {
execptr->end = asptr->lptr;
}
- /* プログラム名のクリア */
- asptr->prog = NULL;
+ FREE(asptr->prog);
status = true;
break;
case DS:
assembleline(" POP GR2", pass);
assembleline(" POP GR1", pass);
- free_chk(line, "writeIN.line");
+ FREE(line);
}
/**
assembleline(" SVC 2", pass);
assembleline(" POP GR2", pass);
assembleline(" POP GR1", pass);
- free_chk(line, "writeOUT.line");
+ FREE(line);
}
/** マクロ命令「RPUSH」をメモリに書き込む
sprintf(line, " PUSH 0,GR%d", i);
assembleline(line, pass);
}
- free_chk(line, "writeRPUSH.line");
+ FREE(line);
}
/**
sprintf(line, " POP GR%d", i);
assembleline(line, pass);
}
- free_chk(line, "writeRPOP.line");
+ FREE(line);
}
/**
}
/**
- * 1行をアセンブル
+ * トークンをアセンブル
*/
bool assembletok(const CMDLINE *cmdl, PASS pass)
{
bool status = false;
+
/* 命令がない場合 */
if(cmdl->cmd == NULL){
- /* ラベルが定義されていて命令がない場合はエラー */
- if(cmdl->label != NULL) {
- setcerr(105, NULL); /* no command in the line */
- }
+ ;
}
/* アセンブラ命令の処理 */
else if(cerr->num == 0 && assemblecmd(cmdl, pass) == true) {
bool assembleline(const char *line, PASS pass)
{
CMDLINE *cmdl;
+ bool status = true;
+ int i;
- if((cmdl = linetok(line)) != NULL) {
- if(pass == FIRST && cmdl->label != NULL) {
- if(addlabel(asptr->prog, cmdl->label, asptr->ptr) == false) {
- return false;
+ cmdl = linetok(line);
+ status = (cerr->num == 0) ? true : false;
+ if(cmdl != NULL) {
+ if(status == true) {
+ if(pass == FIRST && cmdl->label != NULL) {
+ status = addlabel(asptr->prog, cmdl->label, asptr->ptr);
}
+ if(status == true) {
+ status = assembletok(cmdl, pass);
+ }
+ FREE(cmdl->label);
}
- if(assembletok(cmdl, pass) == false) {
- return false;
+ if(cmdl->opd != NULL) {
+ for(i = 0; i < cmdl->opd->opdc; i++) {
+ FREE(cmdl->opd->opdv[i]);
+ }
}
+ FREE(cmdl->opd);
+ FREE(cmdl->cmd);
}
- return true;
+ FREE(cmdl);
+ return status;
}
/**
{
int lineno = 0;
bool status = true;
- CMDLINE *cmdl;
- char *line;
+ char *line = malloc_chk(LINESIZE + 1, "line");
FILE *fp;
if((fp = fopen(file, "r")) == NULL) {
perror(file);
return false;
}
- for(; ;) {
- cmdl = malloc_chk(sizeof(CMDLINE), "cmdl");
- line = malloc_chk(LINESIZE + 1, "line");
- if((line = fgets(line, LINESIZE, fp)) == NULL) {
- break;
- }
+ while(fgets(line, LINESIZE, fp)) {
lineno++;
if((pass == FIRST && asmode.src == true) ||
(pass == SECOND && asmode.asdetail == true))
if(assembleline(line, pass) == false) {
break;
}
- if(cerr->num > 0) {
- break;
- }
- free_chk(line, "line");
- free_chk(cmdl, "cmdl");
}
if(cerr->num > 0) {
fprintf(stderr, "Assemble error - %d: %s\n", cerr->num, cerr->msg);
printline(stderr, file, lineno, line);
status = false;
}
+ FREE(line);
fclose(fp);
return status;
}
} else if(pass == SECOND) {
asptr->ptr = beginptr[i];
}
- asptr->prog = NULL;
if(execmode.trace == true || execmode.dump == true || asmode.src == true ||
asmode.label == true || asmode.asdetail == true)
{
}
if(pass == SECOND) {
freelabel(); /* ラベルハッシュ表を解放 */
- free_chk(asptr->prog, "asptr.prog"); /* プログラム名を解放 */
- free_chk(asptr, "asptr"); /* アセンブル時のプロパティを解放 */
free_cmdtype_code(); /* 命令の名前とタイプがキーのハッシュ表を解放 */
+ FREE(asptr); /* アセンブル時のプロパティを解放 */
}
}
if(res == true) {
if(objfile != NULL) {
outassemble(objfile);
- free_chk(objfile, "objfile");
+ FREE(objfile);
}
if(asmode.onlyassemble == false) {
create_code_type(); /* 命令のコードとタイプがキーのハッシュ表を作成 */
/**
* エラーリスト
*/
-CERRLIST *cerrlist;
+CERRLIST *cerrlist = NULL;
/**
* エラーリストを作成または追加する
*/
-bool addcerrlist(int newerrc, CERR newerrv[])
+void addcerrlist(int newerrc, CERR newerrv[])
{
int i;
- CERRLIST *p, *q;
+ CERRLIST *p = NULL, *q;
assert(newerrc > 0 && newerrv != NULL);
- if(cerrlist == NULL) {
- p = cerrlist = malloc_chk(sizeof(CERRLIST), "cerrlist");
- } else {
- for(p = cerrlist; p != NULL; p = p->next) {
- q = p;
- }
- p = q->next = malloc_chk(sizeof(CERRLIST), "cerrlist.next");
- }
for(i = 0; i < newerrc; i++) {
+ if(p == NULL) {
+ p = q = malloc_chk(sizeof(CERRLIST), "cerrlist");
+ } else {
+ p = p->next = malloc_chk(sizeof(CERRLIST), "cerrlist.next");
+ }
p->cerr = &newerrv[i];
- q = p;
- p = p->next = malloc_chk(sizeof(CERRLIST), "cerrlist.next");
+ p->next = NULL;
}
- q->next = NULL;
- return true;
+ p->next = cerrlist;
+ cerrlist = q;
}
/**
CERRLIST *p = cerrlist, *q;
/* 現在のエラーメッセージを解放 */
- free_chk(cerr->msg, "cerr.msg");
+ FREE(cerr->msg);
/* 現在のエラーを解放 */
- free_chk(cerr, "cerr");
+ FREE(cerr);
/* エラーリストを解放 */
for(p = cerrlist; p != NULL; p = q) {
q = p->next;
- free_chk(p, "freecerr.p");
+ FREE(p);
}
}
keys[1]->val.i = (int)(type & 070);
/* ハッシュ値の計算 */
hashval = hash(2, keys, cmdtabsize);
- free_chk(keys[0]->val.s, "keys[0].val.s");
- free_chk(keys[0], "keys[0]");
- free_chk(keys[1], "keys[1]");
+ FREE(keys[0]->val.s);
+ FREE(keys[0]);
+ FREE(keys[1]);
/* ハッシュ値を返す */
return hashval;
}
for(i = 0; i < cmdtabsize; i++) {
for(p = cmdtype_code[i]; p != NULL; p = q) {
q = p->next;
- free_chk(p, "free_cmdtype_code");
+ FREE(p);
}
}
}
unsigned hash_code(WORD code)
{
HKEY *keys[1];
+ unsigned h;
/* 命令コードを設定 */
keys[0] = malloc_chk(sizeof(HKEY), "hash_code.key");
keys[0]->type = INT;
keys[0]->val.i = (int)(code >> 8);
- /* ハッシュ値を返す */
- return hash(1, keys, cmdtabsize);
+ h = hash(1, keys, cmdtabsize);
+ FREE(keys[0]);
+ return h;
}
/**
for(i = 0; i < cmdtabsize; i++) {
for(p = code_type[i]; p != NULL; p = q) {
q = p->next;
- free_chk(p, "code_type");
+ FREE(p);
}
}
}
strcpy(t, s);
return t;
}
-
-/**
- * メモリを解放
- */
-void free_chk(void *ptr, char *tag)
-{
- free(ptr);
- ptr = NULL;
-}
{0, 0, 0, 0},
};
-/**
- * comet2コマンドのエラー
- */
-static CERR cerr_comet2[] = {
- { 208, "object file is not specified" },
-};
-
/**
* comet2コマンドのメイン
*/
const char *usage = "Usage: %s [-tTdh] [-M <MEMORYSIZE>] [-C <CLOCKS>] FILE\n";
cerr_init();
- addcerrlist(ARRAYSIZE(cerr_comet2), cerr_comet2);
+ addcerrlist_load();
addcerrlist_exec();
/* オプションの処理 */
* 実行エラーの定義
*/
static CERR cerr_exec[] = {
- { 201, "Loading - full of COMET II memory" },
{ 202, "SVC input - out of Input memory" },
{ 203, "SVC output - out of COMET II memory" },
{ 204, "Program Register (PR) - out of COMET II memory" },
{ 210, "not command code of COMET II" },
};
+/**
+ * アセンブル結果読み込みエラーの定義
+ */
+static CERR cerr_load[] = {
+ { 201, "Loading - full of COMET II memory" },
+ { 208, "object file is not specified" },
+};
+
/**
* 実行モード: trace, logical, dump
*/
EXECMODE execmode = {false, false, false};
/**
- * 実行エラーをエラーリストに追加
+ * アセンブル結果読み込みエラーをエラーリストに追加
*/
-bool addcerrlist_exec()
+void addcerrlist_load()
{
- return addcerrlist(ARRAYSIZE(cerr_exec), cerr_exec);
+ addcerrlist(ARRAYSIZE(cerr_load), cerr_load);
}
+/**
+ * 実行エラーをエラーリストに追加
+ */
+void addcerrlist_exec()
+{
+ addcerrlist(ARRAYSIZE(cerr_exec), cerr_exec);
+}
/**
* 指定されたファイルからアセンブル結果を読み込む
*/
sys->memory[sys->cpu->gr[1]+i] = *(buffer + i);
}
sys->memory[sys->cpu->gr[2]] = i + 1;
- free_chk(buffer, "buffer");
+ FREE(buffer);
}
/**
unsigned labelhash(const char *prog, const char *label)
{
HKEY *keys[2];
- int i = 0;
+ int i = 0, j;
+ unsigned h;
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_chk(prog, "labelhash.key[].val");
+ keys[i]->val.s = strdup_chk(prog, "labelhash.key.val");
+ i++;
}
- 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_chk(label, "labelhash.key[].val");
- /* ハッシュ値を返す */
- return hash(i+1, keys, LABELTABSIZE);
+ keys[i]->val.s = strdup_chk(label, "labelhash.key.val");
+ h = hash(i+1, keys, LABELTABSIZE);
+ for(j = 0; j < i + 1; j++) {
+ FREE(keys[j]->val.s);
+ FREE(keys[j]);
+ }
+ return h;
}
/**
WORD getlabel(const char *prog, const char *label)
{
assert(label != NULL);
- LABELTAB *np;
+ LABELTAB *p;
- 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)
+ for(p = labels[labelhash(prog, label)]; p != NULL; p = p->next) {
+ if((prog == NULL || (p->prog != NULL && strcmp(prog, p->prog) == 0)) &&
+ strcmp(label, p->label) == 0)
{
- return np->adr;
+ return p->adr;
}
}
return 0xFFFF;
void printlabel()
{
int i, asize = 0;
- LABELTAB *np;
+ LABELTAB *p;
LABELARRAY *ar[labelcnt];
for(i = 0; i < LABELTABSIZE; i++) {
- for(np = labels[i]; np != NULL; np = np->next) {
- assert(np->label != NULL);
+ for(p = labels[i]; p != NULL; p = p->next) {
+ assert(p->label != NULL);
ar[asize] = malloc_chk(sizeof(LABELARRAY), "ar[]");
- if(np->prog == NULL) {
+ if(p->prog == NULL) {
ar[asize]->prog = NULL;
} else {
- ar[asize]->prog = strdup_chk(np->prog, "ar[].prog");
+ ar[asize]->prog = strdup_chk(p->prog, "ar[].prog");
}
- ar[asize]->label = strdup_chk(np->label, "ar[].label");
- ar[asize++]->adr = np->adr;
+ ar[asize]->label = strdup_chk(p->label, "ar[].label");
+ ar[asize++]->adr = p->adr;
}
}
qsort(ar, asize, sizeof(*ar), compare_adr);
for(i = 0; i < LABELTABSIZE; i++) {
for(p = labels[i]; p != NULL; p = q) {
q = p->next;
- free_chk(p->prog, "freelabel.p.prog");
- free_chk(p->label, "freelabel.p.label");
- free_chk(p, "freelabel.p");
+ FREE(p->prog);
+ FREE(p->label);
+ FREE(p);
}
}
}
*/
void shutdown()
{
- free_chk(execptr, "execptr");
- free_chk(sys->memory, "sys.memory");
- free_chk(sys->cpu, "sys.cpu");
- free_chk(sys, "sys");
+ FREE(execptr);
+ FREE(sys->memory);
+ FREE(sys->cpu);
+ FREE(sys);
}
if(str == NULL) {
return opd;
}
- p = q = r = strdup_chk(str, "opdtopk.p");
+ p = q = r = strdup_chk(str, "opdtok.p");
do {
/* オペランド数が多すぎる場合はエラー */
if(opd->opdc >= OPDSIZE) {
rcnt = 0;
}
} while(sepc == ',');
- free_chk(p, "opdtok.p");
+ FREE(p);
return opd;
}
{
char *tokens, *p, *sepp;
bool quoting = false;
- CMDLINE *cmdl = malloc_chk(sizeof(CMDLINE), "cmdl");
+ CMDLINE *cmdl = NULL;
if(line == NULL || strlen(line) == 0) {
return NULL;
break;
}
}
- if(*tokens == '\0') {
- return NULL;
- }
- p = tokens;
- /* 行の先頭が空白またはタブの場合、ラベルは空 */
- if((sepp = p + strcspn(p, " \t\n")) == p){
- cmdl->label = NULL;
- } else { /* ラベルを取得 */
- *sepp = '\0';
- /* 文字列が長すぎる場合はエラー */
- if(strlen(p) > LABELSIZE) {
- setcerr(104, p); /* label length is too long */
+ if(*tokens != '\0') {
+ p = tokens;
+ cmdl = malloc_chk(sizeof(CMDLINE), "cmdl");
+ /* ラベルの取得。行の先頭が空白またはタブの場合、ラベルは空 */
+ if((sepp = p + strcspn(p, " \t\n")) == p){
+ cmdl->label = NULL;
+ } else { /* ラベルを取得 */
+ *sepp = '\0';
+ /* 文字列が長すぎる場合はエラー */
+ if(strlen(p) > LABELSIZE) {
+ setcerr(104, p); /* label length is too long */
+ }
+ cmdl->label = strdup_chk(p, "cmdl.label");
+ p = sepp + 1;
}
- cmdl->label = strdup_chk(p, "cmdl.label");
- p = sepp + 1;
- }
- while(*p == ' ' || *p == '\t') {
- p++;
- }
- /* 命令がない場合、終了 */
- if(*p == '\n' || *p == '\0') {
- /* ラベルが定義されていて命令がない場合はエラー */
- if(cmdl->label != NULL) {
- setcerr(105, NULL); /* no command in the line */
+ /* ラベルと命令の間の空白をスキップ */
+ while(*p == ' ' || *p == '\t') {
+ p++;
+ }
+ /* 命令とオペランドの取得 */
+ if(*p == '\n' || *p == '\0') { /* 命令がない場合は、終了 */
+ if(cmdl->label != NULL) { /* ラベルが定義されていて命令がない場合はエラー */
+ setcerr(105, NULL); /* no command in the line */
+ }
+ } else {
+ /* 命令の取得 */
+ sepp = p + strcspn(p, " \t\n");
+ *sepp = '\0';
+ cmdl->cmd = strdup_chk(p, "cmdl.cmd");
+ p = sepp + 1;
+ /* 命令とオペランドの間の空白をスキップ */
+ while(*p == ' ' || *p == '\t') {
+ p++;
+ }
+ /* 改行かタブまでの文字列を取得。
+ 「'」で囲まれた文字列に含まれる場合があるため、空白は無視 */
+ if((sepp = p + strcspn(p, "\t\n")) > p) {
+ *sepp = '\0';
+ cmdl->opd = opdtok(p);
+ } else {
+ cmdl->opd = malloc_chk(sizeof(OPD *), "cmdl.opd");
+ cmdl->opd->opdc = 0;
+ }
}
- return NULL;
- }
- /* 命令を取得 */
- sepp = p + strcspn(p, " \t\n");
- *sepp = '\0';
- cmdl->cmd = strdup_chk(p, "cmdl.cmd");
- p = sepp + 1;
- while(*p == ' ' || *p == '\t') {
- p++;
- }
- /* オペランドを取得 */
- cmdl->opd = malloc_chk(sizeof(OPD), "cmdl.opd");
- /* 改行かタブまでの文字列を取得。
- 「'」で囲まれた文字列に含まれる場合があるため、空白は無視 */
- if((sepp = p + strcspn(p, "\t\n")) > p) {
- *sepp = '\0';
- cmdl->opd = opdtok(p);
- } else {
- cmdl->opd->opdc = 0;
}
+ FREE(tokens);
return cmdl;
}
/**
* wordのエラーをエラーリストに追加
*/
-bool addcerrlist_word()
+void addcerrlist_word()
{
- return addcerrlist(ARRAYSIZE(cerr_word), cerr_word);
+ addcerrlist(ARRAYSIZE(cerr_word), cerr_word);
}
/**
*(digit + j) = *(p + (i - 1) - j);
}
*(digit + j + 1) = '\0';
- free_chk(p, "word2n.p");
+ FREE(p);
return digit;
}
-126: source file is not specified
+202: SVC input - out of Input memory
+203: SVC output - out of COMET II memory
+204: Program Register (PR) - out of COMET II memory
+205: Stack Pointer (SP) - cannot allocate stack buffer
+206: Address - out of COMET II memory
+207: Stack Pointer (SP) - out of COMET II memory
+201: Load object file - full of COMET II memory
+114: not integer
+115: not hex
+116: out of hex range
+114: not integer
+115: not hex
+116: out of hex range
101: label already defined
102: label table is full
103: label not found
123: unclosed quote
124: more than one character in literal
125: not GR in operand x
-114: not integer
-115: not hex
-116: out of hex range
-114: not integer
-115: not hex
-116: out of hex range
-201: Load object file - full of COMET II memory
-202: SVC input - out of Input memory
-203: SVC output - out of COMET II memory
-204: Program Register (PR) - out of COMET II memory
-205: Stack Pointer (SP) - cannot allocate stack buffer
-206: Address - out of COMET II memory
-207: Stack Pointer (SP) - out of COMET II memory
+126: source file is not specified
-#FFFF ---> 000
-#0001 ---> 000
+#FFFF ---> 077
+#0001 ---> 077
#0000 ---> 000
#1000 ---> 011
#1100 ---> 010