Added function prototypes as requested in issue #74

git-svn-id: http://picoc.googlecode.com/svn/trunk@410 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2010-03-01 20:39:08 +00:00
parent cd4bea4903
commit ea10e1a369
7 changed files with 125 additions and 107 deletions

View file

@ -23,7 +23,7 @@ void LibraryInit(struct Table *GlobalTable, const char *LibraryName, struct Libr
Tokens = LexAnalyse(IntrinsicName, (*FuncList)[Count].Prototype, strlen((char *)(*FuncList)[Count].Prototype), NULL); Tokens = LexAnalyse(IntrinsicName, (*FuncList)[Count].Prototype, strlen((char *)(*FuncList)[Count].Prototype), NULL);
LexInitParser(&Parser, (*FuncList)[Count].Prototype, Tokens, IntrinsicName, TRUE); LexInitParser(&Parser, (*FuncList)[Count].Prototype, Tokens, IntrinsicName, TRUE);
TypeParse(&Parser, &ReturnType, &Identifier); TypeParse(&Parser, &ReturnType, &Identifier);
NewValue = ParseFunctionDefinition(&Parser, ReturnType, Identifier, TRUE); NewValue = ParseFunctionDefinition(&Parser, ReturnType, Identifier);
NewValue->Val->FuncDef.Intrinsic = (*FuncList)[Count].Func; NewValue->Val->FuncDef.Intrinsic = (*FuncList)[Count].Func;
HeapFreeMem(Tokens); HeapFreeMem(Tokens);
} }
@ -578,51 +578,51 @@ void LibMemcmp(struct ParseState *Parser, struct Value *ReturnValue, struct Valu
/* list of all library functions and their prototypes */ /* list of all library functions and their prototypes */
struct LibraryFunction CLibrary[] = struct LibraryFunction CLibrary[] =
{ {
{ LibPrintf, "void printf(char *, ...)" }, { LibPrintf, "void printf(char *, ...);" },
{ LibSPrintf, "char *sprintf(char *, char *, ...)" }, { LibSPrintf, "char *sprintf(char *, char *, ...);" },
{ LibGets, "void gets(char *, int)" }, { LibGets, "void gets(char *, int);" },
{ LibGetc, "int getchar()" }, { LibGetc, "int getchar();" },
{ LibExit, "void exit()" }, { LibExit, "void exit();" },
#ifdef PICOC_MATH_LIBRARY #ifdef PICOC_MATH_LIBRARY
{ LibSin, "float sin(float)" }, { LibSin, "float sin(float);" },
{ LibCos, "float cos(float)" }, { LibCos, "float cos(float);" },
{ LibTan, "float tan(float)" }, { LibTan, "float tan(float);" },
{ LibAsin, "float asin(float)" }, { LibAsin, "float asin(float);" },
{ LibAcos, "float acos(float)" }, { LibAcos, "float acos(float);" },
{ LibAtan, "float atan(float)" }, { LibAtan, "float atan(float);" },
{ LibSinh, "float sinh(float)" }, { LibSinh, "float sinh(float);" },
{ LibCosh, "float cosh(float)" }, { LibCosh, "float cosh(float);" },
{ LibTanh, "float tanh(float)" }, { LibTanh, "float tanh(float);" },
{ LibExp, "float exp(float)" }, { LibExp, "float exp(float);" },
{ LibFabs, "float fabs(float)" }, { LibFabs, "float fabs(float);" },
{ LibLog, "float log(float)" }, { LibLog, "float log(float);" },
{ LibLog10, "float log10(float)" }, { LibLog10, "float log10(float);" },
{ LibPow, "float pow(float,float)" }, { LibPow, "float pow(float,float);" },
{ LibSqrt, "float sqrt(float)" }, { LibSqrt, "float sqrt(float);" },
{ LibRound, "float round(float)" }, { LibRound, "float round(float);" },
{ LibCeil, "float ceil(float)" }, { LibCeil, "float ceil(float);" },
{ LibFloor, "float floor(float)" }, { LibFloor, "float floor(float);" },
#endif #endif
{ LibMalloc, "void *malloc(int)" }, { LibMalloc, "void *malloc(int);" },
#ifndef NO_CALLOC #ifndef NO_CALLOC
{ LibCalloc, "void *calloc(int,int)" }, { LibCalloc, "void *calloc(int,int);" },
#endif #endif
#ifndef NO_REALLOC #ifndef NO_REALLOC
{ LibRealloc, "void *realloc(void *,int)" }, { LibRealloc, "void *realloc(void *,int);" },
#endif #endif
{ LibFree, "void free(void *)" }, { LibFree, "void free(void *);" },
#ifndef NO_STRING_FUNCTIONS #ifndef NO_STRING_FUNCTIONS
{ LibStrcpy, "void strcpy(char *,char *)" }, { LibStrcpy, "void strcpy(char *,char *);" },
{ LibStrncpy, "void strncpy(char *,char *,int)" }, { LibStrncpy, "void strncpy(char *,char *,int);" },
{ LibStrcmp, "int strcmp(char *,char *)" }, { LibStrcmp, "int strcmp(char *,char *);" },
{ LibStrncmp, "int strncmp(char *,char *,int)" }, { LibStrncmp, "int strncmp(char *,char *,int);" },
{ LibStrcat, "void strcat(char *,char *)" }, { LibStrcat, "void strcat(char *,char *);" },
{ LibIndex, "char *index(char *,int)" }, { LibIndex, "char *index(char *,int);" },
{ LibRindex, "char *rindex(char *,int)" }, { LibRindex, "char *rindex(char *,int);" },
{ LibStrlen, "int strlen(char *)" }, { LibStrlen, "int strlen(char *);" },
{ LibMemset, "void memset(void *,int,int)" }, { LibMemset, "void memset(void *,int,int);" },
{ LibMemcpy, "void memcpy(void *,void *,int)" }, { LibMemcpy, "void memcpy(void *,void *,int);" },
{ LibMemcmp, "int memcmp(void *,void *,int)" }, { LibMemcmp, "int memcmp(void *,void *,int);" },
#endif #endif
{ NULL, NULL } { NULL, NULL }
}; };

View file

@ -1227,6 +1227,9 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
struct ParseState FuncParser; struct ParseState FuncParser;
int Count; int Count;
if (FuncValue->Val->FuncDef.Body.Pos == NULL)
ProgramFail(Parser, "'%s' is undefined", FuncName);
memcpy((void *)&FuncParser, (void *)&FuncValue->Val->FuncDef.Body, sizeof(struct ParseState)); memcpy((void *)&FuncParser, (void *)&FuncValue->Val->FuncDef.Body, sizeof(struct ParseState));
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;

View file

@ -736,63 +736,63 @@ void Cerrormsg (struct ParseState *Parser, struct Value *ReturnValue, struct Val
/* list of all library functions and their prototypes */ /* list of all library functions and their prototypes */
struct LibraryFunction PlatformLibrary[] = struct LibraryFunction PlatformLibrary[] =
{ {
{ Csignal, "int signal()" }, { Csignal, "int signal();" },
{ Cinput, "int input()" }, { Cinput, "int input();" },
{ Cdelay, "void delay(int)" }, { Cdelay, "void delay(int);" },
{ Crand, "int rand(int)" }, { Crand, "int rand(int);" },
{ Ctime, "int time()" }, { Ctime, "int time();" },
{ Ciodir, "void iodir(int)" }, { Ciodir, "void iodir(int);" },
{ Cioread, "int ioread()" }, { Cioread, "int ioread();" },
{ Ciowrite, "void iowrite(int)" }, { Ciowrite, "void iowrite(int);" },
{ Cpeek, "int peek(int, int)" }, { Cpeek, "int peek(int, int);" },
{ Cpoke, "void poke(int, int, int)" }, { Cpoke, "void poke(int, int, int);" },
{ Cmotors, "void motors(int, int)" }, { Cmotors, "void motors(int, int);" },
{ Cmotors2, "void motors2(int, int)" }, { Cmotors2, "void motors2(int, int);" },
{ Cservos, "void servos(int, int)" }, { Cservos, "void servos(int, int);" },
{ Cservos2, "void servos2(int, int)" }, { Cservos2, "void servos2(int, int);" },
{ Cencoders, "void encoders()" }, { Cencoders, "void encoders();" },
{ Claser, "void laser(int)" }, { Claser, "void laser(int);" },
{ Csonar, "int sonar(int)" }, { Csonar, "int sonar(int);" },
{ Crange, "int range()" }, { Crange, "int range();" },
{ Cbattery, "int battery()" }, { Cbattery, "int battery();" },
{ Cvcolor, "void vcolor(int, int, int, int, int, int, int)" }, { Cvcolor, "void vcolor(int, int, int, int, int, int, int);" },
{ Cvfind, "int vfind(int, int, int, int, int)" }, { Cvfind, "int vfind(int, int, int, int, int);" },
{ Cvcam, "void vcam(int)" }, { Cvcam, "void vcam(int);" },
{ Cvcap, "void vcap()" }, { Cvcap, "void vcap();" },
{ Cvrcap, "void vrcap()" }, { Cvrcap, "void vrcap();" },
{ Cvdiff, "void vdiff(int)" }, { Cvdiff, "void vdiff(int);" },
{ Cvpix, "void vpix(int, int)" }, { Cvpix, "void vpix(int, int);" },
{ Cvscan, "int vscan(int, int)" }, { Cvscan, "int vscan(int, int);" },
{ Cvmean, "void vmean()" }, { Cvmean, "void vmean();" },
{ Cvblob, "int vblob(int, int)" }, { Cvblob, "int vblob(int, int);" },
{ Cvjpeg, "int vjpeg(int)" }, { Cvjpeg, "int vjpeg(int);" },
{ Cvsend, "void vsend(int)" }, { Cvsend, "void vsend(int);" },
{ Ccompass, "int compass()" }, { Ccompass, "int compass();" },
{ Canalog, "int analog(int)" }, { Canalog, "int analog(int);" },
{ Ctilt, "int tilt(int)" }, { Ctilt, "int tilt(int);" },
{ Cgps, "void gps()" }, { Cgps, "void gps();" },
{ Creadi2c, "int readi2c(int, int)" }, { Creadi2c, "int readi2c(int, int);" },
{ Creadi2c2, "int readi2c2(int, int)" }, { Creadi2c2, "int readi2c2(int, int);" },
{ Cwritei2c, "void writei2c(int, int, int)" }, { Cwritei2c, "void writei2c(int, int, int);" },
{ Csin, "int sin(int)" }, { Csin, "int sin(int);" },
{ Ccos, "int cos(int)" }, { Ccos, "int cos(int);" },
{ Ctan, "int tan(int)" }, { Ctan, "int tan(int);" },
{ Casin, "int asin(int, int)" }, { Casin, "int asin(int, int);" },
{ Cacos, "int acos(int, int)" }, { Cacos, "int acos(int, int);" },
{ Catan, "int atan(int, int)" }, { Catan, "int atan(int, int);" },
{ Cgps_head, "int gps_head(int, int, int, int)" }, { Cgps_head, "int gps_head(int, int, int, int);" },
{ Cgps_dist, "int gps_dist(int, int, int, int)" }, { Cgps_dist, "int gps_dist(int, int, int, int);" },
{ Csqrt, "int sqrt(int)" }, { Csqrt, "int sqrt(int);" },
{ Cnnshow, "void nnshow(int)" }, { Cnnshow, "void nnshow(int);" },
{ Cnnset, "void nnset(int, int, int, int, int, int, int, int, int)" }, { Cnnset, "void nnset(int, int, int, int, int, int, int, int, int);" },
{ Cnninit, "void nninit()" }, { Cnninit, "void nninit();" },
{ Cnntrain, "void nntrain()" }, { Cnntrain, "void nntrain();" },
{ Cnntest, "int nntest(int, int, int, int, int, int, int, int)" }, { Cnntest, "int nntest(int, int, int, int, int, int, int, int);" },
{ Cnnmatchblob, "int nnmatchblob(int)" }, { Cnnmatchblob, "int nnmatchblob(int);" },
{ Cnnlearnblob, "void nnlearnblob(int)" }, { Cnnlearnblob, "void nnlearnblob(int);" },
{ Cautorun, "void autorun(int)" }, { Cautorun, "void autorun(int);" },
{ Clineno, "int lineno()" }, { Clineno, "int lineno();" },
{ Cerrormsg, "void errormsg(char *)" }, { Cerrormsg, "void errormsg(char *);" },
{ NULL, NULL } { NULL, NULL }
}; };

View file

@ -22,9 +22,9 @@ void Cerrormsg (struct ParseState *Parser, struct Value *ReturnValue, struct Val
/* list of all library functions and their prototypes */ /* list of all library functions and their prototypes */
struct LibraryFunction PlatformLibrary[] = struct LibraryFunction PlatformLibrary[] =
{ {
{ Ctest, "void test(int)" }, { Ctest, "void test(int);" },
{ Clineno, "int lineno()" }, { Clineno, "int lineno();" },
{ Cerrormsg, "void errorprintf(char *,...)" }, { Cerrormsg, "void errorprintf(char *,...);" },
{ NULL, NULL } { NULL, NULL }
}; };

27
parse.c
View file

@ -27,12 +27,13 @@ enum ParseResult ParseStatementMaybeRun(struct ParseState *Parser, int Condition
} }
/* parse a function definition and store it for later */ /* parse a function definition and store it for later */
struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, char *Identifier, int IsPrototype) struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, char *Identifier)
{ {
struct ValueType *ParamType; struct ValueType *ParamType;
char *ParamIdentifier; char *ParamIdentifier;
enum LexToken Token; enum LexToken Token;
struct Value *FuncValue; struct Value *FuncValue;
struct Value *OldFuncValue;
struct ParseState ParamParser; struct ParseState ParamParser;
struct ParseState FuncBody; struct ParseState FuncBody;
int ParamCount = 0; int ParamCount = 0;
@ -90,9 +91,14 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp
if (FuncValue->Val->FuncDef.NumParams != 0 && Token != TokenCloseBracket && Token != TokenComma && Token != TokenEllipsis) if (FuncValue->Val->FuncDef.NumParams != 0 && Token != TokenCloseBracket && Token != TokenComma && Token != TokenEllipsis)
ProgramFail(&ParamParser, "bad parameter"); ProgramFail(&ParamParser, "bad parameter");
if (!IsPrototype) /* look for a function body */
Token = LexGetToken(Parser, NULL, FALSE);
if (Token == TokenSemicolon)
LexGetToken(Parser, NULL, TRUE); /* it's a prototype, absorb the trailing semicolon */
else
{ {
if (LexGetToken(Parser, NULL, FALSE) != TokenLeftBrace) /* it's a full function definition with a body */
if (Token != TokenLeftBrace)
ProgramFail(Parser, "bad function definition"); ProgramFail(Parser, "bad function definition");
FuncBody = *Parser; FuncBody = *Parser;
@ -101,11 +107,20 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp
FuncValue->Val->FuncDef.Body = FuncBody; FuncValue->Val->FuncDef.Body = FuncBody;
FuncValue->Val->FuncDef.Body.Pos = LexCopyTokens(&FuncBody, Parser); FuncValue->Val->FuncDef.Body.Pos = LexCopyTokens(&FuncBody, Parser);
/* is this function already in the global table? */
if (TableGet(&GlobalTable, Identifier, &OldFuncValue))
{
if (OldFuncValue->Val->FuncDef.Body.Pos == NULL)
TableDelete(&GlobalTable, Identifier); /* override an old function prototype */
else
ProgramFail(Parser, "'%s' is already defined", Identifier);
}
} }
if (!TableSet(&GlobalTable, Identifier, FuncValue)) if (!TableSet(&GlobalTable, Identifier, FuncValue))
ProgramFail(Parser, "'%s' is already defined", Identifier); ProgramFail(Parser, "'%s' is already defined", Identifier);
return FuncValue; return FuncValue;
} }
@ -184,7 +199,7 @@ int ParseDeclaration(struct ParseState *Parser, enum LexToken Token)
/* handle function definitions */ /* handle function definitions */
if (LexGetToken(Parser, NULL, FALSE) == TokenOpenBracket) if (LexGetToken(Parser, NULL, FALSE) == TokenOpenBracket)
{ {
ParseFunctionDefinition(Parser, Typ, Identifier, FALSE); ParseFunctionDefinition(Parser, Typ, Identifier);
return FALSE; return FALSE;
} }
else else

View file

@ -311,7 +311,7 @@ void LexInteractiveStatementPrompt();
/* parse.c */ /* parse.c */
enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemicolon); enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemicolon);
struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, char *Identifier, int IsProtoType); struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, char *Identifier);
void Parse(const char *FileName, const char *Source, int SourceLen, int RunIt); void Parse(const char *FileName, const char *Source, int SourceLen, int RunIt);
void ParseInteractive(); void ParseInteractive();
void ParseCleanup(); void ParseCleanup();

View file

@ -26,7 +26,7 @@ void VariableFree(struct Value *Val)
if (Val->ValOnHeap) if (Val->ValOnHeap)
{ {
/* free function bodies */ /* free function bodies */
if (Val->Typ == &FunctionType && Val->Val->FuncDef.Intrinsic == NULL) if (Val->Typ == &FunctionType && Val->Val->FuncDef.Intrinsic == NULL && Val->Val->FuncDef.Body.Pos != NULL)
HeapFreeMem((void *)Val->Val->FuncDef.Body.Pos); HeapFreeMem((void *)Val->Val->FuncDef.Body.Pos);
/* free macro bodies */ /* free macro bodies */