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