⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tm.c

📁 SIP软件开发记录 由于通信网的封闭性
💻 C
📖 第 1 页 / 共 2 页
字号:
/* File: tm.c
 * The TM ( Tiny Machine ) computer
 * K. C. Louden CCPP-C
 *
 * Compiler Construction: Principles and Practice
 * Kenneth C. Louden
 * 编译原理及实践
 * (美) Kenneth C. Louden 著
 * 冯博琴 冯岚 等译
 * 机械工业出版社 IBSN 7-111-07703-2
 * 源代码:zwf编辑并修订
 * Code Modify: Larry Li 2001.11
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif

//#define CHINESE

/* const */
#define IADDR_SIZE 1024
#define DADDR_SIZE 1024
#define NO_REGS 8
#define PC_REG 7

#define LINESIZE 121
#define WORDSIZE 20

/* type */
typedef enum {
	opclRR,
	opclRM,
	opclRA
} OPCLASS;

typedef enum {
	opHALT,
	opIN,
	opOUT,
	opADD,
	opSUB,
	opMUL,
	opDIV,
	opRRLim,

	opLD,
	opST,
	opRMLim,

	opLDA,
	opLDC,
	opJLT,
	opJLE,
	opJGT,
	opJGE,
	opJEQ,
	opJNE,
	opRALim
} OPCODE;

typedef enum {
	srOKAY,
	srHALT,
	srIMEM_ERR,
	srDMEM_ERR,
	srZERODIVIDE
} STEPRESULT;

typedef struct {
	int iop;
	int iarg1;
	int iarg2;
	int iarg3;
} INSTRUCTION;

/* vars */
int iloc = 0;
int dloc = 0;
int traceflag = FALSE;
int icountflag = FALSE;

INSTRUCTION iMem[IADDR_SIZE];
int dMem[DADDR_SIZE];
int reg[NO_REGS];

char *opCodeTab[] = {
	"HALT", "IN", "OUT", "ADD", "SUB", "MUL", "DIV", "????",
	"LD", "ST", "????",
	"LDA", "LDC", "JLT", "JLE", "JGT", "JGE", "JEQ", "JNE", "????"
};

#ifdef CHINESE
char *stepResultTab[] = {
	"就绪", "停止", "初始化内存失败",
	"数据储存失败", "零除错误"
};
#else
char *stepResultTab[] = {
	"OK", "Halted", "Instruction Memory Fault",
	"Data Memory Fault", "Division by 0"
};
#endif

char pgmName[20];
FILE *pgm;

char in_Line[LINESIZE];
int lineLen;
int inCol;
int num;
char word[WORDSIZE];
char ch;
int done;

/* opClass */
int opClass(int c)
{
	if (c <= opRRLim)
		return opclRR;
	if (c <= opRMLim)
		return opclRM;
	return opclRA;
}

/* writeInstruction */
void writeInstruction(int loc)
{
	printf("%5d: ", loc);
	if ((loc >= 0) && (loc < IADDR_SIZE)) {
		printf("%6s%3d,", opCodeTab[iMem[loc].iop], iMem[loc].iarg1);
		switch (opClass(iMem[loc].iop)) {
		case opclRR:
			printf("%1d,%1d", iMem[loc].iarg2, iMem[loc].iarg3);
			break;
		case opclRM:
		case opclRA:
			printf("%3d(%1d)", iMem[loc].iarg2, iMem[loc].iarg3);
			break;
		}
		printf("\n");
	}
}

/* getCh */
void getCh(void)
{
	if (++inCol < lineLen)
		ch = in_Line[inCol];
	else
		ch = ' ';
}

/* nonBlank */
int nonBlank(void)
{
	while ((inCol < lineLen) && (in_Line[inCol] == ' '))
		inCol++;
	if (inCol < lineLen) {
		ch = in_Line[inCol];
		return TRUE;
	} else {
		ch = ' ';
		return FALSE;
	}
}

/* getNum */
int getNum(void)
{
	int sign;
	int term;
	int temp = FALSE;

	num = 0;
	do {
		sign = 1;
		while (nonBlank() && ((ch == '+') || (ch == '-'))) {
			temp = FALSE;
			if (ch == '-')
				sign = -sign;
			getCh();
		}
		term = 0;
		nonBlank();
		while (isdigit(ch)) {
			temp = TRUE;
			term = term * 10 + (ch - '0');
			getCh();
		}
		num += term * sign;
	} while ((nonBlank()) && ((ch == '+') || (ch == '-')));
	return temp;
}

/* getWord */
int getWord(void)
{
	int temp = FALSE;
	int length = 0;

	if (nonBlank()) {
		while (isalnum(ch)) {
			if (length < WORDSIZE - 1)
				word[length++] = ch;
			getCh();
		}
		word[length] = '\0';
		temp = (length != 0);
	}
	return temp;
}

/* skipCh */
int skipCh(char c)
{
	int temp = FALSE;

	if (nonBlank() && (ch == c)) {
		getCh();
		temp = TRUE;
	}
	return temp;
}

