2008-10-12 20:53:28 -04:00
# include <stdio.h>
# include "picoc.h"
2008-12-23 21:30:29 -05:00
/* parameter passing area */
struct Value Parameter [ PARAMETER_MAX ] ;
int ParameterUsed = 0 ;
struct Value ReturnValue ;
2008-12-18 19:22:52 -05:00
/* local prototypes */
2009-01-23 22:15:02 -05:00
int ParseExpression ( struct LexState * Lexer , struct Value * * Result , int RunIt ) ;
void ParseIntExpression ( struct LexState * Lexer , struct Value * * Result , int RunIt ) ;
2008-12-20 20:36:09 -05:00
int ParseStatement ( struct LexState * Lexer , int RunIt ) ;
2008-12-23 21:30:29 -05:00
int ParseArguments ( struct LexState * Lexer , int RunIt ) ;
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
}
/* parse a parameter list, defining parameters as local variables in the current scope */
void ParseParameterList ( struct LexState * CallLexer , struct LexState * FuncLexer , int RunIt )
{
2009-01-21 04:02:05 -05:00
struct ValueType * Typ ;
2009-01-23 22:15:02 -05:00
Str Identifier ;
2008-12-23 22:27:53 -05:00
enum LexToken Token = LexGetPlainToken ( FuncLexer ) ; /* open bracket */
2008-12-23 21:30:29 -05:00
int ParamCount ;
2008-12-23 22:27:53 -05:00
for ( ParamCount = 0 ; ParamCount < ParameterUsed ; ParamCount + + )
2008-12-23 21:30:29 -05:00
{
2009-01-23 22:15:02 -05:00
TypeParse ( FuncLexer , & Typ , & Identifier ) ;
if ( Identifier - > Len ! = 0 )
2009-01-05 00:50:04 -05:00
{ /* there's an identifier */
if ( RunIt )
{
if ( Parameter [ ParamCount ] . Typ ! = Typ )
ProgramFail ( CallLexer , " parameter %d has the wrong type " , ParamCount + 1 ) ;
2009-01-23 22:15:02 -05:00
VariableDefine ( FuncLexer , & Identifier , & Parameter [ ParamCount ] ) ;
2009-01-05 00:50:04 -05:00
}
2009-01-23 22:15:02 -05:00
}
2009-01-05 00:50:04 -05:00
2009-01-23 22:15:02 -05:00
Token = LexGetPlainToken ( FuncLexer ) ;
if ( ParamCount < ParameterUsed - 1 & & Token ! = TokenComma )
2009-01-05 00:50:04 -05:00
ProgramFail ( FuncLexer , " comma expected " ) ;
2009-01-23 22:15:02 -05:00
}
if ( Token ! = TokenCloseBracket )
ProgramFail ( FuncLexer , " ')' expected " ) ;
2008-12-23 22:27:53 -05:00
if ( ParameterUsed = = 0 )
Token = LexGetPlainToken ( FuncLexer ) ;
2008-12-23 21:30:29 -05:00
2008-12-23 22:27:53 -05:00
if ( Token ! = TokenCloseBracket )
2008-12-23 21:30:29 -05:00
ProgramFail ( CallLexer , " wrong number of arguments " ) ;
}
/* do a function call */
2009-01-23 22:15:02 -05:00
void ParseFunctionCall ( struct LexState * Lexer , struct Value * * Result , Str * FuncName , int RunIt )
2008-12-23 21:30:29 -05:00
{
enum LexToken Token = LexGetPlainToken ( Lexer ) ; /* open bracket */
/* parse arguments */
ParameterUsed = 0 ;
do {
if ( ParseExpression ( Lexer , & Parameter [ ParameterUsed ] , RunIt ) )
{
if ( RunIt & & ParameterUsed > = PARAMETER_MAX )
ProgramFail ( Lexer , " too many arguments " ) ;
ParameterUsed + + ;
Token = LexGetPlainToken ( Lexer ) ;
if ( Token ! = TokenComma & & Token ! = TokenCloseBracket )
ProgramFail ( Lexer , " comma expected " ) ;
}
else
{
Token = LexGetPlainToken ( Lexer ) ;
2008-12-23 22:27:53 -05:00
if ( ! TokenCloseBracket )
2008-12-23 21:30:29 -05:00
ProgramFail ( Lexer , " bad argument " ) ;
}
} while ( Token ! = TokenCloseBracket ) ;
if ( RunIt )
{
struct LexState FuncLexer ;
2009-01-21 04:02:05 -05:00
struct ValueType * ReturnType ;
2008-12-23 21:30:29 -05:00
struct Value * LValue ;
VariableGet ( Lexer , FuncName , Result , & LValue ) ;
2009-01-21 04:02:05 -05:00
if ( Result - > Typ - > Base ! = TypeFunction )
2008-12-23 21:30:29 -05:00
ProgramFail ( Lexer , " not a function - can't call " ) ;
2009-01-03 23:08:49 -05:00
2009-01-23 06:34:12 -05:00
VariableStackFrameAdd ( Lexer ) ;
2009-01-21 04:02:05 -05:00
if ( Result - > Val - > Integer > = 0 )
FuncLexer = FunctionStore [ Result - > Val - > Integer ] ;
2008-12-26 23:36:45 -05:00
else
2009-01-21 04:02:05 -05:00
IntrinsicGetLexer ( & FuncLexer , Result - > Val - > Integer ) ;
2008-12-26 23:36:45 -05:00
2009-01-23 06:34:12 -05:00
TypeParse ( & FuncLexer , & ReturnType ) ; /* return type */
2008-12-23 21:30:29 -05:00
Result - > Typ = TypeVoid ;
LexGetPlainToken ( & FuncLexer ) ; /* function name again */
ParseParameterList ( Lexer , & FuncLexer , TRUE ) ; /* parameters */
2009-01-21 04:02:05 -05:00
if ( Result - > Val - > Integer > = 0 )
2008-12-26 23:36:45 -05:00
{
if ( LexPeekPlainToken ( & FuncLexer ) ! = TokenLeftBrace | | ! ParseStatement ( & FuncLexer , TRUE ) )
ProgramFail ( & FuncLexer , " function body expected " ) ;
2008-12-23 21:30:29 -05:00
2008-12-26 23:36:45 -05:00
if ( ReturnType ! = Result - > Typ )
ProgramFail ( & FuncLexer , " bad return value " ) ;
}
else
2009-01-21 04:02:05 -05:00
IntrinsicCall ( Lexer , Result , ReturnType , Result - > Val - > Integer ) ;
2008-12-23 21:30:29 -05:00
}
}
2008-12-18 19:22:52 -05:00
/* parse a single value */
2009-01-23 22:15:02 -05:00
int ParseValue ( struct LexState * Lexer , struct Value * * Result , struct Value * * LValue , int RunIt )
2008-10-16 03:04:23 -04:00
{
2008-11-21 21:56:08 -05:00
struct LexState PreState = * Lexer ;
2009-01-21 04:02:05 -05:00
enum LexToken Token = LexGetToken ( Lexer , Result - > Val ) ;
2008-12-20 05:24:34 -05:00
* LValue = NULL ;
2008-10-16 03:04:23 -04:00
2008-11-21 21:56:08 -05:00
switch ( Token )
{
2009-01-21 04:02:05 -05:00
case TokenIntegerConstant : case TokenCharacterConstant : Result - > Typ = & IntType ; break ;
case TokenFPConstant : Result - > Typ = & FPType ; break ;
case TokenStringConstant : Result - > Typ = & StringType ; break ;
2008-11-21 21:56:08 -05:00
case TokenMinus : case TokenUnaryExor : case TokenUnaryNot :
2008-12-20 22:46:32 -05:00
ParseIntExpression ( Lexer , Result , RunIt ) ;
2008-12-18 19:22:52 -05:00
2008-12-20 22:46:32 -05:00
if ( RunIt )
2008-11-21 21:56:08 -05:00
{
2008-12-20 22:46:32 -05:00
switch ( Token )
{
2009-01-21 04:02:05 -05:00
case TokenMinus : Result - > Val - > Integer = - ( Result - > Val - > Integer ) ; break ;
case TokenUnaryExor : Result - > Val - > Integer = ~ ( Result - > Val - > Integer ) ; break ;
case TokenUnaryNot : Result - > Val - > Integer = ! ( Result - > Val - > Integer ) ; break ;
2008-12-20 22:46:32 -05:00
default : break ;
}
2008-11-21 21:56:08 -05:00
}
break ;
case TokenOpenBracket :
2008-12-20 22:46:32 -05:00
if ( ! ParseExpression ( Lexer , Result , RunIt ) )
2008-11-21 21:56:08 -05:00
ProgramFail ( Lexer , " invalid expression " ) ;
2008-12-22 06:52:31 -05:00
if ( LexGetPlainToken ( Lexer ) ! = TokenCloseBracket )
2008-11-21 21:56:08 -05:00
ProgramFail ( Lexer , " ')' expected " ) ;
break ;
case TokenAsterisk :
case TokenAmpersand :
ProgramFail ( Lexer , " not implemented " ) ;
case TokenIdentifier :
2008-12-23 21:30:29 -05:00
if ( LexPeekPlainToken ( Lexer ) = = TokenOpenBracket )
2009-01-21 04:02:05 -05:00
ParseFunctionCall ( Lexer , Result , & Result - > Val - > String , RunIt ) ;
2008-12-23 21:30:29 -05:00
else
{
if ( RunIt )
2009-01-03 23:08:49 -05:00
{
2009-01-21 04:02:05 -05:00
VariableGet ( Lexer , & Result - > Val - > String , Result , LValue ) ;
if ( Result - > Typ - > Base = = TypeMacro )
2009-01-04 23:28:54 -05:00
{
2009-01-21 04:02:05 -05:00
struct LexState MacroLexer = FunctionStore [ Result - > Val - > Integer ] ;
2009-01-04 23:28:54 -05:00
if ( ! ParseExpression ( & MacroLexer , Result , TRUE ) )
ProgramFail ( & MacroLexer , " expression expected " ) ;
}
else if ( ! ISVALUETYPE ( Result - > Typ ) )
2009-01-03 23:08:49 -05:00
ProgramFail ( Lexer , " bad variable type " ) ;
}
2008-12-23 21:30:29 -05:00
}
2008-11-21 21:56:08 -05:00
break ;
default :
* Lexer = PreState ;
2008-12-20 05:24:34 -05:00
return FALSE ;
2008-11-21 21:56:08 -05:00
}
2008-10-16 03:04:23 -04:00
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-01-23 22:15:02 -05:00
int ParseExpression ( struct LexState * Lexer , struct Value * * Result , int RunIt )
2008-11-21 21:56:08 -05:00
{
struct Value CurrentValue ;
2008-12-20 05:24:34 -05:00
struct Value * CurrentLValue ;
2008-11-21 21:56:08 -05:00
struct Value TotalValue ;
2008-12-20 05:24:34 -05:00
struct Value * TotalLValue ;
2008-11-21 21:56:08 -05:00
2008-12-20 22:46:32 -05:00
if ( ! ParseValue ( Lexer , & TotalValue , & TotalLValue , RunIt ) )
2008-11-21 21:56:08 -05:00
return FALSE ;
while ( TRUE )
2008-10-16 03:04:23 -04:00
{
2009-01-21 04:02:05 -05:00
enum LexToken Token = LexPeekToken ( Lexer , CurrentValue . Val ) ;
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 :
case TokenArithmeticExor : case TokenDot :
2008-12-22 06:52:31 -05:00
LexGetPlainToken ( Lexer ) ;
2008-11-21 21:56:08 -05:00
break ;
2008-12-20 05:24:34 -05:00
case TokenAssign : case TokenAddAssign : case TokenSubtractAssign :
2008-12-22 06:52:31 -05:00
LexGetPlainToken ( Lexer ) ;
2008-12-20 22:46:32 -05:00
if ( ! ParseExpression ( Lexer , & CurrentValue , RunIt ) )
2008-12-20 05:24:34 -05:00
ProgramFail ( Lexer , " expression expected " ) ;
2008-12-20 22:46:32 -05:00
if ( RunIt )
2008-12-20 05:24:34 -05:00
{
2009-01-21 04:02:05 -05:00
if ( CurrentValue . Typ - > Base ! = TypeInt | | TotalValue . Typ - > Base ! = TypeInt )
2008-12-20 22:46:32 -05:00
ProgramFail ( Lexer , " can't assign " ) ;
switch ( Token )
{
2009-01-21 04:02:05 -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
}
* TotalLValue = TotalValue ;
2008-12-20 05:24:34 -05:00
}
// fallthrough
2008-11-21 21:56:08 -05:00
default :
2008-12-20 22:46:32 -05:00
if ( RunIt )
* Result = TotalValue ;
2008-11-21 21:56:08 -05:00
return TRUE ;
}
2008-12-20 22:46:32 -05:00
if ( ! ParseValue ( Lexer , & CurrentValue , & CurrentLValue , RunIt ) )
2008-11-21 21:56:08 -05:00
return FALSE ;
2008-12-20 05:24:34 -05:00
2008-12-20 22:46:32 -05:00
if ( RunIt )
2008-10-16 03:04:23 -04:00
{
2009-01-21 04:02:05 -05:00
if ( CurrentValue . Typ - > Base = = TypeFP | | TotalValue . Typ - > Base = = TypeFP )
2008-12-26 21:25:49 -05:00
{ /* convert both to floating point */
2009-01-21 04:02:05 -05:00
if ( CurrentValue . Typ - > Base = = TypeInt )
CurrentValue . Val - > FP = ( double ) CurrentValue . Val - > Integer ; // XXX - fixme
else if ( CurrentValue . Typ - > Base ! = TypeFP )
2008-12-26 21:25:49 -05:00
ProgramFail ( Lexer , " bad type for operator " ) ;
2009-01-21 04:02:05 -05:00
if ( TotalValue . Typ - > Base = = TypeInt )
TotalValue . Val - > FP = ( double ) TotalValue . Val - > Integer ; // XXX - fixme
else if ( TotalValue . Typ - > Base ! = TypeFP )
2008-12-26 21:25:49 -05:00
ProgramFail ( Lexer , " bad type for operator " ) ;
2009-01-21 04:02:05 -05:00
TotalValue . Typ = & IntType ;
2008-12-26 21:25:49 -05:00
switch ( Token )
{
2009-01-21 04:02:05 -05:00
case TokenPlus : TotalValue . Val - > FP + = CurrentValue . Val - > FP ; TotalValue . Typ = & FPType ; break ;
case TokenMinus : TotalValue . Val - > FP - = CurrentValue . Val - > FP ; TotalValue . Typ = & FPType ; break ;
case TokenAsterisk : TotalValue . Val - > FP * = CurrentValue . Val - > FP ; TotalValue . Typ = & FPType ; break ;
case TokenSlash : TotalValue . Val - > FP / = CurrentValue . Val - > FP ; TotalValue . Typ = & FPType ; break ;
case TokenEquality : TotalValue . Val - > Integer = TotalValue . Val - > FP = = CurrentValue . Val - > FP ; break ;
case TokenLessThan : TotalValue . Val - > Integer = TotalValue . Val - > FP < CurrentValue . Val - > FP ; break ;
case TokenGreaterThan : TotalValue . Val - > Integer = TotalValue . Val - > FP > CurrentValue . Val - > FP ; break ;
case TokenLessEqual : TotalValue . Val - > Integer = TotalValue . Val - > FP < = CurrentValue . Val - > FP ; break ;
case TokenGreaterEqual : TotalValue . Val - > Integer = TotalValue . Val - > FP > = CurrentValue . Val - > FP ; break ;
2008-12-26 21:25:49 -05:00
case TokenLogicalAnd : case TokenLogicalOr : case TokenAmpersand : case TokenArithmeticOr : case TokenArithmeticExor : ProgramFail ( Lexer , " bad type for operator " ) ; break ;
case TokenDot : ProgramFail ( Lexer , " operator not supported " ) ; break ;
default : break ;
}
}
else
2008-12-20 22:46:32 -05:00
{
2009-01-21 04:02:05 -05:00
if ( CurrentValue . Typ - > Base ! = TypeInt | | TotalValue . Typ - > Base ! = TypeInt )
2008-12-26 21:25:49 -05:00
ProgramFail ( Lexer , " bad operand types " ) ;
/* integer arithmetic */
switch ( Token )
{
2009-01-21 04:02:05 -05:00
case TokenPlus : TotalValue . Val - > Integer + = CurrentValue . Val - > Integer ; break ;
case TokenMinus : TotalValue . Val - > Integer - = CurrentValue . Val - > Integer ; break ;
case TokenAsterisk : TotalValue . Val - > Integer * = CurrentValue . Val - > Integer ; break ;
case TokenSlash : TotalValue . Val - > Integer / = CurrentValue . Val - > Integer ; break ;
case TokenEquality : TotalValue . Val - > Integer = TotalValue . Val - > Integer = = CurrentValue . Val - > Integer ; break ;
case TokenLessThan : TotalValue . Val - > Integer = TotalValue . Val - > Integer < CurrentValue . Val - > Integer ; break ;
case TokenGreaterThan : TotalValue . Val - > Integer = TotalValue . Val - > Integer > CurrentValue . Val - > Integer ; break ;
case TokenLessEqual : TotalValue . Val - > Integer = TotalValue . Val - > Integer < = CurrentValue . Val - > Integer ; break ;
case TokenGreaterEqual : TotalValue . Val - > Integer = TotalValue . Val - > Integer > = CurrentValue . Val - > Integer ; break ;
case TokenLogicalAnd : TotalValue . Val - > Integer = TotalValue . Val - > Integer & & CurrentValue . Val - > Integer ; break ;
case TokenLogicalOr : TotalValue . Val - > Integer = TotalValue . Val - > Integer | | CurrentValue . Val - > Integer ; break ;
case TokenAmpersand : TotalValue . Val - > Integer = TotalValue . Val - > Integer & CurrentValue . Val - > Integer ; break ;
case TokenArithmeticOr : TotalValue . Val - > Integer = TotalValue . Val - > Integer | CurrentValue . Val - > Integer ; break ;
case TokenArithmeticExor : TotalValue . Val - > Integer = TotalValue . Val - > Integer ^ CurrentValue . Val - > Integer ; break ;
2008-12-26 21:25:49 -05:00
case TokenDot : ProgramFail ( Lexer , " operator not supported " ) ; break ;
default : break ;
}
2008-12-20 22:46:32 -05:00
}
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-01-23 22:15:02 -05:00
void ParseIntExpression ( struct LexState * Lexer , struct Value * * Result , int RunIt )
2008-12-18 19:22:52 -05:00
{
2008-12-20 22:46:32 -05:00
if ( ! ParseExpression ( Lexer , Result , RunIt ) )
2008-12-18 19:22:52 -05:00
ProgramFail ( Lexer , " expression expected " ) ;
2009-01-21 04:02:05 -05:00
if ( RunIt & & Result - > Typ - > Base ! = TypeInt )
2008-12-18 19:22:52 -05:00
ProgramFail ( Lexer , " integer value expected " ) ;
}
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 */
void ParseFunctionDefinition ( struct LexState * Lexer , Str * Identifier , struct LexState * PreState )
2008-12-20 06:46:21 -05:00
{
2009-01-21 04:02:05 -05:00
struct Value * FuncValue ;
2008-12-20 20:36:09 -05:00
if ( FunctionStoreUsed > = FUNCTION_STORE_MAX )
2009-01-04 23:28:54 -05:00
ProgramFail ( Lexer , " too many functions/macros defined " ) ;
2008-12-20 20:36:09 -05:00
FunctionStore [ FunctionStoreUsed ] = * PreState ;
2008-12-22 06:52:31 -05:00
LexGetPlainToken ( Lexer ) ;
2009-01-21 04:02:05 -05:00
if ( LexGetPlainToken ( Lexer ) ! = TokenCloseBracket | | LexPeekToken ( Lexer , FuncValue - > Val ) ! = TokenLeftBrace )
2008-12-20 20:36:09 -05:00
ProgramFail ( Lexer , " bad function definition " ) ;
if ( ! ParseStatement ( Lexer , FALSE ) )
ProgramFail ( Lexer , " function definition expected " ) ;
FunctionStore [ FunctionStoreUsed ] . End = Lexer - > Pos ;
2009-01-23 06:34:12 -05:00
FuncValue = VariableAllocValueAndData ( Lexer , sizeof ( int ) ) ;
2009-01-21 04:02:05 -05:00
FuncValue - > Typ = & FunctionType ;
FuncValue - > Val - > Integer = FunctionStoreUsed ;
2008-12-20 20:36:09 -05:00
FunctionStoreUsed + + ;
2009-01-21 04:02:05 -05:00
if ( ! TableSet ( & GlobalTable , Identifier , FuncValue ) )
2008-12-20 20:36:09 -05:00
ProgramFail ( Lexer , " '%S' is already defined " , Identifier ) ;
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 */
void ParseMacroDefinition ( struct LexState * Lexer )
{
union AnyValue MacroName ;
2009-01-21 04:02:05 -05:00
struct Value * MacroValue ;
2009-01-04 23:28:54 -05:00
if ( LexGetToken ( Lexer , & MacroName ) ! = TokenIdentifier )
ProgramFail ( Lexer , " identifier expected " ) ;
if ( FunctionStoreUsed > = FUNCTION_STORE_MAX )
ProgramFail ( Lexer , " too many functions/macros defined " ) ;
FunctionStore [ FunctionStoreUsed ] = * Lexer ;
LexToEndOfLine ( Lexer ) ;
FunctionStore [ FunctionStoreUsed ] . End = Lexer - > Pos ;
2009-01-23 06:34:12 -05:00
MacroValue = VariableAllocValueAndData ( Lexer , sizeof ( int ) ) ;
2009-01-21 04:02:05 -05:00
MacroValue - > Typ = & MacroType ;
MacroValue - > Val - > Integer = FunctionStoreUsed ;
2009-01-04 23:28:54 -05:00
FunctionStoreUsed + + ;
2009-01-21 04:02:05 -05:00
if ( ! TableSet ( & GlobalTable , & MacroName . String , MacroValue ) )
2009-01-04 23:28:54 -05:00
ProgramFail ( Lexer , " '%S' is already defined " , & MacroName . String ) ;
}
2009-01-23 22:15:02 -05:00
void ParseFor ( struct LexState * Lexer , int RunIt )
2009-01-03 23:08:49 -05:00
{
struct Value Conditional ;
struct LexState PreConditional ;
struct LexState PreIncrement ;
struct LexState PreStatement ;
struct LexState After ;
if ( LexGetPlainToken ( Lexer ) ! = TokenOpenBracket )
ProgramFail ( Lexer , " '(' expected " ) ;
if ( ! ParseStatement ( Lexer , RunIt ) )
ProgramFail ( Lexer , " statement expected " ) ;
PreConditional = * Lexer ;
ParseIntExpression ( Lexer , & Conditional , RunIt ) ;
if ( LexGetPlainToken ( Lexer ) ! = TokenSemicolon )
ProgramFail ( Lexer , " ';' expected " ) ;
PreIncrement = * Lexer ;
ParseStatement ( Lexer , FALSE ) ;
if ( LexGetPlainToken ( Lexer ) ! = TokenCloseBracket )
ProgramFail ( Lexer , " ')' expected " ) ;
PreStatement = * Lexer ;
2009-01-21 04:02:05 -05:00
if ( ! ParseStatement ( Lexer , RunIt & & Conditional . Val - > Integer ) )
2009-01-03 23:08:49 -05:00
ProgramFail ( Lexer , " statement expected " ) ;
After = * Lexer ;
2009-01-21 04:02:05 -05:00
while ( Conditional . Val - > Integer & & RunIt )
2009-01-03 23:08:49 -05:00
{
* Lexer = PreIncrement ;
ParseStatement ( Lexer , TRUE ) ;
* Lexer = PreConditional ;
ParseIntExpression ( Lexer , & Conditional , RunIt ) ;
2009-01-21 04:02:05 -05:00
if ( Conditional . Val - > Integer )
2009-01-03 23:08:49 -05:00
{
* Lexer = PreStatement ;
ParseStatement ( Lexer , TRUE ) ;
}
}
* Lexer = After ;
}
2008-12-18 19:22:52 -05:00
/* parse a statement */
2008-11-21 21:56:08 -05:00
int ParseStatement ( struct LexState * Lexer , int RunIt )
{
2009-01-03 23:08:49 -05:00
struct Value CValue ;
2008-11-21 21:56:08 -05:00
struct LexState PreState = * Lexer ;
2008-12-20 20:36:09 -05:00
union AnyValue LexerValue ;
2009-01-21 04:02:05 -05:00
struct ValueType * Typ ;
2008-12-20 20:36:09 -05:00
enum LexToken Token = LexGetToken ( Lexer , & LexerValue ) ;
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 :
2008-12-20 06:46:21 -05:00
* Lexer = PreState ;
2009-01-03 23:08:49 -05:00
ParseExpression ( Lexer , & CValue , RunIt ) ;
2008-11-21 21:56:08 -05:00
break ;
case TokenLeftBrace :
while ( ParseStatement ( Lexer , RunIt ) )
{ }
2008-12-22 06:52:31 -05:00
if ( LexGetPlainToken ( Lexer ) ! = TokenRightBrace )
2008-11-21 21:56:08 -05:00
ProgramFail ( Lexer , " '}' expected " ) ;
break ;
case TokenIf :
2009-01-03 23:08:49 -05:00
ParseIntExpression ( Lexer , & CValue , RunIt ) ;
2008-11-21 21:56:08 -05:00
2009-01-21 04:02:05 -05:00
if ( ! ParseStatement ( Lexer , RunIt & & CValue . Val - > Integer ) )
2008-11-21 21:56:08 -05:00
ProgramFail ( Lexer , " statement expected " ) ;
2008-12-20 20:36:09 -05:00
if ( LexPeekToken ( Lexer , & LexerValue ) = = TokenElse )
2008-11-21 21:56:08 -05:00
{
2008-12-20 20:36:09 -05:00
LexGetToken ( Lexer , & LexerValue ) ;
2009-01-21 04:02:05 -05:00
if ( ! ParseStatement ( Lexer , RunIt & & ! CValue . Val - > Integer ) )
2008-11-21 21:56:08 -05:00
ProgramFail ( Lexer , " statement expected " ) ;
}
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
{
2008-11-21 21:56:08 -05:00
struct LexState PreConditional = * Lexer ;
do
{
* Lexer = PreConditional ;
2009-01-03 23:08:49 -05:00
ParseIntExpression ( Lexer , & CValue , RunIt ) ;
2008-11-21 21:56:08 -05:00
2009-01-21 04:02:05 -05:00
if ( ! ParseStatement ( Lexer , RunIt & & CValue . Val - > Integer ) )
2008-11-21 21:56:08 -05:00
ProgramFail ( Lexer , " statement expected " ) ;
2009-01-21 04:02:05 -05:00
} while ( RunIt & & CValue . Val - > Integer ) ;
2008-11-21 21:56:08 -05:00
}
break ;
case TokenDo :
{
struct LexState PreStatement = * Lexer ;
do
{
* Lexer = PreStatement ;
if ( ! ParseStatement ( Lexer , RunIt ) )
ProgramFail ( Lexer , " statement expected " ) ;
2009-01-03 23:08:49 -05:00
ParseIntExpression ( Lexer , & CValue , RunIt ) ;
2008-11-21 21:56:08 -05:00
2009-01-21 04:02:05 -05:00
} while ( CValue . Val - > Integer & & RunIt ) ;
2008-11-21 21:56:08 -05:00
}
break ;
case TokenFor :
2009-01-23 22:15:02 -05:00
ParseFor ( Lexer , RunIt ) ;
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 :
2008-12-22 06:52:31 -05:00
* Lexer = PreState ;
2009-01-23 06:34:12 -05:00
TypeParse ( Lexer , & Typ ) ;
2008-12-20 20:36:09 -05:00
if ( LexGetToken ( Lexer , & LexerValue ) ! = TokenIdentifier )
2008-11-21 21:56:08 -05:00
ProgramFail ( Lexer , " identifier expected " ) ;
2008-12-20 06:46:21 -05:00
/* handle function definitions */
2008-12-22 06:52:31 -05:00
if ( LexPeekPlainToken ( Lexer ) = = TokenOpenBracket )
2008-12-20 20:36:09 -05:00
ParseFunctionDefinition ( Lexer , & LexerValue . String , & PreState ) ;
2008-12-20 06:46:21 -05:00
else
2008-12-23 21:30:29 -05:00
{
struct Value InitValue ;
2009-01-21 04:02:05 -05:00
if ( Typ - > Base = = TypeFP )
InitValue . Val - > FP = 0.0 ;
2008-12-26 21:25:49 -05:00
else
2009-01-21 04:02:05 -05:00
InitValue . Val - > Integer = 0 ;
2008-12-26 21:25:49 -05:00
2008-12-23 21:30:29 -05:00
InitValue . Typ = Typ ;
VariableDefine ( Lexer , & LexerValue . String , & InitValue ) ;
}
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-01-04 23:28:54 -05:00
ParseMacroDefinition ( Lexer ) ;
2009-01-03 23:08:49 -05:00
break ;
case TokenHashInclude :
2009-01-04 23:38:19 -05:00
if ( LexGetToken ( Lexer , & LexerValue ) ! = TokenStringConstant )
ProgramFail ( Lexer , " \" filename.h \" expected " ) ;
ScanFile ( & LexerValue . String ) ;
LexToEndOfLine ( Lexer ) ;
break ;
2009-01-04 23:28:54 -05:00
case TokenSwitch :
case TokenCase :
2009-01-05 00:50:04 -05:00
case TokenBreak :
2009-01-04 23:28:54 -05:00
case TokenReturn :
2008-12-23 22:27:53 -05:00
case TokenDefault :
2009-01-04 23:28:54 -05:00
ProgramFail ( Lexer , " not implemented yet " ) ;
2008-12-23 22:27:53 -05:00
break ;
2008-11-21 21:56:08 -05:00
default :
* Lexer = PreState ;
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 */
2008-12-20 05:24:34 -05:00
void Parse ( const Str * FileName , const Str * Source , int RunIt )
2008-10-12 20:53:28 -04:00
{
2008-10-14 00:51:34 -04:00
struct LexState Lexer ;
2008-10-12 20:53:28 -04:00
2008-10-14 00:51:34 -04:00
LexInit ( & Lexer , Source , FileName , 1 ) ;
2008-10-12 20:53:28 -04:00
2008-12-20 05:24:34 -05:00
while ( ParseStatement ( & Lexer , RunIt ) )
{ }
if ( Lexer . Pos ! = Lexer . End )
ProgramFail ( & Lexer , " parse error " ) ;
2008-10-12 20:53:28 -04:00
}