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:
parent
fa3e9a1187
commit
a591133f35
4
Makefile
4
Makefile
|
@ -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
60
include.c
Normal 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
15
lex.c
|
@ -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
58
library_stdio.c
Normal 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 */
|
|
@ -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);
|
||||
}
|
||||
|
|
2
parse.c
2
parse.c
|
@ -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
10
picoc.h
|
@ -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
14
type.c
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue