bool_t delchar(bool_t fixpos, bool_t undo) /* bool_t fixpos; /* if TRUE fix the cursor position when done */ /* bool_t undo; /* if TRUE put char deleted into Undo buffer */ { int i; /* Check for degenerate case; there's nothing in the file. */ if (bufempty()) return FALSE; if (lineempty(Curschar)) /* can't do anything */ return FALSE; if (undo) AppendToUndobuff(mkstr(gchar(Curschar))); /* Delete the char. at Curschar by shifting everything in the line down. */ for (i = Curschar->index + 1; i < Curschar->linep->size; i++) Curschar->linep->s[i - 1] = Curschar->linep->s[i]; /* * If we just took off the last character of a non-blank line, we don't * want to end up positioned at the newline. */ if (fixpos) { if (gchar(Curschar) == NUL && Curschar->index > 0 && State != INSERT) Curschar->index--; } CHANGED; return TRUE; }
int symb(void) { int c; char *cp; if(peeks) { c = peeks; peeks = 0; return c; } while ((c = gchar()) > 0) { if ((c == ' ') || (c == '\t')) continue; if (c == '!') while((c > 0) && (c != '\n')) c = gchar(); else break; } /* end while */ if(c <= 0) { peeks = EON; return EON; } if(c == '\n') return LINE; if(c == ':') return COLON; if(c == '%') return PERC; if(c == '.') { c = gchar(); if(c == 'o') return OUT; if(c == 'r') return ITER; if(c == 'x') return EXTERN; return UNKN; } numb = 1; cp = name; while((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '-' || c == '_' || c == '+' || c == '[' || c == ']') { *cp++ = c; if(c < '0' || c > '9') numb = 0; c = gchar(); } if(cp != name) { peekc = c; *cp = 0; if(numb) { numb = atol(name); return NUMB; } return NAME; } return UNKN; }
symb(void) { int c; char *cp; if(peeks) { c = peeks; peeks = 0; return(c); } c = gchar(); while(c == ' ') c = gchar(); if(c <= 0) { peeks = EON; return(EON); } if(c == '\n') return(LINE); if(c == ':') return(COLON); if(c == '%') return(PERC); if(c == '.') { c = gchar(); if(c == 'o') return(OUT); if(c == 'r') return ITER; if(c == 'x') return EXTERN; return(UNKN); } numb = 1; cp = name; while((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '-' || c == '_' || c == '+' || c == '[' || c == ']' || c == '#' || c == '$' || c == '~' || c == '*' || c == '<' || c == '>' || c == '@') { *cp++ = c; if(c < '0' || c > '9') numb = 0; c = gchar(); } if(cp != name) { peekc = c; *cp = 0; if(numb) { numb = atol(name); return NUMB; } return NAME; } return(UNKN); }
inline int RD() { int res; char cr; while( (cr=gchar())<'0' || cr>'9'); res=cr-'0'; while( (cr=gchar())>='0' && cr<='9') res=(res<<1)+(res<<3)+cr-'0'; return res; }
extern int yylex() { static bool dollar = FALSE; bool saw_meta = FALSE; int c; size_t i; /* The purpose of all these local assignments is to */ const char *meta; /* allow optimizing compilers like gcc to load these */ char *buf = realbuf; /* values into registers. On a sparc this is a */ YYSTYPE *y = &yylval; /* win, in code size *and* execution time */ if (errset) { errset = FALSE; return '\n'; } /* rc variable-names may contain only alnum, '*' and '_', so use dnw if we are scanning one. */ meta = (dollar ? dnw : nw); if (newline) { --lineno; /* slight space optimization; nextline() always increments lineno */ nextline(); newline = FALSE; } top: while ((c = gchar()) == ' ' || c == '\t') w = NW; if (c != '(') dollar = FALSE; if (c == EOF) return END; if (!meta[(unsigned char) c]) { /* it's a word or keyword. */ checkfreecaret; w = RW; i = 0; read: do { buf[i++] = c; if (c == '?' || c == '[' || c == '*') saw_meta = TRUE; if (i >= bufsize) buf = realbuf = erenew_arr(char, buf, bufsize *= 2); } while ((c = gchar()) != EOF && !meta[(unsigned char) c]); while (c == '\\') { if ((c = gchar()) == '\n') { nextline(); c = ' '; /* Pretend a space was read */ break; } else { bs: if (meta != dnw) { /* all words but varnames may have a bslash */ buf[i++] = '\\'; if (i >= bufsize) buf = realbuf = erenew_arr(char, buf, bufsize *= 2); if (!meta[(unsigned char) c]) goto read; } else { ugchar(c); c = '\\'; break; } }
int symb(void) { int c; char *cp; if(peeks) { c = peeks; peeks = 0; return c; } c = gchar(); while(c == ' ') c = gchar(); if(c <= 0) { peeks = EON; return EON; } if(c == '\n') return LINE; if(c == ':') return COLON; if(c == '%') return PERC; if(c == '.') { c = gchar(); if(c == 'o') return OUT; if(c == 'r') return ITER; if(c == 'x') return EXTERN; return UNKN; } numb = 1; cp = name; while(cclass[c]) { *cp++ = c; if(cclass[c] != 2) numb = 0; c = gchar(); } if(cp != name) { peekc = c; *cp = 0; if(numb) { numb = atol(name); return NUMB; } return NAME; } return UNKN; }
void inschar(char c) { register char *p; register char *pend; if (last_command == 'R' && (gchar(Curschar) != NUL)) { pchar(Curschar, c); } else { /* make room for the new char. */ if (!canincrease(1)) return; p = &Curschar->linep->s[strlen(Curschar->linep->s) + 1]; pend = &Curschar->linep->s[Curschar->index]; for (; p > pend; p--) *p = *(p - 1); *p = c; } if (RedrawingDisabled) { Curschar->index++; return; } /* * If we're in insert mode and showmatch mode is set, then check for * right parens and braces. If there isn't a match, then beep. If there * is a match AND it's on the screen, then flash to it briefly. If it * isn't on the screen, don't do anything. */ if (P(P_SM) && State == INSERT && (c == ')' || c == '}' || c == ']')) { LPtr *lpos, csave; if ((lpos = showmatch()) == NULL) /* no match, so beep */ beep(); else if (LINEOF(lpos) >= LINEOF(Topchar)) { /* show the new char first */ s_refresh(VALID_TO_CURSCHAR); csave = *Curschar; *Curschar = *lpos; /* move to matching char */ cursupdate(UPDATE_CURSOR); windgoto(Cursrow, Curscol); delay(); /* brief pause */ *Curschar = csave; /* restore cursor position */ cursupdate(UPDATE_ALL); } } inc(Curschar); CHANGED; }
main() { reset(); enable_interrupt(); while() { elegir_luz(); encender_luz(); } /***** rutina de interrupcion *****/ if (scan_inter () != 1) { if (shift_reg == FLAG) { switch (p_buffer) { case (0) : comienzo = 1; break; case (1) : if (comienzo==1) { p_buffer = 0; device = gchar(); if ( device == IDENTIFICATIVO) { acknowledge(); p_out = 0; wserial( gout () ); more = 1; } } break; default : if ( device == IDENTIFICATIVO ) { if (verificar() == NAK) no_acknowledge (); else { ack_nak = interpretar (); if ( ack_nak == ACK ) acknowledge (); else no_acknowledge (); } p_out = 0; wserial( gout () ); more = 1; } break; } p_buffer = 0; } else pchar(shift_reg); } else { if (more == 0) goto RTI; wserial( gout () ); if (shift_reg == 'f') { p_out = 1; more = 0; } } RTI (); }
static void getpair(int c) { int n; fd_left = fd_right = UNSET; if (c != '[') { ugchar(c); return; } if ((unsigned int) (n = gchar() - '0') > 9) { scanerror("expected digit after '['"); return; } while ((unsigned int) (c = gchar() - '0') <= 9) n = n * 10 + c; fd_left = n; c += '0'; switch (c) { default: scanerror("expected '=' or ']' after digit"); return; case ']': return; case '=': if ((unsigned int) (n = gchar() - '0') > 9) { if (n != ']' - '0') { scanerror("expected digit or ']' after '='"); return; } fd_right = CLOSED; } else { while ((unsigned int) (c = gchar() - '0') <= 9) n = n * 10 + c; if (c != ']' - '0') { scanerror("expected ']' after digit"); return; } fd_right = n; } } }
int rdata(void) { int s, c; long v; if(ndc < 0) ndc = 0; if(ndc) { for(s=0; s<ndc; s++) { itmp[itmpp++] = dctmp[s]; if(itmpp >= NTMP) { fprintf(stderr, "rdata: no room\n"); #ifdef PLAN9 exits("rdata no room"); #else exit(1); #endif } } ndc = -1; return 0; } mask = ~0L; loop: s = symb(); if(s == EON) return 1; if(s == ITER) { fprintf(stdout, ".r"); for(;;) { c = gchar(); if(c < 0) goto loop; putchar(c); if(c == '\n') goto loop; } } if(s == EXTERN) { fprintf(stdout, ".x"); while((c = gchar()) != '\n') putchar(c); putchar(c); goto loop; } if(s != OUT) expect(".o"); fflush(stdout); fprintf(stdout, ".o"); for(;;) { s = symb(); if(s == NUMB) { fprintf(stdout, " %ld", numb); continue; } if(s == NAME) { fprintf(stdout, " %s", name); continue; } break; } fprintf(stdout, "\n"); if(s != LINE) expect("new line"); for(;;) { s = symb(); if(s == LINE) continue; if(s != NUMB) break; v = numb; c = symb(); if(c != COLON && c != PERC) expect(":"); s = symb(); if(s != NUMB) expect("number"); if(c == PERC) { if(ndc >= NDC) { fprintf(stderr, "NDC(%d) too small\n", NDC); doexit(1); } dctmp[ndc++] = v; } if(mask == ~0L) mask = numb; else if(mask != numb) { fprintf(stderr, "whoops, masks different\n"); #ifdef PLAN9 exits("whoooops, masks different"); #else exit(1); #endif } v &= mask; if((itmpp == 0) || (itmp[itmpp-1] < v)) { itmp[itmpp++] = v; if(itmpp >= NTMP) { fprintf(stderr, "rdata: no room\n"); #ifdef PLAN9 exits("rdata no room"); #else exit(1); #endif } continue; } if(itmp[itmpp-1] > v) { fprintf(stderr, "input not sorted\n"); #ifdef PLAN9 exits("input not sorted"); #else exit(1); #endif } } peeks = s; return 0; }
rdata(void) { char c; char *xcp; char *cmdlinepart = ""; int s, pindex, ipin; long v; loop: s = symb(); if(s == EON) { (void) postamble(); return 1; } if(s == EXTERN) { if (extern_id && strlen(extern_id) > 0) { /* seen -t */ cmdlinepart = malloc(strlen(extern_id) + 1); strcpy(cmdlinepart, extern_id); } else extern_id = malloc(STRLEN); while(isspace(c = gchar())); xcp = extern_id; *xcp++ = toupper(c); while((c = gchar()) != '\n') *xcp++ = toupper(c); *xcp = '\0'; if (strlen(cmdlinepart) > 0) if (strcmp(cmdlinepart, extern_id) != 0) fprint(2, "warning: -t %s and .x %s don't agree\n", cmdlinepart, extern_id); else; else (void) rdlibrary(); goto loop; } if(s == ITER) { fprint(2, ".r"); for(;;) { c = gchar(); if(c < 0) goto loop; fprint(2, "%c", (char) c); if(c == '\n') goto loop; } } if(s != OUT) expect(".o"); if (!extern_id || (strlen(extern_id) == 0)) expect(".x"); s = symb(); if(s != NUMB) expect("output pin"); opin = numb; if (opin > MAXPIN) { fprint(2, "output pin %d > MAXPIN! Time to recompile!\n", opin); exit(1); } if (!(pin_array[opin].properties & OUTPUT_TYPE)) fprint(2, "output pin %d not found\n", opin); if (pin_array[opin].flags & USED_FLAG) fprint(2, "pin %d already used\n", opin); pin_array[opin].flags |= USED_FLAG; if (iflag) fprint(2, "\n.o %d", opin); for(pindex=0;;) { s = symb(); if(s != NUMB) break; /*??*/ if(s == NAME) { fprint(2, "name %s unexpected", name); continue; } ipin = numb; if (!(pin_array[ipin].properties & INPUT_TYPE)) { fprint(2, "pin %d isn't an input\n", ipin); continue; } if (pindex > NINPUTS) { fprint(2, "too many inputs (NINPUTS too small)\n"); exit(0); } input_pin[pindex++] = ipin; if (iflag) fprint(2, " %d", ipin); } input_pin[pindex] = 0; if (iflag) fprint(2, "\n"); if(s != LINE) expect("new line"); nimp = 0; for(;;) { s = symb(); if(s == LINE) continue; if(s != NUMB) break; v = numb; c = symb(); if(c != COLON && c != PERC) expect(":"); s = symb(); if(s != NUMB) expect("number"); if(c == PERC) { expect("code for %"); /* tee hee */ continue; } if(nimp >= NIMP) { fprint(2, "buffer[IMP] too small\n"); exit(1); } if (iflag) fprint(2, " %d:%d", v, numb); imp[nimp].val = v; imp[nimp].mask = numb; nimp++; } if (iflag) fprint(2, "\n"); peeks = s; return 0; }
void edit() { extern bool_t need_redraw; int c; register char *p, *q; Prenum = 0; /* position the display and the cursor at the top of the file. */ *Topchar = *Filemem; *Curschar = *Filemem; Cursrow = Curscol = 0; do_mlines(); /* check for mode lines before starting */ updatescreen(); for ( ;; ) { /* Figure out where the cursor is based on Curschar. */ cursupdate(); if (need_redraw && !anyinput()) { updatescreen(); need_redraw = FALSE; } if (!anyinput()) windgoto(Cursrow,Curscol); c = vgetc(); if (State == NORMAL) { /* We're in the normal (non-insert) mode. */ /* Pick up any leading digits and compute 'Prenum' */ if ( (Prenum>0 && isdigit(c)) || (isdigit(c) && c!='0') ){ Prenum = Prenum*10 + (c-'0'); continue; } /* execute the command */ normal(c); Prenum = 0; } else { /* * Insert or Replace mode. */ switch (c) { case ESC: /* an escape ends input mode */ /* * If we just did an auto-indent, truncate the * line, and put the cursor back. */ if (did_ai) { Curschar->linep->s[0] = NUL; Curschar->index = 0; did_ai = FALSE; } set_want_col = TRUE; /* Don't end up on a '\n' if you can help it. */ if (gchar(Curschar) == NUL && Curschar->index != 0) dec(Curschar); /* * The cursor should end up on the last inserted * character. This is an attempt to match the real * 'vi', but it may not be quite right yet. */ if (Curschar->index != 0 && !endofline(Curschar)) dec(Curschar); State = NORMAL; msg(""); /* construct the Redo buffer */ p=Redobuff; q=Insbuff; while ( q < Insptr ) *p++ = *q++; *p++ = ESC; *p = NUL; updatescreen(); break; case CTRL('D'): /* * Control-D is treated as a backspace in insert * mode to make auto-indent easier. This isn't * completely compatible with vi, but it's a lot * easier than doing it exactly right, and the * difference isn't very noticeable. */ case BS: /* can't backup past starting point */ if (Curschar->linep == Insstart->linep && Curschar->index <= Insstart->index) { beep(); break; } /* can't backup to a previous line */ if (Curschar->linep != Insstart->linep && Curschar->index <= 0) { beep(); break; } did_ai = FALSE; dec(Curschar); if (State == INSERT) delchar(TRUE); /* * It's a little strange to put backspaces into * the redo buffer, but it makes auto-indent a * lot easier to deal with. */ *Insptr++ = BS; Ninsert++; cursupdate(); updateline(); break; case CR: case NL: if (State == REPLACE) /* DMT added, 12/89 */ delchar(FALSE); *Insptr++ = NL; Ninsert++; opencmd(FORWARD, TRUE); /* open a new line */ break; default: did_ai = FALSE; insertchar(c); break; } } } }
/* * lfiletonext() - like filetonext() but only for cursor line * * Returns true if the size of the cursor line (in rows) hasn't changed. * This determines whether or not we need to call filetonext() to examine * the entire screen for changes. */ static bool_t lfiletonext() { register int row, col; register char *screenp; LPTR memp; register char *nextrow; char extra[16]; int nextra = 0; register int c; int n; bool_t eof; screenp = Nextscreen + (Cline_row * Columns); memp = *Curschar; memp.index = 0; eof = FALSE; col = 0; row = Cline_row; while (!eof) { /* Get the next character to put on the screen. */ /* The 'extra' array contains the extra stuff that is */ /* inserted to represent special characters (tabs, and */ /* other non-printable stuff. The order in the 'extra' */ /* array is reversed. */ if ( nextra > 0 ) c = extra[--nextra]; else { c = (unsigned)(0xff & gchar(&memp)); if (inc(&memp) == -1) eof = TRUE; /* when getting a character from the file, we */ /* may have to turn it into something else on */ /* the way to putting it into 'Nextscreen'. */ if ( c == TAB && !P(P_LS) ) { strcpy(extra," "); /* tab amount depends on current column */ nextra = ((P(P_TS)-1) - col%P(P_TS)); c = ' '; } else if ( c == NUL && P(P_LS) ) { extra[0] = NUL; nextra = 1; c = '$'; } else if ( c != NUL && (n=chars[c].ch_size) > 1 ) { char *p; nextra = 0; p = chars[c].ch_str; /* copy 'ch-str'ing into 'extra' in reverse */ while ( n > 1 ) extra[nextra++] = p[--n]; c = p[0]; } } if ( c == NUL ) { row++; /* get pointer to start of next row */ nextrow = &Nextscreen[row*Columns]; /* blank out the rest of this row */ while ( screenp != nextrow ) *screenp++ = ' '; col = 0; break; } if ( col >= Columns ) { row++; col = 0; } /* store the character in Nextscreen */ *screenp++ = c; col++; } return ((row - Cline_row) == Cline_size); }
void edit() { int c; char *p, *q; Prenum = 0; /* position the display and the cursor at the top of the file. */ *Topchar = *Filemem; *Curschar = *Filemem; Cursrow = Curscol = 0; for ( ;; ) { /* Figure out where the cursor is based on Curschar. */ cursupdate(); windgoto(Cursrow,Curscol); c = vgetc(); if (State == NORMAL) { /* We're in the normal (non-insert) mode. */ /* Pick up any leading digits and compute 'Prenum' */ if ( (Prenum>0 && isdigit(c)) || (isdigit(c) && c!='0') ){ Prenum = Prenum*10 + (c-'0'); continue; } /* execute the command */ normal(c); Prenum = 0; } else { switch (c) { /* We're in insert mode */ case ESC: /* an escape ends input mode */ set_want_col = TRUE; /* Don't end up on a '\n' if you can help it. */ if (gchar(Curschar) == NUL && Curschar->index != 0) dec(Curschar); /* * The cursor should end up on the last inserted * character. This is an attempt to match the real * 'vi', but it may not be quite right yet. */ if (Curschar->index != 0 && !endofline(Curschar)) dec(Curschar); State = NORMAL; msg(""); *Uncurschar = *Insstart; Undelchars = Ninsert; /* Undobuff[0] = '\0'; */ /* construct the Redo buffer */ p=Redobuff; q=Insbuff; while ( q < Insptr ) *p++ = *q++; *p++ = ESC; *p = NUL; updatescreen(); break; case CTRL('D'): /* * Control-D is treated as a backspace in insert * mode to make auto-indent easier. This isn't * completely compatible with vi, but it's a lot * easier than doing it exactly right, and the * difference isn't very noticeable. */ case BS: /* can't backup past starting point */ if (Curschar->linep == Insstart->linep && Curschar->index <= Insstart->index) { beep(); break; } /* can't backup to a previous line */ if (Curschar->linep != Insstart->linep && Curschar->index <= 0) { beep(); break; } did_ai = FALSE; dec(Curschar); delchar(TRUE); Insptr--; Ninsert--; cursupdate(); updateline(); break; case CR: case NL: *Insptr++ = NL; Ninsert++; opencmd(FORWARD, TRUE); /* open a new line */ cursupdate(); updatescreen(); break; default: did_ai = FALSE; insertchar(c); break; } } } }
inttoktype yylex() { register ptrall bufptr; register inttoktype val; register struct exp *locxp; /* * No local variables to be allocated; this saves * one piddling instruction.. */ static int Lastjxxx; bufptr = tokptr; /*copy in the global value*/ top: if (bufptr < tokub){ gtoken(val, bufptr); switch(yylval = val){ case PARSEEOF: yylval = val = PARSEEOF; break; case BFINT: case INT: if (xp >= &explist[NEXP]) yyerror("Too many expressions; try simplyfing"); else locxp = xp++; locxp->e_number = Znumber; locxp->e_number.num_tag = TYPL; glong(locxp->e_xvalue, bufptr); makevalue: locxp->e_xtype = XABS; locxp->e_xloc = 0; locxp->e_xname = NULL; yylval = (int)locxp; break; case BIGNUM: if (xp >= &explist[NEXP]) yyerror("Too many expressions; try simplyfing"); else locxp = xp++; gnumber(locxp->e_number, bufptr); goto makevalue; case NAME: gptr(yylval, bufptr); lastnam = (struct symtab *)yylval; break; case SIZESPEC: case REG: gchar(yylval, bufptr); break; case INSTn: case INST0: gopcode(yyopcode, bufptr); break; case IJXXX: gopcode(yyopcode, bufptr); /* We can't cast Lastjxxx into (int *) here.. */ gptr(Lastjxxx, bufptr); lastjxxx = (struct symtab *)Lastjxxx; break; case ILINESKIP: gint(yylval, bufptr); lineno += yylval; goto top; case SKIP: eatskiplg(bufptr); goto top; case VOID: goto top; case STRING: case ISTAB: case ISTABSTR: case ISTABNONE: case ISTABDOT: case IALIGN: gptr(yylval, bufptr); break; } #ifdef DEBUG if (toktrace){ char *tok_to_name(); printf("P: %d T#: %4d, %s ", passno, bufptr - firsttoken, tok_to_name(val)); switch(val){ case INT: printf("val %d", ((struct exp *)yylval)->e_xvalue); break; case BFINT: printf("val %d", ((struct exp *)yylval)->e_xvalue); break; case BIGNUM: bignumprint(((struct exp*)yylval)->e_number); break; case NAME: printf("\"%.8s\"", FETCHNAME((struct symtab *)yylval)); break; case REG: printf(" r%d", yylval); break; case IJXXX: case INST0: case INSTn: printf("%.8s", FETCHNAME(ITABFETCH(yyopcode))); break; case STRING: printf("length %d, seekoffset %d, place 0%o ", ((struct strdesc *)yylval)->sd_strlen, ((struct strdesc *)yylval)->sd_stroff, ((struct strdesc *)yylval)->sd_place ); if (((struct strdesc *)yylval)->sd_place & STR_CORE) printf("value\"%*s\"", ((struct strdesc *)yylval)->sd_strlen, ((struct strdesc *)yylval)->sd_string); break; } /*end of the debug switch*/ printf("\n"); } #endif DEBUG } else { /* start a new buffer */ if (useVM){ if (passno == 2){ tok_temp = emptybuf->tok_next; emptybuf->tok_next = tok_free; tok_free = emptybuf; emptybuf = tok_temp; } else { emptybuf = emptybuf->tok_next; } bufno += 1; if (emptybuf == 0){ struct tokbufdesc *newdallop; int i; if (passno == 2) goto badread; emptybuf = newdallop = (struct tokbufdesc *) Calloc(TOKDALLOP, sizeof (struct tokbufdesc)); for (i=0; i < TOKDALLOP; i++){ buftail->tok_next = newdallop; buftail = newdallop; newdallop += 1; } buftail->tok_next = 0; } /*end of need to get more buffers*/ (bytetoktype *)bufptr = &(emptybuf->toks[0]); if (passno == 1) scan_dot_s(emptybuf); } else { /*don't use VM*/ bufno ^= 1; emptybuf = &tokbuf[bufno]; ((bytetoktype *)bufptr) = &(emptybuf->toks[0]); if (passno == 1){ /* * First check if there are things to write * out at all */ if (emptybuf->tok_count >= 0){ if (writeTEST((char *)emptybuf, sizeof *emptybuf, 1, tokfile)){ yyerror("Unexpected end of file writing the interpass tmp file"); exit(2); } } scan_dot_s(emptybuf); } else { /*pass 2*/ if (readTEST((char *)emptybuf, sizeof *emptybuf, 1, tokfile)){ badread: yyerror("Unexpected end of file while reading the interpass tmp file"); exit(1); } } } /*end of using a real live file*/ (char *)tokub = (char *)bufptr + emptybuf->tok_count; #ifdef DEBUG firsttoken = bufptr; if (debug) printf("created buffernumber %d with %d tokens\n", bufno, emptybuf->tok_count); #endif DEBUG goto top; } /*end of reading/creating a new buffer*/ tokptr = bufptr; /*copy back the global value*/ return(val); } /*end of yylex*/
static void filetonext() { register int row, col; register char *screenp = Nextscreen; LPTR memp; LPTR save; /* save pos. in case line won't fit */ register char *endscreen; register char *nextrow; char extra[16]; int nextra = 0; register int c; int n; int done; int srow; /* starting row of the current line */ save = memp = *Topchar; /* The number of rows shown is Rows-1. */ /* The last line is the status/command line. */ endscreen = &screenp[(Rows-1)*Columns]; srow = done = row = col = 0; while ( screenp < endscreen && !done) { /* Get the next character to put on the screen. */ /* The 'extra' array contains the extra stuff that is */ /* inserted to represent special characters (tabs, and */ /* other non-printable stuff. The order in the 'extra' */ /* array is reversed. */ if ( nextra > 0 ) c = extra[--nextra]; else { c = (unsigned)(0xff & gchar(&memp)); if (inc(&memp) == -1) done = 1; /* when getting a character from the file, we */ /* may have to turn it into something else on */ /* the way to putting it into 'Nextscreen'. */ if ( c == TAB && !P(P_LS) ) { strcpy(extra," "); /* tab amount depends on current column */ nextra = ((P(P_TS)-1) - col%P(P_TS)); c = ' '; } else if ( c == NUL && P(P_LS) ) { extra[0] = NUL; nextra = 1; c = '$'; } else if ( (n = chars[c].ch_size) > 1 ) { char *p; nextra = 0; p = chars[c].ch_str; /* copy 'ch-str'ing into 'extra' in reverse */ while ( n > 1 ) extra[nextra++] = p[--n]; c = p[0]; } } if ( c == NUL ) { srow = ++row; /* * Save this position in case the next line won't * fit on the screen completely. */ save = memp; /* get pointer to start of next row */ nextrow = &Nextscreen[row*Columns]; /* blank out the rest of this row */ while ( screenp != nextrow ) *screenp++ = ' '; col = 0; continue; } if ( col >= Columns ) { row++; col = 0; } /* store the character in Nextscreen */ *screenp++ = c; col++; } /* * If we didn't hit the end of the file, and we didn't finish * the last line we were working on, then the line didn't fit. */ if (!done && c != NUL) { /* * Clear the rest of the screen and mark the unused lines. */ screenp = &Nextscreen[srow * Columns]; while (screenp < endscreen) *screenp++ = ' '; for (; srow < (Rows-1) ;srow++) Nextscreen[srow * Columns] = '@'; *Botchar = save; return; } /* make sure the rest of the screen is blank */ while ( screenp < endscreen ) *screenp++ = ' '; /* put '~'s on rows that aren't part of the file. */ if ( col != 0 ) row++; while ( row < Rows ) { Nextscreen[row*Columns] = '~'; row++; } if (done) /* we hit the end of the file */ *Botchar = *Fileend; else *Botchar = memp; }
rdata(void) { int s, c; long v; loop: s = symb(); if(s == EON) return(1); if(s == EXTERN) { fprintf(stdout, ".x"); while((c = gchar()) != '\n') putchar(c); putchar(c); goto loop; } if(s == ITER) { fprintf(stdout, ".r"); for(;;) { c = gchar(); if(c < 0) goto loop; putchar(c); if(c == '\n') goto loop; } } if(s != OUT) expect(".o"); fflush(stdout); fprintf(stdout, ".o"); opin = -1; for(;;) { s = symb(); if(s == NUMB) { fprintf(stdout, " %ld", numb); if(opin == -1) opin = numb; continue; } if(s == NAME) { fprintf(stdout, " %s", name); if(opin == -1) opin = 0; continue; } break; } fprintf(stdout, "\n"); if(s != LINE) expect("new line"); nimp = 0; ndtc = 0; for(;;) { s = symb(); if(s == LINE) continue; if(s != NUMB) break; v = numb; c = symb(); if(c != COLON && c != PERC) expect(":"); s = symb(); if(s != NUMB) expect("number"); if(c == PERC) { if(ndtc >= NDTC) { fprintf(stderr, "buffer[DTC] too small\n"); #ifdef PLAN9 exits("buffer[DTC] too small"); #else exit(1); #endif } dtc[ndtc].val = v; dtc[ndtc].mask = numb; ndtc++; /*oterm(v, numb, '%');*/ continue; } if(nimp >= NIMP) { fprintf(stderr, "buffer[IMP] too small\n"); #ifdef PLAN9 exits("buffer[IMP] too small"); #else exit(1); #endif } imp[nimp].val = v; imp[nimp].mask = numb; nimp++; } peeks = s; return(0); }
extern int yylex() { static bool dollar = FALSE; bool saw_meta = FALSE; int c; SIZE_T i; /* The purpose of all these local assignments is to */ char *meta; /* allow optimizing compilers like gcc to load these */ char *buf = realbuf; /* values into registers. On a sparc this is a */ YYSTYPE *y = &yylval; /* win, in code size *and* execution time */ if (errset) { errset = FALSE; return '\n'; } /* rc variable-names may contain only alnum, '*' and '_', so use dnw if we are scanning one. */ meta = (dollar ? dnw : nw); dollar = FALSE; if (newline) { --lineno; /* slight space optimization; print_prompt2() always increments lineno */ print_prompt2(); newline = FALSE; } top: while ((c = gchar()) == ' ' || c == '\t') w = NW; if (c == EOF) return END; if (!meta[(unsigned char) c]) { /* it's a word or keyword. */ checkfreecaret; w = RW; i = 0; read: do { buf[i++] = c; if (c == '?' || c == '[' || c == '*') saw_meta = TRUE; if (i >= bufsize) buf = realbuf = erealloc(buf, bufsize *= 2); } while ((c = gchar()) != EOF && !meta[(unsigned char) c]); while (c == '\\') { if ((c = gchar()) == '\n') { print_prompt2(); c = ' '; /* Pretend a space was read */ break; } else { bs: if (meta != dnw) { /* all words but varnames may have a bslash */ buf[i++] = '\\'; if (i >= bufsize) buf = realbuf = erealloc(buf, bufsize *= 2); if (!meta[(unsigned char) c]) goto read; } else { ugchar(c); c = '\\'; break; } } } ugchar(c); buf[i] = '\0'; w = KW; if (i == 2) { if (*buf == 'i' && buf[1] == 'f') return IF; if (*buf == 'f' && buf[1] == 'n') return FN; if (*buf == 'i' && buf[1] == 'n') return IN; } if (streq(buf, "for")) return FOR; if (streq(buf, "else")) return ELSE; if (streq(buf, "switch")) return SWITCH; if (streq(buf, "while")) return WHILE; if (streq(buf, "case")) return CASE; w = RW; y->word.w = ncpy(buf); if (saw_meta) { char *r, *s; y->word.m = nalloc(strlen(buf) + 1); for (r = buf, s = y->word.m; *r != '\0'; r++, s++) *s = (*r == '?' || *r == '[' || *r == '*'); } else { y->word.m = NULL; } return WORD; } if (c == '`' || c == '!' || c == '@' || c == '~' || c == '$' || c == '\'') { checkfreecaret; if (c == '!' || c == '@' || c == '~') w = KW; } switch (c) { case '!': return BANG; case '@': return SUBSHELL; case '~': return TWIDDLE; case '`': c = gchar(); if (c == '`') return BACKBACK; ugchar(c); return '`'; case '$': dollar = TRUE; c = gchar(); if (c == '#') return COUNT; if (c == '^') return FLAT; ugchar(c); return '$'; case '\'': w = RW; i = 0; do { buf[i++] = c; if (c == '\n') print_prompt2(); if (c == EOF) { w = NW; scanerror("eof in quoted string"); return HUH; } if (i >= bufsize) buf = realbuf = erealloc(buf, bufsize *= 2); } while ((c = gchar()) != '\'' || (c = gchar()) == '\''); /* quote "'" thus: 'how''s it going?' */ ugchar(c); buf[i] = '\0'; y->word.w = ncpy(buf); y->word.m = NULL; return WORD; case '\\': if ((c = gchar()) == '\n') { print_prompt2(); goto top; /* Pretend it was just another space. */ } ugchar(c); c = '\\'; checkfreecaret; c = gchar(); i = 0; goto bs; case '(': if (w == RW) /* SUB's happen only after real words, not keyowrds, so if () and while () work */ c = SUB; w = NW; return c; case '#': while ((c = gchar()) != '\n') /* skip comment until newline */ if (c == EOF) return END; /* FALLTHROUGH */ case '\n': lineno++; newline = TRUE; /* FALLTHROUGH */ case ';': case '^': case ')': case '=': case '{': case '}': w = NW; return c; case '&': w = NW; c = gchar(); if (c == '&') return ANDAND; ugchar(c); return '&'; case '|': w = NW; c = gchar(); if (c == '|') return OROR; getpair(c); if (errset) return HUH; if ((y->pipe.left = fd_left) == UNSET) y->pipe.left = 1; /* default to fd 1 */ if ((y->pipe.right = fd_right) == UNSET) y->pipe.right = 0; /* default to fd 0 */ if (y->pipe.right == CLOSED) { scanerror("expected digit after '='"); /* can't close a pipe */ return HUH; } return PIPE; case '>': c = gchar(); if (c == '>') { c = gchar(); y->redir.type = rAppend; } else y->redir.type = rCreate; y->redir.fd = 1; goto common; case '<': c = gchar(); if (c == '<') { c = gchar(); if (c == '<') { c = gchar(); y->redir.type = rHerestring; } else { y->redir.type = rHeredoc; } } else y->redir.type = rFrom; y->redir.fd = 0; common: w = NW; getpair(c); if (errset) return HUH; if (fd_right == UNSET) { /* redirection, not dup */ if (fd_left != UNSET) { y->redir.fd = fd_left; return SREDIR; } return (y->redir.type == rFrom || y->redir.type == rCreate) ? REDIR : SREDIR; } else { /* dup; recast yylval */ y->dup.type = y->redir.type; y->dup.left = fd_left; y->dup.right = fd_right; return DUP; } default: w = NW; return c; /* don't know what it is, let yacc barf on it */ } }
/* Read an S-expression */ long l_read(void) { long s, v, t; char token[32]; char ch, i; /* skip spaces */ if ((ch = skip_space()) < 0){ /* eof */ return TAG_EOF; } else if (ch == ';'){ /* comment */ while (gchar() != '\n') ; return -1; } #ifdef ZX81 else if (ch == '\"'){ /* quote macro */ #else else if (ch == '\''){ /* quote macro */ #endif if ((t = l_read()) < 0) return -1; if (t == TAG_EOF) return err_msg(errmsg_eof, 0, 0); t = l_cons(t, TAG_NIL); s = l_cons((TAG_SYMB|KW_QUOTE), t); } else if (ch != '('){ /* t, nil, symbol, or integer */ token[0] = ch; for (i = 1; ; i++){ ch = gchar(); if (isspace(ch) || iscntrl(ch) || (ch < 0) || (ch == ';') || (ch == '(') || (ch == ')')){ ugchar(ch); token[i] = '\0'; /* Changed to permint the definition of "1+" and "1-" */ if ((isdigit((char)token[0]) && (token[1] != '+') && (token[1] != '-')) /* if (isdigit((char)token[0]) */ || ((token[0] == '-') && isdigit((char)token[1])) || ((token[0] == '+') && isdigit((char)token[1]))){ /* integer */ s = int_make_l(atol(token)); #ifdef SCHEME } else if (strcmp(token, "#f") == 0){ /* nil */ s = TAG_NIL; } else if (strcmp(token, "#t") == 0){ /* t */ s = TAG_T; #else } else if (strcmp(token, "nil") == 0){ /* nil */ s = TAG_NIL; } else if (strcmp(token, "t") == 0){ /* t */ s = TAG_T; #endif } else { /* symbol */ s = TAG_SYMB | symb_make(token); } break; } token[i] = ch; } } else /* ch == '(' */ { /* list */ if ((ch = skip_space()) < 0){ return err_msg(errmsg_eof, 0, 0); } else if (ch == ')'){ s = TAG_NIL; /* "()" = nil */ } else { ugchar(ch); if ((t = l_read()) < 0) return err_msg(errmsg_eof, 0, 0); if (t == TAG_EOF) return -1; if ((s = v = l_cons(t, TAG_NIL)) < 0) return -1; if (gc_protect(s) < 0) return -1; for (;;){ if ((ch = skip_space()) < 0) /* look ahead next char */ return err_msg(errmsg_eof, 0, 0); if (ch == ')') break; ugchar(ch); if ((t = l_read()) < 0) return -1; if (t == TAG_EOF) return err_msg(errmsg_eof, 0, 0); if ((t = l_cons(t, TAG_NIL)) < 0) return -1; rplacd(v, t); v = l_cdr(v); } gc_unprotect(s); } } return s; } char skip_space(void) { char ch; for (;;){ if ((ch = gchar()) < 0) return -1; /* end-of-file */ if (!isspace(ch) && !iscntrl(ch)) break; } return ch; }
toktype yylex() { register ptrall bufptr; register toktype val; register struct exp *locxp; bufptr = tokptr; /*copy in the global value*/ top: if (bufptr < tokub){ gtoken(val, bufptr); switch(yylval = val){ case PARSEEOF : yylval = val = PARSEEOF; break; case INT: locxp = xp++; glong(locxp->xvalue, bufptr); makevalue: locxp->xtype = XABS; locxp->xloc = 0; locxp->xname = NULL; yylval = (int)locxp; break; case FLTNUM: /*case patched on 3-Jan-80*/ locxp = xp++; gdouble(locxp->doubval.dvalue, bufptr); /* * We make sure that locxp->xvalue * is not in the range suitable for * a short literal. The field * xvalue is only used for * integers, not doubles, but when * we test for short literals * in ascode.c, we look * at the field xvalue when * it encounters an in line * floating number. Ergo, * give it a bad value. */ locxp->xvalue = -1; goto makevalue; case NAME: gptr(yylval, bufptr); lastnam = (struct symtab *)yylval; break; case SIZESPEC: case REG: case INSTn: case INST0: gchar(yylval, bufptr); break; case IJXXX: gchar(yylval, bufptr); gptr(lastjxxx, bufptr); break; case ILINESKIP: gint(yylval, bufptr); lineno += yylval; goto top; case SKIP: eatskiplg(bufptr); goto top; case VOID: goto top; case STRING: strptr = &strbuf[strno ^= 1]; strptr->str_lg = *((lgtype *)bufptr); movestr(&strptr->str[0], (char *)bufptr + sizeof(lgtype), strptr->str_lg); eatstrlg(bufptr); yylval = (int)strptr; break; case ISTAB: case ISTABSTR: case ISTABNONE: case ISTABDOT: case IALIGN: gptr(yylval, bufptr); break; } /*end of the switch*/ #ifdef DEBUG if (toktrace) switch(val){ case INT: printf("Class integer val %d\n", ((struct exp *)yylval)->xvalue); break; case FLTNUM: printf("Class floating point num value %4.3f\n", ((struct exp *)yylval) -> doubval.dvalue); break; case NAME: printf("Class name, \"%.8s\"\n", ((struct symtab *)yylval)->name); break; case REG: printf("Class register, number %d\n", yylval); break; case INSTn: printf("Class INSTn, %.8s\n", itab[0xFF &yylval]->name); break; case IJXXX: printf("Class IJXXX, %.8s\n", itab[0xFF &yylval]->name); break; case INST0: printf("Class INST0, %.8s\n", itab[0xFF &yylval]->name); break; case STRING: printf("Class string, length %d\n", ((struct strdesc *)yylval)->str_lg); break; default: printf("Pass: %d Tok: %d Other class: %d, 0%o, '%c'\n", passno, bufptr - firsttoken, val,val, val); break; } /*end of the debug switch*/ #endif } /*end of this buffer*/ else { if (useVM){ bufno += 1; emptybuf = emptybuf->tok_next; if (emptybuf == 0){ struct tokbufdesc *newdallop; int i; if (passno == 2) goto badread; emptybuf = newdallop = (struct tokbufdesc *)sbrk( TOKDALLOP*sizeof (struct tokbufdesc)); if (emptybuf == (struct tokbufdesc *)-1) goto badwrite; for (i=0; i < TOKDALLOP; i++){ buftail->tok_next = newdallop; buftail = newdallop; newdallop += 1; } buftail->tok_next = 0; } /*end of need to get more buffers*/ (toktype *)bufptr = &(emptybuf->toks[0]); if (passno == 1) scan_dot_s(emptybuf); } else { /*don't use VM*/ bufno ^= 1; emptybuf = &tokbuf[bufno]; ((toktype *)bufptr) = &(emptybuf->toks[0]); if (passno == 1){ /* * First check if there are things to write * out at all */ if (emptybuf->tok_count >= 0){ if (fwrite(emptybuf, sizeof *emptybuf, 1, tmpfil) != 1){ badwrite: yyerror("Unexpected end of file writing the interpass tmp file"); exit(2); } } scan_dot_s(emptybuf); } else { /*pass 2*/ if (fread(emptybuf, sizeof *emptybuf, 1, tmpfil) != 1){ badread: yyerror("Unexpected end of file while reading the interpass tmp file"); exit(1); } } /*end of pass2*/ } /*end of using a real live file*/ (char *)tokub = (char *)bufptr + emptybuf->tok_count; #ifdef DEBUG firsttoken = bufptr; if (debug) printf("created buffernumber %d with %d tokens\n", bufno, emptybuf->tok_count); #endif goto top; } /*end of reading/creating a new buffer*/ tokptr = bufptr; /*copy back the global value*/ return(val); } /*end of yylex*/