URL
https://opencores.org/ocsvn/thor/thor/trunk
Subversion Repositories thor
[/] [thor/] [trunk/] [FT64v5/] [software/] [CC64/] [source/] [NextToken.cpp] - Rev 59
Go to most recent revision | Compare with Previous | Blame | View Log
// ============================================================================ // __ // \\__/ o\ (C) 2012-2017 Robert Finch, Waterloo // \ __ / All rights reserved. // \/_// robfinch<remove>@finitron.ca // || // // C64 - 'C' derived language compiler // - 64 bit CPU // // This source file is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published // by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This source file is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. // // ============================================================================ // #include "stdafx.h" /* * 68000 C compiler * * Copyright 1984, 1985, 1986 Matthew Brandt. * all commercial rights reserved. * * This compiler is intended as an instructive tool for personal use. Any * use for profit without the written consent of the author is prohibited. * * This compiler may be distributed freely for non-commercial use as long * as this notice stays intact. Please forward any enhancements or questions * to: * * Matthew Brandt * Box 920337 * Norcross, Ga 30092 */ /******************************************************* Modified to support Raptor64 'C64' language by Robert Finch robfinch@opencores.org *******************************************************/ extern char *errtext(int); int inComment = FALSE; int my_errno[80]; int numerrs; char inpline[520]; int total_errors = 0; extern char *lptr; /* shared with preproc */ extern std::ifstream *inclfile[10]; /* shared with preproc */ extern int inclline[10]; /* shared with preproc */ extern int incldepth; /* shared with preproc */ char *linstack[20]; /* stack for substitutions */ char chstack[20]; /* place to save lastch */ int lstackptr = 0; /* substitution stack pointer */ static char numstr[100]; static char *numstrptr; static char backup_token = 0; int isalnum(char c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); } int isidch(char c) { return isalnum(c) || c == '_' || c == '$'; } int my_isspace(char c) { return c == ' ' || c == '\t' || c == '\n' || c=='\r'; } int isdigit(char c) { return (c >= '0' && c <= '9'); } void initsym() { lptr = inpline; inpline[0] = 0; numerrs = 0; total_errors = 0; lineno = 0; } int getline(int listflag) { int rv; if(lineno > 0 && listflag) { lfs.printf("%6d\t%s",lineno,inpline); while(numerrs) { numerrs--; if (numerrs < 80) lfs.printf(" *** error %d: %s\n",my_errno[numerrs],errtext(my_errno[numerrs])); } numerrs = 0; } ++lineno; memset(inpline, 0, sizeof(inpline)); ifs->getline(inpline,512); strcat_s(inpline,sizeof(inpline),"\n"); rv = ifs->gcount()==0; //printf("line:%.60s\r\n", inpline); if( rv && incldepth > 0 ) { ifs->close(); ifs = inclfile[--incldepth]; lineno = inclline[incldepth]; return getline(0); } if( rv ) return 1; lptr = inpline; if(inpline[0] == '#' && !inComment) return preprocess(); return 0; } /* * getch - basic get character routine. */ int getch() { while( (lastch = *lptr++) == '\0') { if( lstackptr > 0 ) { lptr = linstack[--lstackptr]; lastch = chstack[lstackptr]; goto j1; } if(getline(incldepth == 0)) return lastch = -1; } j1: if (numstrptr >= &numstr[0] && numstrptr < &numstr[98]) { *numstrptr = lastch; numstrptr++; } return lastch; } // // getid - get an identifier. // // identifiers are any isidch conglomerate // that doesn't start with a numeric character. // this set INCLUDES keywords. // void getid() { int i; i = 0; lastid[0] = '_'; while(isidch(lastch)) { if(i < 120) { lastkw[i] = lastch; i++; lastid[i] = lastch; } getch(); } lastkw[i] = '\0'; lastid[i+1] = '\0'; lastst = id; } /* * getsch - get a character in a quoted string. * * this routine handles all of the escape mechanisms * for characters in strings and character constants. */ int getsch() /* return an in-quote character */ { register int i, j; if(lastch == '\n') return -1; if(lastch != '\\' || !parseEsc) { i = lastch; getch(); return i; } getch(); /* get an escaped character */ if(isdigit(lastch)) { i = 0; for(j = i = 0;j < 3;++j) { if(lastch <= '7' && lastch >= '0') i = (i << 3) + lastch - '0'; else break; getch(); } return i; } i = lastch; getch(); switch(i) { case '\n': getch(); return getsch(); case 'b': return '\b'; case 'f': return '\f'; case 'n': return '\n'; case 'r': return '\r'; case 't': return '\t'; default: return i; } } void getFilename() { int i; char j; for(i = 0;i < MAX_STRLEN;++i) { if(lastch == '>') break; if((j = getsch()) == -1) break; else laststr[i] = j; } laststr[i] = 0; lastst = sconst; if(lastch != '>') error(ERR_SYNTAX); else getch(); } int64_t radix36(char c) { if(isdigit(c)) return c - '0'; if(c >= 'a' && c <= 'z') return c - 'a' + 10; if(c >= 'A' && c <= 'Z') return c - 'A' + 10; return -1; } /* * getbase - get an integer in any base. */ void getbase(int64_t b) { register int64_t i0, i1, i2; register int64_t i, j; int k; i = 0; i0 = 0; i1 = 0; while(isalnum(lastch)) { if((j = radix36(lastch)) < b) { i = i * b + j; i2 = i0; for (k = 0; k < b; k++) { i0 = i0 + i2; if (i0 & 0x1000000000000000LL) { i0 = i0 - 0x1000000000000000LL; i1 = i1 + 1; } } i0 = i0 + j; if (i0 & 0x1000000000000000LL) { i0 = i0 - 0x1000000000000000LL; i1 = i1 + 1; } getch(); } else break; } if (lastch=='L' || lastch=='U') // ignore a 'L'ong suffix and 'U'nsigned getch(); ival = i; /* rval.exp = 0x804E; rval.man1 = (i1 >> 32) & 0xffffL; rval.man2 = (i1 >> 16) & 0xffffL; rval.man3 = i1 & 0xffffL; rval.man4 = (i0 >> 16) & 0ffffL; rval.man5 = i0 & 0xffffL; // normalize the number while (!(rval.man1 & 0x8000)) { rval.exp--; rval.man1 = (rval.man1 << 1) | (rval.man2 & 0x8000) ? 1 : 0; rval.man2 = (rval.man2 << 1) | (rval.man3 & 0x8000) ? 1 : 0; rval.man3 = (rval.man3 << 1) | (rval.man4 & 0x8000) ? 1 : 0; rval.man4 = (rval.man4 << 1) | (rval.man5 & 0x8000) ? 1 : 0; rval.man5 = (rval.man5 << 1); } */ lastst = iconst; } // // getfrac - get fraction part of a floating number. // void getfrac() { Float128 frmul128,tmp,ch128,fract128; double frmul; double fract = 0.0; Float128::Assign(&frmul128,Float128::One()); frmul = 1.0; while(isdigit(lastch)) { Float128::IntToFloat(&ch128,lastch-'0'); Float128::Mul(&tmp,&fract128,Float128::Ten()); Float128::Add(&fract128,&ch128,&tmp); fract = fract * 10.0 + (lastch - '0'); getch(); frmul *= 10.0; Float128::Mul(&frmul128,&frmul128,Float128::Ten()); } fract = fract / frmul; rval += fract; Float128::Div(&fract128,&fract128,&frmul128); Float128::Add(&rval128,&rval128,&fract128); } /* * getexp - get exponent part of floating number. * * this algorithm is primative but usefull. Floating * exponents are limited to +/-255 but most hardware * won't support more anyway. */ void getexp() { double expo, exmul; Float128 exp128, exmul128; Float128::Assign(&exp128,Float128::One()); expo = 1.0; if(lastst != rconst) rval = (double)ival; if(lastch == '-') { Float128::Assign(&exmul128,Float128::OneTenth()); exmul = 0.1; getch(); } else if (lastch=='+') { getch(); Float128::Assign(&exmul128,Float128::Ten()); exmul = 10.0; } else { Float128::Assign(&exmul128,Float128::Ten()); exmul = 10.0; } getbase(10); if(ival > 32767) error(ERR_FPCON); else while(ival--) { Float128::Mul(&exp128,&exp128,&exmul128); expo *= exmul; } Float128::Mul(&rval128,&rval128,&exp128); rval *= expo; } /* * getnum - get a number from input. * * getnum handles all of the numeric input. it accepts * decimal, octal, hexidecimal, and floating point numbers. */ void getnum() { register int i; i = 0; ival = 0; rval = 0.0; Float128::Assign(&rval128,Float128::Zero()); numstrptr = &numstr[0]; *numstrptr = lastch; numstrptr++; if(lastch == '0') { getch(); if (lastch=='.') goto j1; if(lastch == 'x' || lastch == 'X') { getch(); getbase(16); } else getbase(8); } else { getbase(10); j1: if(lastch == '.') { getch(); rval = (double)ival; /* float the integer part */ Float128::IntToFloat(&rval128, (__int64)ival); getfrac(); /* add the fractional part */ lastst = rconst; } if(lastch == 'e' || lastch == 'E') { getch(); getexp(); /* get the exponent */ // This must be reset because getting the exponent // calls getbase() which will set lastst=iconst lastst = rconst; } if (lastst==rconst && (lastch=='Q' || lastch=='q' || lastch=='D' || lastch=='d' || lastch=='s' || lastch=='S' || lastch=='T' || lastch=='t')) { float_precision = tolower(lastch); getch(); } else float_precision = 'd'; // Ignore 'U' unsigned suffix if (lastch=='U' || lastch=='u') { getch(); } } numstrptr[-1]='\0'; numstrptr = NULL; // dd_real::read(numstr,rval); // printf("leave getnum=%s\r\n", numstr); } void SkipSpaces() { while( my_isspace(lastch) ) { getch(); } } /* * NextToken - get next symbol from input stream. * * NextToken is the basic lexical analyzer. It builds * basic tokens out of the characters on the input * stream and sets the following global variables: * * lastch: A look behind buffer. * lastst: type of last symbol read. * laststr: last string constant read. * lastid: last identifier read. * ival: last integer constant read. * rval: last real constant read. * * NextToken should be called for all your input needs... */ void NextToken() { int i, j; SYM *sp; int tch; restart: /* we come back here after comments */ if (backup_token) { backup_token = 0; lastch = '('; lastst = openpa; return; } SkipSpaces(); if( lastch == -1) { lastst = my_eof; dfs.printf("Returning EOF from NextToken.\n"); } else if(isdigit(lastch)) { getnum(); } else if(isidch(lastch)) { getid(); if( (sp = defsyms.Find(lastid,false)) != NULL) { tch = lastch; if (!(lastch==')' && sp->value.s[0]=='(')) { if (lstackptr < 19) { linstack[lstackptr] = lptr; chstack[lstackptr++] = tch; lptr = sp->value.s; } getch(); goto restart; } } } else { switch(lastch) { case '+': getch(); if(lastch == '+') { getch(); lastst = autoinc; } else if(lastch == '=') { getch(); lastst = asplus; } else lastst = plus; break; case '-': getch(); if(lastch == '-') { getch(); lastst = autodec; } else if(lastch == '=') { getch(); lastst = asminus; } else if(lastch == '>') { getch(); lastst = pointsto; } else lastst = minus; break; case '*': getch(); if(lastch == '=') { getch(); lastst = astimes; } else lastst = star; break; case '/': getch(); if(lastch == '=') { getch(); lastst = asdivide; } else if(lastch == '*') { inComment = TRUE; getch(); for(;;) { if(lastch == '*') { getch(); if(lastch == '/') { getch(); inComment = FALSE; goto restart; } } else getch(); } } else if (lastch == '/') { inComment = TRUE; for(;;) { getch(); if (lastch=='\n' || lastch==-1) { //getch(); inComment = FALSE; goto restart; } } } else lastst = divide; break; case '^': getch(); if( lastch == '=') { lastst = asxor; getch(); } else lastst = uparrow; break; case ';': getch(); lastst = semicolon; break; case ':': getch(); if (lastch==':') { lastst = double_colon; getch(); } else lastst = colon; break; case '=': getch(); if(lastch == '=') { getch(); lastst = eq; } else lastst = assign; break; case '>': getch(); if(lastch == '=') { getch(); lastst = geq; } else if(lastch == '>') { getch(); if(lastch == '=') { getch(); lastst = asrshift; } else if (lastch=='>') { getch(); if (lastch=='=') { getch(); lastst = asrrot; } else lastst = rrot; } else lastst = rshift; } else lastst = gt; break; case '<': getch(); if(lastch == '=') { getch(); lastst = leq; } else if(lastch == '<') { getch(); if(lastch == '=') { getch(); lastst = aslshift; } else if (lastch=='<') { getch(); if (lastch=='=') { getch(); lastst = aslrot; } else lastst = lrot; } else lastst = lshift; } else if (lastch == '>') { getch(); lastst = neq; } else lastst = lt; break; case '\'': getch(); ival = getsch(); /* get a string char */ if(lastch != '\'') error(ERR_SYNTAX); else getch(); lastst = cconst; break; case '\"': getch(); for(i = 0;i < MAX_STRLEN;++i) { if(lastch == '\"') break; if((j = getsch()) == -1) break; else laststr[i] = j; } laststr[i] = 0; lastst = sconst; if(lastch != '\"') error(ERR_SYNTAX); else getch(); break; case '!': getch(); if(lastch == '=') { getch(); lastst = neq; } else lastst = nott; break; case '%': getch(); if(lastch == '=') { getch(); lastst = asmodop; } else lastst = modop; break; case '~': getch(); lastst = cmpl; break; case '.': getch(); lastst = dot; if (lastch=='.') { getch(); if (lastch=='.') { getch(); lastst = ellipsis; strcpy_s(lastid, sizeof(lastid), "..."); } } break; case ',': getch(); lastst = comma; break; case '&': getch(); if( lastch == '&') { lastst = land; getch(); } else if( lastch == '=') { lastst = asand; getch(); } else lastst = bitandd; break; case '|': getch(); if(lastch == '|') { lastst = lor; getch(); } else if( lastch == '=') { lastst = asor; getch(); } else lastst = bitorr; break; case '(': getch(); lastst = openpa; break; case ')': getch(); lastst = closepa; break; case '[': getch(); lastst = openbr; break; case ']': getch(); lastst = closebr; break; case '{': getch(); lastst = begin; break; case '}': getch(); lastst = end; break; case '?': getch(); lastst = hook; break; case '\\': getch(); goto restart; default: getch(); error(ERR_ILLCHAR); goto restart; /* get a real token */ } } if(lastst == id) IdentifyKeyword(); // printf("token: %d",lastst); // if (lastst==id) // printf("lastid=%s| ", lastid); } void needpunc(enum e_sym p,int clue) { if( lastst == p) NextToken(); else { //printf("%d %s\r\n", lineno, inpline); printf("*************clue:%d************\r\n",clue); error(ERR_PUNCT); } } void backup() { backup_token = 1; }
Go to most recent revision | Compare with Previous | Blame | View Log