Added support for #include of predefined libraries.

Created a stdio.h predefined library.


git-svn-id: http://picoc.googlecode.com/svn/trunk@420 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2010-06-05 19:00:46 +00:00
parent fa3e9a1187
commit a591133f35
8 changed files with 160 additions and 9 deletions

View file

@ -3,7 +3,9 @@ CFLAGS=-Wall -pedantic -g -DUNIX_HOST
LIBS=-lm
TARGET = picoc
SRCS = picoc.c table.c lex.c parse.c expression.c heap.c type.c variable.c clibrary.c library_unix.c platform.c platform_unix.c math_library.c
SRCS = picoc.c table.c lex.c parse.c expression.c heap.c type.c \
variable.c clibrary.c library_unix.c platform.c platform_unix.c \
math_library.c include.c library_stdio.c
OBJS := $(SRCS:%.c=%.o)
all: depend $(TARGET)

60
include.c Normal file
View file

@ -0,0 +1,60 @@
#include "picoc.h"
#ifndef NO_HASH_INCLUDE
/* a list of libraries we can include */
struct IncludeLibrary
{
const char *IncludeName;
void (*SetupFunction)(void);
struct LibraryFunction (*FuncList)[];
const char *SetupCSource;
};
struct IncludeLibrary IncludeLibInfo[] =
{
{ "stdio.h",
&StdioSetupFunc,
&StdioFunctions,
StdioDefs },
{ NULL, NULL, NULL, NULL }
};
/* include one of a number of predefined libraries, or perhaps an actual file */
void IncludeFile(char *FileName)
{
struct IncludeLibrary *LInclude;
/* scan for the include file name to see if it's in our list of predefined includes */
for (LInclude = &IncludeLibInfo[0]; LInclude->IncludeName != NULL; LInclude++)
{
if (strcmp(LInclude->IncludeName, FileName) == 0)
{
/* found it - protect against multiple inclusion */
if (!VariableDefined(FileName))
{
VariableDefine(NULL, FileName, NULL, &VoidType, FALSE);
/* parse the setup C source code - may define types etc. */
if (LInclude->SetupFunction != NULL)
(*LInclude->SetupFunction)();
/* parse the setup C source code - may define types etc. */
if (LInclude->SetupCSource != NULL)
Parse(FileName, LInclude->SetupCSource, strlen(LInclude->SetupCSource), TRUE);
/* set up the library functions */
if (LInclude->FuncList != NULL)
LibraryInit(&GlobalTable, FileName, LInclude->FuncList);
}
return;
}
}
/* not a predefined file, read a real file */
PlatformScanFile(FileName);
}
#endif /* NO_HASH_INCLUDE */

15
lex.c
View file

@ -211,6 +211,9 @@ enum LexToken LexGetWord(struct LexState *Lexer, struct Value *Value)
Value->Val->Identifier = TableStrRegister2(StartPos, Lexer->Pos - StartPos);
Token = LexCheckReservedWord(Value->Val->Identifier);
if (Token == TokenHashInclude)
Lexer->ScanningHashInclude = TRUE;
if (Token != TokenNone)
return Token;
@ -270,7 +273,7 @@ unsigned char LexUnEscapeCharacter(const char **From, const char *End)
}
/* get a string constant - used while scanning */
enum LexToken LexGetStringConstant(struct LexState *Lexer, struct Value *Value)
enum LexToken LexGetStringConstant(struct LexState *Lexer, struct Value *Value, char EndChar)
{
int Escape = FALSE;
const char *StartPos = Lexer->Pos;
@ -280,7 +283,7 @@ enum LexToken LexGetStringConstant(struct LexState *Lexer, struct Value *Value)
char *RegString;
struct Value *ArrayValue;
while (Lexer->Pos != Lexer->End && (*Lexer->Pos != '"' || Escape))
while (Lexer->Pos != Lexer->End && (*Lexer->Pos != EndChar || Escape))
{
/* find the end */
if (Escape)
@ -315,7 +318,7 @@ enum LexToken LexGetStringConstant(struct LexState *Lexer, struct Value *Value)
/* create the the pointer for this char* */
Value->Typ = CharPtrType;
Value->Val->NativePointer = RegString;
if (*Lexer->Pos == '"')
if (*Lexer->Pos == EndChar)
LEXER_INC(Lexer);
return TokenStringConstant;
@ -370,6 +373,7 @@ enum LexToken LexScanGetToken(struct LexState *Lexer, struct Value **Value)
{
Lexer->Line++;
Lexer->Pos++;
Lexer->ScanningHashInclude = FALSE;
#ifdef FANCY_ERROR_REPORTING
Lexer->CharacterPos = 0;
#endif
@ -393,7 +397,7 @@ enum LexToken LexScanGetToken(struct LexState *Lexer, struct Value **Value)
LEXER_INC(Lexer);
switch (ThisChar)
{
case '"': GotToken = LexGetStringConstant(Lexer, *Value); break;
case '"': GotToken = LexGetStringConstant(Lexer, *Value, '"'); break;
case '\'': GotToken = LexGetCharacterConstant(Lexer, *Value); break;
case '(': GotToken = TokenOpenBracket; break;
case ')': GotToken = TokenCloseBracket; break;
@ -403,7 +407,7 @@ enum LexToken LexScanGetToken(struct LexState *Lexer, struct Value **Value)
case '*': NEXTIS('=', TokenMultiplyAssign, TokenAsterisk); break;
case '/': if (NextChar == '/' || NextChar == '*') LexSkipComment(Lexer, NextChar); else NEXTIS('=', TokenDivideAssign, TokenSlash); break;
case '%': NEXTIS('=', TokenModulusAssign, TokenModulus); break;
case '<': NEXTIS3PLUS('=', TokenLessEqual, '<', TokenShiftLeft, '=', TokenShiftLeftAssign, TokenLessThan); break;
case '<': if (Lexer->ScanningHashInclude) GotToken = LexGetStringConstant(Lexer, *Value, '>'); else { NEXTIS3PLUS('=', TokenLessEqual, '<', TokenShiftLeft, '=', TokenShiftLeftAssign, TokenLessThan); } break;
case '>': NEXTIS3PLUS('=', TokenGreaterEqual, '>', TokenShiftRight, '=', TokenShiftRightAssign, TokenGreaterThan); break;
case ';': GotToken = TokenSemicolon; break;
case '&': NEXTIS3('=', TokenArithmeticAndAssign, '&', TokenLogicalAnd, TokenAmpersand); break;
@ -524,6 +528,7 @@ void *LexAnalyse(const char *FileName, const char *Source, int SourceLen, int *T
Lexer.End = Source + SourceLen;
Lexer.Line = 1;
Lexer.FileName = FileName;
Lexer.ScanningHashInclude = FALSE;
#ifdef FANCY_ERROR_REPORTING
Lexer.CharacterPos = 1;
Lexer.SourceText = Source;

58
library_stdio.c Normal file
View file

@ -0,0 +1,58 @@
/* stdio.h library */
#include "picoc.h"
#ifndef NO_HASH_INCLUDE
void StdioFopen(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
ReturnValue->Val->NativePointer = fopen(Param[0]->Val->NativePointer, Param[1]->Val->NativePointer);
}
void StdioFclose(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
ReturnValue->Val->Integer = fclose(Param[0]->Val->NativePointer);
}
void StdioFread(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
ReturnValue->Val->Integer = fread(Param[0]->Val->NativePointer, Param[1]->Val->Integer, Param[2]->Val->Integer, Param[3]->Val->NativePointer);
}
void StdioFwrite(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
ReturnValue->Val->Integer = fwrite(Param[0]->Val->NativePointer, Param[1]->Val->Integer, Param[2]->Val->Integer, Param[3]->Val->NativePointer);
}
void StdioFgetc(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
ReturnValue->Val->Integer = fgetc(Param[0]->Val->NativePointer);
}
void StdioFgets(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
ReturnValue->Val->NativePointer = fgets(Param[0]->Val->NativePointer, Param[1]->Val->Integer, Param[2]->Val->NativePointer);
}
const char StdioDefs[] = "\
typedef struct FILEStruct FILE; \
";
struct LibraryFunction StdioFunctions[] =
{
{ StdioFopen, "FILE *fopen(char *, char *);" },
{ StdioFclose, "int fclose(FILE *);" },
{ StdioFread, "int fread(void *, int, int, FILE *);" },
{ StdioFwrite, "int fwrite(void *, int, int, FILE *);" },
{ StdioFgetc, "int fgetc(FILE *);" },
{ StdioFgetc, "int getc(FILE *);" },
{ StdioFgets, "char *fgets(char *, int, FILE *);" },
{ NULL, NULL }
};
void StdioSetupFunc(void)
{
/* make a "struct FILEStruct" which is the same size as a native FILE structure */
TypeCreateOpaqueStruct(NULL, TableStrRegister("FILEStruct"), sizeof(FILE));
}
#endif /* NO_HASH_INCLUDE */

View file

@ -10,11 +10,13 @@ void Ctest (struct ParseState *Parser, struct Value *ReturnValue, struct Value *
Param[0]->Val->Integer = 1234;
}
void Clineno (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
void Clineno (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
ReturnValue->Val->Integer = Parser->Line;
}
void Cerrormsg (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
void Cerrormsg (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
PlatformErrorPrefix(Parser);
LibPrintf(Parser, ReturnValue, Param, NumArgs);
}

View file

@ -488,7 +488,7 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi
if (LexGetToken(Parser, &LexerValue, TRUE) != TokenStringConstant)
ProgramFail(Parser, "\"filename.h\" expected");
PlatformScanFile((char *)LexerValue->Val->NativePointer);
IncludeFile((char *)LexerValue->Val->NativePointer);
CheckTrailingSemicolon = FALSE;
break;
#endif

10
picoc.h
View file

@ -227,6 +227,7 @@ struct LexState
const char *End;
const char *FileName;
int Line;
int ScanningHashInclude;
#ifdef FANCY_ERROR_REPORTING
int CharacterPos;
const char *SourceText;
@ -338,6 +339,7 @@ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ);
void TypeParseIdentPart(struct ParseState *Parser, struct ValueType *BasicTyp, struct ValueType **Typ, char **Identifier);
void TypeParse(struct ParseState *Parser, struct ValueType **Typ, char **Identifier);
struct ValueType *TypeGetMatching(struct ParseState *Parser, struct ValueType *ParentType, enum BaseType Base, int ArraySize, const char *Identifier);
struct ValueType *TypeCreateOpaqueStruct(struct ParseState *Parser, const char *StructName, int Size);
/* heap.c */
void HeapInit();
@ -398,4 +400,12 @@ void PlatformLibraryInit();
void Initialise();
void Cleanup();
/* include.c */
void IncludeFile(char *Filename);
/* library_stdio.c */
extern const char StdioDefs[];
extern struct LibraryFunction StdioFunctions[];
void StdioSetupFunc(void);
#endif /* PICOC_H */

14
type.c
View file

@ -242,6 +242,20 @@ void TypeParseStruct(struct ParseState *Parser, struct ValueType **Typ, int IsSt
LexGetToken(Parser, NULL, TRUE);
}
/* create a system struct which has no user-visible members */
struct ValueType *TypeCreateOpaqueStruct(struct ParseState *Parser, const char *StructName, int Size)
{
struct ValueType *Typ = TypeGetMatching(Parser, &UberType, TypeStruct, 0, StructName);
/* create the (empty) table */
Typ->Members = VariableAlloc(Parser, sizeof(struct Table) + STRUCT_TABLE_SIZE * sizeof(struct TableEntry), TRUE);
Typ->Members->HashTable = (struct TableEntry **)((char *)Typ->Members + sizeof(struct Table));
TableInitTable(Typ->Members, (struct TableEntry **)((char *)Typ->Members + sizeof(struct Table)), STRUCT_TABLE_SIZE, TRUE);
Typ->Sizeof = Size;
return Typ;
}
/* parse an enum declaration */
void TypeParseEnum(struct ParseState *Parser, struct ValueType **Typ)
{