2008-10-12 20:53:28 -04:00
# include <stdio.h>
2008-12-18 19:22:52 -05:00
# include <string.h>
2008-10-12 20:53:28 -04:00
# include "picoc.h"
/* the table of global definitions */
struct Table GlobalTable ;
struct TableEntry GlobalHashTable [ GLOBAL_TABLE_SIZE ] ;
2008-12-20 20:36:09 -05:00
/* the table of function definitions */
struct LexState FunctionStore [ FUNCTION_STORE_MAX ] ;
int FunctionStoreUsed = 0 ;
2008-10-12 20:53:28 -04:00
2008-12-21 21:29:19 -05:00
/* the stack */
struct StackFrame Stack [ STACK_MAX ] ;
int StackUsed = 0 ;
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 */
2008-12-20 22:46:32 -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 ( )
{
2008-12-21 21:29:19 -05:00
TableInit ( & GlobalTable , & GlobalHashTable [ 0 ] , GLOBAL_TABLE_SIZE ) ;
2008-12-26 23:36:45 -05:00
IntrinsicInit ( & GlobalTable ) ;
2008-10-12 20:53:28 -04:00
}
2008-12-18 19:22:52 -05:00
/* define a variable */
2008-12-23 21:30:29 -05:00
void VariableDefine ( struct LexState * Lexer , const Str * Ident , struct Value * InitValue )
2008-12-18 19:22:52 -05:00
{
2008-12-23 21:30:29 -05:00
if ( ! TableSet ( ( StackUsed = = 0 ) ? & GlobalTable : & Stack [ StackUsed - 1 ] . LocalTable , Ident , InitValue ) )
2008-12-18 19:22:52 -05:00
ProgramFail ( Lexer , " '%S' is already defined " , Ident ) ;
}
/* get the value of a variable. must be defined */
2008-12-20 05:24:34 -05:00
void VariableGet ( struct LexState * Lexer , Str * Ident , struct Value * Val , struct Value * * LVal )
2008-12-18 19:22:52 -05:00
{
2008-12-26 23:36:45 -05:00
if ( StackUsed = = 0 | | ! TableGet ( & Stack [ StackUsed - 1 ] . LocalTable , Ident , LVal ) )
2008-12-21 21:29:19 -05:00
{
2008-12-26 22:04:58 -05:00
if ( ! TableGet ( & GlobalTable , Ident , LVal ) )
ProgramFail ( Lexer , " '%S' is undefined " , Ident ) ;
2008-12-21 21:29:19 -05:00
}
2008-12-18 19:22:52 -05:00
2008-12-20 05:24:34 -05:00
* Val = * * LVal ;
2008-12-18 19:22:52 -05:00
}
2008-12-21 21:29:19 -05:00
/* add a stack frame when doing a function call */
void StackFrameAdd ( struct LexState * Lexer )
{
struct StackFrame * NewFrame = & Stack [ StackUsed ] ;
if ( StackUsed > = STACK_MAX )
ProgramFail ( Lexer , " too many nested function calls " ) ;
NewFrame - > ReturnLex = * Lexer ;
TableInit ( & NewFrame - > LocalTable , & NewFrame - > LocalHashTable [ 0 ] , LOCAL_TABLE_SIZE ) ;
StackUsed + + ;
}
2008-12-23 21:30:29 -05:00
/* parse a type specification */
int ParseType ( struct LexState * Lexer , enum ValueType * Typ )
{
struct LexState Before = * Lexer ;
enum LexToken Token = LexGetPlainToken ( Lexer ) ;
switch ( Token )
{
case TokenIntType : case TokenCharType : * Typ = TypeInt ; return TRUE ;
2008-12-26 21:25:49 -05:00
case TokenFloatType : case TokenDoubleType : * Typ = TypeFP ; return TRUE ;
2008-12-23 21:30:29 -05:00
case TokenVoidType : * Typ = TypeVoid ; return TRUE ;
default : * Lexer = Before ; return FALSE ;
}
}
/* parse a parameter list, defining parameters as local variables in the current scope */
void ParseParameterList ( struct LexState * CallLexer , struct LexState * FuncLexer , int RunIt )
{
enum ValueType Typ ;
union AnyValue 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
{
ParseType ( FuncLexer , & Typ ) ;
Token = LexGetToken ( FuncLexer , & Identifier ) ;
2008-12-23 22:27:53 -05:00
if ( Token ! = TokenIdentifier )
ProgramFail ( FuncLexer , " invalid parameter " ) ;
if ( RunIt )
2008-12-23 21:30:29 -05:00
{
2008-12-23 22:27:53 -05:00
if ( Parameter [ ParamCount ] . Typ ! = Typ )
ProgramFail ( CallLexer , " parameter %d has the wrong type " , ParamCount + 1 ) ;
2008-12-23 21:30:29 -05:00
2008-12-23 22:27:53 -05:00
VariableDefine ( FuncLexer , & Identifier . String , & Parameter [ ParamCount ] ) ;
2008-12-23 21:30:29 -05:00
}
2008-12-23 22:27:53 -05:00
Token = LexGetPlainToken ( FuncLexer ) ;
2008-12-23 21:30:29 -05:00
if ( Token ! = TokenComma & & Token ! = TokenCloseBracket )
ProgramFail ( FuncLexer , " comma 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 */
void ParseFunctionCall ( struct LexState * Lexer , struct Value * Result , Str * FuncName , int RunIt )
{
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 ;
enum ValueType ReturnType ;
struct Value * LValue ;
VariableGet ( Lexer , FuncName , Result , & LValue ) ;
if ( Result - > Typ ! = TypeFunction )
ProgramFail ( Lexer , " not a function - can't call " ) ;
StackFrameAdd ( Lexer ) ;
2008-12-26 23:36:45 -05:00
if ( Result - > Val . Integer > = 0 )
FuncLexer = FunctionStore [ Result - > Val . Integer ] ;
else
IntrinsicGetLexer ( & FuncLexer , Result - > Val . Integer ) ;
2008-12-23 21:30:29 -05:00
ParseType ( & FuncLexer , & ReturnType ) ; /* return type */
Result - > Typ = TypeVoid ;
LexGetPlainToken ( & FuncLexer ) ; /* function name again */
ParseParameterList ( Lexer , & FuncLexer , TRUE ) ; /* parameters */
2008-12-26 23:36:45 -05:00
if ( Result - > Val . Integer > = 0 )
{
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
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 */
2008-12-20 22:46:32 -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 ;
2008-12-20 20:36:09 -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 )
{
2008-12-26 21:25:49 -05:00
case TokenIntegerConstant : case TokenCharacterConstant : Result - > Typ = TypeInt ; break ;
case TokenFPConstant : Result - > Typ = TypeFP ; break ;
case TokenStringConstant : Result - > Typ = TypeString ; 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 )
{
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 ;
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 )
ParseFunctionCall ( Lexer , Result , & Result - > Val . String , RunIt ) ;
else
{
if ( RunIt )
VariableGet ( Lexer , & Result - > Val . String , Result , LValue ) ;
}
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 */
2008-12-20 22:46:32 -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
{
2008-12-20 20:36:09 -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
{
2008-12-20 22:46:32 -05:00
if ( CurrentValue . Typ ! = TypeInt | | TotalValue . Typ ! = TypeInt )
ProgramFail ( Lexer , " can't assign " ) ;
switch ( Token )
{
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 ; printf ( " ---> %d \n " , TotalValue . Val . Integer ) ; break ;
}
* 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
{
2008-12-26 21:25:49 -05:00
if ( CurrentValue . Typ = = TypeFP | | TotalValue . Typ = = TypeFP )
{ /* convert both to floating point */
if ( CurrentValue . Typ = = TypeInt )
CurrentValue . Val . FP = ( double ) CurrentValue . Val . Integer ;
else if ( CurrentValue . Typ ! = TypeFP )
ProgramFail ( Lexer , " bad type for operator " ) ;
if ( TotalValue . Typ = = TypeInt )
TotalValue . Val . FP = ( double ) TotalValue . Val . Integer ;
else if ( TotalValue . Typ ! = TypeFP )
ProgramFail ( Lexer , " bad type for operator " ) ;
TotalValue . Typ = TypeInt ;
switch ( Token )
{
case TokenPlus : TotalValue . Val . FP + = CurrentValue . Val . FP ; TotalValue . Typ = TypeFP ; break ;
case TokenMinus : TotalValue . Val . FP - = CurrentValue . Val . FP ; TotalValue . Typ = TypeFP ; break ;
case TokenAsterisk : TotalValue . Val . FP * = CurrentValue . Val . FP ; TotalValue . Typ = TypeFP ; break ;
case TokenSlash : TotalValue . Val . FP / = CurrentValue . Val . FP ; TotalValue . Typ = TypeFP ; 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 ;
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
{
2008-12-26 21:25:49 -05:00
if ( CurrentValue . Typ ! = TypeInt | | TotalValue . Typ ! = TypeInt )
ProgramFail ( Lexer , " bad operand types " ) ;
/* integer arithmetic */
switch ( Token )
{
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 : printf ( " compare %d <= %d \n " , TotalValue . Val . Integer , CurrentValue . Val . Integer ) ; 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 ;
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 */
2008-12-20 22:46:32 -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 " ) ;
2008-12-20 22:46:32 -05:00
if ( RunIt & & Result - > Typ ! = 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
{
2008-12-20 20:36:09 -05:00
struct Value FuncValue ;
if ( FunctionStoreUsed > = FUNCTION_STORE_MAX )
ProgramFail ( Lexer , " too many functions defined " ) ;
FunctionStore [ FunctionStoreUsed ] = * PreState ;
2008-12-22 06:52:31 -05:00
LexGetPlainToken ( Lexer ) ;
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 ;
FuncValue . Typ = TypeFunction ;
FuncValue . Val . Integer = FunctionStoreUsed ;
FunctionStoreUsed + + ;
2008-12-20 22:13:25 -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
}
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 )
{
2008-12-18 19:22:52 -05:00
struct Value Conditional ;
2008-11-21 21:56:08 -05:00
struct LexState PreState = * Lexer ;
2008-12-20 20:36:09 -05:00
union AnyValue LexerValue ;
2008-12-22 06:52:31 -05:00
enum 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 ;
2008-12-20 22:46:32 -05:00
ParseExpression ( Lexer , & Conditional , 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 :
2008-12-20 22:46:32 -05:00
ParseIntExpression ( Lexer , & Conditional , RunIt ) ;
2008-11-21 21:56:08 -05:00
2008-12-18 19:22:52 -05:00
if ( ! ParseStatement ( Lexer , RunIt & & Conditional . 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 ) ;
2008-12-18 19:22:52 -05:00
if ( ! ParseStatement ( Lexer , RunIt & & ! Conditional . 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 ;
2008-12-20 22:46:32 -05:00
ParseIntExpression ( Lexer , & Conditional , RunIt ) ;
2008-11-21 21:56:08 -05:00
2008-12-18 19:22:52 -05:00
if ( ! ParseStatement ( Lexer , RunIt & & Conditional . Val . Integer ) )
2008-11-21 21:56:08 -05:00
ProgramFail ( Lexer , " statement expected " ) ;
2008-12-20 22:46:32 -05:00
} while ( RunIt & & Conditional . 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 " ) ;
2008-12-20 22:46:32 -05:00
ParseIntExpression ( Lexer , & Conditional , RunIt ) ;
2008-11-21 21:56:08 -05:00
2008-12-18 19:22:52 -05:00
} while ( Conditional . Val . Integer & & RunIt ) ;
2008-11-21 21:56:08 -05:00
}
break ;
case TokenFor :
{
struct LexState PreConditional ;
struct LexState PreIncrement ;
struct LexState PreStatement ;
struct LexState After ;
2008-12-20 20:36:09 -05:00
if ( LexGetToken ( Lexer , & LexerValue ) ! = TokenOpenBracket )
2008-11-21 21:56:08 -05:00
ProgramFail ( Lexer , " '(' expected " ) ;
if ( ! ParseStatement ( Lexer , RunIt ) )
ProgramFail ( Lexer , " statement expected " ) ;
PreConditional = * Lexer ;
2008-12-20 22:46:32 -05:00
ParseIntExpression ( Lexer , & Conditional , RunIt ) ;
2008-11-21 21:56:08 -05:00
2008-12-20 20:36:09 -05:00
if ( LexGetToken ( Lexer , & LexerValue ) ! = TokenSemicolon )
2008-11-21 21:56:08 -05:00
ProgramFail ( Lexer , " ';' expected " ) ;
PreIncrement = * Lexer ;
ParseStatement ( Lexer , FALSE ) ;
2008-12-20 20:36:09 -05:00
if ( LexGetToken ( Lexer , & LexerValue ) ! = TokenCloseBracket )
2008-11-21 21:56:08 -05:00
ProgramFail ( Lexer , " ')' expected " ) ;
PreStatement = * Lexer ;
2008-12-20 22:46:32 -05:00
if ( ! ParseStatement ( Lexer , RunIt & & Conditional . Val . Integer ) )
2008-11-21 21:56:08 -05:00
ProgramFail ( Lexer , " statement expected " ) ;
After = * Lexer ;
2008-12-18 19:22:52 -05:00
while ( Conditional . Val . Integer & & RunIt )
2008-11-21 21:56:08 -05:00
{
* Lexer = PreIncrement ;
ParseStatement ( Lexer , TRUE ) ;
* Lexer = PreConditional ;
2008-12-20 22:46:32 -05:00
ParseIntExpression ( Lexer , & Conditional , RunIt ) ;
2008-11-21 21:56:08 -05:00
2008-12-18 19:22:52 -05:00
if ( Conditional . Val . Integer )
2008-11-21 21:56:08 -05:00
{
* Lexer = PreStatement ;
ParseStatement ( Lexer , TRUE ) ;
}
}
* Lexer = After ;
}
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 ;
ParseType ( 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 ;
2008-12-26 21:25:49 -05:00
if ( Typ = = TokenFloatType )
InitValue . Val . FP = 0.0 ;
else
InitValue . Val . Integer = 0 ;
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
case TokenDefault :
if ( RunIt )
printf ( " Hello \n " ) ;
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
}