// Parse a character constant of the form 'c' void chrconst(void) { fetchc(); symval = inchar; sym = s_nval; fetchc(); if (inchar != '\'') expectedchar('\''); fetchc(); // consume " }
// Comment: Skip from // to end of line, return next symbol void skipcomment(void) { while (sym == s_comment) { while (inchar && (inchar != '\n') && (inchar != '\r')) fetchc(); if (!inchar) { sym = s_eof; return; } else { fetchc(); // eat \r or \n getsym(); // and tee up what's next } } }
// Parse an identifier from the input stream void parseid(void) { char c = *idbuf = tolower(inchar); byte idbuflen = 1; fetchc(); while (isalnum(inchar) || (inchar == '.') || (inchar == '_')) { if (idbuflen >= IDLEN) overflow(M_id); idbuf[idbuflen++] = tolower(inchar); fetchc(); } idbuf[idbuflen] = 0; // do we have a one-char alpha nvar identifier? if ((idbuflen == 1) && isalpha(c)) { sym = s_nvar; symval = c - 'a'; } // a pin identifier 'a'digit* or 'd'digit*? else if ((idbuflen <= 3) && ((c == 'a') || (c == 'd')) && isdigit(idbuf[1]) && ( #if !defined(TINY85) isdigit(idbuf[2]) || #endif (idbuf[2] == 0))) { sym = (c == 'a') ? s_apin : s_dpin; symval = pinnum(idbuf); } // reserved word? else if (findindex(idbuf, (const prog_char *) reservedwords, 1)) { sym = pgm_read_byte(reservedwordtypes + symval); // e.g., s_if or s_while } // function? else if (findindex(idbuf, (const prog_char *) functiondict, 1)) sym = s_nfunct; #ifdef LONG_ALIASES else if (findindex(idbuf, (const prog_char *) aliasdict, 0)) sym = s_nfunct; #endif #ifdef PIN_ALIASES else if (findpinname(idbuf)) {;} // sym and symval are set in findpinname #endif #ifdef USER_FUNCTIONS else if (find_user_function(idbuf)) sym = s_nfunct; #endif else findscript(idbuf); }
// Parse a numeric constant from the input stream void parsenum(void) { byte radix; radix = 10; symval = inchar - '0'; for (;;) { fetchc(); inchar = tolower(inchar); if ((radix == 10) && (symval == 0)) { if (inchar == 'x') { radix = 16; continue; } else if (inchar == 'b') { radix = 2; continue; } } if (isdigit(inchar)) { inchar = inchar - '0'; if (inchar >= radix) break; symval = (symval*radix) + inchar; } else if (radix == 16) { if ((inchar >= 'a') && (inchar <= 'f')) symval = (symval*radix) + inchar - 'a' + 10; else break; } else break; } sym = s_nval; }
int gethex(byte count) { int value = 0; while (count--) { value = (value << 4) + hexval(inchar); fetchc(); } return value; }
// Parse a "quoted string" from the input. // // Enter with sym = s_quote therefore inchar = first char in string // Exit with inchar = first char past closing s_quote // // Callers will need to call getsym() to resume parsing // void parsestring(void (*charFunc)(char)) { for (;;) { if (inchar == ASC_QUOTE) { // found the string terminator fetchc(); // consume it so's we move along break; // done with the big loop } else if (inchar == ASC_BKSLASH) { // bkslash escape conventions per K&R C fetchc(); switch (inchar) { // pass-thrus case ASC_QUOTE: break; // just a dbl quote, move along case ASC_BKSLASH: break; // just a backslash, move along // minor translations case 'n': inchar = '\n'; break; case 't': inchar = '\t'; break; case 'r': inchar = '\r'; break; case 'x': // bkslash x hexdigit hexdigit fetchc(); if (ishex(inchar)) { byte firstnibble = hexval(inchar); fetchc(); if (ishex(inchar)) { inchar = hexval(inchar) + (firstnibble << 4); break; } } unexpected(M_char); inchar = 'x'; break; } } // Process the character we just extracted (*charFunc)(inchar); fetchc(); if (!inchar) unexpected(M_eof); // get next else end of input before string terminator } }
// Parse a one- or two-char operator like >, >=, >>, ... void parseop(void) { sym = inchar; // think horse not zebra fetchc(); // inchar has second char of token or ?? const prog_char *tk = twochartokens; byte index = 0; for (;;) { byte c1 = pgm_read_byte(tk++); if (!c1) return; byte c2 = pgm_read_byte(tk++); if ((sym == c1) && (inchar == c2)) { sym = (byte) pgm_read_byte(twocharsyms + index); fetchc(); if (sym == s_comment) skipcomment(); return; } index++; } }
///////// // // "cat": copy file to serial out // numvar sdcat(void) { if (!scriptfileexists((char *) getarg(1))) return 0; numvar fetchmark = markparsepoint(); initparsepoint(SCRIPT_FILE, 0L, (char *) getarg(1)); while (inchar) { if (inchar == '\n') spb('\r'); spb(inchar); fetchc(); } returntoparsepoint(fetchmark, 1); return 1; }
// One-char literal symbols, like '*' and '+'. void litsym(void) { sym = inchar; fetchc(); }
// Skip to next nonblank and return the symbol therefrom void skpwhite(void) { while (chartype(inchar) == 0) fetchc(); getsym(); }