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 CC=gcc
CFLAGS=-Wall -g #-DDEBUG_HEAP -DDEBUG_LEXER CFLAGS=-Wall -g #-DDEBUG_LEXER #-DDEBUG_HEAP -DDEBUG_LEXER
LIBS=-lm LIBS=-lm
TARGET = picoc TARGET = picoc

View file

@ -23,9 +23,9 @@ struct IntrinsicFunction
const char *Prototype; const char *Prototype;
} Intrinsics[] = } Intrinsics[] =
{ {
{ IntrinsicSayHello, "void sayhello()" }, /* -1 */ { IntrinsicSayHello, "void sayhello()" },
{ IntrinsicPrintf, "void printf()" }, /* -2 */ { IntrinsicPrintf, "void printf(char *, ...)" },
{ IntrinsicPrintInt, "void printint(int)" }, /* -3 */ { IntrinsicPrintInt, "void printint(int)" },
}; };
void IntrinsicInit(struct Table *GlobalTable) 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 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 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 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 union AnyValue LexAnyValue;
static struct Value LexValue = { TypeVoid, &LexAnyValue, FALSE, FALSE }; 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 = TokenArithmeticExor; break;
case '~': GotToken = TokenUnaryExor; break; case '~': GotToken = TokenUnaryExor; break;
case ',': GotToken = TokenComma; break; case ',': GotToken = TokenComma; break;
case '.': GotToken = TokenDot; break; case '.': NEXTISEXACTLY3('.', '.', TokenEllipsis, TokenDot); break;
case ':': GotToken = TokenColon; break; case ':': GotToken = TokenColon; break;
default: LexFail(Lexer, "illegal character '%c'", ThisChar); 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 (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); ProgramFail(Parser, "too many arguments to %s()", FuncName);
if (FuncValue->Val->FuncDef.ParamType[ArgCount] != Param->Typ) 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++; ArgCount++;
@ -58,7 +59,7 @@ void ParseFunctionCall(struct ParseState *Parser, struct Value **Result, const c
ProgramFail(Parser, "comma expected"); ProgramFail(Parser, "comma expected");
} }
else else
{ { /* end of argument list? */
Token = LexGetToken(Parser, NULL, TRUE); Token = LexGetToken(Parser, NULL, TRUE);
if (!TokenCloseBracket) if (!TokenCloseBracket)
ProgramFail(Parser, "bad argument"); 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); VariableStackFrameAdd(Parser, FuncValue->Val->FuncDef.Intrinsic ? FuncValue->Val->FuncDef.NumParams : 0);
TopStackFrame->NumParams = ArgCount; TopStackFrame->NumParams = ArgCount;
TopStackFrame->ReturnValue = *Result; 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]); VariableDefine(Parser, FuncValue->Val->FuncDef.ParamName[Count], ParamArray[Count]);
if (!ParseStatement(&FuncParser)) if (!ParseStatement(&FuncParser))
@ -90,7 +91,7 @@ void ParseFunctionCall(struct ParseState *Parser, struct Value **Result, const c
VariableStackFramePop(Parser); VariableStackFramePop(Parser);
} }
else else
FuncValue->Val->FuncDef.Intrinsic(*Result, ParamArray); FuncValue->Val->FuncDef.Intrinsic(*Result, ParamArray, ArgCount);
HeapPopStackFrame(); HeapPopStackFrame();
} }
@ -450,18 +451,28 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp
FuncValue->Typ = &FunctionType; FuncValue->Typ = &FunctionType;
FuncValue->Val->FuncDef.ReturnType = ReturnType; FuncValue->Val->FuncDef.ReturnType = ReturnType;
FuncValue->Val->FuncDef.NumParams = ParamCount; FuncValue->Val->FuncDef.NumParams = ParamCount;
FuncValue->Val->FuncDef.VarArgs = FALSE;
FuncValue->Val->FuncDef.ParamType = (void *)FuncValue->Val + sizeof(struct FuncDef); 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.ParamName = (void *)FuncValue->Val->FuncDef.ParamType + sizeof(struct ValueType *) * ParamCount;
FuncValue->Val->FuncDef.Body = *Parser; FuncValue->Val->FuncDef.Body = *Parser;
for (ParamCount = 0; ParamCount < FuncValue->Val->FuncDef.NumParams; ParamCount++) for (ParamCount = 0; ParamCount < FuncValue->Val->FuncDef.NumParams; ParamCount++)
{ /* harvest the parameters into the function definition */ { /* harvest the parameters into the function definition */
TypeParse(&ParamParser, &ParamType, &ParamIdentifier); if (ParamCount == FuncValue->Val->FuncDef.NumParams-1 && LexGetToken(&ParamParser, NULL, FALSE) == TokenEllipsis)
FuncValue->Val->FuncDef.ParamType[ParamCount] = ParamType; { /* ellipsis at end */
FuncValue->Val->FuncDef.ParamName[ParamCount] = ParamIdentifier; 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); 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"); ProgramFail(&ParamParser, "comma expected");
} }

View file

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

View file

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

View file

@ -1 +1 @@
IntrinsicPrintf Hello world