rem: int ch = 0, next, got_ch_already = 0;
add: int ch = 0, got_ch_already = 0;
context: read_list(Scheme_Object *port,	  Scheme_Object *stxsrc, long line, long col, long pos,	  int closer, int shape, int use_stack,	  Scheme_Hash_Table **ht,	  Scheme_Object *indentation,	  ReadParams *params){  Scheme_Object *list = NULL, *last = NULL, *car, *cdr, *pair, *infixed = NULL, *prefetched = NULL;  int ch = 0, next, got_ch_already = 0;  int brackets = params->square_brackets_are_parens;  int braces = params->curly_braces_are_parens;  long start, startcol, startline, dotpos, dotcol, dotline, dot2pos, dot2line, dot2col;  scheme_tell_all(port, &startline, &startcol, &start);  if (stxsrc) {    /* Push onto the indentation stack: */    Scheme_Indent *indt;    indt = (Scheme_Indent *)scheme_malloc_atomic_tagged(sizeof(Scheme_Indent));    indt->type = scheme_indent_type;    indt->closer = closer;    indt->max_indent = startcol + 1;    indt->multiline = 0;    indt->suspicious_line = 0;    indt->suspicious_quote = 0;    indt->start_line = startline;    indt->last_line = startline;    indentation = scheme_make_pair((Scheme_Object *)indt, indentation);  }  while (1) {    if (prefetched)      ch = 0;    else if (got_ch_already)      got_ch_already = 0;    else      ch = skip_whitespace_comments(port, stxsrc, ht, indentation, params);    if ((ch == EOF) && (closer != EOF)) {      char *suggestion = "";      if (SCHEME_PAIRP(indentation)) {	Scheme_Indent *indt;	indt = (Scheme_Indent *)SCHEME_CAR(indentation);	if (indt->suspicious_line) {	  suggestion = scheme_malloc_atomic(100);	  sprintf(suggestion,		  "; indentation suggests a missing '%c' before line %ld",		  indt->suspicious_closer,		  indt->suspicious_line);	}      }      scheme_read_err(port, stxsrc, startline, startcol, start, SPAN(port, start), EOF, indentation,		      "read: expected a '%c'%s", closer, suggestion);      return NULL;    }    if (ch == closer) {      if (shape == mz_shape_hash_elem) {	scheme_read_err(port, stxsrc, startline, startcol, start, SPAN(port, start), ch, indentation,			"read: expected dotted hash pair before '%c'",			closer);	return NULL;      }      if (params->honu_mode) {	/* Finish up the list */	if (!list)	  list = scheme_null;	if (closer == ')')	  car = honu_parens;	else if (closer == ']')	  car = honu_brackets;	else if (closer == '}')	  car = honu_braces;	else	  car = NULL;	if (car) {	  if (stxsrc)	    car = scheme_make_stx_w_offset(car, line, col, pos, SPAN(port, pos), stxsrc, STX_SRCTAG);	  list = scheme_make_pair(car, list);	  if (stxsrc)	    SCHEME_SET_PAIR_IMMUTABLE(list);	}      } else {	if (!list) {	  list = scheme_null;	}      }      pop_indentation(indentation);      list = (stxsrc	      ? scheme_make_stx_w_offset(list, line, col, pos, SPAN(port, pos), stxsrc, STX_SRCTAG)	      : list);      if (params->honu_mode && (closer == EOF)) {	list = honu_add_module_wrapper(list, stxsrc, port);      }      list = attach_shape_property(list, stxsrc, params, closer);      return list;    }    if (shape == mz_shape_hash_list) {      /* Make sure we found a parenthesized something. */      if (!(ch == '(')	  && ! (ch == '[' && params->square_brackets_are_parens)	  && !(ch == '{' && params->curly_braces_are_parens)) {	long xl, xc, xp;		/* If it's a special or we have a readtable, we need to read ahead	   to make sure that it's not a comment. For consistency, always	   read ahead. */	scheme_ungetc(ch, port);	prefetched = read_inner(port, stxsrc, ht, indentation, params, RETURN_FOR_SPECIAL_COMMENT);	if (!prefetched)	  continue; /* It was a comment; try again. */	scheme_tell_all(port, &xl, &xc, &xp);	scheme_read_err(port, stxsrc, xl, xc, xp, 1,			ch, indentation,			"read: expected '('%s%s to start a hash pair",			params->square_brackets_are_parens ? " or '['" : "",			params->curly_braces_are_parens ? " or '{'" : "");	return NULL;      } else {	/* Found paren. Use read_list directly so we can specify mz_shape_hash_elem. */	long xl, xc, xp;	scheme_tell_all(port, &xl, &xc, &xp);	car = read_list(port, stxsrc, xl, xc, xp,			((ch == '(') ? ')' : ((ch == '[') ? ']' : '}')),			mz_shape_hash_elem, use_stack, ht, indentation, params);	/* car is guaranteed to have an appropriate shape */      }    } else {      if (prefetched) {	car = prefetched;	prefetched = NULL;      } else {	scheme_ungetc(ch, port);	car = read_inner(port, stxsrc, ht, indentation, params, RETURN_FOR_SPECIAL_COMMENT);	if (!car) continue; /* special was a comment */      }      /* can't be eof, due to check above */    }    if (USE_LISTSTACK(use_stack)) {      if (local_list_stack_pos >= NUM_CELLS_PER_STACK) {	/* Overflow */	Scheme_Simple_Object *sa;	sa = MALLOC_N_RT(Scheme_Simple_Object, NUM_CELLS_PER_STACK);	local_list_stack = sa;	local_list_stack_pos = 0;      }      pair = (Scheme_Object *)(local_list_stack + (local_list_stack_pos++));      pair->type = scheme_pair_type;      SCHEME_CAR(pair) = car;      SCHEME_CDR(pair) = scheme_null;    } else {      pair = scheme_make_pair(car, scheme_null);      if (stxsrc)	SCHEME_SET_PAIR_IMMUTABLE(pair);    }  retry_before_dot:    ch = skip_whitespace_comments(port, stxsrc, ht, indentation, params);    if ((ch == closer) && !params->honu_mode) {      if (shape == mz_shape_hash_elem) {	scheme_read_err(port, stxsrc, startline, startcol, start, SPAN(port, start), ch, indentation,			"read: expected `.' and value for hash before '%c'",			closer);	return NULL;      }      cdr = pair;      if (!list)	list = cdr;      else	SCHEME_CDR(last) = cdr;      if (infixed) {	/* Assert: we're not using the list stack */	list = scheme_make_pair(infixed, list);	if (stxsrc)	  SCHEME_SET_PAIR_IMMUTABLE(list);      }      pop_indentation(indentation);      list = (stxsrc	      ? scheme_make_stx_w_offset(list, line, col, pos, SPAN(port, pos), stxsrc, STX_SRCTAG)	      : list);      list = attach_shape_property(list, stxsrc, params, closer);      return list;    } else if (!params->honu_mode	       && params->can_read_dot	       && (ch == '.')	       && (next = scheme_peekc_special_ok(port),		   ((next == EOF)		    || (next == SCHEME_SPECIAL)		    || (!params->table 			&& (scheme_isspace(next)			    || (next == '(')			    || (next == ')')			    || (next == '"')			    || (next == ';')			    || (next == '\'')			    || (next == '`')			    || (next == ',')			    || ((next == '[') && brackets)			    || ((next == '{') && braces)			    || ((next == ']') && brackets)			    || ((next == '}') && braces)))		    || (params->table 			&& (readtable_kind(params->table, next, params) 			    & (READTABLE_WHITESPACE | READTABLE_TERMINATING)))))) {      scheme_tell_all(port, &dotline, &dotcol, &dotpos);      track_indentation(indentation, dotline, dotcol);      if (((shape != mz_shape_cons) && (shape != mz_shape_hash_elem)) || infixed) {	scheme_read_err(port, stxsrc, dotline, dotcol, dotpos, 1, 0, indentation,			"read: illegal use of \".\"");	return NULL;      }      /* can't be eof, due to check above: */      cdr = read_inner(port, stxsrc, ht, indentation, params, 0);      ch = skip_whitespace_comments(port, stxsrc, ht, indentation, params);      if (ch != closer) {	if (ch == '.') {	  /* Parse as infix: */	  if (shape == mz_shape_hash_elem) {	    scheme_read_err(port, stxsrc, startline, startcol, start, SPAN(port, start), ch, indentation,			    "read: expected '%c' after hash value",			    closer);	    return NULL;	  }	  {	    scheme_tell_all(port, &dot2line, &dot2col, &dot2pos);	    track_indentation(indentation, dot2line, dot2col);	  }	  infixed = cdr;	  if (!list)	    list = pair;	  else	    SCHEME_CDR(last) = pair;	  last = pair;	  /* Make sure there's not a closing paren immediately after the dot: */	  ch = skip_whitespace_comments(port, stxsrc, ht, indentation, params);	  if ((ch == closer) || (ch == EOF)) {	    scheme_read_err(port, stxsrc, dotline, dotcol, dotpos, 1, (ch == EOF) ? EOF : 0, indentation,			    "read: illegal use of \".\"");	    return NULL;	  }	  got_ch_already = 1;	} else {	  scheme_read_err(port, stxsrc, dotline, dotcol, dotpos, 1, (ch == EOF) ? EOF : 0, indentation,			  "read: illegal use of \".\"");	  return NULL;	}      } else {	SCHEME_CDR(pair) = cdr;	cdr = pair;	if (!list)	  list = cdr;	else	  SCHEME_CDR(last) = cdr;	/* Assert: infixed is NULL (otherwise we raised an exception above) */	pop_indentation(indentation);	list = (stxsrc		? scheme_make_stx_w_offset(list, line, col, pos, SPAN(port, pos), stxsrc, STX_SRCTAG)		: list);	list = attach_shape_property(list, stxsrc, params, closer);	return list;      }    } else {      if ((ch == SCHEME_SPECIAL) || (params->table && (ch != EOF))) {	/* We have to try the read, because it might be a comment. */	scheme_ungetc(ch, port);	prefetched = read_inner(port, stxsrc, ht, indentation, params, RETURN_FOR_SPECIAL_COMMENT);	if (!prefetched)	  goto retry_before_dot;      } else {	got_ch_already = 1;      }      if (shape == mz_shape_hash_elem) {	scheme_read_err(port, stxsrc, startline, startcol, start, SPAN(port, start), ch, indentation,			"read: expected `.' and value for hash");	return NULL;      }      cdr = pair;      if (!list)	list = cdr;      else	SCHEME_CDR(last) = cdr;      last = cdr;    }  }}