Implemented ellipsis for stdargs and stdarg stack handling

git-svn-id: http://picoc.googlecode.com/svn/trunk@95 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-02-20 09:04:45 +00:00
parent e6e62a26df
commit 89e5c66189
7 changed files with 31 additions and 18 deletions

View file

@ -1,5 +1,5 @@
CC=gcc
CFLAGS=-Wall -g #-DDEBUG_HEAP -DDEBUG_LEXER
CFLAGS=-Wall -g #-DDEBUG_LEXER #-DDEBUG_HEAP -DDEBUG_LEXER
LIBS=-lm
TARGET = picoc

View file

@ -23,9 +23,9 @@ struct IntrinsicFunction
const char *Prototype;
} Intrinsics[] =
{
{ IntrinsicSayHello, "void sayhello()" }, /* -1 */
{ IntrinsicPrintf, "void printf()" }, /* -2 */
{ IntrinsicPrintInt, "void printint(int)" }, /* -3 */
{ IntrinsicSayHello, "void sayhello()" },
{ IntrinsicPrintf, "void printf(char *, ...)" },
{ IntrinsicPrintInt, "void printint(int)" },
};
void IntrinsicInit(struct Table *GlobalTable)

3
lex.c
View file

@ -14,6 +14,7 @@
#define NEXTIS(c,x,y) { if (NextChar == (c)) { Lexer->Pos++; GotToken = (x); } else GotToken = (y); }
#define NEXTIS3(c,x,d,y,z) { if (NextChar == (c)) { Lexer->Pos++; GotToken = (x); } else NEXTIS(d,y,z) }
#define NEXTIS4(c,x,d,y,e,z,a) { if (NextChar == (c)) { Lexer->Pos++; GotToken = (x); } else NEXTIS3(d,y,e,z,a) }
#define NEXTISEXACTLY3(c,d,y,z) { if (NextChar == (c) && Lexer->Pos[1] == (d)) { Lexer->Pos += 2; GotToken = (y); } else GotToken = (z); }
static union AnyValue LexAnyValue;
static struct Value LexValue = { TypeVoid, &LexAnyValue, FALSE, FALSE };
@ -325,7 +326,7 @@ enum LexToken LexScanGetToken(struct LexState *Lexer, struct Value **Value)
case '^': GotToken = TokenArithmeticExor; break;
case '~': GotToken = TokenUnaryExor; break;
case ',': GotToken = TokenComma; break;
case '.': GotToken = TokenDot; break;
case '.': NEXTISEXACTLY3('.', '.', TokenEllipsis, TokenDot); break;
case ':': GotToken = TokenColon; break;
default: LexFail(Lexer, "illegal character '%c'", ThisChar); break;
}

31
parse.c
View file

