2008-10-12 20:53:28 -04:00
# include "picoc.h"
2009-02-24 06:16:37 -05:00
# ifdef NO_CTYPE
2009-02-23 20:01:02 -05:00
# define isalpha(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z'))
2009-02-24 06:16:37 -05:00
# define isdigit(c) ((c) >= '0' && (c) <= '9')
# define isalnum(c) (isalpha(c) || isdigit(c))
# define isspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n')
2009-02-23 20:01:02 -05:00
# endif
2009-01-03 23:08:49 -05:00
# define isCidstart(c) (isalpha(c) || (c)=='_' || (c)=='#')
2008-10-14 07:46:42 -04:00
# define isCident(c) (isalnum(c) || (c)=='_')
2008-10-13 06:53:25 -04:00
2009-03-07 20:09:42 -05:00
# define IS_HEX_ALPHA_DIGIT(c) (((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
# define IS_BASE_DIGIT(c,b) (((c) >= '0' && (c) < '0' + (((b)<10)?(b):10)) || (((b) > 10) ? IS_HEX_ALPHA_DIGIT(c) : FALSE))
# define GET_BASE_DIGIT(c) (((c) <= '9') ? ((c) - '0') : (((c) <= 'F') ? ((c) - 'A' + 10) : ((c) - 'a' + 10)))
2009-06-04 03:41:06 -04:00
# define NEXTIS(c,x,y) { if (NextChar == (c)) { LEXER_INC(Lexer); GotToken = (x); } else GotToken = (y); }
# define NEXTIS3(c,x,d,y,z) { if (NextChar == (c)) { LEXER_INC(Lexer); GotToken = (x); } else NEXTIS(d,y,z) }
# define NEXTIS4(c,x,d,y,e,z,a) { if (NextChar == (c)) { LEXER_INC(Lexer); GotToken = (x); } else NEXTIS3(d,y,e,z,a) }
# define NEXTIS3PLUS(c,x,d,y,e,z,a) { if (NextChar == (c)) { LEXER_INC(Lexer); GotToken = (x); } else if (NextChar == (d)) { if (Lexer->Pos[1] == (e)) { LEXER_INCN(Lexer, 2); GotToken = (z); } else { LEXER_INC(Lexer); GotToken = (y); } } else GotToken = (a); }
# define NEXTISEXACTLY3(c,d,y,z) { if (NextChar == (c) && Lexer->Pos[1] == (d)) { LEXER_INCN(Lexer, 2); GotToken = (y); } else GotToken = (z); }
# ifdef FANCY_ERROR_REPORTING
# define LEXER_INC(l) ( (l)->Pos++, (l)->CharacterPos++ )
# define LEXER_INCN(l, n) ( (l)->Pos+=(n), (l)->CharacterPos+=(n) )
# define TOKEN_DATA_OFFSET 2
# else
# define LEXER_INC(l) (l)->Pos++
# define LEXER_INCN(l, n) (l)->Pos+=(n)
# define TOKEN_DATA_OFFSET 1
# endif
2008-10-12 20:53:28 -04:00
2009-04-22 08:06:58 -04:00
# define MAX_CHAR_VALUE 255 /* maximum value which can be represented by a "char" data type */
2009-01-26 03:57:32 -05:00
static union AnyValue LexAnyValue ;
static struct Value LexValue = { TypeVoid , & LexAnyValue , FALSE , FALSE } ;
2008-10-13 06:53:25 -04:00
2008-10-12 20:53:28 -04:00
struct ReservedWord
{
const char * Word ;
enum LexToken Token ;
2009-02-01 23:53:45 -05:00
const char * SharedWord ; /* word stored in shared string space */
2008-10-12 20:53:28 -04:00
} ;
2008-10-13 06:53:25 -04:00
static struct ReservedWord ReservedWords [ ] =
2008-10-12 20:53:28 -04:00
{
2009-02-01 23:53:45 -05:00
{ " #define " , TokenHashDefine , NULL } ,
{ " #include " , TokenHashInclude , NULL } ,
{ " break " , TokenBreak , NULL } ,
{ " case " , TokenCase , NULL } ,
{ " char " , TokenCharType , NULL } ,
2009-02-17 18:36:09 -05:00
{ " continue " , TokenContinue , NULL } ,
2009-02-01 23:53:45 -05:00
{ " default " , TokenDefault , NULL } ,
2009-03-15 06:44:56 -04:00
{ " delete " , TokenDelete , NULL } ,
2009-02-01 23:53:45 -05:00
{ " do " , TokenDo , NULL } ,
2009-02-23 19:21:17 -05:00
# ifndef NO_FP
2009-02-01 23:53:45 -05:00
{ " double " , TokenDoubleType , NULL } ,
2009-02-23 19:21:17 -05:00
# endif
2009-02-01 23:53:45 -05:00
{ " else " , TokenElse , NULL } ,
{ " enum " , TokenEnumType , NULL } ,
2009-02-23 19:21:17 -05:00
# ifndef NO_FP
2009-02-01 23:53:45 -05:00
{ " float " , TokenFloatType , NULL } ,
2009-02-23 19:21:17 -05:00
# endif
2009-02-01 23:53:45 -05:00
{ " for " , TokenFor , NULL } ,
{ " if " , TokenIf , NULL } ,
{ " int " , TokenIntType , NULL } ,
{ " long " , TokenLongType , NULL } ,
2009-03-16 00:25:58 -04:00
{ " new " , TokenNew , NULL } ,
2009-02-01 23:53:45 -05:00
{ " return " , TokenReturn , NULL } ,
2009-10-11 07:09:07 -04:00
{ " short " , TokenShortType , NULL } ,
2009-02-28 14:57:03 -05:00
{ " signed " , TokenSignedType , NULL } ,
2009-02-28 17:13:55 -05:00
{ " sizeof " , TokenSizeof , NULL } ,
2009-02-01 23:53:45 -05:00
{ " struct " , TokenStructType , NULL } ,
{ " switch " , TokenSwitch , NULL } ,
{ " typedef " , TokenTypedef , NULL } ,
{ " union " , TokenUnionType , NULL } ,
{ " unsigned " , TokenUnsignedType , NULL } ,
{ " void " , TokenVoidType , NULL } ,
{ " while " , TokenWhile , NULL }
2008-10-12 20:53:28 -04:00
} ;
2009-03-07 02:49:17 -05:00
/* linked list of tokens used in interactive mode */
struct TokenLine
{
struct TokenLine * Next ;
unsigned char * Tokens ;
int NumBytes ;
} ;
2009-03-07 23:26:28 -05:00
static struct TokenLine * InteractiveHead = NULL ;
static struct TokenLine * InteractiveTail = NULL ;
static struct TokenLine * InteractiveCurrentLine = NULL ;
static int LexUseStatementPrompt = FALSE ;
2009-03-07 02:49:17 -05:00
2009-02-01 23:53:45 -05:00
/* initialise the lexer */
void LexInit ( )
{
int Count ;
for ( Count = 0 ; Count < sizeof ( ReservedWords ) / sizeof ( struct ReservedWord ) ; Count + + )
2009-02-20 21:35:52 -05:00
ReservedWords [ Count ] . SharedWord = TableStrRegister ( ReservedWords [ Count ] . Word ) ;
2009-02-01 06:31:18 -05:00
}
2009-03-11 19:49:10 -04:00
/* deallocate */
void LexCleanup ( )
{
LexInteractiveClear ( NULL ) ;
}
2009-02-01 23:53:45 -05:00
/* check if a word is a reserved word - used while scanning */
2009-02-01 06:31:18 -05:00
enum LexToken LexCheckReservedWord ( const char * Word )
2008-10-12 20:53:28 -04:00
{
int Count ;
for ( Count = 0 ; Count < sizeof ( ReservedWords ) / sizeof ( struct ReservedWord ) ; Count + + )
{
2009-02-01 23:53:45 -05:00
if ( Word = = ReservedWords [ Count ] . SharedWord )
2008-10-13 06:53:25 -04:00
return ReservedWords [ Count ] . Token ;
2008-10-12 20:53:28 -04:00
}
return TokenNone ;
}
2009-03-07 20:09:42 -05:00
/* get a numeric literal - used while scanning */
2009-02-01 06:31:18 -05:00
enum LexToken LexGetNumber ( struct LexState * Lexer , struct Value * Value )
2008-10-12 20:53:28 -04:00
{
2008-10-14 22:09:47 -04:00
int Result = 0 ;
2009-03-07 20:09:42 -05:00
int Base = 10 ;
2009-04-22 08:06:58 -04:00
enum LexToken ResultToken ;
2009-02-23 19:21:17 -05:00
# ifndef NO_FP
2008-12-26 21:25:49 -05:00
double FPResult ;
double FPDiv ;
2009-02-23 19:21:17 -05:00
# endif
2008-10-14 22:09:47 -04:00
2009-03-07 20:09:42 -05:00
if ( * Lexer - > Pos = = ' 0 ' )
2009-04-22 08:06:58 -04:00
{
/* a binary, octal or hex literal */
2009-06-04 03:41:06 -04:00
LEXER_INC ( Lexer ) ;
2009-03-07 20:09:42 -05:00
if ( Lexer - > Pos ! = Lexer - > End )
{
if ( * Lexer - > Pos = = ' x ' | | * Lexer - > Pos = = ' X ' )
2009-06-04 03:41:06 -04:00
{ Base = 16 ; LEXER_INC ( Lexer ) ; }
2009-03-07 20:09:42 -05:00
else if ( * Lexer - > Pos = = ' b ' | | * Lexer - > Pos = = ' B ' )
2009-06-04 03:41:06 -04:00
{ Base = 2 ; LEXER_INC ( Lexer ) ; }
2009-05-28 20:40:45 -04:00
else if ( * Lexer - > Pos ! = ' . ' )
2009-03-07 20:09:42 -05:00
Base = 8 ;
}
}
2008-12-26 21:25:49 -05:00
2009-03-07 20:09:42 -05:00
/* get the value */
2009-06-04 03:41:06 -04:00
for ( ; Lexer - > Pos ! = Lexer - > End & & IS_BASE_DIGIT ( * Lexer - > Pos , Base ) ; LEXER_INC ( Lexer ) )
2009-03-07 20:09:42 -05:00
Result = Result * Base + GET_BASE_DIGIT ( * Lexer - > Pos ) ;
2009-04-22 08:06:58 -04:00
if ( Result < = MAX_CHAR_VALUE )
{
Value - > Typ = & CharType ;
Value - > Val - > Character = Result ;
ResultToken = TokenCharacterConstant ;
}
else
{
Value - > Typ = & IntType ;
Value - > Val - > Integer = Result ;
ResultToken = TokenIntegerConstant ;
}
2009-02-23 19:21:17 -05:00
# ifndef NO_FP
2008-12-26 21:25:49 -05:00
if ( Lexer - > Pos = = Lexer - > End | | * Lexer - > Pos ! = ' . ' )
2009-04-22 08:06:58 -04:00
return ResultToken ;
2008-12-26 21:25:49 -05:00
2009-02-01 06:31:18 -05:00
Value - > Typ = & FPType ;
2009-06-04 03:41:06 -04:00
LEXER_INC ( Lexer ) ;
for ( FPDiv = 1.0 / Base , FPResult = ( double ) Result ; Lexer - > Pos ! = Lexer - > End & & IS_BASE_DIGIT ( * Lexer - > Pos , Base ) ; LEXER_INC ( Lexer ) , FPDiv / = ( double ) Base )
2009-03-07 20:09:42 -05:00
FPResult + = GET_BASE_DIGIT ( * Lexer - > Pos ) * FPDiv ;
2008-12-26 21:25:49 -05:00
if ( Lexer - > Pos ! = Lexer - > End & & ( * Lexer - > Pos = = ' e ' | | * Lexer - > Pos = = ' E ' ) )
2008-12-20 06:46:21 -05:00
{
2009-10-29 15:26:47 -04:00
double ExponentMultiplier = 1.0 ;
2009-06-04 03:41:06 -04:00
LEXER_INC ( Lexer ) ;
2009-10-29 15:26:47 -04:00
if ( Lexer - > Pos ! = Lexer - > End & & * Lexer - > Pos = = ' - ' )
{
ExponentMultiplier = - 1.0 ;
LEXER_INC ( Lexer ) ;
}
2009-06-04 03:41:06 -04:00
for ( Result = 0 ; Lexer - > Pos ! = Lexer - > End & & IS_BASE_DIGIT ( * Lexer - > Pos , Base ) ; LEXER_INC ( Lexer ) )
2009-03-07 20:09:42 -05:00
Result = Result * ( double ) Base + GET_BASE_DIGIT ( * Lexer - > Pos ) ;
2008-12-26 21:25:49 -05:00
2009-10-29 15:26:47 -04:00
FPResult * = math_pow ( ( double ) Base , ( double ) Result * ExponentMultiplier ) ;
2008-12-20 06:46:21 -05:00
}
2008-12-26 21:25:49 -05:00
2009-05-26 20:06:09 -04:00
Value - > Val - > FP = FPResult ;
2008-12-26 21:25:49 -05:00
return TokenFPConstant ;
2009-02-23 19:21:17 -05:00
# else
2009-05-16 08:51:55 -04:00
return ResultToken ;
2009-02-23 19:21:17 -05:00
# endif
2008-10-12 20:53:28 -04:00
}
2009-02-01 23:53:45 -05:00
/* get a reserved word or identifier - used while scanning */
2009-02-01 06:31:18 -05:00
enum LexToken LexGetWord ( struct LexState * Lexer , struct Value * Value )
2008-10-12 20:53:28 -04:00
{
2009-06-04 03:41:06 -04:00
const char * StartPos = Lexer - > Pos ;
2008-10-14 07:46:42 -04:00
enum LexToken Token ;
2009-06-04 03:41:06 -04:00
do {
LEXER_INC ( Lexer ) ;
} while ( Lexer - > Pos ! = Lexer - > End & & isCident ( * Lexer - > Pos ) ) ;
2008-10-14 07:46:42 -04:00
2009-02-20 21:35:52 -05:00
Value - > Typ = NULL ;
2009-06-04 03:41:06 -04:00
Value - > Val - > Identifier = TableStrRegister2 ( StartPos , Lexer - > Pos - StartPos ) ;
2008-10-14 07:46:42 -04:00
2009-02-20 21:35:52 -05:00
Token = LexCheckReservedWord ( Value - > Val - > Identifier ) ;
2008-10-14 07:46:42 -04:00
if ( Token ! = TokenNone )
return Token ;
2008-10-13 06:53:25 -04:00
return TokenIdentifier ;
}
2009-06-02 22:57:23 -04:00
/* unescape a character from an octal character constant */
unsigned char LexUnEscapeCharacterConstant ( const char * * From , const char * End , unsigned char FirstChar , int Base )
{
unsigned char Total = GET_BASE_DIGIT ( FirstChar ) ;
int CCount ;
for ( CCount = 0 ; IS_BASE_DIGIT ( * * From , Base ) & & CCount < 2 ; CCount + + , ( * From ) + + )
Total = Total * Base + GET_BASE_DIGIT ( * * From ) ;
return Total ;
}
2009-02-18 23:34:36 -05:00
/* unescape a character from a string or character constant */
unsigned char LexUnEscapeCharacter ( const char * * From , const char * End )
{
unsigned char ThisChar ;
while ( * From ! = End & & * * From = = ' \\ ' & &
& ( * From ) [ 1 ] ! = End & & ( * From ) [ 1 ] = = ' \n ' )
( * From ) + = 2 ; /* skip escaped end of lines */
if ( * From = = End )
return ' \\ ' ;
if ( * * From = = ' \\ ' )
2009-04-22 08:06:58 -04:00
{
/* it's escaped */
2009-02-18 23:34:36 -05:00
( * From ) + + ;
if ( * From = = End )
return ' \\ ' ;
ThisChar = * ( * From ) + + ;
switch ( ThisChar )
{
case ' \\ ' : return ' \\ ' ;
case ' \' ' : return ' \' ' ;
case ' " ' : return ' " ' ;
case ' a ' : return ' \a ' ;
case ' b ' : return ' \b ' ;
case ' f ' : return ' \f ' ;
case ' n ' : return ' \n ' ;
case ' r ' : return ' \r ' ;
case ' t ' : return ' \t ' ;
case ' v ' : return ' \v ' ;
2009-06-02 22:57:23 -04:00
case ' 0 ' : case ' 1 ' : case ' 2 ' : case ' 3 ' : return LexUnEscapeCharacterConstant ( From , End , ThisChar , 8 ) ;
case ' x ' : return LexUnEscapeCharacterConstant ( From , End , ' 0 ' , 16 ) ;
2009-02-18 23:34:36 -05:00
default : return ThisChar ;
}
}
else
return * ( * From ) + + ;
}
2009-02-01 23:53:45 -05:00
/* get a string constant - used while scanning */
2009-02-01 06:31:18 -05:00
enum LexToken LexGetStringConstant ( struct LexState * Lexer , struct Value * Value )
2008-10-13 06:53:25 -04:00
{
2008-10-14 22:09:47 -04:00
int Escape = FALSE ;
2009-02-01 06:31:18 -05:00
const char * StartPos = Lexer - > Pos ;
2009-02-18 23:34:36 -05:00
const char * EndPos ;
char * EscBuf ;
char * EscBufPos ;
2009-03-11 18:28:42 -04:00
char * RegString ;
2009-02-20 21:35:52 -05:00
struct Value * ArrayValue ;
2008-10-14 22:09:47 -04:00
2008-12-18 23:24:55 -05:00
while ( Lexer - > Pos ! = Lexer - > End & & ( * Lexer - > Pos ! = ' " ' | | Escape ) )
2009-04-22 08:06:58 -04:00
{
/* find the end */
2008-10-14 22:09:47 -04:00
if ( Escape )
Escape = FALSE ;
else if ( * Lexer - > Pos = = ' \\ ' )
Escape = TRUE ;
2008-12-18 23:24:55 -05:00
2009-06-04 03:41:06 -04:00
LEXER_INC ( Lexer ) ;
2008-10-14 22:09:47 -04:00
}
2009-02-18 23:34:36 -05:00
EndPos = Lexer - > Pos ;
EscBuf = HeapAllocStack ( EndPos - StartPos ) ;
2009-02-20 21:35:52 -05:00
if ( EscBuf = = NULL )
LexFail ( Lexer , " out of memory " ) ;
2009-02-18 23:34:36 -05:00
for ( EscBufPos = EscBuf , Lexer - > Pos = StartPos ; Lexer - > Pos ! = EndPos ; )
* EscBufPos + + = LexUnEscapeCharacter ( & Lexer - > Pos , EndPos ) ;
2009-03-11 18:28:42 -04:00
/* try to find an existing copy of this string literal */
RegString = TableStrRegister2 ( EscBuf , EscBufPos - EscBuf ) ;
2009-02-18 23:34:36 -05:00
HeapPopStack ( EscBuf , EndPos - StartPos ) ;
2009-03-11 18:28:42 -04:00
ArrayValue = VariableStringLiteralGet ( RegString ) ;
if ( ArrayValue = = NULL )
{
/* create and store this string literal */
ArrayValue = VariableAllocValueAndData ( NULL , sizeof ( struct ArrayValue ) , FALSE , NULL , TRUE ) ;
ArrayValue - > Typ = CharArrayType ;
2009-10-23 15:01:32 -04:00
# ifndef NATIVE_POINTERS
2009-03-11 18:28:42 -04:00
ArrayValue - > Val - > Array . Size = EscBufPos - EscBuf + 1 ;
2009-10-23 15:01:32 -04:00
# endif
2009-03-11 18:28:42 -04:00
ArrayValue - > Val - > Array . Data = RegString ;
VariableStringLiteralDefine ( RegString , ArrayValue ) ;
}
/* create the the pointer for this char* */
2009-02-20 21:35:52 -05:00
Value - > Typ = CharPtrType ;
2009-05-05 20:25:09 -04:00
# ifndef NATIVE_POINTERS
2009-02-20 21:35:52 -05:00
Value - > Val - > Pointer . Segment = ArrayValue ;
2009-03-15 03:07:21 -04:00
Value - > Val - > Pointer . Offset = 0 ;
2009-05-05 20:25:09 -04:00
# else
2009-06-04 20:55:54 -04:00
Value - > Val - > NativePointer = RegString ;
2009-05-05 20:25:09 -04:00
# endif
2008-12-18 23:24:55 -05:00
if ( * Lexer - > Pos = = ' " ' )
2009-06-04 03:41:06 -04:00
LEXER_INC ( Lexer ) ;
2008-10-14 22:09:47 -04:00
2008-10-13 06:53:25 -04:00
return TokenStringConstant ;
}
2009-02-01 23:53:45 -05:00
/* get a character constant - used while scanning */
2009-02-01 06:31:18 -05:00
enum LexToken LexGetCharacterConstant ( struct LexState * Lexer , struct Value * Value )
2008-10-13 06:53:25 -04:00
{
2009-04-22 08:06:58 -04:00
Value - > Typ = & CharType ;
Value - > Val - > Character = LexUnEscapeCharacter ( & Lexer - > Pos , Lexer - > End ) ;
2009-02-23 20:01:02 -05:00
if ( Lexer - > Pos ! = Lexer - > End & & * Lexer - > Pos ! = ' \' ' )
2009-02-18 23:34:36 -05:00
LexFail ( Lexer , " expected \" ' \" " ) ;
2008-10-14 07:46:42 -04:00
2009-06-04 03:41:06 -04:00
LEXER_INC ( Lexer ) ;
2008-10-13 06:53:25 -04:00
return TokenCharacterConstant ;
2008-10-12 20:53:28 -04:00
}
2009-02-01 23:53:45 -05:00
/* skip a comment - used while scanning */
void LexSkipComment ( struct LexState * Lexer , char NextChar )
2009-01-03 23:08:49 -05:00
{
2009-06-04 03:41:06 -04:00
LEXER_INC ( Lexer ) ;
2009-01-03 23:08:49 -05:00
if ( NextChar = = ' * ' )
2009-04-22 08:06:58 -04:00
{
/* conventional C comment */
2009-01-03 23:08:49 -05:00
while ( Lexer - > Pos ! = Lexer - > End & & ( * ( Lexer - > Pos - 1 ) ! = ' * ' | | * Lexer - > Pos ! = ' / ' ) )
2009-06-04 03:41:06 -04:00
LEXER_INC ( Lexer ) ;
2009-01-03 23:08:49 -05:00
if ( Lexer - > Pos ! = Lexer - > End )
2009-06-04 03:41:06 -04:00
LEXER_INC ( Lexer ) ;
2009-01-03 23:08:49 -05:00
}
else
2009-04-22 08:06:58 -04:00
{
/* C++ style comment */
2009-01-03 23:08:49 -05:00
while ( Lexer - > Pos ! = Lexer - > End & & * Lexer - > Pos ! = ' \n ' )
2009-06-04 03:41:06 -04:00
LEXER_INC ( Lexer ) ;
2009-01-03 23:08:49 -05:00
}
}
2009-02-01 23:53:45 -05:00
/* get a single token from the source - used while scanning */
enum LexToken LexScanGetToken ( struct LexState * Lexer , struct Value * * Value )
2008-10-12 20:53:28 -04:00
{
char ThisChar ;
char NextChar ;
2009-02-01 23:53:45 -05:00
enum LexToken GotToken = TokenNone ;
2008-10-12 20:53:28 -04:00
2009-02-01 23:53:45 -05:00
do
2009-02-01 06:31:18 -05:00
{
2009-02-03 06:09:07 -05:00
* Value = & LexValue ;
while ( Lexer - > Pos ! = Lexer - > End & & isspace ( * Lexer - > Pos ) )
{
if ( * Lexer - > Pos = = ' \n ' )
2009-02-12 04:34:16 -05:00
{
2009-02-03 06:09:07 -05:00
Lexer - > Line + + ;
2009-02-12 04:34:16 -05:00
Lexer - > Pos + + ;
2009-06-04 03:41:06 -04:00
# ifdef FANCY_ERROR_REPORTING
Lexer - > CharacterPos = 0 ;
# endif
2009-02-12 04:34:16 -05:00
return TokenEndOfLine ;
}
2009-02-03 06:09:07 -05:00
2009-06-04 03:41:06 -04:00
LEXER_INC ( Lexer ) ;
2009-02-03 06:09:07 -05:00
}
2009-06-02 02:40:47 -04:00
if ( Lexer - > Pos = = Lexer - > End | | * Lexer - > Pos = = ' \0 ' )
2009-03-07 02:49:17 -05:00
return TokenEOF ;
2009-02-01 23:53:45 -05:00
ThisChar = * Lexer - > Pos ;
if ( isCidstart ( ThisChar ) )
return LexGetWord ( Lexer , * Value ) ;
if ( isdigit ( ThisChar ) )
return LexGetNumber ( Lexer , * Value ) ;
NextChar = ( Lexer - > Pos + 1 ! = Lexer - > End ) ? * ( Lexer - > Pos + 1 ) : 0 ;
2009-06-04 03:41:06 -04:00
LEXER_INC ( Lexer ) ;
2009-02-01 23:53:45 -05:00
switch ( ThisChar )
{
2009-02-02 18:45:34 -05:00
case ' " ' : GotToken = LexGetStringConstant ( Lexer , * Value ) ; break ;
case ' \' ' : GotToken = LexGetCharacterConstant ( Lexer , * Value ) ; break ;
case ' ( ' : GotToken = TokenOpenBracket ; break ;
case ' ) ' : GotToken = TokenCloseBracket ; break ;
2009-03-03 05:53:45 -05:00
case ' = ' : NEXTIS ( ' = ' , TokenEqual , TokenAssign ) ; break ;
2009-02-02 18:45:34 -05:00
case ' + ' : NEXTIS3 ( ' = ' , TokenAddAssign , ' + ' , TokenIncrement , TokenPlus ) ; break ;
case ' - ' : NEXTIS4 ( ' = ' , TokenSubtractAssign , ' > ' , TokenArrow , ' - ' , TokenDecrement , TokenMinus ) ; break ;
2009-02-28 14:57:03 -05:00
case ' * ' : NEXTIS ( ' = ' , TokenMultiplyAssign , TokenAsterisk ) ; break ;
case ' / ' : if ( NextChar = = ' / ' | | NextChar = = ' * ' ) LexSkipComment ( Lexer , NextChar ) ; else NEXTIS ( ' = ' , TokenDivideAssign , TokenSlash ) ; break ;
case ' % ' : NEXTIS ( ' = ' , TokenModulusAssign , TokenModulus ) ; break ;
case ' < ' : NEXTIS3PLUS ( ' = ' , TokenLessEqual , ' < ' , TokenShiftLeft , ' = ' , TokenShiftLeftAssign , TokenLessThan ) ; break ;
case ' > ' : NEXTIS3PLUS ( ' = ' , TokenGreaterEqual , ' > ' , TokenShiftRight , ' = ' , TokenShiftRightAssign , TokenGreaterThan ) ; break ;
2009-02-02 18:45:34 -05:00
case ' ; ' : GotToken = TokenSemicolon ; break ;
2009-02-28 14:57:03 -05:00
case ' & ' : NEXTIS3 ( ' = ' , TokenArithmeticAndAssign , ' & ' , TokenLogicalAnd , TokenAmpersand ) ; break ;
case ' | ' : NEXTIS3 ( ' = ' , TokenArithmeticOrAssign , ' | ' , TokenLogicalOr , TokenArithmeticOr ) ; break ;
2009-02-02 18:45:34 -05:00
case ' { ' : GotToken = TokenLeftBrace ; break ;
case ' } ' : GotToken = TokenRightBrace ; break ;
case ' [ ' : GotToken = TokenLeftSquareBracket ; break ;
case ' ] ' : GotToken = TokenRightSquareBracket ; break ;
2009-02-28 14:57:03 -05:00
case ' ! ' : NEXTIS ( ' = ' , TokenNotEqual , TokenUnaryNot ) ; break ;
case ' ^ ' : NEXTIS ( ' = ' , TokenArithmeticExorAssign , TokenArithmeticExor ) ; break ;
2009-02-02 18:45:34 -05:00
case ' ~ ' : GotToken = TokenUnaryExor ; break ;
case ' , ' : GotToken = TokenComma ; break ;
2009-02-20 04:04:45 -05:00
case ' . ' : NEXTISEXACTLY3 ( ' . ' , ' . ' , TokenEllipsis , TokenDot ) ; break ;
2009-02-28 14:57:03 -05:00
case ' ? ' : GotToken = TokenQuestionMark ; break ;
2009-02-18 03:19:06 -05:00
case ' : ' : GotToken = TokenColon ; break ;
2009-02-02 18:45:34 -05:00
default : LexFail ( Lexer , " illegal character '%c' " , ThisChar ) ; break ;
2009-02-01 23:53:45 -05:00
}
} while ( GotToken = = TokenNone ) ;
2008-10-12 20:53:28 -04:00
2009-02-01 23:53:45 -05:00
return GotToken ;
2008-10-12 20:53:28 -04:00
}
2009-02-02 19:13:50 -05:00
/* what size value goes with each token */
int LexTokenSize ( enum LexToken Token )
{
switch ( Token )
{
case TokenIdentifier : case TokenStringConstant : return sizeof ( char * ) ;
2009-04-22 08:06:58 -04:00
case TokenIntegerConstant : return sizeof ( int ) ;
case TokenCharacterConstant : return sizeof ( unsigned char ) ;
2009-02-02 19:13:50 -05:00
case TokenFPConstant : return sizeof ( double ) ;
default : return 0 ;
}
}
2009-02-01 23:53:45 -05:00
/* produce tokens from the lexer and return a heap buffer with the result - used for scanning */
2009-03-07 02:49:17 -05:00
void * LexTokenise ( struct LexState * Lexer , int * TokenLen )
2009-01-04 23:52:33 -05:00
{
2009-02-01 23:53:45 -05:00
enum LexToken Token ;
void * HeapMem ;
struct Value * GotValue ;
2009-02-02 17:33:07 -05:00
int MemUsed = 0 ;
2009-02-02 19:13:50 -05:00
int ValueSize ;
2009-06-04 03:41:06 -04:00
# ifdef FANCY_ERROR_REPORTING
int ReserveSpace = ( Lexer - > End - Lexer - > Pos ) * 4 + 1 ;
# else
2009-02-20 04:46:46 -05:00
int ReserveSpace = ( Lexer - > End - Lexer - > Pos ) * 3 + 1 ;
2009-06-04 03:41:06 -04:00
# endif
2009-02-20 04:46:46 -05:00
void * TokenSpace = HeapAllocStack ( ReserveSpace ) ;
2009-06-02 03:50:46 -04:00
char * TokenPos = ( char * ) TokenSpace ;
2009-06-04 03:41:06 -04:00
# ifdef FANCY_ERROR_REPORTING
int LastCharacterPos = 0 ;
# endif
2009-02-20 04:46:46 -05:00
if ( TokenSpace = = NULL )
LexFail ( Lexer , " out of memory " ) ;
2009-02-01 23:53:45 -05:00
do
2009-04-22 08:06:58 -04:00
{
/* store the token at the end of the stack area */
2009-02-01 23:53:45 -05:00
Token = LexScanGetToken ( Lexer , & GotValue ) ;
2009-02-03 05:39:48 -05:00
# ifdef DEBUG_LEXER
2009-02-02 19:43:13 -05:00
printf ( " Token: %02x \n " , Token ) ;
2009-02-03 05:39:48 -05:00
# endif
2009-02-20 04:46:46 -05:00
* ( unsigned char * ) TokenPos = Token ;
TokenPos + + ;
2009-02-01 23:53:45 -05:00
MemUsed + + ;
2009-06-04 03:41:06 -04:00
# ifdef FANCY_ERROR_REPORTING
* ( unsigned char * ) TokenPos = ( unsigned char ) LastCharacterPos ;
TokenPos + + ;
MemUsed + + ;
# endif
2009-02-02 19:13:50 -05:00
ValueSize = LexTokenSize ( Token ) ;
if ( ValueSize > 0 )
2009-04-22 08:06:58 -04:00
{
/* store a value as well */
2009-04-03 23:11:12 -04:00
memcpy ( TokenPos , ( void * ) GotValue - > Val , ValueSize ) ;
2009-02-20 04:46:46 -05:00
TokenPos + = ValueSize ;
2009-02-01 23:53:45 -05:00
MemUsed + = ValueSize ;
}
2009-10-31 10:18:46 -04:00
2009-06-04 03:41:06 -04:00
# ifdef FANCY_ERROR_REPORTING
LastCharacterPos = Lexer - > CharacterPos ;
# endif
2009-10-31 10:18:46 -04:00
2009-02-01 23:53:45 -05:00
} while ( Token ! = TokenEOF ) ;
2009-06-02 04:00:02 -04:00
HeapMem = HeapAllocMem ( MemUsed ) ;
2009-02-20 04:46:46 -05:00
if ( HeapMem = = NULL )
LexFail ( Lexer , " out of memory " ) ;
2009-06-04 03:41:06 -04:00
assert ( ReserveSpace > = MemUsed ) ;
2009-02-20 04:46:46 -05:00
memcpy ( HeapMem , TokenSpace , MemUsed ) ;
HeapPopStack ( TokenSpace , ReserveSpace ) ;
2009-02-03 05:39:48 -05:00
# ifdef DEBUG_LEXER
2009-02-02 19:43:13 -05:00
{
int Count ;
2009-10-31 10:18:46 -04:00
printf ( " Tokens: " ) ;
2009-02-02 19:43:13 -05:00
for ( Count = 0 ; Count < MemUsed ; Count + + )
2009-06-04 03:41:06 -04:00
printf ( " %02x " , * ( ( unsigned char * ) HeapMem + Count ) ) ;
2009-02-02 19:43:13 -05:00
printf ( " \n " ) ;
}
2009-02-03 05:39:48 -05:00
# endif
2009-03-07 02:49:17 -05:00
if ( TokenLen )
* TokenLen = MemUsed ;
2009-02-02 19:43:13 -05:00
2009-02-01 23:53:45 -05:00
return HeapMem ;
2009-02-01 06:31:18 -05:00
}
2009-02-02 06:50:55 -05:00
/* lexically analyse some source text */
2009-03-07 02:49:17 -05:00
void * LexAnalyse ( const char * FileName , const char * Source , int SourceLen , int * TokenLen )
2009-02-02 06:50:55 -05:00
{
struct LexState Lexer ;
2009-10-31 10:18:46 -04:00
printf ( " LexAnalyse( \" %s \" ) \n " , Source ) ;
2009-02-02 06:50:55 -05:00
Lexer . Pos = Source ;
Lexer . End = Source + SourceLen ;
Lexer . Line = 1 ;
Lexer . FileName = FileName ;
2009-06-04 03:41:06 -04:00
# ifdef FANCY_ERROR_REPORTING
Lexer . CharacterPos = 1 ;
Lexer . SourceText = Source ;
# endif
2009-10-31 10:18:46 -04:00
2009-03-07 02:49:17 -05:00
return LexTokenise ( & Lexer , TokenLen ) ;
2009-02-02 06:50:55 -05:00
}
/* prepare to parse a pre-tokenised buffer */
2009-06-04 03:41:06 -04:00
void LexInitParser ( struct ParseState * Parser , const char * SourceText , void * TokenSource , const char * FileName , int RunIt )
2009-02-02 06:50:55 -05:00
{
Parser - > Pos = TokenSource ;
2009-06-04 03:41:06 -04:00
Parser - > Line = 1 ;
2009-02-02 06:50:55 -05:00
Parser - > FileName = FileName ;
2009-02-18 03:19:06 -05:00
Parser - > Mode = RunIt ? RunModeRun : RunModeSkip ;
Parser - > SearchLabel = 0 ;
2009-06-04 03:41:06 -04:00
# ifdef FANCY_ERROR_REPORTING
Parser - > CharacterPos = 0 ;
Parser - > SourceText = SourceText ;
# endif
2009-02-02 06:50:55 -05:00
}
2009-02-01 23:53:45 -05:00
/* get the next token given a parser state */
2009-02-01 06:31:18 -05:00
enum LexToken LexGetToken ( struct ParseState * Parser , struct Value * * Value , int IncPos )
{
2009-05-04 08:02:16 -04:00
enum LexToken Token = TokenNone ;
2009-02-02 19:13:50 -05:00
int ValueSize ;
2009-03-07 02:49:17 -05:00
2009-10-31 10:18:46 -04:00
printf ( " Parser->Pos == %08lx \n " , ( unsigned long ) Parser - > Pos ) ;
2009-03-07 06:08:00 -05:00
do
2009-04-22 08:06:58 -04:00
{
/* get the next token */
2009-03-07 23:26:28 -05:00
if ( Parser - > Pos = = NULL & & InteractiveHead ! = NULL )
Parser - > Pos = InteractiveHead - > Tokens ;
2009-10-31 10:18:46 -04:00
2009-03-07 06:08:00 -05:00
if ( Parser - > FileName ! = StrEmpty | | InteractiveHead ! = NULL )
2009-04-22 08:06:58 -04:00
{
/* skip leading newlines */
2009-03-07 06:08:00 -05:00
while ( ( Token = ( enum LexToken ) * ( unsigned char * ) Parser - > Pos ) = = TokenEndOfLine )
{
Parser - > Line + + ;
2009-06-04 03:41:06 -04:00
Parser - > Pos + = TOKEN_DATA_OFFSET ;
2009-03-07 06:08:00 -05:00
}
2009-03-07 02:49:17 -05:00
}
2009-01-04 23:52:33 -05:00
2009-03-07 06:08:00 -05:00
if ( Parser - > FileName = = StrEmpty & & ( InteractiveHead = = NULL | | Token = = TokenEOF ) )
2009-04-22 08:06:58 -04:00
{
/* we're at the end of an interactive input token list */
2009-03-07 06:08:00 -05:00
char LineBuffer [ LINEBUFFER_MAX ] ;
void * LineTokens ;
int LineBytes ;
struct TokenLine * LineNode ;
2009-10-31 10:18:46 -04:00
2009-06-04 03:41:06 -04:00
if ( InteractiveHead = = NULL | | ( unsigned char * ) Parser - > Pos = = & InteractiveTail - > Tokens [ InteractiveTail - > NumBytes - TOKEN_DATA_OFFSET ] )
2009-04-22 08:06:58 -04:00
{
/* get interactive input */
2009-03-07 23:26:28 -05:00
if ( LexUseStatementPrompt )
{
PlatformPrintf ( INTERACTIVE_PROMPT_STATEMENT ) ;
LexUseStatementPrompt = FALSE ;
}
2009-03-07 06:08:00 -05:00
else
2009-03-07 23:26:28 -05:00
PlatformPrintf ( INTERACTIVE_PROMPT_LINE ) ;
2009-03-07 06:08:00 -05:00
if ( PlatformGetLine ( & LineBuffer [ 0 ] , LINEBUFFER_MAX ) = = NULL )
return TokenEOF ;
/* put the new line at the end of the linked list of interactive lines */
2009-03-07 06:23:42 -05:00
LineTokens = LexAnalyse ( StrEmpty , & LineBuffer [ 0 ] , strlen ( LineBuffer ) , & LineBytes ) ;
2009-10-31 10:18:46 -04:00
printf ( " Added new line node at %08lx-%08lx with text %s \n " , ( unsigned long ) LineTokens , ( unsigned long ) LineTokens + LineBytes - TOKEN_DATA_OFFSET , & LineBuffer [ 0 ] ) ;
2009-03-07 06:08:00 -05:00
LineNode = VariableAlloc ( Parser , sizeof ( struct TokenLine ) , TRUE ) ;
LineNode - > Tokens = LineTokens ;
LineNode - > NumBytes = LineBytes ;
if ( InteractiveHead = = NULL )
2009-04-22 08:06:58 -04:00
{
/* start a new list */
2009-03-07 06:08:00 -05:00
InteractiveHead = LineNode ;
Parser - > Line = 1 ;
2009-06-04 03:41:06 -04:00
Parser - > CharacterPos = 0 ;
2009-03-07 06:08:00 -05:00
}
else
InteractiveTail - > Next = LineNode ;
InteractiveTail = LineNode ;
InteractiveCurrentLine = LineNode ;
Parser - > Pos = LineTokens ;
2009-03-07 02:49:17 -05:00
}
else
2009-04-22 08:06:58 -04:00
{
/* go to the next token line */
2009-10-31 10:18:46 -04:00
printf ( " Next token line... \n " ) ;
2009-06-04 03:41:06 -04:00
if ( Parser - > Pos ! = & InteractiveCurrentLine - > Tokens [ InteractiveCurrentLine - > NumBytes - TOKEN_DATA_OFFSET ] )
2009-04-22 08:06:58 -04:00
{
/* scan for the line */
2009-06-04 03:41:06 -04:00
for ( InteractiveCurrentLine = InteractiveHead ; Parser - > Pos ! = & InteractiveCurrentLine - > Tokens [ InteractiveCurrentLine - > NumBytes - TOKEN_DATA_OFFSET ] ; InteractiveCurrentLine = InteractiveCurrentLine - > Next )
2009-10-31 10:18:46 -04:00
{
printf ( " InteractiveCurrentLine = %08lx-%08lx, Pos = %08lx, NumBytes = %d \n " , ( unsigned long ) & InteractiveCurrentLine - > Tokens [ 0 ] , ( unsigned long ) & InteractiveCurrentLine - > Tokens [ InteractiveCurrentLine - > NumBytes - TOKEN_DATA_OFFSET ] , ( unsigned long ) Parser - > Pos , InteractiveCurrentLine - > NumBytes ) ;
assert ( InteractiveCurrentLine - > Next ! = NULL ) ;
printf ( " next InteractiveCurrentLine = %08lx-%08lx, Pos = %08lx, NumBytes = %d \n " , ( unsigned long ) & InteractiveCurrentLine - > Next - > Tokens [ 0 ] , ( unsigned long ) & InteractiveCurrentLine - > Next - > Tokens [ InteractiveCurrentLine - > Next - > NumBytes - TOKEN_DATA_OFFSET ] , ( unsigned long ) Parser - > Pos , InteractiveCurrentLine - > Next - > NumBytes ) ;
}
2009-03-07 06:08:00 -05:00
}
2009-10-31 10:18:46 -04:00
assert ( InteractiveCurrentLine ! = NULL ) ;
2009-03-07 06:08:00 -05:00
InteractiveCurrentLine = InteractiveCurrentLine - > Next ;
2009-10-31 10:18:46 -04:00
assert ( InteractiveCurrentLine ! = NULL ) ;
2009-03-07 06:08:00 -05:00
Parser - > Pos = InteractiveCurrentLine - > Tokens ;
2009-03-07 02:49:17 -05:00
}
2009-03-07 06:08:00 -05:00
Token = ( enum LexToken ) * ( unsigned char * ) Parser - > Pos ;
2009-03-07 02:49:17 -05:00
}
2009-03-07 06:08:00 -05:00
} while ( ( Parser - > FileName = = StrEmpty & & Token = = TokenEOF ) | | Token = = TokenEndOfLine ) ;
2009-03-07 02:49:17 -05:00
2009-06-04 03:41:06 -04:00
# ifdef FANCY_ERROR_REPORTING
Parser - > CharacterPos = * ( ( unsigned char * ) Parser - > Pos + 1 ) ;
# endif
2009-02-02 19:13:50 -05:00
ValueSize = LexTokenSize ( Token ) ;
if ( ValueSize > 0 )
2009-04-22 08:06:58 -04:00
{
/* this token requires a value - unpack it */
2009-02-01 06:31:18 -05:00
if ( Value ! = NULL )
2009-02-02 19:13:50 -05:00
{
switch ( Token )
{
2009-06-04 20:55:54 -04:00
# ifndef NATIVE_POINTERS
2009-05-26 23:23:41 -04:00
case TokenStringConstant : LexValue . Typ = CharPtrType ; LexValue . Val - > Pointer . Offset = 0 ; break ;
2009-06-04 20:55:54 -04:00
# else
case TokenStringConstant : LexValue . Typ = CharPtrType ; break ;
# endif
2009-02-20 21:35:52 -05:00
case TokenIdentifier : LexValue . Typ = NULL ; break ;
2009-04-22 08:06:58 -04:00
case TokenIntegerConstant : LexValue . Typ = & IntType ; break ;
case TokenCharacterConstant : LexValue . Typ = & CharType ; break ;
2009-02-23 19:21:17 -05:00
# ifndef NO_FP
2009-02-02 19:13:50 -05:00
case TokenFPConstant : LexValue . Typ = & FPType ; break ;
2009-02-23 19:21:17 -05:00
# endif
2009-02-02 19:13:50 -05:00
default : break ;
}
2009-06-04 03:41:06 -04:00
memcpy ( ( void * ) LexValue . Val , ( void * ) ( ( char * ) Parser - > Pos + TOKEN_DATA_OFFSET ) , ValueSize ) ;
2009-02-02 19:13:50 -05:00
LexValue . ValOnHeap = FALSE ;
LexValue . ValOnStack = FALSE ;
2009-02-15 00:52:03 -05:00
LexValue . IsLValue = FALSE ;
2009-02-26 04:56:22 -05:00
LexValue . LValueFrom = NULL ;
2009-02-01 06:31:18 -05:00
* Value = & LexValue ;
}
if ( IncPos )
2009-06-04 03:41:06 -04:00
Parser - > Pos + = ValueSize + TOKEN_DATA_OFFSET ;
2009-01-04 23:52:33 -05:00
}
else
{
2009-02-03 19:17:30 -05:00
if ( IncPos & & Token ! = TokenEOF )
2009-06-04 03:41:06 -04:00
Parser - > Pos + = TOKEN_DATA_OFFSET ;
2009-01-04 23:52:33 -05:00
}
2009-02-03 05:39:48 -05:00
# ifdef DEBUG_LEXER
2009-06-04 03:41:06 -04:00
printf ( " Got token=%02x inc=%d pos=%d \n " , Token , IncPos , Parser - > CharacterPos ) ;
2009-02-03 05:39:48 -05:00
# endif
2009-10-31 10:18:46 -04:00
assert ( Token > = TokenNone & & Token < = TokenEndOfFunction ) ;
2009-02-01 23:53:45 -05:00
return Token ;
2008-12-22 06:52:31 -05:00
}
2009-03-07 01:17:11 -05:00
/* find the end of the line */
void LexToEndOfLine ( struct ParseState * Parser )
2009-03-06 02:27:45 -05:00
{
2009-03-07 01:17:11 -05:00
while ( TRUE )
2009-03-06 02:27:45 -05:00
{
2009-03-07 01:17:11 -05:00
enum LexToken Token = ( enum LexToken ) * ( unsigned char * ) Parser - > Pos ;
if ( Token = = TokenEndOfLine | | Token = = TokenEOF )
return ;
2009-03-06 02:27:45 -05:00
else
LexGetToken ( Parser , NULL , TRUE ) ;
2009-03-07 01:17:11 -05:00
}
}
2009-10-31 10:18:46 -04:00
/* copy the tokens from StartParser to EndParser into new memory, removing TokenEOFs and terminate with a TokenEndOfFunction */
2009-03-07 01:17:11 -05:00
void * LexCopyTokens ( struct ParseState * StartParser , struct ParseState * EndParser )
{
int MemSize = 0 ;
2009-03-07 06:08:00 -05:00
int CopySize ;
2009-03-07 01:17:11 -05:00
unsigned char * Pos = ( unsigned char * ) StartParser - > Pos ;
unsigned char * NewTokens ;
2009-03-07 06:08:00 -05:00
unsigned char * NewTokenPos ;
struct TokenLine * ILine ;
2009-03-07 01:17:11 -05:00
2009-03-07 06:08:00 -05:00
if ( InteractiveHead = = NULL )
2009-04-22 08:06:58 -04:00
{
/* non-interactive mode - copy the tokens */
2009-03-07 06:08:00 -05:00
MemSize = EndParser - > Pos - StartParser - > Pos ;
NewTokens = VariableAlloc ( StartParser , MemSize + 1 , TRUE ) ;
2009-04-03 23:11:12 -04:00
memcpy ( NewTokens , ( void * ) StartParser - > Pos , MemSize ) ;
2009-03-07 06:08:00 -05:00
}
else
2009-04-22 08:06:58 -04:00
{
/* we're in interactive mode - add up line by line */
2009-03-07 06:08:00 -05:00
for ( InteractiveCurrentLine = InteractiveHead ; InteractiveCurrentLine ! = NULL & & ( Pos < & InteractiveCurrentLine - > Tokens [ 0 ] | | Pos > = & InteractiveCurrentLine - > Tokens [ InteractiveCurrentLine - > NumBytes ] ) ; InteractiveCurrentLine = InteractiveCurrentLine - > Next )
{ } /* find the line we just counted */
2009-06-02 03:50:46 -04:00
if ( EndParser - > Pos > = StartParser - > Pos & & EndParser - > Pos < & InteractiveCurrentLine - > Tokens [ InteractiveCurrentLine - > NumBytes ] )
2009-04-22 08:06:58 -04:00
{
/* all on a single line */
2009-10-31 10:18:46 -04:00
MemSize = EndParser - > Pos - StartParser - > Pos - TOKEN_DATA_OFFSET ;
2009-03-07 06:08:00 -05:00
NewTokens = VariableAlloc ( StartParser , MemSize + 1 , TRUE ) ;
2009-04-03 23:11:12 -04:00
memcpy ( NewTokens , ( void * ) StartParser - > Pos , MemSize ) ;
2009-03-07 06:08:00 -05:00
}
else
2009-04-22 08:06:58 -04:00
{
/* it's spread across multiple lines */
2009-10-31 10:18:46 -04:00
MemSize = & InteractiveCurrentLine - > Tokens [ InteractiveCurrentLine - > NumBytes - TOKEN_DATA_OFFSET ] - Pos ;
{
int Count ;
printf ( " Adding up: %d bytes - " , MemSize ) ;
for ( Count = 0 ; Count < MemSize ; Count + + )
printf ( " %02x " , Pos [ Count ] ) ;
printf ( " \n " ) ;
}
2009-06-02 03:50:46 -04:00
for ( ILine = InteractiveCurrentLine - > Next ; ILine ! = NULL & & ( EndParser - > Pos < & ILine - > Tokens [ 0 ] | | EndParser - > Pos > = & ILine - > Tokens [ ILine - > NumBytes ] ) ; ILine = ILine - > Next )
2009-10-31 10:18:46 -04:00
{
{
int Count ;
printf ( " Adding up: %d bytes - " , ILine - > NumBytes - TOKEN_DATA_OFFSET ) ;
for ( Count = 0 ; Count < ILine - > NumBytes - TOKEN_DATA_OFFSET ; Count + + )
printf ( " %02x " , ILine - > Tokens [ Count ] ) ;
printf ( " \n " ) ;
}
MemSize + = ILine - > NumBytes - TOKEN_DATA_OFFSET ;
}
2009-03-07 06:08:00 -05:00
assert ( ILine ! = NULL ) ;
2009-06-02 03:50:46 -04:00
MemSize + = EndParser - > Pos - & ILine - > Tokens [ 0 ] ;
2009-10-31 10:18:46 -04:00
{
int Count ;
printf ( " Adding up: %d bytes - " , EndParser - > Pos - & ILine - > Tokens [ 0 ] ) ;
for ( Count = 0 ; Count < EndParser - > Pos - & ILine - > Tokens [ 0 ] ; Count + + )
printf ( " %02x " , ILine - > Tokens [ Count ] ) ;
printf ( " \n " ) ;
}
2009-03-07 06:08:00 -05:00
NewTokens = VariableAlloc ( StartParser , MemSize + 1 , TRUE ) ;
2009-10-31 10:18:46 -04:00
CopySize = & InteractiveCurrentLine - > Tokens [ InteractiveCurrentLine - > NumBytes - TOKEN_DATA_OFFSET ] - Pos ;
2009-03-07 06:08:00 -05:00
memcpy ( NewTokens , Pos , CopySize ) ;
2009-10-31 10:18:46 -04:00
{
int Count ;
printf ( " Copying - " ) ;
for ( Count = 0 ; Count < CopySize ; Count + + )
printf ( " %02x " , Pos [ Count ] ) ;
printf ( " \n " ) ;
}
2009-03-07 06:08:00 -05:00
NewTokenPos = NewTokens + CopySize ;
2009-06-02 03:50:46 -04:00
for ( ILine = InteractiveCurrentLine - > Next ; ILine ! = NULL & & ( EndParser - > Pos < & ILine - > Tokens [ 0 ] | | EndParser - > Pos > = & ILine - > Tokens [ ILine - > NumBytes ] ) ; ILine = ILine - > Next )
2009-03-07 06:08:00 -05:00
{
2009-10-31 10:18:46 -04:00
{
int Count ;
printf ( " Copying - " ) ;
for ( Count = 0 ; Count < ILine - > NumBytes - TOKEN_DATA_OFFSET ; Count + + )
printf ( " %02x " , ILine - > Tokens [ Count ] ) ;
printf ( " \n " ) ;
}
memcpy ( NewTokenPos , & ILine - > Tokens [ 0 ] , ILine - > NumBytes - TOKEN_DATA_OFFSET ) ;
NewTokenPos + = ILine - > NumBytes - TOKEN_DATA_OFFSET ;
2009-03-07 06:08:00 -05:00
}
assert ( ILine ! = NULL ) ;
2009-10-31 10:18:46 -04:00
{
int Count ;
printf ( " Copying - " ) ;
for ( Count = 0 ; Count < EndParser - > Pos - & ILine - > Tokens [ 0 ] ; Count + + )
printf ( " %02x " , ILine - > Tokens [ Count ] ) ;
printf ( " \n " ) ;
}
2009-06-02 03:50:46 -04:00
memcpy ( NewTokenPos , & ILine - > Tokens [ 0 ] , EndParser - > Pos - & ILine - > Tokens [ 0 ] ) ;
2009-03-07 06:08:00 -05:00
}
2009-03-07 01:17:11 -05:00
}
2009-03-07 02:49:17 -05:00
NewTokens [ MemSize ] = ( unsigned char ) TokenEndOfFunction ;
2009-10-31 10:18:46 -04:00
printf ( " Copied tokens to address range %08lx-%08lx, size %d \n " , ( unsigned long ) NewTokens , ( unsigned long ) NewTokens + MemSize + 1 , MemSize + 1 ) ;
{
int Count ;
for ( Count = 0 ; Count < = MemSize ; Count + + )
printf ( " %02x " , NewTokens [ Count ] ) ;
printf ( " \n " ) ;
}
2009-03-07 01:17:11 -05:00
return NewTokens ;
2009-03-06 02:27:45 -05:00
}
2009-03-07 06:08:00 -05:00
2009-03-07 23:26:28 -05:00
/* indicate that we've completed up to this point in the interactive input and free expired tokens */
void LexInteractiveClear ( struct ParseState * Parser )
{
while ( InteractiveHead ! = NULL )
{
struct TokenLine * NextLine = InteractiveHead - > Next ;
2009-06-02 04:00:02 -04:00
HeapFreeMem ( InteractiveHead - > Tokens ) ;
HeapFreeMem ( InteractiveHead ) ;
2009-03-07 23:26:28 -05:00
InteractiveHead = NextLine ;
}
2009-03-11 19:49:10 -04:00
if ( Parser ! = NULL )
Parser - > Pos = NULL ;
2009-03-07 23:26:28 -05:00
InteractiveTail = NULL ;
}
2009-03-07 06:08:00 -05:00
/* indicate that we've completed up to this point in the interactive input and free expired tokens */
void LexInteractiveCompleted ( struct ParseState * Parser )
{
2009-06-02 03:50:46 -04:00
while ( InteractiveHead ! = NULL & & ! ( Parser - > Pos > = & InteractiveHead - > Tokens [ 0 ] & & Parser - > Pos < & InteractiveHead - > Tokens [ InteractiveHead - > NumBytes ] ) )
2009-04-22 08:06:58 -04:00
{
/* this token line is no longer needed - free it */
2009-03-07 23:26:28 -05:00
struct TokenLine * NextLine = InteractiveHead - > Next ;
2009-06-02 04:00:02 -04:00
HeapFreeMem ( InteractiveHead - > Tokens ) ;
HeapFreeMem ( InteractiveHead ) ;
2009-03-07 23:26:28 -05:00
InteractiveHead = NextLine ;
if ( InteractiveHead = = NULL )
2009-04-22 08:06:58 -04:00
{
/* we've emptied the list */
2009-03-07 23:26:28 -05:00
Parser - > Pos = NULL ;
InteractiveTail = NULL ;
}
}
}
/* the next time we prompt, make it the full statement prompt */
void LexInteractiveStatementPrompt ( )
{
LexUseStatementPrompt = TRUE ;
2009-03-07 06:08:00 -05:00
}