2008-10-12 20:53:28 -04:00
# include <stdio.h>
# include "picoc.h"
2008-12-18 19:22:52 -05:00
/* local prototypes */
2009-02-01 06:31:18 -05:00
int ParseArguments ( struct ParseState * Parser , int RunIt ) ;
2009-02-18 03:19:06 -05:00
int ParseStatementMaybeRun ( struct ParseState * Parser , int Condition ) ;
2008-10-14 00:51:34 -04:00
2008-12-18 19:22:52 -05:00
/* initialise the parser */
2008-10-12 20:53:28 -04:00
void ParseInit ( )
{
2009-01-23 06:34:12 -05:00
VariableInit ( ) ;
2008-12-26 23:36:45 -05:00
IntrinsicInit ( & GlobalTable ) ;
2009-01-23 06:34:12 -05:00
TypeInit ( ) ;
2008-12-23 21:30:29 -05:00
}
/* do a function call */
2009-02-19 18:29:35 -05:00
void ParseFunctionCall ( struct ParseState * Parser , struct Value * * Result , const char * FuncName )
2008-12-23 21:30:29 -05:00
{
2009-02-02 06:08:36 -05:00
struct Value * FuncValue ;
2009-02-19 18:29:35 -05:00
struct Value * Param ;
int ArgCount ;
2009-02-01 06:31:18 -05:00
enum LexToken Token = LexGetToken ( Parser , NULL , TRUE ) ; /* open bracket */
2008-12-23 21:30:29 -05:00
2009-02-18 03:19:06 -05:00
if ( Parser - > Mode = = RunModeRun )
2009-02-02 06:08:36 -05:00
{ /* get the function definition */
VariableGet ( Parser , FuncName , & FuncValue ) ;
if ( FuncValue - > Typ - > Base ! = TypeFunction )
ProgramFail ( Parser , " not a function - can't call " ) ;
2009-02-03 19:17:30 -05:00
2009-02-19 18:29:35 -05:00
* Result = VariableAllocValueFromType ( Parser , FuncValue - > Val - > FuncDef . ReturnType , FALSE ) ;
VariableStackFrameAdd ( Parser , FuncValue - > Val - > FuncDef . Intrinsic ? FuncValue - > Val - > FuncDef . NumParams : 0 ) ;
TopStackFrame - > ReturnValue = * Result ;
2009-02-02 06:08:36 -05:00
}
2008-12-23 21:30:29 -05:00
/* parse arguments */
2009-02-19 18:29:35 -05:00
ArgCount = 0 ;
2008-12-23 21:30:29 -05:00
do {
2009-02-19 18:29:35 -05:00
if ( ParseExpression ( Parser , & Param ) )
2008-12-23 21:30:29 -05:00
{
2009-02-19 18:29:35 -05:00
if ( Parser - > Mode = = RunModeRun )
{
if ( ArgCount > = FuncValue - > Val - > FuncDef . NumParams )
ProgramFail ( Parser , " too many arguments to %s() " , FuncName ) ;
2008-12-23 21:30:29 -05:00
2009-02-19 18:29:35 -05:00
if ( FuncValue - > Val - > FuncDef . ParamType [ ArgCount ] ! = Param - > Typ )
ProgramFail ( Parser , " parameter %d to %s() is the wrong type " , ArgCount , FuncName ) ;
if ( FuncValue - > Val - > FuncDef . Intrinsic )
TopStackFrame - > Parameter [ ArgCount ] = Param ;
else
VariableDefine ( Parser , FuncValue - > Val - > FuncDef . ParamName [ ArgCount ] , Param ) ;
}
ArgCount + + ;
2009-02-01 06:31:18 -05:00
Token = LexGetToken ( Parser , NULL , TRUE ) ;
2008-12-23 21:30:29 -05:00
if ( Token ! = TokenComma & & Token ! = TokenCloseBracket )
2009-02-01 06:31:18 -05:00
ProgramFail ( Parser , " comma expected " ) ;
2008-12-23 21:30:29 -05:00
}
else
{
2009-02-01 06:31:18 -05:00
Token = LexGetToken ( Parser , NULL , TRUE ) ;
2008-12-23 22:27:53 -05:00
if ( ! TokenCloseBracket )
2009-02-01 06:31:18 -05:00
ProgramFail ( Parser , " bad argument " ) ;
2008-12-23 21:30:29 -05:00
}
} while ( Token ! = TokenCloseBracket ) ;
2009-02-18 03:19:06 -05:00
if ( Parser - > Mode = = RunModeRun )
2009-02-02 06:08:36 -05:00
{ /* run the function */
2009-02-19 18:29:35 -05:00
if ( ArgCount < FuncValue - > Val - > FuncDef . NumParams )
ProgramFail ( Parser , " not enough arguments to '%s' " , FuncName ) ;
2008-12-23 21:30:29 -05:00
2009-02-19 18:29:35 -05:00
TopStackFrame - > NumParams = ArgCount ;
2009-02-02 06:08:36 -05:00
if ( FuncValue - > Val - > FuncDef . Intrinsic = = NULL )
2009-01-26 03:57:32 -05:00
{ /* run a user-defined function */
2009-02-02 06:08:36 -05:00
struct ParseState FuncParser = FuncValue - > Val - > FuncDef . Body ;
2009-02-18 03:19:06 -05:00
if ( ! ParseStatement ( & FuncParser ) )
2009-02-02 06:08:36 -05:00
ProgramFail ( & FuncParser , " function body expected " ) ;
2008-12-23 21:30:29 -05:00
2009-02-02 06:08:36 -05:00
if ( FuncValue - > Val - > FuncDef . ReturnType ! = ( * Result ) - > Typ )
ProgramFail ( & FuncParser , " bad type of return value " ) ;
2008-12-26 23:36:45 -05:00
}
else
2009-02-02 06:08:36 -05:00
FuncValue - > Val - > FuncDef . Intrinsic ( ) ;
2009-02-19 18:29:35 -05:00
VariableStackFramePop ( Parser ) ;
2008-12-23 21:30:29 -05:00
}
}
2008-12-18 19:22:52 -05:00
/* parse a single value */
2009-02-19 18:29:35 -05:00
int ParseValue ( struct ParseState * Parser , struct Value * * Result )
2008-10-16 03:04:23 -04:00
{
2009-02-01 06:31:18 -05:00
struct ParseState PreState = * Parser ;
2009-01-26 03:57:32 -05:00
struct Value * LexValue ;
int IntValue ;
2009-02-01 06:31:18 -05:00
enum LexToken Token = LexGetToken ( Parser , & LexValue , TRUE ) ;
2009-02-03 19:17:30 -05:00
struct Value * LocalLValue = NULL ;
2009-02-11 01:42:30 -05:00
struct ValueType * VType ;
2009-02-03 19:17:30 -05:00
int Success = TRUE ;
2008-10-16 03:04:23 -04:00
2008-11-21 21:56:08 -05:00
switch ( Token )
{
2009-01-26 03:57:32 -05:00
case TokenIntegerConstant : case TokenCharacterConstant : case TokenFPConstant : case TokenStringConstant :
2009-02-19 18:29:35 -05:00
* Result = VariableAllocValueAndCopy ( Parser , LexValue , FALSE ) ;
2009-01-26 03:57:32 -05:00
break ;
2008-11-21 21:56:08 -05:00
case TokenMinus : case TokenUnaryExor : case TokenUnaryNot :
2009-02-18 03:19:06 -05:00
IntValue = ParseIntExpression ( Parser ) ;
if ( Parser - > Mode = = RunModeRun )
2008-11-21 21:56:08 -05:00
{
2009-02-19 18:29:35 -05:00
* Result = VariableAllocValueFromType ( Parser , & IntType , FALSE ) ;
2008-12-20 22:46:32 -05:00
switch ( Token )
{
2009-01-26 03:57:32 -05:00
case TokenMinus : ( * Result ) - > Val - > Integer = - IntValue ; break ;
case TokenUnaryExor : ( * Result ) - > Val - > Integer = ~ IntValue ; break ;
case TokenUnaryNot : ( * Result ) - > Val - > Integer = ! IntValue ; break ;
2008-12-20 22:46:32 -05:00
default : break ;
}
2008-11-21 21:56:08 -05:00
}
break ;
case TokenOpenBracket :
2009-02-19 18:29:35 -05:00
if ( ! ParseExpression ( Parser , Result ) )
2009-02-01 06:31:18 -05:00
ProgramFail ( Parser , " invalid expression " ) ;
2008-11-21 21:56:08 -05:00
2009-02-01 06:31:18 -05:00
if ( LexGetToken ( Parser , NULL , TRUE ) ! = TokenCloseBracket )
ProgramFail ( Parser , " ')' expected " ) ;
2008-11-21 21:56:08 -05:00
break ;
case TokenAsterisk :
2009-02-19 18:29:35 -05:00
if ( ! ParseExpression ( Parser , Result ) )
2009-02-11 01:42:30 -05:00
ProgramFail ( Parser , " invalid expression " ) ;
if ( ( * Result ) - > Typ - > Base ! = TypePointer )
ProgramFail ( Parser , " can't dereference this non-pointer " ) ;
LocalLValue = ( * Result ) - > Val - > Pointer . Segment ;
VariableStackPop ( Parser , * Result ) ;
2009-02-19 18:29:35 -05:00
* Result = VariableAllocValueShared ( Parser , LocalLValue ) ;
2009-02-11 01:42:30 -05:00
break ;
2008-11-21 21:56:08 -05:00
2009-02-10 06:19:48 -05:00
case TokenAmpersand :
2009-02-19 18:29:35 -05:00
if ( ! ParseValue ( Parser , Result ) | | ! ( * Result ) - > IsLValue )
2009-02-10 06:19:48 -05:00
ProgramFail ( Parser , " can't get the address of this " ) ;
2009-02-11 01:42:30 -05:00
VType = ( * Result ) - > Typ ;
2009-02-10 06:19:48 -05:00
VariableStackPop ( Parser , * Result ) ;
2009-02-19 18:29:35 -05:00
* Result = VariableAllocValueFromType ( Parser , TypeGetMatching ( Parser , VType , TypePointer , 0 , StrEmpty ) , FALSE ) ;
2009-02-10 06:19:48 -05:00
( * Result ) - > Val - > Pointer . Segment = LocalLValue ;
2009-02-10 17:25:20 -05:00
( * Result ) - > Val - > Pointer . Data . Offset = 0 ;
2009-02-10 06:19:48 -05:00
break ;
2008-11-21 21:56:08 -05:00
case TokenIdentifier :
2009-02-01 06:31:18 -05:00
if ( LexGetToken ( Parser , NULL , FALSE ) = = TokenOpenBracket )
2009-02-19 18:29:35 -05:00
ParseFunctionCall ( Parser , Result , LexValue - > Val - > String ) ;
2008-12-23 21:30:29 -05:00
else
{
2009-02-18 03:19:06 -05:00
if ( Parser - > Mode = = RunModeRun )
2009-01-03 23:08:49 -05:00
{
2009-02-03 19:17:30 -05:00
VariableGet ( Parser , LexValue - > Val - > String , & LocalLValue ) ;
if ( LocalLValue - > Typ - > Base = = TypeMacro )
2009-01-04 23:28:54 -05:00
{
2009-02-03 19:17:30 -05:00
struct ParseState MacroLexer = LocalLValue - > Val - > Parser ;
2009-01-04 23:28:54 -05:00
2009-02-19 18:29:35 -05:00
if ( ! ParseExpression ( & MacroLexer , Result ) )
2009-01-04 23:28:54 -05:00
ProgramFail ( & MacroLexer , " expression expected " ) ;
}
2009-02-10 03:42:09 -05:00
else if ( LocalLValue - > Typ = = TypeVoid )
ProgramFail ( Parser , " a void value isn't much use here " ) ;
2009-02-03 19:17:30 -05:00
else
2009-02-12 07:15:25 -05:00
{ /* it's a value variable */
2009-02-19 18:29:35 -05:00
* Result = VariableAllocValueShared ( Parser , LocalLValue ) ;
2009-02-12 07:15:25 -05:00
}
}
/* see if there's a postfix operator */
Token = LexGetToken ( Parser , & LexValue , FALSE ) ;
if ( Token = = TokenIncrement | | Token = = TokenDecrement )
{ /* it's a postincrement or postdecrement */
LexGetToken ( Parser , & LexValue , TRUE ) ;
2009-02-18 03:19:06 -05:00
if ( Parser - > Mode = = RunModeRun )
2009-02-12 07:15:25 -05:00
{
2009-02-15 00:52:03 -05:00
if ( ! ( * Result ) - > IsLValue | | ( * Result ) - > Typ - > Base ! = TypeInt )
2009-02-12 07:15:25 -05:00
ProgramFail ( Parser , " can't %s this " , ( Token = = TokenIncrement ) ? " increment " : " decrement " ) ;
if ( Token = = TokenIncrement )
2009-02-15 00:52:03 -05:00
( * Result ) - > Val - > Integer + + ;
2009-02-12 07:15:25 -05:00
else
2009-02-15 00:52:03 -05:00
( * Result ) - > Val - > Integer - - ;
2009-02-12 07:15:25 -05:00
}
2009-01-03 23:08:49 -05:00
}
2009-02-15 01:46:37 -05:00
else if ( Token = = TokenLeftSquareBracket )
{ /* array access */
LexGetToken ( Parser , & LexValue , TRUE ) ;
2009-02-18 03:19:06 -05:00
IntValue = ParseIntExpression ( Parser ) ;
2009-02-15 01:46:37 -05:00
if ( LexGetToken ( Parser , & LexValue , TRUE ) ! = TokenRightSquareBracket )
ProgramFail ( Parser , " expected ']' " ) ;
2009-02-18 03:19:06 -05:00
if ( Parser - > Mode = = RunModeRun )
2009-02-15 01:46:37 -05:00
{ /* look up the array element */
if ( ( * Result ) - > Typ - > Base ! = TypeArray )
ProgramFail ( Parser , " not an array " ) ;
if ( IntValue < 0 | | IntValue > = ( * Result ) - > Typ - > ArraySize )
ProgramFail ( Parser , " illegal array index " ) ;
VariableStackPop ( Parser , * Result ) ;
2009-02-19 18:29:35 -05:00
* Result = VariableAllocValueFromExistingData ( Parser , ( * Result ) - > Typ - > FromType , ( union AnyValue * ) ( ( void * ) ( * Result ) - > Val + ( * Result ) - > Typ - > FromType - > Sizeof * IntValue ) , TRUE ) ;
2009-02-15 01:46:37 -05:00
}
}
2008-12-23 21:30:29 -05:00
}
2008-11-21 21:56:08 -05:00
break ;
default :
2009-02-01 06:31:18 -05:00
* Parser = PreState ;
2009-02-03 19:17:30 -05:00
Success = FALSE ;
break ;
2008-11-21 21:56:08 -05:00
}
2008-10-16 03:04:23 -04:00
2009-02-03 19:17:30 -05:00
return Success ;
2008-11-21 21:56:08 -05:00
}
2009-02-19 18:29:35 -05:00
struct Value * ParsePushFP ( struct ParseState * Parser , double NewFP )
2009-01-26 03:57:32 -05:00
{
2009-02-19 18:29:35 -05:00
struct Value * Val = VariableAllocValueFromType ( Parser , & FPType , FALSE ) ;
2009-01-26 03:57:32 -05:00
Val - > Val - > FP = NewFP ;
return Val ;
}
2009-02-19 18:29:35 -05:00
struct Value * ParsePushInt ( struct ParseState * Parser , int NewInt )
2009-01-26 03:57:32 -05:00
{
2009-02-19 18:29:35 -05:00
struct Value * Val = VariableAllocValueFromType ( Parser , & IntType , FALSE ) ;
2009-01-26 03:57:32 -05:00
Val - > Val - > Integer = NewInt ;
return Val ;
}
2008-12-18 19:22:52 -05:00
/* parse an expression. operator precedence is not supported */
2009-02-19 18:29:35 -05:00
int ParseExpression ( struct ParseState * Parser , struct Value * * Result )
2008-11-21 21:56:08 -05:00
{
2009-01-26 03:57:32 -05:00
struct Value * CurrentValue ;
struct Value * TotalValue ;
2008-11-21 21:56:08 -05:00
2009-02-19 18:29:35 -05:00
if ( ! ParseValue ( Parser , & TotalValue ) )
2008-11-21 21:56:08 -05:00
return FALSE ;
while ( TRUE )
2008-10-16 03:04:23 -04:00
{
2009-02-01 06:31:18 -05:00
enum LexToken Token = LexGetToken ( Parser , NULL , FALSE ) ;
2008-11-21 21:56:08 -05:00
switch ( Token )
{
case TokenPlus : case TokenMinus : case TokenAsterisk : case TokenSlash :
case TokenEquality : case TokenLessThan : case TokenGreaterThan :
case TokenLessEqual : case TokenGreaterEqual : case TokenLogicalAnd :
2008-12-20 05:24:34 -05:00
case TokenLogicalOr : case TokenAmpersand : case TokenArithmeticOr :
2009-02-09 06:40:56 -05:00
case TokenArithmeticExor :
2009-02-01 06:31:18 -05:00
LexGetToken ( Parser , NULL , TRUE ) ;
2008-11-21 21:56:08 -05:00
break ;
2009-02-09 06:40:56 -05:00
case TokenDot :
{
struct Value * Ident ;
LexGetToken ( Parser , NULL , TRUE ) ;
if ( LexGetToken ( Parser , & Ident , TRUE ) ! = TokenIdentifier )
ProgramFail ( Parser , " need an structure or union member after '.' " ) ;
2009-02-18 03:19:06 -05:00
if ( Parser - > Mode = = RunModeRun )
2009-02-09 06:40:56 -05:00
{
void * TotalValueData = ( void * ) TotalValue - > Val ;
2009-02-10 03:42:09 -05:00
if ( TotalValue - > Typ - > Base ! = TypeStruct & & TotalValue - > Typ - > Base ! = TypeUnion )
2009-02-09 06:40:56 -05:00
ProgramFail ( Parser , " can't use '.' on something that's not a struct or union " ) ;
2008-12-20 05:24:34 -05:00
2009-02-09 06:40:56 -05:00
if ( ! TableGet ( TotalValue - > Typ - > Members , Ident - > Val - > String , & CurrentValue ) )
ProgramFail ( Parser , " structure doesn't have a member called '%s' " , Ident - > Val - > String ) ;
VariableStackPop ( Parser , TotalValue ) ;
2009-02-19 18:29:35 -05:00
TotalValue = VariableAllocValueFromExistingData ( Parser , CurrentValue - > Typ , TotalValueData + CurrentValue - > Val - > Integer , TRUE ) ;
2009-02-09 06:40:56 -05:00
}
2009-02-10 03:42:09 -05:00
continue ;
2009-02-09 06:40:56 -05:00
}
2008-12-20 05:24:34 -05:00
case TokenAssign : case TokenAddAssign : case TokenSubtractAssign :
2009-02-01 06:31:18 -05:00
LexGetToken ( Parser , NULL , TRUE ) ;
2009-02-19 18:29:35 -05:00
if ( ! ParseExpression ( Parser , & CurrentValue ) )
2009-02-01 06:31:18 -05:00
ProgramFail ( Parser , " expression expected " ) ;
2008-12-20 05:24:34 -05:00
2009-02-18 03:19:06 -05:00
if ( Parser - > Mode = = RunModeRun )
2008-12-20 05:24:34 -05:00
{
2009-02-15 00:52:03 -05:00
if ( CurrentValue - > Typ - > Base ! = TypeInt | | ! TotalValue - > IsLValue | | TotalValue - > Typ - > Base ! = TypeInt )
2009-02-01 06:31:18 -05:00
ProgramFail ( Parser , " can't assign " ) ;
2008-12-20 22:46:32 -05:00
switch ( Token )
{
2009-02-15 00:52:03 -05:00
case TokenAddAssign : TotalValue - > Val - > Integer + = CurrentValue - > Val - > Integer ; break ;
case TokenSubtractAssign : TotalValue - > Val - > Integer - = CurrentValue - > Val - > Integer ; break ;
default : TotalValue - > Val - > Integer = CurrentValue - > Val - > Integer ; break ;
2008-12-20 22:46:32 -05:00
}
2009-02-01 06:31:18 -05:00
VariableStackPop ( Parser , CurrentValue ) ;
2008-12-20 05:24:34 -05:00
}
// fallthrough
2008-11-21 21:56:08 -05:00
default :
2009-02-18 03:19:06 -05:00
if ( Parser - > Mode = = RunModeRun )
2008-12-20 22:46:32 -05:00
* Result = TotalValue ;
2008-11-21 21:56:08 -05:00
return TRUE ;
}
2009-02-19 18:29:35 -05:00
if ( ! ParseValue ( Parser , & CurrentValue ) )
2008-11-21 21:56:08 -05:00
return FALSE ;
2008-12-20 05:24:34 -05:00
2009-02-18 03:19:06 -05:00
if ( Parser - > Mode = = RunModeRun )
2008-10-16 03:04:23 -04:00
{
2009-01-26 03:57:32 -05:00
if ( CurrentValue - > Typ - > Base = = TypeFP | | TotalValue - > Typ - > Base = = TypeFP )
2009-02-15 01:46:37 -05:00
{ /* floating point expression */
2009-02-15 01:16:54 -05:00
double FPTotal , FPCurrent , FPResult ;
2008-12-26 21:25:49 -05:00
2009-01-26 03:57:32 -05:00
if ( CurrentValue - > Typ - > Base ! = TypeFP | | TotalValue - > Typ - > Base ! = TypeFP )
{ /* convert both to floating point */
if ( CurrentValue - > Typ - > Base = = TypeInt )
FPCurrent = ( double ) CurrentValue - > Val - > Integer ;
else if ( CurrentValue - > Typ - > Base = = TypeFP )
FPCurrent = CurrentValue - > Val - > FP ;
else
2009-02-01 06:31:18 -05:00
ProgramFail ( Parser , " bad type for operator " ) ;
2009-01-26 03:57:32 -05:00
if ( TotalValue - > Typ - > Base = = TypeInt )
FPTotal = ( double ) TotalValue - > Val - > Integer ;
else if ( TotalValue - > Typ - > Base = = TypeFP )
FPTotal = TotalValue - > Val - > FP ;
else
2009-02-01 06:31:18 -05:00
ProgramFail ( Parser , " bad type for operator " ) ;
2009-01-26 03:57:32 -05:00
}
2009-02-01 06:31:18 -05:00
VariableStackPop ( Parser , CurrentValue ) ;
VariableStackPop ( Parser , TotalValue ) ;
2009-01-26 03:57:32 -05:00
2008-12-26 21:25:49 -05:00
switch ( Token )
{
2009-02-15 01:16:54 -05:00
case TokenPlus : FPResult = FPTotal + FPCurrent ; break ;
case TokenMinus : FPResult = FPTotal - FPCurrent ; break ;
case TokenAsterisk : FPResult = FPTotal * FPCurrent ; break ;
case TokenSlash : FPResult = FPTotal / FPCurrent ; break ;
case TokenEquality : FPResult = FPTotal = = FPCurrent ; break ;
case TokenLessThan : FPResult = FPTotal < FPCurrent ; break ;
case TokenGreaterThan : FPResult = FPTotal > FPCurrent ; break ;
case TokenLessEqual : FPResult = FPTotal < = FPCurrent ; break ;
case TokenGreaterEqual : FPResult = FPTotal > = FPCurrent ; break ;
2009-02-01 06:31:18 -05:00
case TokenLogicalAnd : case TokenLogicalOr : case TokenAmpersand : case TokenArithmeticOr : case TokenArithmeticExor : ProgramFail ( Parser , " bad type for operator " ) ; break ;
2008-12-26 21:25:49 -05:00
default : break ;
}
2009-02-19 18:29:35 -05:00
TotalValue = ParsePushFP ( Parser , FPResult ) ;
2008-12-26 21:25:49 -05:00
}
else
2009-02-15 01:46:37 -05:00
{ /* integer expression */
2009-02-15 01:16:54 -05:00
int IntX , IntY , IntResult ;
2009-01-26 03:57:32 -05:00
if ( CurrentValue - > Typ - > Base ! = TypeInt | | TotalValue - > Typ - > Base ! = TypeInt )
2009-02-01 06:31:18 -05:00
ProgramFail ( Parser , " bad operand types " ) ;
2008-12-26 21:25:49 -05:00
2009-02-15 01:16:54 -05:00
IntX = TotalValue - > Val - > Integer ;
IntY = CurrentValue - > Val - > Integer ;
VariableStackPop ( Parser , CurrentValue ) ;
VariableStackPop ( Parser , TotalValue ) ;
2008-12-26 21:25:49 -05:00
/* integer arithmetic */
switch ( Token )
{
2009-02-15 01:16:54 -05:00
case TokenPlus : IntResult = IntX + IntY ; break ;
case TokenMinus : IntResult = IntX - IntY ; break ;
case TokenAsterisk : IntResult = IntX * IntY ; break ;
case TokenSlash : IntResult = IntX / IntY ; break ;
case TokenEquality : IntResult = IntX = = IntY ; break ;
case TokenLessThan : IntResult = IntX < IntY ; break ;
case TokenGreaterThan : IntResult = IntX > IntY ; break ;
case TokenLessEqual : IntResult = IntX < = IntY ; break ;
case TokenGreaterEqual : IntResult = IntX > = IntY ; break ;
case TokenLogicalAnd : IntResult = IntX & & IntY ; break ;
case TokenLogicalOr : IntResult = IntX | | IntY ; break ;
case TokenAmpersand : IntResult = IntX & IntY ; break ;
case TokenArithmeticOr : IntResult = IntX | IntY ; break ;
case TokenArithmeticExor : IntResult = IntX ^ IntY ; break ;
2008-12-26 21:25:49 -05:00
default : break ;
}
2009-02-19 18:29:35 -05:00
TotalValue = ParsePushInt ( Parser , IntResult ) ;
2008-12-20 22:46:32 -05:00
}
2009-02-15 01:16:54 -05:00
2009-01-26 03:57:32 -05:00
* Result = TotalValue ;
2008-11-21 21:56:08 -05:00
}
}
return TRUE ;
}
2008-12-18 19:22:52 -05:00
/* parse an expression. operator precedence is not supported */
2009-02-18 03:19:06 -05:00
int ParseIntExpression ( struct ParseState * Parser )
2008-12-18 19:22:52 -05:00
{
2009-01-26 03:57:32 -05:00
struct Value * Val ;
int Result = 0 ;
2009-02-19 18:29:35 -05:00
if ( ! ParseExpression ( Parser , & Val ) )
2009-02-01 06:31:18 -05:00
ProgramFail ( Parser , " expression expected " ) ;
2008-12-18 19:22:52 -05:00
2009-02-18 03:19:06 -05:00
if ( Parser - > Mode = = RunModeRun )
2009-01-26 03:57:32 -05:00
{
if ( Val - > Typ - > Base ! = TypeInt )
2009-02-01 06:31:18 -05:00
ProgramFail ( Parser , " integer value expected " ) ;
2009-01-26 03:57:32 -05:00
Result = Val - > Val - > Integer ;
2009-02-01 06:31:18 -05:00
VariableStackPop ( Parser , Val ) ;
2009-01-26 03:57:32 -05:00
}
return Result ;
2008-12-18 19:22:52 -05:00
}
2008-11-21 21:56:08 -05:00
2008-12-20 20:36:09 -05:00
/* parse a function definition and store it for later */
2009-02-02 06:08:36 -05:00
struct Value * ParseFunctionDefinition ( struct ParseState * Parser , struct ValueType * ReturnType , const char * Identifier , int IsPrototype )
2008-12-20 06:46:21 -05:00
{
2009-02-02 06:08:36 -05:00
struct ValueType * ParamType ;
const char * ParamIdentifier ;
2009-02-01 06:31:18 -05:00
enum LexToken Token ;
struct Value * FuncValue ;
struct ParseState ParamParser ;
int ParamCount = 0 ;
2008-12-20 20:36:09 -05:00
2009-02-01 06:31:18 -05:00
LexGetToken ( Parser , NULL , TRUE ) ; /* open bracket */
ParamParser = * Parser ;
Token = LexGetToken ( Parser , NULL , TRUE ) ;
if ( Token ! = TokenCloseBracket & & Token ! = TokenEOF )
{ /* count the number of parameters */
ParamCount + + ;
while ( ( Token = LexGetToken ( Parser , NULL , TRUE ) ) ! = TokenCloseBracket & & Token ! = TokenEOF )
{
if ( Token = = TokenComma )
ParamCount + + ;
}
}
2009-02-02 06:08:36 -05:00
if ( ParamCount > PARAMETER_MAX )
ProgramFail ( Parser , " too many parameters " ) ;
2008-12-20 20:36:09 -05:00
2009-02-15 00:52:03 -05:00
FuncValue = VariableAllocValueAndData ( Parser , sizeof ( struct FuncDef ) + sizeof ( struct ValueType * ) * ParamCount + sizeof ( const char * ) * ParamCount , FALSE , TRUE ) ;
2009-01-21 04:02:05 -05:00
FuncValue - > Typ = & FunctionType ;
2009-02-01 06:31:18 -05:00
FuncValue - > Val - > FuncDef . ReturnType = ReturnType ;
FuncValue - > Val - > FuncDef . NumParams = ParamCount ;
FuncValue - > Val - > FuncDef . ParamType = ( void * ) FuncValue - > Val + sizeof ( struct FuncDef ) ;
FuncValue - > Val - > FuncDef . ParamName = ( void * ) FuncValue - > Val - > FuncDef . ParamType + sizeof ( struct ValueType * ) * ParamCount ;
FuncValue - > Val - > FuncDef . Body = * Parser ;
for ( ParamCount = 0 ; ParamCount < FuncValue - > Val - > FuncDef . NumParams ; ParamCount + + )
{ /* harvest the parameters into the function definition */
2009-02-02 06:08:36 -05:00
TypeParse ( & ParamParser , & ParamType , & ParamIdentifier ) ;
FuncValue - > Val - > FuncDef . ParamType [ ParamCount ] = ParamType ;
FuncValue - > Val - > FuncDef . ParamName [ ParamCount ] = ParamIdentifier ;
2009-02-01 06:31:18 -05:00
2009-02-02 06:08:36 -05:00
Token = LexGetToken ( & ParamParser , NULL , TRUE ) ;
2009-02-03 05:39:48 -05:00
if ( Token ! = TokenComma & & ParamCount ! = FuncValue - > Val - > FuncDef . NumParams - 1 )
2009-02-02 06:08:36 -05:00
ProgramFail ( & ParamParser , " comma expected " ) ;
2009-02-01 06:31:18 -05:00
}
2009-02-01 22:27:05 -05:00
if ( ! IsPrototype )
{
if ( LexGetToken ( Parser , NULL , FALSE ) ! = TokenLeftBrace )
ProgramFail ( Parser , " bad function definition " ) ;
2009-02-18 03:19:06 -05:00
if ( ! ParseStatementMaybeRun ( Parser , FALSE ) )
2009-02-01 22:27:05 -05:00
ProgramFail ( Parser , " function definition expected " ) ;
}
2009-01-21 04:02:05 -05:00
if ( ! TableSet ( & GlobalTable , Identifier , FuncValue ) )
2009-02-02 06:08:36 -05:00
ProgramFail ( Parser , " '%s' is already defined " , Identifier ) ;
2009-02-01 22:27:05 -05:00
return FuncValue ;
2008-12-20 06:46:21 -05:00
}
2009-01-04 23:28:54 -05:00
/* parse a #define macro definition and store it for later */
2009-02-01 06:31:18 -05:00
void ParseMacroDefinition ( struct ParseState * Parser )
2009-01-04 23:28:54 -05:00
{
2009-01-26 03:57:32 -05:00
struct Value * MacroName ;
2009-02-15 00:52:03 -05:00
struct Value * MacroValue = VariableAllocValueAndData ( Parser , sizeof ( struct ParseState ) , FALSE , TRUE ) ;
2009-01-04 23:28:54 -05:00
2009-02-01 06:31:18 -05:00
if ( LexGetToken ( Parser , & MacroName , TRUE ) ! = TokenIdentifier )
ProgramFail ( Parser , " identifier expected " ) ;
2009-01-04 23:28:54 -05:00
2009-02-01 06:31:18 -05:00
MacroValue - > Val - > Parser = * Parser ;
2009-01-21 04:02:05 -05:00
MacroValue - > Typ = & MacroType ;
2009-01-04 23:28:54 -05:00
2009-02-02 06:08:36 -05:00
if ( ! TableSet ( & GlobalTable , MacroName - > Val - > String , MacroValue ) )
ProgramFail ( Parser , " '%s' is already defined " , & MacroName - > Val - > String ) ;
2009-01-04 23:28:54 -05:00
}
2009-02-19 04:07:00 -05:00
/* copy where we're at in the parsing */
void ParserCopyPos ( struct ParseState * To , struct ParseState * From )
{
To - > Pos = From - > Pos ;
To - > Line = From - > Line ;
}
2009-02-12 07:15:25 -05:00
/* parse a "for" statement */
2009-02-18 03:19:06 -05:00
void ParseFor ( struct ParseState * Parser )
2009-01-03 23:08:49 -05:00
{
2009-01-26 03:57:32 -05:00
int Condition ;
2009-02-01 06:31:18 -05:00
struct ParseState PreConditional ;
struct ParseState PreIncrement ;
struct ParseState PreStatement ;
struct ParseState After ;
2009-01-03 23:08:49 -05:00
2009-02-01 06:31:18 -05:00
if ( LexGetToken ( Parser , NULL , TRUE ) ! = TokenOpenBracket )
ProgramFail ( Parser , " '(' expected " ) ;
2009-01-03 23:08:49 -05:00
2009-02-18 03:19:06 -05:00
if ( ! ParseStatement ( Parser ) )
2009-02-01 06:31:18 -05:00
ProgramFail ( Parser , " statement expected " ) ;
2009-01-03 23:08:49 -05:00
2009-02-12 07:15:25 -05:00
if ( LexGetToken ( Parser , NULL , TRUE ) ! = TokenSemicolon )
ProgramFail ( Parser , " ';' expected " ) ;
2009-02-19 04:07:00 -05:00
ParserCopyPos ( & PreConditional , Parser ) ;
2009-02-18 03:19:06 -05:00
Condition = ParseIntExpression ( Parser ) ;
2009-01-03 23:08:49 -05:00
2009-02-01 06:31:18 -05:00
if ( LexGetToken ( Parser , NULL , TRUE ) ! = TokenSemicolon )
ProgramFail ( Parser , " ';' expected " ) ;
2009-01-03 23:08:49 -05:00
2009-02-19 04:07:00 -05:00
ParserCopyPos ( & PreIncrement , Parser ) ;
2009-02-18 03:19:06 -05:00
ParseStatementMaybeRun ( Parser , FALSE ) ;
2009-01-03 23:08:49 -05:00
2009-02-01 06:31:18 -05:00
if ( LexGetToken ( Parser , NULL , TRUE ) ! = TokenCloseBracket )
ProgramFail ( Parser , " ')' expected " ) ;
2009-01-03 23:08:49 -05:00
2009-02-19 04:07:00 -05:00
ParserCopyPos ( & PreStatement , Parser ) ;
2009-02-18 03:19:06 -05:00
if ( ! ParseStatementMaybeRun ( Parser , Condition ) )
2009-02-01 06:31:18 -05:00
ProgramFail ( Parser , " statement expected " ) ;
2009-01-03 23:08:49 -05:00
2009-02-19 04:07:00 -05:00
if ( Parser - > Mode = = RunModeContinue )
Parser - > Mode = RunModeRun ;
ParserCopyPos ( & After , Parser ) ;
2009-02-18 03:19:06 -05:00
while ( Condition & & Parser - > Mode = = RunModeRun )
2009-01-03 23:08:49 -05:00
{
2009-02-19 04:07:00 -05:00
ParserCopyPos ( Parser , & PreIncrement ) ;
2009-02-18 03:19:06 -05:00
ParseStatement ( Parser ) ;
2009-01-03 23:08:49 -05:00
2009-02-19 04:07:00 -05:00
ParserCopyPos ( Parser , & PreConditional ) ;
2009-02-18 03:19:06 -05:00
Condition = ParseIntExpression ( Parser ) ;
2009-01-03 23:08:49 -05:00
2009-01-26 03:57:32 -05:00
if ( Condition )
2009-01-03 23:08:49 -05:00
{
2009-02-19 04:07:00 -05:00
ParserCopyPos ( Parser , & PreStatement ) ;
2009-02-18 03:19:06 -05:00
ParseStatement ( Parser ) ;
2009-02-19 04:07:00 -05:00
if ( Parser - > Mode = = RunModeContinue )
Parser - > Mode = RunModeRun ;
2009-01-03 23:08:49 -05:00
}
}
2009-02-19 04:07:00 -05:00
if ( Parser - > Mode = = RunModeBreak )
Parser - > Mode = RunModeRun ;
ParserCopyPos ( Parser , & After ) ;
2009-01-03 23:08:49 -05:00
}
2009-02-18 03:19:06 -05:00
/* parse a statement, but only run it if Condition is TRUE */
int ParseStatementMaybeRun ( struct ParseState * Parser , int Condition )
{
if ( Parser - > Mode ! = RunModeSkip & & ! Condition )
{
enum RunMode OldMode = Parser - > Mode ;
Parser - > Mode = RunModeSkip ;
int Result = ParseStatement ( Parser ) ;
Parser - > Mode = OldMode ;
return Result ;
}
else
return ParseStatement ( Parser ) ;
}
2009-02-19 04:07:00 -05:00
/* parse a block of code and return what mode it returned in */
enum RunMode ParseBlock ( struct ParseState * Parser , int AbsorbOpenBrace , int Condition )
{
if ( AbsorbOpenBrace & & LexGetToken ( Parser , NULL , TRUE ) ! = TokenLeftBrace )
ProgramFail ( Parser , " '{' expected " ) ;
if ( Parser - > Mode ! = RunModeSkip & & ! Condition )
{ /* condition failed - skip this block instead */
enum RunMode OldMode = Parser - > Mode ;
Parser - > Mode = RunModeSkip ;
while ( ParseStatement ( Parser ) )
{ }
Parser - > Mode = OldMode ;
}
else
{ /* just run it in its current mode */
while ( ParseStatement ( Parser ) )
{ }
}
if ( LexGetToken ( Parser , NULL , TRUE ) ! = TokenRightBrace )
ProgramFail ( Parser , " '}' expected " ) ;
return Parser - > Mode ;
}
2008-12-18 19:22:52 -05:00
/* parse a statement */
2009-02-18 03:19:06 -05:00
int ParseStatement ( struct ParseState * Parser )
2008-11-21 21:56:08 -05:00
{
2009-01-26 03:57:32 -05:00
struct Value * CValue ;
int Condition ;
2009-02-01 06:31:18 -05:00
struct ParseState PreState = * Parser ;
2009-02-02 06:08:36 -05:00
const char * Identifier ;
2009-01-21 04:02:05 -05:00
struct ValueType * Typ ;
2009-02-01 06:31:18 -05:00
enum LexToken Token = LexGetToken ( Parser , NULL , TRUE ) ;
2008-11-21 21:56:08 -05:00
switch ( Token )
{
2008-12-20 05:24:34 -05:00
case TokenEOF :
return FALSE ;
2008-11-21 21:56:08 -05:00
case TokenIdentifier :
2009-02-01 06:31:18 -05:00
* Parser = PreState ;
2009-02-19 18:29:35 -05:00
ParseExpression ( Parser , & CValue ) ;
2009-02-18 03:19:06 -05:00
if ( Parser - > Mode = = RunModeRun )
2009-02-12 07:15:25 -05:00
VariableStackPop ( Parser , CValue ) ;
2008-11-21 21:56:08 -05:00
break ;
case TokenLeftBrace :
2009-02-19 04:07:00 -05:00
ParseBlock ( Parser , FALSE , TRUE ) ;
2008-11-21 21:56:08 -05:00
break ;
case TokenIf :
2009-02-18 06:03:14 -05:00
if ( LexGetToken ( Parser , NULL , TRUE ) ! = TokenOpenBracket )
2009-02-17 18:36:09 -05:00
ProgramFail ( Parser , " '(' expected " ) ;
2009-02-18 03:19:06 -05:00
Condition = ParseIntExpression ( Parser ) ;
2008-11-21 21:56:08 -05:00
2009-02-18 06:03:14 -05:00
if ( LexGetToken ( Parser , NULL , TRUE ) ! = TokenCloseBracket )
2009-02-17 18:36:09 -05:00
ProgramFail ( Parser , " ')' expected " ) ;
2009-02-18 03:19:06 -05:00
if ( ! ParseStatementMaybeRun ( Parser , Condition ) )
2009-02-01 06:31:18 -05:00
ProgramFail ( Parser , " statement expected " ) ;
2008-11-21 21:56:08 -05:00
2009-02-01 06:31:18 -05:00
if ( LexGetToken ( Parser , NULL , FALSE ) = = TokenElse )
2008-11-21 21:56:08 -05:00
{
2009-02-01 06:31:18 -05:00
LexGetToken ( Parser , NULL , TRUE ) ;
2009-02-18 03:19:06 -05:00
if ( ! ParseStatementMaybeRun ( Parser , ! Condition ) )
2009-02-01 06:31:18 -05:00
ProgramFail ( Parser , " statement expected " ) ;
2008-11-21 21:56:08 -05:00
}
2008-10-16 03:04:23 -04:00
break ;
2008-11-21 21:56:08 -05:00
case TokenWhile :
2008-10-16 03:04:23 -04:00
{
2009-02-19 04:07:00 -05:00
struct ParseState PreConditional ;
ParserCopyPos ( & PreConditional , Parser ) ;
2008-11-21 21:56:08 -05:00
do
{
2009-02-19 04:07:00 -05:00
ParserCopyPos ( Parser , & PreConditional ) ;
2009-02-18 03:19:06 -05:00
Condition = ParseIntExpression ( Parser ) ;
2009-02-19 04:07:00 -05:00
ParseBlock ( Parser , TRUE , Condition ) ;
if ( Parser - > Mode = = RunModeContinue )
Parser - > Mode = RunModeRun ;
} while ( Parser - > Mode = = RunModeRun & & Condition ) ;
2008-11-21 21:56:08 -05:00
2009-02-19 04:07:00 -05:00
if ( Parser - > Mode = = RunModeBreak )
Parser - > Mode = RunModeRun ;
2008-11-21 21:56:08 -05:00
}
break ;
case TokenDo :
{
2009-02-19 04:07:00 -05:00
struct ParseState PreStatement ;
ParserCopyPos ( & PreStatement , Parser ) ;
2008-11-21 21:56:08 -05:00
do
{
2009-02-19 04:07:00 -05:00
ParserCopyPos ( Parser , & PreStatement ) ;
ParseBlock ( Parser , TRUE , TRUE ) ;
if ( Parser - > Mode = = RunModeContinue )
Parser - > Mode = RunModeRun ;
2009-02-19 06:01:14 -05:00
if ( LexGetToken ( Parser , NULL , TRUE ) ! = TokenWhile )
ProgramFail ( Parser , " 'while' expected " ) ;
2009-02-18 03:19:06 -05:00
Condition = ParseIntExpression ( Parser ) ;
2008-11-21 21:56:08 -05:00
2009-02-18 03:19:06 -05:00
} while ( Condition & & Parser - > Mode = = RunModeRun ) ;
2009-02-19 04:07:00 -05:00
if ( Parser - > Mode = = RunModeBreak )
Parser - > Mode = RunModeRun ;
2008-11-21 21:56:08 -05:00
}
break ;
case TokenFor :
2009-02-18 03:19:06 -05:00
ParseFor ( Parser ) ;
2008-11-21 21:56:08 -05:00
break ;
case TokenSemicolon : break ;
case TokenIntType :
case TokenCharType :
2008-12-26 21:25:49 -05:00
case TokenFloatType :
case TokenDoubleType :
2008-11-21 21:56:08 -05:00
case TokenVoidType :
2009-02-10 03:42:09 -05:00
case TokenStructType :
case TokenUnionType :
2009-02-01 06:31:18 -05:00
* Parser = PreState ;
TypeParse ( Parser , & Typ , & Identifier ) ;
2009-02-10 03:42:09 -05:00
if ( Token = = TokenVoidType & & Identifier ! = StrEmpty )
ProgramFail ( Parser , " can't define a void variable " ) ;
if ( ( Token ! = TokenVoidType & & Token ! = TokenStructType & & Token ! = TokenUnionType ) & & Identifier = = StrEmpty )
2009-02-01 06:31:18 -05:00
ProgramFail ( Parser , " identifier expected " ) ;
2008-11-21 21:56:08 -05:00
2009-02-10 03:42:09 -05:00
if ( Identifier ! = StrEmpty )
{
/* handle function definitions */
if ( LexGetToken ( Parser , NULL , FALSE ) = = TokenOpenBracket )
ParseFunctionDefinition ( Parser , Typ , Identifier , FALSE ) ;
else
2009-02-19 18:29:35 -05:00
VariableDefine ( Parser , Identifier , VariableAllocValueFromType ( Parser , Typ , TRUE ) ) ;
2009-02-10 03:42:09 -05:00
}
2008-11-21 21:56:08 -05:00
break ;
2008-12-23 22:27:53 -05:00
2009-01-03 23:08:49 -05:00
case TokenHashDefine :
2009-02-01 06:31:18 -05:00
ParseMacroDefinition ( Parser ) ;
2009-01-03 23:08:49 -05:00
break ;
case TokenHashInclude :
2009-01-26 03:57:32 -05:00
{
struct Value * LexerValue ;
2009-02-01 06:31:18 -05:00
if ( LexGetToken ( Parser , & LexerValue , TRUE ) ! = TokenStringConstant )
ProgramFail ( Parser , " \" filename.h \" expected " ) ;
2009-01-04 23:38:19 -05:00
2009-02-02 06:08:36 -05:00
ScanFile ( LexerValue - > Val - > String ) ;
2009-01-04 23:38:19 -05:00
break ;
2009-01-26 03:57:32 -05:00
}
2009-01-04 23:38:19 -05:00
2009-01-04 23:28:54 -05:00
case TokenSwitch :
2009-02-18 06:03:14 -05:00
if ( LexGetToken ( Parser , NULL , TRUE ) ! = TokenOpenBracket )
2009-02-17 18:36:09 -05:00
ProgramFail ( Parser , " '(' expected " ) ;
2009-02-18 03:19:06 -05:00
Condition = ParseIntExpression ( Parser ) ;
2009-02-17 18:36:09 -05:00
2009-02-18 06:03:14 -05:00
if ( LexGetToken ( Parser , NULL , TRUE ) ! = TokenCloseBracket )
2009-02-17 18:36:09 -05:00
ProgramFail ( Parser , " ')' expected " ) ;
2009-02-18 06:03:14 -05:00
if ( LexGetToken ( Parser , NULL , FALSE ) ! = TokenLeftBrace )
2009-02-17 18:36:09 -05:00
ProgramFail ( Parser , " '{' expected " ) ;
2009-02-18 06:03:14 -05:00
{ /* new block so we can store parser state */
2009-02-18 03:19:06 -05:00
enum RunMode OldMode = Parser - > Mode ;
int OldSearchLabel = Parser - > SearchLabel ;
Parser - > Mode = RunModeCaseSearch ;
Parser - > SearchLabel = Condition ;
2009-02-19 04:07:00 -05:00
ParseBlock ( Parser , TRUE , TRUE ) ;
2009-02-18 03:19:06 -05:00
Parser - > Mode = OldMode ;
Parser - > SearchLabel = OldSearchLabel ;
}
2009-02-17 18:36:09 -05:00
break ;
2009-01-04 23:28:54 -05:00
case TokenCase :
2009-02-19 04:07:00 -05:00
if ( Parser - > Mode = = RunModeCaseSearch )
{
Parser - > Mode = RunModeRun ;
Condition = ParseIntExpression ( Parser ) ;
Parser - > Mode = RunModeCaseSearch ;
}
else
Condition = ParseIntExpression ( Parser ) ;
2009-02-18 06:03:14 -05:00
if ( LexGetToken ( Parser , NULL , TRUE ) ! = TokenColon )
2009-02-17 18:36:09 -05:00
ProgramFail ( Parser , " ':' expected " ) ;
2009-02-18 03:19:06 -05:00
if ( Parser - > Mode = = RunModeCaseSearch & & Condition = = Parser - > SearchLabel )
Parser - > Mode = RunModeRun ;
2009-02-17 18:36:09 -05:00
break ;
case TokenDefault :
2009-02-18 06:03:14 -05:00
if ( LexGetToken ( Parser , NULL , TRUE ) ! = TokenColon )
2009-02-17 18:36:09 -05:00
ProgramFail ( Parser , " ':' expected " ) ;
2009-02-18 03:19:06 -05:00
if ( Parser - > Mode = = RunModeCaseSearch )
Parser - > Mode = RunModeRun ;
2009-02-17 18:36:09 -05:00
break ;
2009-01-05 00:50:04 -05:00
case TokenBreak :
2009-02-18 03:19:06 -05:00
if ( Parser - > Mode = = RunModeRun )
Parser - > Mode = RunModeBreak ;
2009-02-17 18:36:09 -05:00
break ;
case TokenContinue :
2009-02-18 03:19:06 -05:00
if ( Parser - > Mode = = RunModeRun )
Parser - > Mode = RunModeContinue ;
2009-02-17 18:36:09 -05:00
break ;
2009-01-04 23:28:54 -05:00
case TokenReturn :
2009-02-18 03:19:06 -05:00
if ( Parser - > Mode = = RunModeRun )
{
// XXX - check return type
// XXX - set return value
Parser - > Mode = RunModeContinue ;
}
2008-12-23 22:27:53 -05:00
break ;
2008-11-21 21:56:08 -05:00
default :
2009-02-01 06:31:18 -05:00
* Parser = PreState ;
2008-11-21 21:56:08 -05:00
return FALSE ;
2008-10-16 03:04:23 -04:00
}
2008-11-21 21:56:08 -05:00
return TRUE ;
}
2008-10-12 20:53:28 -04:00
/* quick scan a source file for definitions */
2009-02-02 06:08:36 -05:00
void Parse ( const char * FileName , const char * Source , int SourceLen , int RunIt )
2008-10-12 20:53:28 -04:00
{
2009-02-01 06:31:18 -05:00
struct ParseState Parser ;
2008-10-12 20:53:28 -04:00
2009-02-02 06:50:55 -05:00
void * Tokens = LexAnalyse ( FileName , Source , SourceLen ) ; // XXX - some better way of storing tokenised input?
2009-02-18 03:19:06 -05:00
LexInitParser ( & Parser , Tokens , FileName , 1 , RunIt ) ;
2009-02-02 06:50:55 -05:00
2009-02-18 03:19:06 -05:00
while ( ParseStatement ( & Parser ) )
2008-12-20 05:24:34 -05:00
{ }
2009-02-02 06:08:36 -05:00
if ( LexGetToken ( & Parser , NULL , FALSE ) ! = TokenEOF )
2009-02-01 06:31:18 -05:00
ProgramFail ( & Parser , " parse error " ) ;
2008-10-12 20:53:28 -04:00
}