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:
parent
e6e62a26df
commit
89e5c66189
2
Makefile
2
Makefile
|
@ -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
|
||||
|
|
|
@ -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
3
lex.c
|
@ -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
31
parse.c
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
3
picoc.h
3
picoc.h
|
@ -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 */
|
||||
|
|
|
@ -1 +1 @@
|
|||
printf()
|
||||
printf("Hello world\n");
|
||||
|
|
|
@ -1 +1 @@
|
|||
IntrinsicPrintf
|
||||
Hello world
|
||||
|
|
Loading…
Reference in a new issue