@ -43,13 +43,14 @@ void ParseFunctionCall(struct ParseState *Parser, struct Value **Result, const c
{
if (Parser->Mode == RunModeRun)
{
if (ArgCount >= FuncValue->Val->FuncDef.NumParams)
if (ArgCount >= FuncValue->Val->FuncDef.NumParams && !FuncValue->Val->FuncDef.VarArgs)
ProgramFail(Parser, "too many arguments to %s()", FuncName);
if (FuncValue->Val->FuncDef.ParamType[ArgCount] != Param->Typ)
ProgramFail(Parser, "parameter %d to %s() is the wrong type", ArgCount, FuncName);
ProgramFail(Parser, "parameter %d to %s() is the wrong type", ArgCount+1, FuncName);
ParamArray[ArgCount] = Param;
if (ArgCount < FuncValue->Val->FuncDef.NumParams)
ParamArray[ArgCount] = Param;
}
ArgCount++;
@ -58,7 +59,7 @@ void ParseFunctionCall(struct ParseState *Parser, struct Value **Result, const c
ProgramFail(Parser, "comma expected");
}
else
{
{ /* end of argument list? */
Token = LexGetToken(Parser, NULL, TRUE);
if (!TokenCloseBracket)
ProgramFail(Parser, "bad argument");
@ -78,7 +79,7 @@ void ParseFunctionCall(struct ParseState *Parser, struct Value **Result, const c
VariableStackFrameAdd(Parser, FuncValue->Val->FuncDef.Intrinsic ? FuncValue->Val->FuncDef.NumParams : 0);
TopStackFrame->NumParams = ArgCount;
TopStackFrame->ReturnValue = *Result;
for (Count = 0; Count < ArgCount; Count++)
for (Count = 0; Count < FuncValue->Val->FuncDef.NumParams; Count++)
VariableDefine(Parser, FuncValue->Val->FuncDef.ParamName[Count], ParamArray[Count]);
if (!ParseStatement(&FuncParser))
@ -90,7 +91,7 @@ void ParseFunctionCall(struct ParseState *Parser, struct Value **Result, const c
VariableStackFramePop(Parser);
}
else
FuncValue->Val->FuncDef.Intrinsic(*Result, ParamArray);
FuncValue->Val->FuncDef.Intrinsic(*Result, ParamArray, ArgCount);
HeapPopStackFrame();
}
@ -450,18 +451,28 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp
FuncValue->Typ = &FunctionType;
FuncValue->Val->FuncDef.ReturnType = ReturnType;
FuncValue->Val->FuncDef.NumParams = ParamCount;
FuncValue->Val->FuncDef.VarArgs = FALSE;
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 */
TypeParse(&ParamParser, &ParamType, &ParamIdentifier);
FuncValue->Val->FuncDef.ParamType[ParamCount] = ParamType;
FuncValue->Val->FuncDef.ParamName[ParamCount] = ParamIdentifier;
if (ParamCount == FuncValue->Val->FuncDef.NumParams-1 && LexGetToken(&ParamParser, NULL, FALSE) == TokenEllipsis)
{ /* ellipsis at end */
FuncValue->Val->FuncDef.NumParams--;
FuncValue->Val->FuncDef.VarArgs = TRUE;
break;
}
else
{ /* add a parameter */
TypeParse(&ParamParser, &ParamType, &ParamIdentifier);
FuncValue->Val->FuncDef.ParamType[ParamCount] = ParamType;
FuncValue->Val->FuncDef.ParamName[ParamCount] = ParamIdentifier;
}
Token = LexGetToken(&ParamParser, NULL, TRUE);
if (Token != TokenComma && ParamCount != FuncValue->Val->FuncDef.NumParams-1)
if (Token != TokenComma && ParamCount < FuncValue->Val->FuncDef.NumParams-1)
ProgramFail(&ParamParser, "comma expected");
}

View file

@ -49,7 +49,7 @@ enum LexToken
TokenOpenBracket, TokenCloseBracket,
TokenAssign, TokenPlus, TokenMinus, TokenAsterisk, TokenSlash,
TokenEquality, TokenLessThan, TokenGreaterThan, TokenLessEqual, TokenGreaterEqual,
TokenSemicolon, TokenComma, TokenDot, TokenColon,
TokenSemicolon, TokenComma, TokenDot, TokenColon, TokenEllipsis,
TokenArrow, TokenAmpersand,
TokenLeftBrace, TokenRightBrace,
TokenLeftSquareBracket, TokenRightSquareBracket,
@ -126,6 +126,7 @@ struct FuncDef
{
struct ValueType *ReturnType; /* the return value type */
int NumParams; /* the number of parameters */
int VarArgs; /* has a variable number of arguments after the explicitly specified ones */
struct ValueType **ParamType; /* array of parameter types */
const char **ParamName; /* array of parameter names */
void (*Intrinsic)(); /* intrinsic call address or NULL */

View file

@ -1 +1 @@
printf()
printf("Hello world\n");

View file

@ -1 +1 @@
IntrinsicPrintf
Hello world