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

📄 smal32.c

📁 极小的CPU的VHDL源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (lim - pos > ttlbuflen - 3)		lim = pos + ttlbuflen - 3;	for (i = pos - 1; i < lim; i++) {		(*len)++;		buf[*len - 1] = line[i];	}}static void newpage(){	/* force listing to the start of a new page */	inbufptr i;	if (!permitlisting) return;	if (lineonpg <= 1) return;	putc('\f', o);   /* formfeed character */	/* note that instead of using a formfeed, this routine	    could be written to simply output blank lines and	    count them with lineonpg until the count was high	    enough to push the listing to a new page      */	lineonpg = 1;	pagenum++;	/* write title to listing file */	fputs("SMAL32, rev  6/98.              ", o);	for (i = 0; i < titlelen; i++)		putc(titlebuf[i], o);	for (i = titlelen; i <= ttlbuflen; i++)		putc(' ', o);	fputs(timestr, o);	fputs("  Page ", o);	writedec(o, pagenum, 1);	putc('\n', o);   /* linefeed character */	fputs("                                ", o);	for (i = 0; i < sbttllen; i++)		putc(sbttlbuf[i], o);	for (i = sbttllen; i <= ttlbuflen; i++)		putc(' ', o);	fputs( datestr, o );	putc('\n', o);   /* linefeed character */	putc('\n', o);}static void listline(){	/*  list one line, including generated code.	    if there are any errors, list the error messages  */	inbufptr i;	ermsg msg;	int col;	int nextcol = 0; /* column on output listing */	int codepos; /* more permanent buffer ptr */	if (!permitlisting) return;	lineonpg++;	if (lineonpg >= linesper) newpage();	col = 1;	codepos = codelen + 1;   /* in case we don't make any code.. */	if (codelen > 0) {  /* list generated code */		if (codeloc.base == abssym)			putc(' ', o);		else			putc('+', o);		writehex(o, codeloc.offset, 6L);		putc(':', o);		col = 9;		i = 0;		while (i < codelen) {  /* list each code item */			_REC_codebuf *WITH;			long width;			i++;			WITH = &codebuf[i - 1];			width = WITH->form * 2;							nextcol = col + width + 2;			if (nextcol > (listcol + 1)) {				codepos = i;				i = codelen;			} else {				if (WITH->val.base != abssym)					putc('+', o);				else					putc(' ', o);				writehex(o, WITH->val.offset, width);				putc(' ', o);				col = nextcol;			}		}	}	for (; col <= listcol; col++)		putc(' ', o);	writedec(o, lineno, 6);	/* text starts in column listcol + 1 */	fputs("  ", o);	for (i = 0; i < length; i++) putc(line[i], o);	/* check for extended code listing */	/* list ALL generated code */	while (codepos <= codelen) {		_REC_codebuf *WITH = &codebuf[codepos - 1];		long width = WITH->form * 2;		nextcol += (width + 2);		if (nextcol > (listcol+1)) {			putc('\n', o);			lineonpg++;			if (lineonpg > linesper) newpage();			fputs("        ", o);			nextcol = 9 + width + 2;		}		if (WITH->val.base != abssym)			putc('+', o);		else			putc(' ', o);		writehex(o, WITH->val.offset, width);		putc(' ', o);		codepos++;	}	codelen = 0;    /* reset record of listed code */	/* write out all accumulated error messages */	if (erset != 0) {   /* if */		for (msg = minermsg; (long)msg <= (long)maxermsg; msg++) {			if (((1L << ((long)msg)) & erset) != 0) {				/* put message into listing */				putc('\n', o);				lineonpg++;				if (lineonpg > linesper) newpage();				fputs( errormsgs[ msg ], o );				for (col = 26; col <= listcol + 7; col++)					putc(' ', o);				for (i = 0; i < ermax; i++)					putc(erbuf[i], o);				ermax = 0;				/* put message to stderr also */				writedec(stderr, lineno, 6);				fputs("  ", stderr);				fputs(errormsgs[ msg ], stderr);				{					int l = length;					if ((l + 26) > 79) l = 79 - 26;					for (i = 0; i < l; i++) {						putc(line[i], stderr);					}				}				putc('\n', stderr);			}		}	}	putc('\n', o);}static void putobj(form, offset, base)int form;long offset;poolref base;{	/* store value (offset,base) in current loc.	   (base=abssym is used for absolute values; typically, relocatable	   values will come from loc.base and loc.offset or expr.base and	   expr.offset.)	   use format form (.25, .5 or 1 word), save information for listing */	if (allowlist) {		/* first assure that code gets loaded in right loc */		if (objloc.offset != loc.offset ||		    objloc.base != loc.base) {			objloc = loc;			fputs(".=", obj);			genval( 4L, loc.offset, loc.base);		}		/* save appropriate listing data */		if (codelen == 0)			codeloc = loc;		if (codelen < listcodes) {			codelen++;			codebuf[codelen - 1].val.offset = offset;			codebuf[codelen - 1].val.base = base;			codebuf[codelen - 1].form = form;		}		/* then generate correct object code */		switch (form) {			case 1: putc('B', obj); break;			case 2: putc('H', obj); break;			case 4: putc('W', obj); break;		}		genval( form, offset, base);		objloc.offset = add(objloc.offset, form);	}	loc.offset = add(loc.offset, form);}static void putascii(pos, lim)inbufptr pos, lim;{	/* generate object code for ascii string */	inbufptr i;	for (i = pos; i < lim; i++) {		putobj(1L, line[i - 1], abssym);	}}/* procedures used only by nextlex */static long number(radix)long radix;{	long acch,accl; /* accumulates the value */	long digit; /* the value of one digit */	/* assume initially that ch is a valid digit */	acch = 0;	accl = 0;	do {		if (charclass[ch] & isdigit)			digit = ch - '0';		else if (charclass[ch] & isupper)			digit = (ch - 'A') + 10;		else			digit = (ch - 'a') + 10;		if (digit >= radix) {			acch = 65536L;		} else {			pos++;			ch = line[pos - 1];			accl = accl * radix + digit;			acch = acch * radix + accl / 65536L;			accl %= 65536L;		}	} while ((charclass[ch] & isalphanum) && (acch < 65536L));	if (digit >= radix) {		errmsg(baddig, pos, pos + 1);		while (charclass[ch] & isalphanum) {			pos++;			ch = line[pos - 1];		}		return 0;	} else if (acch >= 65536L) {		while (charclass[ch] & isalphanum) {			pos++;			ch = line[pos - 1];		}		errmsg(bounds, next.pos, pos);		return 0;	} else if (acch >= 32768L)		return ((acch - 32768L) * 65536L - maxposint + accl - 1);	else		return (acch * 65536L + accl);}/* inside smal32.onepass, lexical analysis routines */static void nextlex(){	/* save the next lexeme information in the current lexeme	   variable, then read a new next one from the input line */	lex = next;	while (line[pos - 1] == ' ') pos++;	ch = line[pos - 1];	next.pos = pos;	if (ch == ';')		next.typ = eol;	else if (charclass[ch] & ispunc) {		switch (ch) {   /* case */		case ':': next.typ = colon; break;		case '.': next.typ = dot; break;		case ',': next.typ = comma; break;		case '=': next.typ = eq; break;		case '>': next.typ = gt; break;		case '<': next.typ = lt; break;		case '+': next.typ = plus; break;		case '-': next.typ = minus; break;		case '\\': next.typ = notsym; break;		case '&': next.typ = andsym; break;		case '!': next.typ = orsym; break;		case '(': next.typ = bpar; break;		case ')': next.typ = epar; break;		}		pos++;	} else if (charclass[ch] & isdigit) {		next.typ = num;		next.UU.val = number(10L);		if (ch == '#') {			if (next.UU.val > 36 || next.UU.val < 2) {				next.UU.val = 36;				errmsg(badrad, next.pos, pos);			}			pos++;			ch = line[pos - 1];			if (charclass[ch] & isalphanum)				next.UU.val = number(next.UU.val);			else				errmsg(baddig, next.pos, pos);		}	} else if (charclass[ch] & isalpha) {		next.typ = id;		do {			pos++;			ch = line[pos - 1];		} while (charclass[ch] & isalphanum);	} else if (ch == '#') {		pos++;		ch = line[pos - 1];		if (charclass[ch] & isalphanum) {			next.typ = num;			next.UU.val = number(16L);		} else   /* if */			next.typ = junk;	} else if (charclass[ch] & isquote) {		char mark = ch;		next.typ = quote;		do {			pos++;		} while (line[pos - 1] != mark && pos <= length);		if (pos <= length)			pos++;		else			errmsg(misquo, next.pos, next.pos + 1);	} else {		do {			pos++;			ch = line[pos - 1];		} while ((charclass[ch] & isvalid) == 0);			next.typ = junk;	}	next.lim = pos;	/* invalid lexeme */}static void startup(){	/* setup for processing one line of input */	getline(); /* read input line */	nextlex(); /* read first lexeme */	nextlex(); /* read second lexeme (allow lookahead) */	/* start parsing by looking for valid start of line */	while ( (lex.typ != id) &&		(lex.typ != eol) &&		(lex.typ != dot)	) {		errmsg(notlab, lex.pos, lex.lim);		nextlex();	}}/* inside smal32.onepass, string pool and symbol table management */static void putch(ch)char ch;{	/* put one char into permanent end of stringpool */	if (poolsp > poolpos) {  /* there is room in pool */		poolpos++;		strpool[poolpos - relsym] = ch;	} else  /* there isn't room */		poolfull = true;}static poolref putpool_(pos, lim)inbufptr pos, lim;{	/* put the string between pos and lim-1 on the current line into		 the string pool, returning it's index in the pool.  the string		 delimiter is appended to the string in the pool.  it is assumed		 that the string will fit (the caller must guarantee this)    */	poolref Result;	inbufptr i;	poolpos++;	Result = poolpos;	for (i = pos - 1; i <= lim - 2; i++) {		strpool[poolpos - relsym] = line[i];		poolpos++;	}	strpool[poolpos - relsym] = pooldel;	return Result;}static boolean poolfit(pos, lim)inbufptr pos, lim;{	/* check to see if text between pos and lim will fit in stringpool */	/* poolfit */	return (poolsp - poolpos > lim - pos);}static boolean poolcmp(poolpos, pos, lim)poolref poolpos;inbufptr pos, lim;{	/* compare the string starting at poolpos in the stringpool with		 that between pos and lim on the current line, return true if		 they are the same; this relies on the fact that the string		 delimiter in the stringpool will never occur in the line   */	while (strpool[poolpos - relsym] == line[pos - 1]) {		poolpos++;		pos++;	}	return (strpool[poolpos - relsym] == pooldel && pos == lim);}static long hash_(pos, lim, modulus)inbufptr pos, lim;long modulus;{	/* compute hash of lexeme between pos and lim,		 return a value between 1 and modulus (inclusive)		 this hash function must match that in "opinit"  */	long acc;	inbufptr p;	/* hash */	acc = 1;	for (p = pos - 1; p <= lim - 2; p++) {		acc = (acc * 5 + line[p]) % modulus + 1;	}	return acc;}static symptr lookup(pos, lim)inbufptr pos, lim;{	/* find the symbol between pos and lim on the current line in	   the symbol table, return the index into the table where it	   was found or inserted; if it could not be inserted, return	   zero      */	symptr Result, s, olds;	association *WITH;	/* lookup */	s = hash_(pos, lim, (long)symsize);	olds = s;	Result = 0;   /* default return value */	do {		WITH = &symtab[s - 1];		if (WITH->id != 0) {   /* with */			if (poolcmp(WITH->id, pos, lim)) {	Result = s;	s = olds;   /* terminate loop */			} else {	if (s < symsize)		s++;	else		s = 1;	if (s == olds)		symfull = true;			}		} else {  /* found unused table entry */			if (poolfit(pos, lim)) {				/* put the symbol in the pool and table */				WITH->id = putpool_(pos, lim);				Result = s;			} else  /* no room in pool for sym */				poolfull = true;			s = olds;   /* terminate loop */		}	} while (s != olds);	return Result;}static void symdump(){	/* dump entire contents of symbol table */        symptr i;        association *WITH;        for (i = 0; i < symsize; i++) {                WITH = &symtab[i];		if (WITH->id != 0) {  /* have nonblank entry */                        writesym(dmp, WITH->id);                        putc('=', dmp);                        putc('\t', dmp); /* sort field delimiter */			/* could use following */			/* genval(..., 4L, WITH->val.offset, WITH->val.base);*/			/* instead, we do it locally to get sortable format */			if (WITH->val.base != abssym) {				if (WITH->val.base = relsym) {					fputs("REL(0)", dmp);				} else {					writesym(dmp, WITH->val.base);				}				putc('+', dmp);			}                        putc('\t', dmp);			putc('#', dmp);			writehex(dmp, WITH->val.offset, 8);        		putc('\n', dmp);		}        }}static opptr oplookup(pos, lim)inbufptr pos, lim;{	/* find the symbol between pos and lim on the current line in		 the opcode table, return the index into the table where it		 was found or should be put; return 0 if it isn't found and		 the table is full         */	opptr Result, s, olds;	_REC_optab *WITH;	s = hash_(pos, lim, (long)opcodes);	olds = s;	Result = 0;   /* default return value */	do {		WITH = &optab[s - 1];		if (WITH->id != 0)   /* with */		{  /* have nonblank entry */			if (poolcmp(WITH->id, pos, lim)) {  /* found it */	Result = s;	s = olds;   /* terminate loop */			} else {	if (s < opcodes)		s++;	else		s = 1;			}		} else {  /* found vacancy */			Result = s;			s = olds;   /* terminate loop */		}	} while (s != olds);	return Result;}/* inside smal32.onepass, utility parsing procedures */static void getcomma(){	/* skip the comma, complain if there isn't one */	if (lex.typ == comma)		nextlex();	else		errmsg(comexp, lex.pos, lex.lim);}static void skipbal(){	/* skip to maching end paren when given begin paren */	long nest;	lexeme par;

⌨️ 快捷键说明

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