/* atEOL */
int atEOL(void)
{
	return (!nonBlank());
}

/* error */
int error(char *msg, int lineNo, int instNo)
{
#ifdef CHINESE
	printf("第 %d 行", lineNo);
#else
	printf("Line %d", lineNo);
#endif
	if (instNo >= 0)
#ifdef CHINESE
		printf(" (指令 %d)", instNo);
#else
		printf(" (Instruction %d)", instNo);
#endif
	printf("   %s\n", msg);
	return FALSE;
}

/* readInstructions */
int readInstructions(void)
{
	OPCODE op;
	int arg1, arg2, arg3;
	int loc, regNo, lineNo;

	for (regNo = 0; regNo < NO_REGS; regNo++)
		reg[regNo] = 0;
	dMem[0] = DADDR_SIZE - 1;
	for (loc = 1; loc < DADDR_SIZE; loc++)
		dMem[loc] = 0;
	for (loc = 0; loc < DADDR_SIZE; loc++) {
		iMem[loc].iop = opHALT;
		iMem[loc].iarg1 = 0;
		iMem[loc].iarg2 = 0;
		iMem[loc].iarg3 = 3;
	}
	lineNo = 0;
	while (!feof(pgm)) {
		fgets(in_Line, LINESIZE - 2, pgm);
		inCol = 0;
		lineNo++;
		lineLen = strlen(in_Line) - 1;
		if (in_Line[lineLen] == '\n')
			in_Line[lineLen] = '\0';
		else
			in_Line[++lineLen] = '\0';
		if ((nonBlank()) && (in_Line[inCol] != '*')) {
			if (!getNum())
#ifdef CHINESE
				return error("地址错误", lineNo, -1);
#else
				return error("Bad location", lineNo, -1);
#endif
			loc = num;
			if (loc > IADDR_SIZE)
#ifdef CHINESE
				return error("地址太大", lineNo, loc);
#else
				return error("Location too large", lineNo, loc);
#endif
			if (!skipCh(':'))
#ifdef CHINESE
				return error("丢失冒号", lineNo, loc);
#else
				return error("Missing colon", lineNo, loc);
#endif
			if (!getWord())
#ifdef CHINESE
				return error("丢失操作符", lineNo, loc);
#else
				return error("Missing opcode", lineNo, loc);
#endif
			op = opHALT;
			while ((op < opRALim)
				   && (strncmp(opCodeTab[op], word, 4) != 0))
				op++;
			if (strncmp(opCodeTab[op], word, 4) != 0)
#ifdef CHINESE
				return error("丢失操作数", lineNo, loc);
#else
				return error("Illegal opcode", lineNo, loc);
#endif
			switch (opClass(op)) {
			case opclRR:
				if ((!getNum()) || (num < 0) || (num >= NO_REGS))
#ifdef CHINESE
					return error("第一个数据错误", lineNo, loc);
#else
					return error("Bad first register", lineNo, loc);
#endif
				arg1 = num;
				if (!skipCh(','))
#ifdef CHINESE
					return error("丢失逗号", lineNo, loc);
#else
					return error("Missing comma", lineNo, loc);
#endif
				if ((!getNum()) || (num < 0) || (num >= NO_REGS))
#ifdef CHINESE
					return error("第二个数据错误", lineNo, loc);
#else
					return error("Bad second register", lineNo, loc);
#endif
				arg2 = num;
				if (!skipCh(','))
#ifdef CHINESE
					return error("丢失逗号", lineNo, loc);
#else
					return error("Missing comma", lineNo, loc);
#endif
				if ((!getNum()) || (num < 0) || (num >= NO_REGS))
#ifdef CHINESE
					return error("第三个数据错误", lineNo, loc);
#else
					return error("Bad third register", lineNo, loc);
#endif
				arg3 = num;
				break;
			case opclRM:
			case opclRA:
				if ((!getNum()) || (num < 0) || (num >= NO_REGS))
#ifdef CHINESE
					return error("第一个数据错误", lineNo, loc);
#else
					return error("Bad first register", lineNo, loc);
#endif
				arg1 = num;
				if (!skipCh(','))
#ifdef CHINESE
					return error("丢失逗号", lineNo, loc);
#else
					return error("Missing comma", lineNo, loc);
#endif
				if (!getNum())
#ifdef CHINESE
					return error("错误位移数据", lineNo, loc);
#else
					return error("Bad displacement", lineNo, loc);
#endif
				arg2 = num;
				if (!skipCh('(') && !skipCh(','))
#ifdef CHINESE
					return error("丢失左括号", lineNo, loc);
#else
					return error("Missing LParen", lineNo, loc);
#endif
				if ((!getNum()) || (num < 0) || (num >= NO_REGS))
#ifdef CHINESE
					return error("第二个数据错误", lineNo, loc);
#else
					return error("Bad second register", lineNo, loc);
#endif
				arg3 = num;
				break;
			}
			iMem[loc].iop = op;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -