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:
parent
cd4bea4903
commit
ea10e1a369
78
clibrary.c
78
clibrary.c
|
@ -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);
|
||||
LexInitParser(&Parser, (*FuncList)[Count].Prototype, Tokens, IntrinsicName, TRUE);
|
||||
TypeParse(&Parser, &ReturnType, &Identifier);
|
||||
NewValue = ParseFunctionDefinition(&Parser, ReturnType, Identifier, TRUE);
|
||||
NewValue = ParseFunctionDefinition(&Parser, ReturnType, Identifier);
|
||||
NewValue->Val->FuncDef.Intrinsic = (*FuncList)[Count].Func;
|
||||
HeapFreeMem(Tokens);
|
||||
}
|
||||
|
@ -578,51 +578,51 @@ void LibMemcmp(struct ParseState *Parser, struct Value *ReturnValue, struct Valu
|
|||
/* list of all library functions and their prototypes */
|
||||
struct LibraryFunction CLibrary[] =
|
||||
{
|
||||
{ LibPrintf, "void printf(char *, ...)" },
|
||||
{ LibSPrintf, "char *sprintf(char *, char *, ...)" },
|
||||
{ LibGets, "void gets(char *, int)" },
|
||||
{ LibGetc, "int getchar()" },
|
||||
{ LibExit, "void exit()" },
|
||||
{ LibPrintf, "void printf(char *, ...);" },
|
||||
{ LibSPrintf, "char *sprintf(char *, char *, ...);" },
|
||||
{ LibGets, "void gets(char *, int);" },
|
||||
{ LibGetc, "int getchar();" },
|
||||
{ LibExit, "void exit();" },
|
||||
#ifdef PICOC_MATH_LIBRARY
|
||||
{ LibSin, "float sin(float)" },
|
||||
{ LibCos, "float cos(float)" },
|
||||
{ LibTan, "float tan(float)" },
|
||||
{ LibAsin, "float asin(float)" },
|
||||
{ LibAcos, "float acos(float)" },
|
||||
{ LibAtan, "float atan(float)" },
|
||||
{ LibSinh, "float sinh(float)" },
|
||||
{ LibCosh, "float cosh(float)" },
|
||||
{ LibTanh, "float tanh(float)" },
|
||||
{ LibExp, "float exp(float)" },
|
||||
{ LibFabs, "float fabs(float)" },
|
||||
{ LibLog, "float log(float)" },
|
||||
{ LibLog10, "float log10(float)" },
|
||||
{ LibPow, "float pow(float,float)" },
|
||||
{ LibSqrt, "float sqrt(float)" },
|
||||
{ LibRound, "float round(float)" },
|
||||
{ LibCeil, "float ceil(float)" },
|
||||
{ LibFloor, "float floor(float)" },
|
||||
{ LibSin, "float sin(float);" },
|
||||
{ LibCos, "float cos(float);" },
|
||||
{ LibTan, "float tan(float);" },
|
||||
{ LibAsin, "float asin(float);" },
|
||||
{ LibAcos, "float acos(float);" },
|
||||
{ LibAtan, "float atan(float);" },
|
||||
{ LibSinh, "float sinh(float);" },
|
||||
{ LibCosh, "float cosh(float);" },
|
||||
{ LibTanh, "float tanh(float);" },
|
||||
{ LibExp, "float exp(float);" },
|
||||
{ LibFabs, "float fabs(float);" },
|
||||
{ LibLog, "float log(float);" },
|
||||
{ LibLog10, "float log10(float);" },
|
||||
{ LibPow, "float pow(float,float);" },
|
||||
{ LibSqrt, "float sqrt(float);" },
|
||||
{ LibRound, "float round(float);" },
|
||||
{ LibCeil, "float ceil(float);" },
|
||||
{ LibFloor, "float floor(float);" },
|
||||
#endif
|
||||
{ LibMalloc, "void *malloc(int)" },
|
||||
{ LibMalloc, "void *malloc(int);" },
|
||||
#ifndef NO_CALLOC
|
||||
{ LibCalloc, "void *calloc(int,int)" },
|
||||
{ LibCalloc, "void *calloc(int,int);" },
|
||||
#endif
|
||||
#ifndef NO_REALLOC
|
||||
{ LibRealloc, "void *realloc(void *,int)" },
|
||||
{ LibRealloc, "void *realloc(void *,int);" },
|
||||
#endif
|
||||
{ LibFree, "void free(void *)" },
|
||||
{ LibFree, "void free(void *);" },
|
||||
#ifndef NO_STRING_FUNCTIONS
|
||||
{ LibStrcpy, "void strcpy(char *,char *)" },
|
||||
{ LibStrncpy, "void strncpy(char *,char *,int)" },
|
||||
{ LibStrcmp, "int strcmp(char *,char *)" },
|
||||
{ LibStrncmp, "int strncmp(char *,char *,int)" },
|
||||
{ LibStrcat, "void strcat(char *,char *)" },
|
||||
{ LibIndex, "char *index(char *,int)" },
|
||||
{ LibRindex, "char *rindex(char *,int)" },
|
||||
{ LibStrlen, "int strlen(char *)" },
|
||||
{ LibMemset, "void memset(void *,int,int)" },
|
||||
{ LibMemcpy, "void memcpy(void *,void *,int)" },
|
||||
{ LibMemcmp, "int memcmp(void *,void *,int)" },
|
||||
{ LibStrcpy, "void strcpy(char *,char *);" },
|
||||
{ LibStrncpy, "void strncpy(char *,char *,int);" },
|
||||
{ LibStrcmp, "int strcmp(char *,char *);" },
|
||||
{ LibStrncmp, "int strncmp(char *,char *,int);" },
|
||||
{ LibStrcat, "void strcat(char *,char *);" },
|
||||
{ LibIndex, "char *index(char *,int);" },
|
||||
{ LibRindex, "char *rindex(char *,int);" },
|
||||
{ LibStrlen, "int strlen(char *);" },
|
||||
{ LibMemset, "void memset(void *,int,int);" },
|
||||
{ LibMemcpy, "void memcpy(void *,void *,int);" },
|
||||
{ LibMemcmp, "int memcmp(void *,void *,int);" },
|
||||
#endif
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
|
|
@ -1227,6 +1227,9 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
|
|||
struct ParseState FuncParser;
|
||||
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));
|
||||
VariableStackFrameAdd(Parser, FuncValue->Val->FuncDef.Intrinsic ? FuncValue->Val->FuncDef.NumParams : 0);
|
||||
TopStackFrame->NumParams = ArgCount;
|
||||
|
|
|
@ -736,63 +736,63 @@ void Cerrormsg (struct ParseState *Parser, struct Value *ReturnValue, struct Val
|
|||
/* list of all library functions and their prototypes */
|
||||
struct LibraryFunction PlatformLibrary[] =
|
||||
{
|
||||
{ Csignal, "int signal()" },
|
||||
{ Cinput, "int input()" },
|
||||
{ Cdelay, "void delay(int)" },
|
||||
{ Crand, "int rand(int)" },
|
||||
{ Ctime, "int time()" },
|
||||
{ Ciodir, "void iodir(int)" },
|
||||
{ Cioread, "int ioread()" },
|
||||
{ Ciowrite, "void iowrite(int)" },
|
||||
{ Cpeek, "int peek(int, int)" },
|
||||
{ Cpoke, "void poke(int, int, int)" },
|
||||
{ Cmotors, "void motors(int, int)" },
|
||||
{ Cmotors2, "void motors2(int, int)" },
|
||||
{ Cservos, "void servos(int, int)" },
|
||||
{ Cservos2, "void servos2(int, int)" },
|
||||
{ Cencoders, "void encoders()" },
|
||||
{ Claser, "void laser(int)" },
|
||||
{ Csonar, "int sonar(int)" },
|
||||
{ Crange, "int range()" },
|
||||
{ Cbattery, "int battery()" },
|
||||
{ Cvcolor, "void vcolor(int, int, int, int, int, int, int)" },
|
||||
{ Cvfind, "int vfind(int, int, int, int, int)" },
|
||||
{ Cvcam, "void vcam(int)" },
|
||||
{ Cvcap, "void vcap()" },
|
||||
{ Cvrcap, "void vrcap()" },
|
||||
{ Cvdiff, "void vdiff(int)" },
|
||||
{ Cvpix, "void vpix(int, int)" },
|
||||
{ Cvscan, "int vscan(int, int)" },
|
||||
{ Cvmean, "void vmean()" },
|
||||
{ Cvblob, "int vblob(int, int)" },
|
||||
{ Cvjpeg, "int vjpeg(int)" },
|
||||
{ Cvsend, "void vsend(int)" },
|
||||
{ Ccompass, "int compass()" },
|
||||
{ Canalog, "int analog(int)" },
|
||||
{ Ctilt, "int tilt(int)" },
|
||||
{ Cgps, "void gps()" },
|
||||
{ Creadi2c, "int readi2c(int, int)" },
|
||||
{ Creadi2c2, "int readi2c2(int, int)" },
|
||||
{ Cwritei2c, "void writei2c(int, int, int)" },
|
||||
{ Csin, "int sin(int)" },
|
||||
{ Ccos, "int cos(int)" },
|
||||
{ Ctan, "int tan(int)" },
|
||||
{ Casin, "int asin(int, int)" },
|
||||
{ Cacos, "int acos(int, int)" },
|
||||
{ Catan, "int atan(int, int)" },
|
||||
{ Cgps_head, "int gps_head(int, int, int, int)" },
|
||||
{ Cgps_dist, "int gps_dist(int, int, int, int)" },
|
||||
{ Csqrt, "int sqrt(int)" },
|
||||
{ Cnnshow, "void nnshow(int)" },
|
||||
{ Cnnset, "void nnset(int, int, int, int, int, int, int, int, int)" },
|
||||
{ Cnninit, "void nninit()" },
|
||||
{ Cnntrain, "void nntrain()" },
|
||||
{ Cnntest, "int nntest(int, int, int, int, int, int, int, int)" },
|
||||
{ Cnnmatchblob, "int nnmatchblob(int)" },
|
||||
{ Cnnlearnblob, "void nnlearnblob(int)" },
|
||||
{ Cautorun, "void autorun(int)" },
|
||||
{ Clineno, "int lineno()" },
|
||||
{ Cerrormsg, "void errormsg(char *)" },
|
||||
{ Csignal, "int signal();" },
|
||||
{ Cinput, "int input();" },
|
||||
{ Cdelay, "void delay(int);" },
|
||||
{ Crand, "int rand(int);" },
|
||||
{ Ctime, "int time();" },
|
||||
{ Ciodir, "void iodir(int);" },
|
||||
{ Cioread, "int ioread();" },
|
||||
{ Ciowrite, "void iowrite(int);" },
|
||||
{ Cpeek, "int peek(int, int);" },
|
||||
{ Cpoke, "void poke(int, int, int);" },
|
||||
{ Cmotors, "void motors(int, int);" },
|
||||
{ Cmotors2, "void motors2(int, int);" },
|
||||
{ Cservos, "void servos(int, int);" },
|
||||
{ Cservos2, "void servos2(int, int);" },
|
||||
{ Cencoders, "void encoders();" },
|
||||
{ Claser, "void laser(int);" },
|
||||
{ Csonar, "int sonar(int);" },
|
||||
{ Crange, "int range();" },
|
||||
{ Cbattery, "int battery();" },
|
||||
{ Cvcolor, "void vcolor(int, int, int, int, int, int, int);" },
|
||||
{ Cvfind, "int vfind(int, int, int, int, int);" },
|
||||
{ Cvcam, "void vcam(int);" },
|
||||
{ Cvcap, "void vcap();" },
|
||||
{ Cvrcap, "void vrcap();" },
|
||||
{ Cvdiff, "void vdiff(int);" },
|
||||
{ Cvpix, "void vpix(int, int);" },
|
||||
{ Cvscan, "int vscan(int, int);" },
|
||||
{ Cvmean, "void vmean();" },
|
||||
{ Cvblob, "int vblob(int, int);" },
|
||||
{ Cvjpeg, "int vjpeg(int);" },
|
||||
{ Cvsend, "void vsend(int);" },
|
||||
{ Ccompass, "int compass();" },
|
||||
{ Canalog, "int analog(int);" },
|
||||
{ Ctilt, "int tilt(int);" },
|
||||
{ Cgps, "void gps();" },
|
||||
{ Creadi2c, "int readi2c(int, int);" },
|
||||
{ Creadi2c2, "int readi2c2(int, int);" },
|
||||
{ Cwritei2c, "void writei2c(int, int, int);" },
|
||||
{ Csin, "int sin(int);" },
|
||||
{ Ccos, "int cos(int);" },
|
||||
{ Ctan, "int tan(int);" },
|
||||
{ Casin, "int asin(int, int);" },
|
||||
{ Cacos, "int acos(int, int);" },
|
||||
{ Catan, "int atan(int, int);" },
|
||||
{ Cgps_head, "int gps_head(int, int, int, int);" },
|
||||
{ Cgps_dist, "int gps_dist(int, int, int, int);" },
|
||||
{ Csqrt, "int sqrt(int);" },
|
||||
{ Cnnshow, "void nnshow(int);" },
|
||||
{ Cnnset, "void nnset(int, int, int, int, int, int, int, int, int);" },
|
||||
{ Cnninit, "void nninit();" },
|
||||
{ Cnntrain, "void nntrain();" },
|
||||
{ Cnntest, "int nntest(int, int, int, int, int, int, int, int);" },
|
||||
{ Cnnmatchblob, "int nnmatchblob(int);" },
|
||||
{ Cnnlearnblob, "void nnlearnblob(int);" },
|
||||
{ Cautorun, "void autorun(int);" },
|
||||
{ Clineno, "int lineno();" },
|
||||
{ Cerrormsg, "void errormsg(char *);" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -22,9 +22,9 @@ void Cerrormsg (struct ParseState *Parser, struct Value *ReturnValue, struct Val
|
|||
/* list of all library functions and their prototypes */
|
||||
struct LibraryFunction PlatformLibrary[] =
|
||||
{
|
||||
{ Ctest, "void test(int)" },
|
||||
{ Clineno, "int lineno()" },
|
||||
{ Cerrormsg, "void errorprintf(char *,...)" },
|
||||
{ Ctest, "void test(int);" },
|
||||
{ Clineno, "int lineno();" },
|
||||
{ Cerrormsg, "void errorprintf(char *,...);" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
27
parse.c
27
parse.c
|
@ -27,12 +27,13 @@ enum ParseResult ParseStatementMaybeRun(struct ParseState *Parser, int Condition
|
|||
}
|
||||
|
||||
/* 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;
|
||||
char *ParamIdentifier;
|
||||
enum LexToken Token;
|
||||
struct Value *FuncValue;
|
||||
struct Value *OldFuncValue;
|
||||
struct ParseState ParamParser;
|
||||
struct ParseState FuncBody;
|
||||
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)
|
||||
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");
|
||||
|
||||
FuncBody = *Parser;
|
||||
|
@ -101,11 +107,20 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp
|
|||
|
||||
FuncValue->Val->FuncDef.Body = FuncBody;
|
||||
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))
|
||||
ProgramFail(Parser, "'%s' is already defined", Identifier);
|
||||
|
||||
|
||||
return FuncValue;
|
||||
}
|
||||
|
||||
|
@ -184,7 +199,7 @@ int ParseDeclaration(struct ParseState *Parser, enum LexToken Token)
|
|||
/* handle function definitions */
|
||||
if (LexGetToken(Parser, NULL, FALSE) == TokenOpenBracket)
|
||||
{
|
||||
ParseFunctionDefinition(Parser, Typ, Identifier, FALSE);
|
||||
ParseFunctionDefinition(Parser, Typ, Identifier);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
|
|
2
picoc.h
2
picoc.h
|
@ -311,7 +311,7 @@ void LexInteractiveStatementPrompt();
|
|||
|
||||
/* parse.c */
|
||||
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 ParseInteractive();
|
||||
void ParseCleanup();
|
||||
|
|
|
@ -26,7 +26,7 @@ void VariableFree(struct Value *Val)
|
|||
if (Val->ValOnHeap)
|
||||
{
|
||||
/* 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);
|
||||
|
||||
/* free macro bodies */
|
||||
|
|
Loading…
Reference in a new issue