Starting to code the new expression system

git-svn-id: http://picoc.googlecode.com/svn/trunk@148 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-03-03 10:53:45 +00:00
parent eb3fba2d16
commit a3ab81ca23
3 changed files with 156 additions and 109 deletions

2
lex.c
View file

@ -307,7 +307,7 @@ enum LexToken LexScanGetToken(struct LexState *Lexer, struct Value **Value)
case '\'': GotToken = LexGetCharacterConstant(Lexer, *Value); break; case '\'': GotToken = LexGetCharacterConstant(Lexer, *Value); break;
case '(': GotToken = TokenOpenBracket; break; case '(': GotToken = TokenOpenBracket; break;
case ')': GotToken = TokenCloseBracket; break; case ')': GotToken = TokenCloseBracket; break;
case '=': NEXTIS('=', TokenEquality, TokenAssign); break; case '=': NEXTIS('=', TokenEqual, TokenAssign); break;
case '+': NEXTIS3('=', TokenAddAssign, '+', TokenIncrement, TokenPlus); break; case '+': NEXTIS3('=', TokenAddAssign, '+', TokenIncrement, TokenPlus); break;
case '-': NEXTIS4('=', TokenSubtractAssign, '>', TokenArrow, '-', TokenDecrement, TokenMinus); break; case '-': NEXTIS4('=', TokenSubtractAssign, '>', TokenArrow, '-', TokenDecrement, TokenMinus); break;
case '*': NEXTIS('=', TokenMultiplyAssign, TokenAsterisk); break; case '*': NEXTIS('=', TokenMultiplyAssign, TokenAsterisk); break;

228
parse.c
View file

