home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
mitsch75.zip
/
scheme-7_5_17-src.zip
/
scheme-7.5.17
/
src
/
microcode
/
syntax.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-12-05
|
27KB
|
1,029 lines
/* -*-C-*-
$Id: syntax.c,v 1.25 2000/12/05 21:23:48 cph Exp $
Copyright (c) 1987-2000 Massachusetts Institute of Technology
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
This program 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* Primitives to support Edwin syntax tables, word and list parsing. */
/* NOTE: This program was created by translation from the syntax table
code of GNU Emacs; it was translated from the original C to 68000
assembly language (in 1986), and then translated back from 68000
assembly language to C (in 1987). Users should be aware that the GNU
GENERAL PUBLIC LICENSE may apply to this code. A copy of that license
should have been included along with this file. */
#include "scheme.h"
#include "prims.h"
#include "edwin.h"
#include "syntax.h"
/* Syntax Codes */
/* Convert a letter which signifies a syntax code
into the code it signifies. */
#define ILLEGAL ((char) syntaxcode_max)
char syntax_spec_code[0200] =
{
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
((char) syntaxcode_whitespace), ILLEGAL, ((char) syntaxcode_string),
ILLEGAL, ((char) syntaxcode_math), ILLEGAL, ILLEGAL,
((char) syntaxcode_quote),
((char) syntaxcode_open), ((char) syntaxcode_close), ILLEGAL, ILLEGAL,
ILLEGAL, ((char) syntaxcode_whitespace), ((char) syntaxcode_punct),
((char) syntaxcode_charquote),
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ((char) syntaxcode_comment),
ILLEGAL, ((char) syntaxcode_endcomment), ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
((char) syntaxcode_word),
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ((char) syntaxcode_escape), ILLEGAL,
ILLEGAL, ((char) syntaxcode_symbol),
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
((char) syntaxcode_word),
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL
};
/* Indexed by syntax code, give the letter that describes it. */
unsigned char syntax_code_spec[13] =
{
' ', '.', 'w', '_', '(', ')', '\'', '\"', '$', '\\', '/', '<', '>'
};
#define MERGE_PREFIX_BIT(bit) \
{ \
if ((result & bit) != 0) \
error_bad_range_arg (1); \
result |= bit; \
}
#define MERGE_COMMENT(bit) MERGE_PREFIX_BIT ((bit) << 12)
DEFINE_PRIMITIVE ("STRING->SYNTAX-ENTRY", Prim_string_to_syntax_entry, 1, 1, 0)
{
long length, c, result;
unsigned char * scan;
PRIMITIVE_HEADER (1);
CHECK_ARG (1, STRING_P);
length = (STRING_LENGTH (ARG_REF (1)));
scan = (STRING_LOC ((ARG_REF (1)), 0));
if ((length--) > 0)
{
c = (*scan++);
if (c >= 0200) error_bad_range_arg (1);
result = (syntax_spec_code [c]);
if (result == ILLEGAL) error_bad_range_arg (1);
}
else
result = ((long) syntaxcode_whitespace);
if ((length--) > 0)
{
c = (*scan++);
if (c != ' ') result |= (c << 4);
}
while ((length--) > 0)
switch (*scan++)
{
case '1': MERGE_COMMENT (COMSTART_FIRST_B); break;
case '2': MERGE_COMMENT (COMSTART_SECOND_B); break;
case '3': MERGE_COMMENT (COMEND_FIRST_B); break;
case '4': MERGE_COMMENT (COMEND_SECOND_B); break;
case '5': MERGE_COMMENT (COMSTART_FIRST_A); break;
case '6': MERGE_COMMENT (COMSTART_SECOND_A); break;
case '7': MERGE_COMMENT (COMEND_FIRST_A); break;
case '8': MERGE_COMMENT (COMEND_SECOND_A); break;
case 'b':
switch (SYNTAX_ENTRY_CODE (result))
{
case syntaxcode_comment: MERGE_COMMENT (COMSTART_FIRST_B); break;
case syntaxcode_endcomment: MERGE_COMMENT (COMEND_FIRST_B); break;
default: break;
}
break;
case 'p': MERGE_PREFIX_BIT (1 << 20); break;
case ' ': break;
default: error_bad_range_arg (1);
}
if (((SYNTAX_ENTRY_CODE (result)) == syntaxcode_comment)
&& (! ((SYNTAX_ENTRY_COMMENT_BITS (result)) & COMSTART_FIRST)))
MERGE_COMMENT (COMSTART_FIRST_A);
if (((SYNTAX_ENTRY_CODE (result)) == syntaxcode_endcomment)
&& (! ((SYNTAX_ENTRY_COMMENT_BITS (result)) & COMEND_FIRST)))
MERGE_COMMENT (COMEND_FIRST_A);
PRIMITIVE_RETURN (LONG_TO_UNSIGNED_FIXNUM (result));
}
DEFINE_PRIMITIVE ("CHAR->SYNTAX-CODE", Prim_char_to_syntax_code, 2, 2, 0)
{
PRIMITIVE_HEADER (2);
CHECK_ARG (1, SYNTAX_TABLE_P);
PRIMITIVE_RETURN
(ASCII_TO_CHAR
(syntax_code_spec
[((int)
(SYNTAX_ENTRY_CODE
(SYNTAX_TABLE_REF ((ARG_REF (1)), (arg_ascii_char (2))))))]));
}
/* Parser Initialization */
#define NORMAL_INITIALIZATION_COMMON(arity) \
fast SCHEME_OBJECT syntax_table; \
fast SCHEME_OBJECT group; \
fast unsigned char * start; \
unsigned char * first_char, * end; \
long gap_length; \
PRIMITIVE_HEADER (arity); \
CHECK_ARG (1, SYNTAX_TABLE_P); \
syntax_table = (ARG_REF (1)); \
CHECK_ARG (2, GROUP_P); \
group = (ARG_REF (2)); \
first_char = (STRING_LOC ((GROUP_TEXT (group)), 0)); \
start = (first_char + (arg_nonnegative_integer (3))); \
end = (first_char + (arg_nonnegative_integer (4))); \
gap_start = (first_char + (GROUP_GAP_START (group))); \
gap_length = (GROUP_GAP_LENGTH (group)); \
gap_end = (first_char + (GROUP_GAP_END (group)))
#define NORMAL_INITIALIZATION_FORWARD(arity) \
unsigned char * gap_start; \
fast unsigned char * gap_end; \
NORMAL_INITIALIZATION_COMMON (arity); \
if (start >= gap_start) \
start += gap_length; \
if (end >= gap_start) \
end += gap_length
#define NORMAL_INITIALIZATION_BACKWARD(arity) \
fast unsigned char * gap_start; \
unsigned char * gap_end; \
NORMAL_INITIALIZATION_COMMON (arity); \
if (start > gap_start) \
start += gap_length; \
if (end > gap_start) \
end += gap_length
#define SCAN_LIST_INITIALIZATION(initialization) \
long depth, min_depth; \
Boolean sexp_flag, ignore_comments, math_exit; \
int c; \
initialization (7); \
depth = (arg_integer (5)); \
min_depth = ((depth >= 0) ? 0 : depth); \
sexp_flag = (BOOLEAN_ARG (6)); \
ignore_comments = (BOOLEAN_ARG (7)); \
math_exit = false
/* Parse Scanning */
#define PEEK_RIGHT(scan) (SYNTAX_TABLE_REF (syntax_table, (*scan)))
#define PEEK_LEFT(scan) (SYNTAX_TABLE_REF (syntax_table, (scan[-1])))
#define MOVE_RIGHT(scan) do \
{ \
if ((++scan) == gap_start) \
scan = gap_end; \
} while (0)
#define MOVE_LEFT(scan) do \
{ \
if ((--scan) == gap_end) \
scan = gap_start; \
} while (0)
#define READ_RIGHT(scan, target) do \
{ \
target = (SYNTAX_TABLE_REF (syntax_table, (*scan++))); \
if (scan == gap_start) \
scan = gap_end; \
} while (0)
#define READ_LEFT(scan, target) do \
{ \
target = (SYNTAX_TABLE_REF (syntax_table, (*--scan))); \
if (scan == gap_end) \
scan = gap_start; \
} while (0)
#define RIGHT_END_P(scan) (scan >= end)
#define LEFT_END_P(scan) (scan <= end)
#define LOSE_IF(expression) do \
{ \
if (expression) \
PRIMITIVE_RETURN (SHARP_F); \
} while (0)
#define LOSE_IF_RIGHT_END(scan) LOSE_IF (RIGHT_END_P (scan))
#define LOSE_IF_LEFT_END(scan) LOSE_IF (LEFT_END_P (scan))
#define SCAN_TO_INDEX(scan) \
((((scan) > gap_start) ? ((scan) - gap_length) : (scan)) - first_char)
#define INDEX_TO_SCAN(index) \
((((index) + first_char) > gap_start) \
? (((index) + first_char) + gap_length) \
: ((index) + first_char))
#define WIN_IF(expression) do \
{ \
if (expression) \
PRIMITIVE_RETURN (LONG_TO_UNSIGNED_FIXNUM (SCAN_TO_INDEX (start))); \
} while (0)
#define WIN_IF_RIGHT_END(scan) WIN_IF (RIGHT_END_P (scan))
#define WIN_IF_LEFT_END(scan) WIN_IF (LEFT_END_P (scan))
#define RIGHT_QUOTED_P_INTERNAL(scan, quoted) do \
{ \
quoted = false; \
while (true) \
{ \
long sentry; \
if (LEFT_END_P (scan)) \
break; \
READ_LEFT (scan, sentry); \
if (! (SYNTAX_ENTRY_QUOTE (sentry))) \
break; \
quoted = (! quoted); \
} \
} while (0)
#define RIGHT_QUOTED_P(scan_init, quoted) do \
{ \
unsigned char * scan = (scan_init); \
RIGHT_QUOTED_P_INTERNAL (scan, quoted); \
} while (0)
#define LEFT_QUOTED_P(scan_init, quoted) do \
{ \
unsigned char * scan = (scan_init); \
MOVE_LEFT (scan); \
RIGHT_QUOTED_P_INTERNAL (scan, quoted); \
} while (0)
/* Quote Parsers */
DEFINE_PRIMITIVE ("QUOTED-CHAR?", Prim_quoted_char_p, 4, 4, 0)
{
Boolean quoted;
NORMAL_INITIALIZATION_BACKWARD (4);
RIGHT_QUOTED_P (start, quoted);
PRIMITIVE_RETURN (BOOLEAN_TO_OBJECT (quoted));
}
/* This is used in conjunction with `scan-list-backward' to find the
beginning of an s-expression. */
DEFINE_PRIMITIVE ("SCAN-BACKWARD-PREFIX-CHARS", Prim_scan_backward_prefix_chars, 4, 4, 0)
{
Boolean quoted;
NORMAL_INITIALIZATION_BACKWARD (4);
while (true)
{
WIN_IF_LEFT_END (start);
LEFT_QUOTED_P (start, quoted);
WIN_IF (quoted);
{
long sentry = (PEEK_LEFT (start));
WIN_IF (! (((SYNTAX_ENTRY_CODE (sentry)) == syntaxcode_quote)
|| (SYNTAX_ENTRY_PREFIX (sentry))));
}
MOVE_LEFT (start);
}
}
DEFINE_PRIMITIVE ("SCAN-FORWARD-PREFIX-CHARS", Prim_scan_forward_prefix_chars, 4, 4, 0)
{
Boolean quoted;
NORMAL_INITIALIZATION_FORWARD (4);
while (true)
{
WIN_IF_RIGHT_END (start);
RIGHT_QUOTED_P (start, quoted);
WIN_IF (quoted);
{
long sentry = (PEEK_RIGHT (start));
WIN_IF (! (((SYNTAX_ENTRY_CODE (sentry)) == syntaxcode_quote)
|| (SYNTAX_ENTRY_PREFIX (sentry))));
}
MOVE_RIGHT (start);
}
}
/* Word Parsers */
DEFINE_PRIMITIVE ("SCAN-FORWARD-TO-WORD", Prim_scan_forward_to_word, 4, 4, 0)
{
NORMAL_INITIALIZATION_FORWARD (4);
while (true)
{
LOSE_IF_RIGHT_END (start);
WIN_IF ((SYNTAX_ENTRY_CODE (PEEK_RIGHT (start))) == syntaxcode_word);
MOVE_RIGHT (start);
}
}
DEFINE_PRIMITIVE ("SCAN-WORD-FORWARD", Prim_scan_word_forward, 4, 4, 0)
{
NORMAL_INITIALIZATION_FORWARD (4);
while (true)
{
long sentry;
LOSE_IF_RIGHT_END (start);
READ_RIGHT (start, sentry);
if ((SYNTAX_ENTRY_CODE (sentry)) == syntaxcode_word)
break;
}
while (true)
{
WIN_IF_RIGHT_END (start);
WIN_IF ((SYNTAX_ENTRY_CODE (PEEK_RIGHT (start))) != syntaxcode_word);
MOVE_RIGHT (start);
}
}
DEFINE_PRIMITIVE ("SCAN-WORD-BACKWARD", Prim_scan_word_backward, 4, 4, 0)
{
NORMAL_INITIALIZATION_BACKWARD (4);
while (true)
{
long sentry;
LOSE_IF_LEFT_END (start);
READ_LEFT (start, sentry);
if ((SYNTAX_ENTRY_CODE (sentry)) == syntaxcode_word)
break;
}
while (true)
{
WIN_IF_LEFT_END (start);
WIN_IF ((SYNTAX_ENTRY_CODE (PEEK_LEFT (start))) != syntaxcode_word);
MOVE_LEFT (start);
}
}
/* S-Expression Parsers */
DEFINE_PRIMITIVE ("SCAN-LIST-FORWARD", Prim_scan_list_forward, 7, 7, 0)
{
SCAN_LIST_INITIALIZATION (NORMAL_INITIALIZATION_FORWARD);
while (true)
{
long sentry;
LOSE_IF_RIGHT_END (start);
c = (*start);
READ_RIGHT (start, sentry);
{
unsigned int style = 0;
if (((SYNTAX_ENTRY_CODE (sentry))) == syntaxcode_comment)
style = (SYNTAX_ENTRY_COMMENT_STYLE (sentry, COMSTART_FIRST));
else if (! (RIGHT_END_P (start)))
{
style
= ((SYNTAX_ENTRY_COMMENT_STYLE (sentry, COMSTART_FIRST))
& (SYNTAX_ENTRY_COMMENT_STYLE ((PEEK_RIGHT (start)),
COMSTART_SECOND)));
if (style != 0)
MOVE_RIGHT (start);
}
if (style != 0)
{
LOSE_IF_RIGHT_END (start);
while (true)
{
READ_RIGHT (start, sentry);
if ((SYNTAX_ENTRY_COMMENT_BITS (sentry))
& COMEND_FIRST
& style)
{
if (((SYNTAX_ENTRY_CODE (sentry)))
== syntaxcode_endcomment)
break;
LOSE_IF_RIGHT_END (start);
if ((SYNTAX_ENTRY_COMMENT_BITS (PEEK_RIGHT (start)))
& COMEND_SECOND
& style)
{
MOVE_RIGHT (start);
break;
}
}
}
continue;
}
}
if (SYNTAX_ENTRY_PREFIX (sentry))
continue;
switch (SYNTAX_ENTRY_CODE (sentry))
{
case syntaxcode_escape:
case syntaxcode_charquote:
LOSE_IF_RIGHT_END (start);
MOVE_RIGHT (start);
case syntaxcode_word:
case syntaxcode_symbol:
if ((depth != 0) || (! sexp_flag))
break;
while (true)
{
WIN_IF_RIGHT_END (start);
switch (SYNTAX_ENTRY_CODE (PEEK_RIGHT (start)))
{
case syntaxcode_escape:
case syntaxcode_charquote:
MOVE_RIGHT (start);
LOSE_IF_RIGHT_END (start);
case syntaxcode_word:
case syntaxcode_symbol:
MOVE_RIGHT (start);
break;
default:
WIN_IF (true);
}
}
case syntaxcode_math:
if (! sexp_flag)
break;
if ((! (RIGHT_END_P (start))) && (c == *start))
MOVE_RIGHT (start);
if (math_exit)
{
WIN_IF ((--depth) == 0);
LOSE_IF (depth < min_depth);
math_exit = false;
}
else
{
WIN_IF ((++depth) == 0);
math_exit = true;
}
break;
case syntaxcode_open:
WIN_IF ((++depth) == 0);
break;
case syntaxcode_close:
WIN_IF ((--depth) == 0);
LOSE_IF (depth < min_depth);
break;
case syntaxcode_string:
while (true)
{
LOSE_IF_RIGHT_END (start);
if (c == *start)
break;
READ_RIGHT (start, sentry);
if (SYNTAX_ENTRY_QUOTE (sentry))
{
LOSE_IF_RIGHT_END (start);
MOVE_RIGHT (start);
}
}
MOVE_RIGHT (start);
WIN_IF ((depth == 0) && sexp_flag);
break;
default:
break;
}
}
}
DEFINE_PRIMITIVE ("SCAN-LIST-BACKWARD", Prim_scan_list_backward, 7, 7, 0)
{
Boolean quoted;
SCAN_LIST_INITIALIZATION (NORMAL_INITIALIZATION_BACKWARD);
while (true)
{
long sentry;
LOSE_IF_LEFT_END (start);
LEFT_QUOTED_P (start, quoted);
if (quoted)
{
MOVE_LEFT (start);
/* existence of this character is guaranteed by LEFT_QUOTED_P. */
READ_LEFT (start, sentry);
goto word_entry;
}
c = (start[-1]);
READ_LEFT (start, sentry);
{
unsigned int style = 0;
if (((SYNTAX_ENTRY_CODE (sentry))) == syntaxcode_endcomment)
{
if (ignore_comments)
style = (SYNTAX_ENTRY_COMMENT_STYLE (sentry, COMEND_SECOND));
}
else if (! (LEFT_END_P (start)))
{
LEFT_QUOTED_P (start, quoted);
if (!quoted)
{
style
= ((SYNTAX_ENTRY_COMMENT_STYLE (sentry, COMEND_SECOND))
& (SYNTAX_ENTRY_COMMENT_STYLE ((PEEK_LEFT (start)),
COMEND_FIRST)));
if (style != 0)
MOVE_LEFT (start);
}
}
if (style != 0)
{
LOSE_IF_LEFT_END (start);
while (true)
{
READ_LEFT (start, sentry);
if ((((SYNTAX_ENTRY_CODE (sentry))) == syntaxcode_comment)
&& ((SYNTAX_ENTRY_COMMENT_BITS (sentry))
& COMSTART_FIRST
& style))
break;
LOSE_IF_LEFT_END (start);
if (((SYNTAX_ENTRY_COMMENT_BITS (sentry))
& COMSTART_SECOND
& style)
&& ((SYNTAX_ENTRY_COMMENT_BITS (PEEK_LEFT (start)))
& COMSTART_FIRST
& style))
{
MOVE_LEFT (start);
break;
}
}
continue;
}
}
switch (SYNTAX_ENTRY_CODE (sentry))
{
case syntaxcode_word:
case syntaxcode_symbol:
word_entry:
if ((depth != 0) || (! sexp_flag))
break;
while (true)
{
WIN_IF_LEFT_END (start);
LEFT_QUOTED_P (start, quoted);
if (quoted)
MOVE_LEFT (start);
else
{
sentry = (PEEK_LEFT (start));
WIN_IF (((SYNTAX_ENTRY_CODE (sentry)) != syntaxcode_word) &&
((SYNTAX_ENTRY_CODE (sentry)) != syntaxcode_symbol));
}
MOVE_LEFT (start);
}
case syntaxcode_math:
if (! sexp_flag)
break;
if ((! (LEFT_END_P (start))) && (c == start[-1]))
MOVE_LEFT (start);
if (math_exit)
{
WIN_IF ((--depth) == 0);
LOSE_IF (depth < min_depth);
math_exit = false;
}
else
{
WIN_IF ((++depth) == 0);
math_exit = true;
}
break;
case syntaxcode_close:
WIN_IF ((++depth) == 0);
break;
case syntaxcode_open:
WIN_IF ((--depth) == 0);
LOSE_IF (depth < min_depth);
break;
case syntaxcode_string:
while (true)
{
LOSE_IF_LEFT_END (start);
LEFT_QUOTED_P (start, quoted);
if ((! quoted) && (c == start[-1]))
break;
MOVE_LEFT (start);
}
MOVE_LEFT (start);
WIN_IF ((depth == 0) && sexp_flag);
break;
default:
break;
}
}
}
/* Partial S-Expression Parser */
#define LEVEL_ARRAY_LENGTH 100
struct levelstruct { unsigned char * last, * previous; };
#define DONE_IF(expression) do \
{ \
if (expression) \
goto done; \
} while (0)
#define DONE_IF_RIGHT_END(scan) DONE_IF (RIGHT_END_P (scan))
#define SEXP_START() do \
{ \
if (stop_before) goto stop; \
(level -> last) = start; \
} while (0)
DEFINE_PRIMITIVE ("SCAN-SEXPS-FORWARD", Prim_scan_sexps_forward, 7, 7, 0)
{
long target_depth;
Boolean stop_before;
SCHEME_OBJECT state_argument;
long depth = 0;
long in_string = -1; /* -1 or delimiter character */
/* Values of in_comment:
0 = not in comment
1 = in comment
2 = found first start of comment
3 = found first end of comment */
unsigned int in_comment = 0;
unsigned int comment_style = COMMENT_STYLE_A;
unsigned char * comment_start = 0;
Boolean quoted = false;
struct levelstruct level_start[LEVEL_ARRAY_LENGTH];
struct levelstruct *level;
struct levelstruct *level_end;
int c = 0;
long sentry = 0;
SCHEME_OBJECT result;
NORMAL_INITIALIZATION_FORWARD (7);
target_depth = (arg_integer (5));
stop_before = (BOOLEAN_ARG (6));
state_argument = (ARG_REF (7));
level = level_start;
level_end = (level_start + LEVEL_ARRAY_LENGTH);
(level -> previous) = NULL;
/* Initialize the state variables from the state argument. */
if (state_argument == SHARP_F)
{
depth = 0;
in_string = -1;
in_comment = 0;
quoted = false;
}
else if ((VECTOR_P (state_argument)) &&
(VECTOR_LENGTH (state_argument)) == 8)
{
SCHEME_OBJECT temp;
temp = (VECTOR_REF (state_argument, 0));
if (FIXNUM_P (temp))
depth = (FIXNUM_TO_LONG (temp));
else
error_bad_range_arg (7);
temp = (VECTOR_REF (state_argument, 1));
if (temp == SHARP_F)
in_string = -1;
else if ((UNSIGNED_FIXNUM_P (temp)) &&
((UNSIGNED_FIXNUM_TO_LONG (temp)) < MAX_ASCII))
in_string = (UNSIGNED_FIXNUM_TO_LONG (temp));
else
error_bad_range_arg (7);
temp = (VECTOR_REF (state_argument, 2));
if (temp == SHARP_F)
in_comment = 0;
else if (temp == (LONG_TO_UNSIGNED_FIXNUM (1)))
{
in_comment = 1;
comment_style = COMMENT_STYLE_A;
}
else if (temp == (LONG_TO_UNSIGNED_FIXNUM (2)))
{
in_comment = 2;
comment_style = COMMENT_STYLE_A;
}
else if (temp == (LONG_TO_UNSIGNED_FIXNUM (3)))
{
in_comment = 3;
comment_style = COMMENT_STYLE_A;
}
else if (temp == (LONG_TO_UNSIGNED_FIXNUM (4)))
{
in_comment = 2;
comment_style = (COMMENT_STYLE_A | COMMENT_STYLE_B);
}
else if (temp == (LONG_TO_UNSIGNED_FIXNUM (5)))
{
in_comment = 1;
comment_style = COMMENT_STYLE_B;
}
else if (temp == (LONG_TO_UNSIGNED_FIXNUM (6)))
{
in_comment = 2;
comment_style = COMMENT_STYLE_B;
}
else if (temp == (LONG_TO_UNSIGNED_FIXNUM (7)))
{
in_comment = 3;
comment_style = COMMENT_STYLE_B;
}
else
error_bad_range_arg (7);
quoted = ((VECTOR_REF (state_argument, 3)) != SHARP_F);
if (in_comment != 0)
{
temp = (VECTOR_REF (state_argument, 7));
if (MARK_P (temp))
comment_start = (INDEX_TO_SCAN (MARK_INDEX (temp)));
else if (UNSIGNED_FIXNUM_P (temp))
comment_start = (INDEX_TO_SCAN (UNSIGNED_FIXNUM_TO_LONG (temp)));
else
error_bad_range_arg (7);
}
if ((in_comment != 0) && ((in_string != -1) || (quoted != false)))
error_bad_range_arg (7);
}
else
error_bad_range_arg (7);
/* Make sure there is enough room for the result before we start. */
Primitive_GC_If_Needed (8);
/* Enter main loop at place appropiate for initial state. */
switch (in_comment)
{
case 1: goto in_comment_1;
case 2: goto in_comment_2;
case 3: goto in_comment_3;
}
if (quoted)
{
quoted = false;
if (in_string != -1)
goto start_quoted_in_string;
else
goto start_quoted;
}
if (in_string != -1)
goto start_in_string;
while (true)
{
DONE_IF_RIGHT_END (start);
c = (*start);
comment_start = start;
READ_RIGHT (start, sentry);
comment_style = (SYNTAX_ENTRY_COMMENT_STYLE (sentry, COMSTART_FIRST));
if (((SYNTAX_ENTRY_CODE (sentry))) == syntaxcode_comment)
goto in_comment_1;
if (comment_style == 0)
goto not_in_comment;
in_comment_2:
in_comment = 2;
DONE_IF_RIGHT_END (start);
comment_style
&= (SYNTAX_ENTRY_COMMENT_STYLE ((PEEK_RIGHT (start)),
COMSTART_SECOND));
if (comment_style == 0)
goto not_in_comment;
MOVE_RIGHT (start);
in_comment_1:
while (true)
{
in_comment = 1;
DONE_IF_RIGHT_END (start);
READ_RIGHT (start, sentry);
if ((SYNTAX_ENTRY_COMMENT_BITS (sentry))
& COMEND_FIRST
& comment_style)
{
if (((SYNTAX_ENTRY_CODE (sentry))) == syntaxcode_endcomment)
break;
in_comment_3:
in_comment = 3;
DONE_IF_RIGHT_END (start);
if ((SYNTAX_ENTRY_COMMENT_BITS (PEEK_RIGHT (start)))
& COMEND_SECOND
& comment_style)
{
MOVE_RIGHT (start);
break;
}
}
}
not_in_comment:
in_comment = 0;
if (SYNTAX_ENTRY_PREFIX (sentry))
continue;
switch (SYNTAX_ENTRY_CODE (sentry))
{
case syntaxcode_escape:
case syntaxcode_charquote:
SEXP_START ();
start_quoted:
if (RIGHT_END_P (start))
{
quoted = true;
DONE_IF (true);
}
MOVE_RIGHT (start);
goto start_atom;
case syntaxcode_word:
case syntaxcode_symbol:
SEXP_START ();
start_atom:
while (! (RIGHT_END_P (start)))
{
switch (SYNTAX_ENTRY_CODE (PEEK_RIGHT (start)))
{
case syntaxcode_escape:
case syntaxcode_charquote:
MOVE_RIGHT (start);
if (RIGHT_END_P (start))
{
quoted = true;
DONE_IF (true);
}
case syntaxcode_word:
case syntaxcode_symbol:
MOVE_RIGHT (start);
break;
default:
goto end_atom;
}
}
end_atom:
(level -> previous) = (level -> last);
break;
case syntaxcode_open:
SEXP_START ();
depth += 1;
level += 1;
if (level == level_end)
error_bad_range_arg (5); /* random error */
(level -> last) = NULL;
(level -> previous) = NULL;
DONE_IF ((--target_depth) == 0);
break;
case syntaxcode_close:
depth -= 1;
if (level != level_start)
level -= 1;
(level -> previous) = (level -> last);
DONE_IF ((++target_depth) == 0);
break;
case syntaxcode_string:
SEXP_START ();
in_string = (c);
start_in_string:
while (true)
{
DONE_IF_RIGHT_END (start);
if (in_string == (*start))
break;
READ_RIGHT (start, sentry);
if (SYNTAX_ENTRY_QUOTE (sentry))
{
start_quoted_in_string:
if (RIGHT_END_P (start))
{
quoted = true;
DONE_IF (true);
}
MOVE_RIGHT (start);
}
}
in_string = -1;
(level -> previous) = (level -> last);
MOVE_RIGHT (start);
break;
default:
break;
}
}
/* NOTREACHED */
stop:
/* Back up to point at character that starts sexp. */
if (start == gap_end)
start = gap_start;
start -= 1;
done:
result = (allocate_marked_vector (TC_VECTOR, 8, true));
FAST_VECTOR_SET (result, 0, (LONG_TO_FIXNUM (depth)));
FAST_VECTOR_SET
(result, 1,
((in_string == -1)
? SHARP_F
: (LONG_TO_UNSIGNED_FIXNUM (in_string))));
FAST_VECTOR_SET
(result, 2,
((in_comment == 0)
? SHARP_F
: (LONG_TO_UNSIGNED_FIXNUM
(((in_comment == 2)
&& (comment_style == (COMMENT_STYLE_A | COMMENT_STYLE_B)))
? 4
: (comment_style == COMMENT_STYLE_A)
? in_comment
: (in_comment + 4)))));
FAST_VECTOR_SET (result, 3, (BOOLEAN_TO_OBJECT (quoted)));
FAST_VECTOR_SET
(result, 4,
(((level -> previous) == NULL)
? SHARP_F
: (LONG_TO_UNSIGNED_FIXNUM ((SCAN_TO_INDEX (level -> previous)) - 1))));
FAST_VECTOR_SET
(result, 5,
(((level == level_start) || (((level - 1) -> last) == NULL))
? SHARP_F
: (LONG_TO_UNSIGNED_FIXNUM
((SCAN_TO_INDEX ((level - 1) -> last)) - 1))));
FAST_VECTOR_SET
(result, 6, (LONG_TO_UNSIGNED_FIXNUM (SCAN_TO_INDEX (start))));
FAST_VECTOR_SET
(result, 7,
((in_comment == 0)
? SHARP_F
: (LONG_TO_UNSIGNED_FIXNUM (SCAN_TO_INDEX (comment_start)))));
PRIMITIVE_RETURN (result);
}