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);
|
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 }
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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
27
parse.c
|
@ -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
|
||||||
|
|
2
picoc.h
2
picoc.h
|
@ -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();
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in a new issue