@ -3,96 +3,9 @@
/* local prototypes */ /* local prototypes */
int ParseArguments(struct ParseState *Parser, int RunIt); int ParseArguments(struct ParseState *Parser, int RunIt);
int ParseStatementMaybeRun(struct ParseState *Parser, int Condition); int ParseStatementMaybeRun(struct ParseState *Parser, int Condition);
void ParseFunctionCall(struct ParseState *Parser, struct Value **Result, const char *FuncName);
#if 1
/* do a function call */
void ParseFunctionCall(struct ParseState *Parser, struct Value **Result, const char *FuncName)
{
struct Value *FuncValue;
struct Value *Param;
struct Value **ParamArray;
int ArgCount;
enum LexToken Token = LexGetToken(Parser, NULL, TRUE); /* open bracket */
if (Parser->Mode == RunModeRun)
{ /* get the function definition */
VariableGet(Parser, FuncName, &FuncValue);
if (FuncValue->Typ->Base != TypeFunction)
ProgramFail(Parser, "not a function - can't call");
*Result = VariableAllocValueFromType(Parser, FuncValue->Val->FuncDef.ReturnType, FALSE, NULL);
HeapPushStackFrame();
ParamArray = HeapAllocStack(sizeof(struct Value *) * FuncValue->Val->FuncDef.NumParams);
if (ParamArray == NULL)
ProgramFail(Parser, "out of memory");
}
/* parse arguments */
ArgCount = 0;
do {
if (ParseExpression(Parser, &Param))
{
if (Parser->Mode == RunModeRun)
{
if (ArgCount >= FuncValue->Val->FuncDef.NumParams)
{
if (!FuncValue->Val->FuncDef.VarArgs)
ProgramFail(Parser, "too many arguments to %s()", FuncName);
}
else
{
if (FuncValue->Val->FuncDef.ParamType[ArgCount] != Param->Typ)
ProgramFail(Parser, "parameter %d to %s() is the wrong type", ArgCount+1, FuncName);
}
if (ArgCount < FuncValue->Val->FuncDef.NumParams)
ParamArray[ArgCount] = Param;
}
ArgCount++;
Token = LexGetToken(Parser, NULL, TRUE);
if (Token != TokenComma && Token != TokenCloseBracket)
ProgramFail(Parser, "comma expected");
}
else
{ /* end of argument list? */
Token = LexGetToken(Parser, NULL, TRUE);
if (!TokenCloseBracket)
ProgramFail(Parser, "bad argument");
}
} while (Token != TokenCloseBracket);
if (Parser->Mode == RunModeRun)
{ /* run the function */
if (ArgCount < FuncValue->Val->FuncDef.NumParams)
ProgramFail(Parser, "not enough arguments to '%s'", FuncName);
if (FuncValue->Val->FuncDef.Intrinsic == NULL)
{ /* run a user-defined function */
struct ParseState FuncParser = FuncValue->Val->FuncDef.Body;
int Count;
VariableStackFrameAdd(Parser, FuncValue->Val->FuncDef.Intrinsic ? FuncValue->Val->FuncDef.NumParams : 0);
TopStackFrame->NumParams = ArgCount;
TopStackFrame->ReturnValue = *Result;
for (Count = 0; Count < FuncValue->Val->FuncDef.NumParams; Count++)
VariableDefine(Parser, FuncValue->Val->FuncDef.ParamName[Count], ParamArray[Count]);
if (!ParseStatement(&FuncParser))
ProgramFail(&FuncParser, "function body expected");
if (FuncValue->Val->FuncDef.ReturnType != (*Result)->Typ)
ProgramFail(&FuncParser, "bad type of return value");
VariableStackFramePop(Parser);
}
else
FuncValue->Val->FuncDef.Intrinsic(Parser, *Result, ParamArray, ArgCount);
HeapPopStackFrame();
}
}
/* parse a single value */ /* parse a single value */
int ParseValue(struct ParseState *Parser, struct Value **Result) int ParseValue(struct ParseState *Parser, struct Value **Result)
{ {
@ -142,11 +55,11 @@ int ParseValue(struct ParseState *Parser, struct Value **Result)
LocalLValue = (*Result)->Val->Pointer.Segment; LocalLValue = (*Result)->Val->Pointer.Segment;
VariableStackPop(Parser, *Result); VariableStackPop(Parser, *Result);
#if 0 #if 0
*Result = VariableAllocValueAndCopy(struct ParseState *Parser, struct Value *FromValue, int OnHeap) *Result = VariableAllocValueAndCopy(struct ParseState *Parser, struct Value *FromValue, int OnHeap)
*Result = VariableAllocValueFromExistingData(Parser, (*Result)->Typ->FromType, (void *)LocalLValue->Val + LocalLValue->Val->Pointer.Segment, *Result = VariableAllocValueFromExistingData(Parser, (*Result)->Typ->FromType, (void *)LocalLValue->Val + LocalLValue->Val->Pointer.Segment,
LocalLValue->IsLValue, FromValue->IsLValue ? FromValue : NULL); LocalLValue->IsLValue, FromValue->IsLValue ? FromValue : NULL);
#endif #endif
*Result = VariableAllocValueShared(Parser, LocalLValue); *Result = VariableAllocValueShared(Parser, LocalLValue);
break; break;
@ -263,7 +176,7 @@ int ParseExpression(struct ParseState *Parser, struct Value **Result)
switch (Token) switch (Token)
{ {
case TokenPlus: case TokenMinus: case TokenAsterisk: case TokenSlash: case TokenPlus: case TokenMinus: case TokenAsterisk: case TokenSlash:
case TokenEquality: case TokenLessThan: case TokenGreaterThan: case TokenEqual: case TokenLessThan: case TokenGreaterThan:
case TokenLessEqual: case TokenGreaterEqual: case TokenLogicalAnd: case TokenLessEqual: case TokenGreaterEqual: case TokenLogicalAnd:
case TokenLogicalOr: case TokenAmpersand: case TokenArithmeticOr: case TokenLogicalOr: case TokenAmpersand: case TokenArithmeticOr:
case TokenArithmeticExor: case TokenArithmeticExor:
@ -401,7 +314,7 @@ int ParseExpression(struct ParseState *Parser, struct Value **Result)
case TokenMinus: FPResult = FPTotal - FPCurrent; break; case TokenMinus: FPResult = FPTotal - FPCurrent; break;
case TokenAsterisk: FPResult = FPTotal * FPCurrent; break; case TokenAsterisk: FPResult = FPTotal * FPCurrent; break;
case TokenSlash: FPResult = FPTotal / FPCurrent; break; case TokenSlash: FPResult = FPTotal / FPCurrent; break;
case TokenEquality: FPResult = FPTotal == FPCurrent; break; case TokenEqual: FPResult = FPTotal == FPCurrent; break;
case TokenLessThan: FPResult = FPTotal < FPCurrent; break; case TokenLessThan: FPResult = FPTotal < FPCurrent; break;
case TokenGreaterThan: FPResult = FPTotal > FPCurrent; break; case TokenGreaterThan: FPResult = FPTotal > FPCurrent; break;
case TokenLessEqual: FPResult = FPTotal <= FPCurrent; break; case TokenLessEqual: FPResult = FPTotal <= FPCurrent; break;
@ -431,7 +344,7 @@ int ParseExpression(struct ParseState *Parser, struct Value **Result)
case TokenMinus: IntResult = IntX - IntY; break; case TokenMinus: IntResult = IntX - IntY; break;
case TokenAsterisk: IntResult = IntX * IntY; break; case TokenAsterisk: IntResult = IntX * IntY; break;
case TokenSlash: IntResult = IntX / IntY; break; case TokenSlash: IntResult = IntX / IntY; break;
case TokenEquality: IntResult = IntX == IntY; break; case TokenEqual: IntResult = IntX == IntY; break;
case TokenLessThan: IntResult = IntX < IntY; break; case TokenLessThan: IntResult = IntX < IntY; break;
case TokenGreaterThan: IntResult = IntX > IntY; break; case TokenGreaterThan: IntResult = IntX > IntY; break;
case TokenLessEqual: IntResult = IntX <= IntY; break; case TokenLessEqual: IntResult = IntX <= IntY; break;
@ -452,6 +365,45 @@ int ParseExpression(struct ParseState *Parser, struct Value **Result)
return TRUE; return TRUE;
} }
#else
/* operator precedence definitions */
struct OpPrecedence
{
unsigned char PrefixPrecedence;
unsigned char PostfixPrecedence;
unsigned char BinaryPrecedence;
};
static struct OpPrecedence OperatorPrecedence[] =
{
/* TokenComma, */ { 0, 0, 1 },
/* TokenAssign, */ { 0, 0, 2 }, /* TokenAddAssign, */ { 0, 0, 2 }, /* TokenSubtractAssign, */ { 0, 0, 2 },
/* TokenMultiplyAssign, */ { 0, 0, 2 }, /* TokenDivideAssign, */ { 0, 0, 2 }, /* TokenModulusAssign, */ { 0, 0, 2 },
/* TokenShiftLeftAssign, */ { 0, 0, 2 }, /* TokenShiftRightAssign, */ { 0, 0, 2 }, /* TokenArithmeticAndAssign, */ { 0, 0, 2 },
/* TokenArithmeticOrAssign, */ { 0, 0, 2 }, /* TokenArithmeticExorAssign, */ { 0, 0, 2 },
/* TokenQuestionMark, */ { 0, 0, 3 },
/* TokenLogicalOr, */ { 0, 0, 4 },
/* TokenLogicalAnd, */ { 0, 0, 5 },
/* TokenArithmeticOr, */ { 0, 0, 6 },
/* TokenTilde, */ { 0, 0, 7 },
/* TokenAmpersand, */ { 14, 0, 8 },
/* TokenEqual, TokenNotEqual, */ { 0, 0, 9 },
/* TokenLessThan, */ { 0, 0, 10 }, /* TokenGreaterThan, */ { 0, 0, 10 }, /* TokenLessEqual, */ { 0, 0, 10 }, /* TokenGreaterEqual, */ { 0, 0, 10 },
/* TokenShiftLeft, */ { 0, 0, 11 }, /* TokenShiftRight, */ { 0, 0, 11 },
/* TokenPlus, */ { 14, 0, 12 }, /* TokenMinus, */ { 14, 0, 12 },
/* TokenAsterisk, */ { 14, 0, 13 }, /* TokenSlash, */ { 0, 0, 13 }, /* TokenModulus, */ { 0, 0, 13 },
/* TokenIncrement, */ { 14, 15, 0 }, /* TokenDecrement, */ { 14, 15, 0 }, /* TokenUnaryNot, */ { 14, 0, 0 }, /* TokenUnaryExor, */ { 14, 0, 0 }, /* TokenSizeof, */ { 14, 0, 0 },
/* TokenLeftSquareBracket, */ { 15, 0, 0 }, /* TokenRightSquareBracket, */ { 0, 0, 0 }, /* TokenDot, */ { 0, 0, 15 }, /* TokenArrow, */ { 0, 0, 15 },
/* TokenOpenBracket, */ { 15, 0, 0 }, /* TokenCloseBracket, */ { 0, 0, 0 }
};
/* parse an expression with operator precedence */
int ParseExpression(struct ParseState *Parser, struct Value **Result)
{
}
#endif
/* parse an expression. operator precedence is not supported */ /* parse an expression. operator precedence is not supported */
int ParseIntExpression(struct ParseState *Parser) int ParseIntExpression(struct ParseState *Parser)
@ -474,6 +426,94 @@ int ParseIntExpression(struct ParseState *Parser)
return Result; return Result;
} }
/* do a function call */
void ParseFunctionCall(struct ParseState *Parser, struct Value **Result, const char *FuncName)
{
struct Value *FuncValue;
struct Value *Param;
struct Value **ParamArray;
int ArgCount;
enum LexToken Token = LexGetToken(Parser, NULL, TRUE); /* open bracket */
if (Parser->Mode == RunModeRun)
{ /* get the function definition */
VariableGet(Parser, FuncName, &FuncValue);
if (FuncValue->Typ->Base != TypeFunction)
ProgramFail(Parser, "not a function - can't call");
*Result = VariableAllocValueFromType(Parser, FuncValue->Val->FuncDef.ReturnType, FALSE, NULL);
HeapPushStackFrame();
ParamArray = HeapAllocStack(sizeof(struct Value *) * FuncValue->Val->FuncDef.NumParams);
if (ParamArray == NULL)
ProgramFail(Parser, "out of memory");
}
/* parse arguments */
ArgCount = 0;
do {
if (ParseExpression(Parser, &Param))
{
if (Parser->Mode == RunModeRun)
{
if (ArgCount >= FuncValue->Val->FuncDef.NumParams)
{
if (!FuncValue->Val->FuncDef.VarArgs)
ProgramFail(Parser, "too many arguments to %s()", FuncName);
}
else
{
if (FuncValue->Val->FuncDef.ParamType[ArgCount] != Param->Typ)
ProgramFail(Parser, "parameter %d to %s() is the wrong type", ArgCount+1, FuncName);
}
if (ArgCount < FuncValue->Val->FuncDef.NumParams)
ParamArray[ArgCount] = Param;
}
ArgCount++;
Token = LexGetToken(Parser, NULL, TRUE);
if (Token != TokenComma && Token != TokenCloseBracket)
ProgramFail(Parser, "comma expected");
}
else
{ /* end of argument list? */
Token = LexGetToken(Parser, NULL, TRUE);
if (!TokenCloseBracket)
ProgramFail(Parser, "bad argument");
}
} while (Token != TokenCloseBracket);
if (Parser->Mode == RunModeRun)
{ /* run the function */
if (ArgCount < FuncValue->Val->FuncDef.NumParams)
ProgramFail(Parser, "not enough arguments to '%s'", FuncName);
if (FuncValue->Val->FuncDef.Intrinsic == NULL)
{ /* run a user-defined function */
struct ParseState FuncParser = FuncValue->Val->FuncDef.Body;
int Count;
VariableStackFrameAdd(Parser, FuncValue->Val->FuncDef.Intrinsic ? FuncValue->Val->FuncDef.NumParams : 0);
TopStackFrame->NumParams = ArgCount;
TopStackFrame->ReturnValue = *Result;
for (Count = 0; Count < FuncValue->Val->FuncDef.NumParams; Count++)
VariableDefine(Parser, FuncValue->Val->FuncDef.ParamName[Count], ParamArray[Count]);
if (!ParseStatement(&FuncParser))
ProgramFail(&FuncParser, "function body expected");
if (FuncValue->Val->FuncDef.ReturnType != (*Result)->Typ)
ProgramFail(&FuncParser, "bad type of return value");
VariableStackFramePop(Parser);
}
else
FuncValue->Val->FuncDef.Intrinsic(Parser, *Result, ParamArray, ArgCount);
HeapPopStackFrame();
}
}
/* parse a function definition and store it for later */ /* parse a function definition and store it for later */
struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, char *Identifier, int IsPrototype) struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, char *Identifier, int IsPrototype)
{ {

35
picoc.h
View file

@ -30,24 +30,31 @@ struct Table;
/* lexical tokens */ /* lexical tokens */
enum LexToken enum LexToken
{ {
TokenNone, TokenEOF, TokenEndOfLine, TokenComma,
TokenIdentifier, TokenIntegerConstant, TokenFPConstant, TokenStringConstant, TokenCharacterConstant, TokenAssign, TokenAddAssign, TokenSubtractAssign, TokenMultiplyAssign, TokenDivideAssign, TokenModulusAssign,
TokenOpenBracket, TokenCloseBracket,
TokenAssign, TokenPlus, TokenMinus, TokenAsterisk, TokenSlash, TokenModulus,
TokenEquality, TokenNotEqual, TokenLessThan, TokenGreaterThan, TokenLessEqual, TokenGreaterEqual,
TokenSemicolon, TokenComma, TokenDot, TokenQuestionMark, TokenColon, TokenEllipsis,
TokenArrow, TokenAmpersand,
TokenLeftBrace, TokenRightBrace,
TokenLeftSquareBracket, TokenRightSquareBracket,
TokenLogicalAnd, TokenLogicalOr, TokenArithmeticOr, TokenArithmeticExor, TokenUnaryExor, TokenUnaryNot,
TokenAddAssign, TokenSubtractAssign, TokenMultiplyAssign, TokenDivideAssign, TokenModulusAssign,
TokenShiftLeft, TokenShiftRight,
TokenShiftLeftAssign, TokenShiftRightAssign, TokenArithmeticAndAssign, TokenArithmeticOrAssign, TokenArithmeticExorAssign, TokenShiftLeftAssign, TokenShiftRightAssign, TokenArithmeticAndAssign, TokenArithmeticOrAssign, TokenArithmeticExorAssign,
TokenIncrement, TokenDecrement, TokenSizeof, TokenQuestionMark,
TokenLogicalOr,
TokenLogicalAnd,
TokenArithmeticOr,
TokenArithmeticExor,
TokenAmpersand,
TokenEqual, TokenNotEqual,
TokenLessThan, TokenGreaterThan, TokenLessEqual, TokenGreaterEqual,
TokenShiftLeft, TokenShiftRight,
TokenPlus, TokenMinus,
TokenAsterisk, TokenSlash, TokenModulus,
TokenIncrement, TokenDecrement, TokenUnaryNot, TokenUnaryExor, TokenSizeof,
TokenLeftSquareBracket, TokenRightSquareBracket, TokenDot, TokenArrow,
TokenOpenBracket, TokenCloseBracket,
TokenIdentifier, TokenIntegerConstant, TokenFPConstant, TokenStringConstant, TokenCharacterConstant,
TokenSemicolon, TokenColon, TokenEllipsis,
TokenLeftBrace, TokenRightBrace,
TokenIntType, TokenCharType, TokenFloatType, TokenDoubleType, TokenVoidType, TokenEnumType, TokenIntType, TokenCharType, TokenFloatType, TokenDoubleType, TokenVoidType, TokenEnumType,
TokenLongType, TokenSignedType, TokenShortType, TokenStructType, TokenUnionType, TokenUnsignedType, TokenTypedef, TokenLongType, TokenSignedType, TokenShortType, TokenStructType, TokenUnionType, TokenUnsignedType, TokenTypedef,
TokenContinue, TokenDo, TokenElse, TokenFor, TokenIf, TokenWhile, TokenBreak, TokenSwitch, TokenCase, TokenDefault, TokenReturn, TokenContinue, TokenDo, TokenElse, TokenFor, TokenIf, TokenWhile, TokenBreak, TokenSwitch, TokenCase, TokenDefault, TokenReturn,
TokenHashDefine, TokenHashInclude TokenHashDefine, TokenHashInclude,
TokenNone, TokenEOF, TokenEndOfLine
}; };
/* used in dynamic memory allocation */ /* used in dynamic memory allocation */