More work on expressions. Trying to get variable lookups to work in the new system.

git-svn-id: http://picoc.googlecode.com/svn/trunk@217 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-04-05 02:24:00 +00:00
parent 61174fb115
commit 74673d965a

View file

@ -14,10 +14,10 @@
#define BRACKET_PRECEDENCE 20 #define BRACKET_PRECEDENCE 20
#if 1
/* local prototypes */ /* local prototypes */
void ExpressionParseFunctionCall(struct ParseState *Parser, struct Value **Result, const char *FuncName); void ExpressionParseFunctionCall(struct ParseState *Parser, struct Value **Result, const char *FuncName);
#if 1
/* parse a single value */ /* parse a single value */
int ExpressionParseValue(struct ParseState *Parser, struct Value **Result) int ExpressionParseValue(struct ParseState *Parser, struct Value **Result)
{ {
@ -418,8 +418,97 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
return TRUE; return TRUE;
} }
/* do a function call */
void ExpressionParseFunctionCall(struct ParseState *Parser, struct Value **Result, const char *FuncName)
{
struct Value *FuncValue;
struct Value *Param;
struct Value **ParamArray = NULL;
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 (ExpressionParse(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();
}
}
#else #else
/* local prototypes */
enum OperatorOrder enum OperatorOrder
{ {
OrderNone, OrderNone,
@ -470,6 +559,8 @@ static struct OpPrecedence OperatorPrecedence[] =
/* TokenOpenBracket, */ { 15, 0, 0 }, /* TokenCloseBracket, */ { 0, 15, 0 } /* TokenOpenBracket, */ { 15, 0, 0 }, /* TokenCloseBracket, */ { 0, 15, 0 }
}; };
void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionStack **StackTop, const char *FuncName);
/* push a node on to the expression stack */ /* push a node on to the expression stack */
void ExpressionStackPushValueNode(struct ParseState *Parser, struct ExpressionStack **StackTop, struct Value *ValueLoc) void ExpressionStackPushValueNode(struct ParseState *Parser, struct ExpressionStack **StackTop, struct Value *ValueLoc)
@ -480,6 +571,13 @@ void ExpressionStackPushValueNode(struct ParseState *Parser, struct ExpressionSt
*StackTop = StackNode; *StackTop = StackNode;
} }
/* push a blank value on to the expression stack by type */
void ExpressionStackPushValueByType(struct ParseState *Parser, struct ExpressionStack **StackTop, struct ValueType *PushType)
{
struct Value *ValueLoc = VariableAllocValueFromType(Parser, PushType, FALSE, NULL);
ExpressionStackPushValueNode(Parser, StackTop, ValueLoc);
}
/* push a value on to the expression stack */ /* push a value on to the expression stack */
void ExpressionStackPushValue(struct ParseState *Parser, struct ExpressionStack **StackTop, struct Value *PushValue) void ExpressionStackPushValue(struct ParseState *Parser, struct ExpressionStack **StackTop, struct Value *PushValue)
{ {
@ -496,7 +594,7 @@ void ExpressionPushInt(struct ParseState *Parser, struct ExpressionStack **Stack
void ExpressionPushFP(struct ParseState *Parser, struct ExpressionStack **StackTop, double FPValue) void ExpressionPushFP(struct ParseState *Parser, struct ExpressionStack **StackTop, double FPValue)
{ {
struct Value *ValueLoc = VariableAllocValueFromType(Parser, &IntType, FALSE, NULL); struct Value *ValueLoc = VariableAllocValueFromType(Parser, &FPType, FALSE, NULL);
ValueLoc->Val->FP = FPValue; ValueLoc->Val->FP = FPValue;
ExpressionStackPushValueNode(Parser, StackTop, ValueLoc); ExpressionStackPushValueNode(Parser, StackTop, ValueLoc);
} }
@ -895,6 +993,38 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
ProgramFail(Parser, "operator not expected here"); ProgramFail(Parser, "operator not expected here");
} }
} }
else if (Token == TokenIdentifier)
{ /* it's a variable, function or a macro */
if (LexGetToken(Parser, NULL, FALSE) == TokenOpenBracket)
ExpressionParseFunctionCall(Parser, &StackTop, LexValue->Val->Identifier);
else
{
if (Parser->Mode == RunModeRun)
{
struct Value *VariableValue = NULL;
VariableGet(Parser, LexValue->Val->Identifier, &VariableValue);
if (VariableValue->Typ->Base == TypeMacro)
{
ProgramFail(Parser, "XXX macros unimplemented");
#if 0
struct ParseState MacroParser = VariableValue->Val->Parser;
if (!ExpressionParse(&MacroParser, Result) || LexGetToken(&MacroParser, NULL, FALSE) != TokenEndOfFunction)
ProgramFail(&MacroParser, "expression expected");
#endif
}
else if (VariableValue->Typ == TypeVoid)
ProgramFail(Parser, "a void value isn't much use here");
else
{ /* it's a value variable */
ExpressionStackPushValue(Parser, &StackTop, VariableValue);
}
}
else /* push a dummy value */
ExpressionStackPushValueByType(Parser, &StackTop, &VoidType);
}
}
else if ((int)Token <= (int)TokenCharacterConstant) else if ((int)Token <= (int)TokenCharacterConstant)
{ /* it's a value of some sort, push it */ { /* it's a value of some sort, push it */
if (!PrefixState) if (!PrefixState)
@ -926,32 +1056,12 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
return TRUE; return TRUE;
} }
#endif
/* parse an expression. operator precedence is not supported */
int ExpressionParseInt(struct ParseState *Parser)
{
struct Value *Val;
int Result = 0;
if (!ExpressionParse(Parser, &Val))
ProgramFail(Parser, "expression expected");
if (Parser->Mode == RunModeRun)
{
if (Val->Typ->Base != TypeInt)
ProgramFail(Parser, "integer value expected");
Result = Val->Val->Integer;
VariableStackPop(Parser, Val);
}
return Result;
}
/* do a function call */ /* do a function call */
void ExpressionParseFunctionCall(struct ParseState *Parser, struct Value **Result, const char *FuncName) void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionStack **StackTop, const char *FuncName)
{ {
struct Value *ReturnValue;
struct Value *FuncValue; struct Value *FuncValue;
struct Value *Param; struct Value *Param;
struct Value **ParamArray = NULL; struct Value **ParamArray = NULL;
@ -964,7 +1074,8 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct Value **Resul
if (FuncValue->Typ->Base != TypeFunction) if (FuncValue->Typ->Base != TypeFunction)
ProgramFail(Parser, "not a function - can't call"); ProgramFail(Parser, "not a function - can't call");
*Result = VariableAllocValueFromType(Parser, FuncValue->Val->FuncDef.ReturnType, FALSE, NULL); ExpressionStackPushValueByType(Parser, StackTop, FuncValue->Val->FuncDef.ReturnType);
ReturnValue = (*StackTop)->Val;
HeapPushStackFrame(); HeapPushStackFrame();
ParamArray = HeapAllocStack(sizeof(struct Value *) * FuncValue->Val->FuncDef.NumParams); ParamArray = HeapAllocStack(sizeof(struct Value *) * FuncValue->Val->FuncDef.NumParams);
if (ParamArray == NULL) if (ParamArray == NULL)
@ -1018,21 +1129,44 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct Value **Resul
VariableStackFrameAdd(Parser, FuncValue->Val->FuncDef.Intrinsic ? FuncValue->Val->FuncDef.NumParams : 0); VariableStackFrameAdd(Parser, FuncValue->Val->FuncDef.Intrinsic ? FuncValue->Val->FuncDef.NumParams : 0);
TopStackFrame->NumParams = ArgCount; TopStackFrame->NumParams = ArgCount;
TopStackFrame->ReturnValue = *Result; TopStackFrame->ReturnValue = ReturnValue;
for (Count = 0; Count < FuncValue->Val->FuncDef.NumParams; Count++) for (Count = 0; Count < FuncValue->Val->FuncDef.NumParams; Count++)
VariableDefine(Parser, FuncValue->Val->FuncDef.ParamName[Count], ParamArray[Count]); VariableDefine(Parser, FuncValue->Val->FuncDef.ParamName[Count], ParamArray[Count]);
if (!ParseStatement(&FuncParser)) if (!ParseStatement(&FuncParser))
ProgramFail(&FuncParser, "function body expected"); ProgramFail(&FuncParser, "function body expected");
if (FuncValue->Val->FuncDef.ReturnType != (*Result)->Typ) if (FuncValue->Val->FuncDef.ReturnType != ReturnValue->Typ)
ProgramFail(&FuncParser, "bad type of return value"); ProgramFail(&FuncParser, "bad type of return value");
VariableStackFramePop(Parser); VariableStackFramePop(Parser);
} }
else else
FuncValue->Val->FuncDef.Intrinsic(Parser, *Result, ParamArray, ArgCount); FuncValue->Val->FuncDef.Intrinsic(Parser, ReturnValue, ParamArray, ArgCount);
HeapPopStackFrame(); HeapPopStackFrame();
} }
} }
#endif
/* parse an expression. operator precedence is not supported */
int ExpressionParseInt(struct ParseState *Parser)
{
struct Value *Val;
int Result = 0;
if (!ExpressionParse(Parser, &Val))
ProgramFail(Parser, "expression expected");
if (Parser->Mode == RunModeRun)
{
if (Val->Typ->Base != TypeInt)
ProgramFail(Parser, "integer value expected");
Result = Val->Val->Integer;
VariableStackPop(Parser, Val);
}
return Result;
}