Reorganised platform/library stuff for better separation between

platforms.
Removed unnecessary union in pointers.


git-svn-id: http://picoc.googlecode.com/svn/trunk@203 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-03-15 07:07:21 +00:00
parent 436b0cafc0
commit 207549bf17
12 changed files with 260 additions and 276 deletions

View file

@ -3,7 +3,7 @@ CFLAGS=-Wall -g
LIBS=-lm
TARGET = picoc
SRCS = picoc.c table.c lex.c parse.c expression.c heap.c type.c variable.c clibrary.c platform_library.c platform_support.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
OBJS := $(SRCS:%.c=%.o)
all: depend $(TARGET)

2
TODO
View file

@ -9,6 +9,8 @@ Implement:
* pointer arithmetic
* casts
* char access/char array access/char * access
* getc()/gets()/malloc()/free()
* "delete" for interactive mode to remove old functions
Improvements:
* #define with arguments

View file

@ -96,10 +96,10 @@ void LibPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Valu
struct ValueType *FormatType;
int ArgCount = 1;
if (Param[0]->Val->Pointer.Data.Offset < 0 || Param[0]->Val->Pointer.Data.Offset >= CharArray->Val->Array.Size)
if (Param[0]->Val->Pointer.Offset < 0 || Param[0]->Val->Pointer.Offset >= CharArray->Val->Array.Size)
Format = StrEmpty;
else
Format = CharArray->Val->Array.Data + Param[0]->Val->Pointer.Data.Offset;
Format = CharArray->Val->Array.Data + Param[0]->Val->Pointer.Offset;
for (FPos = Format; *FPos != '\0'; FPos++)
{
@ -136,10 +136,10 @@ void LibPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Valu
struct Value *CharArray = NextArg->Val->Pointer.Segment;
char *Str;
if (NextArg->Val->Pointer.Data.Offset < 0 || NextArg->Val->Pointer.Data.Offset >= CharArray->Val->Array.Size)
if (NextArg->Val->Pointer.Offset < 0 || NextArg->Val->Pointer.Offset >= CharArray->Val->Array.Size)
Str = StrEmpty;
else
Str = CharArray->Val->Array.Data + NextArg->Val->Pointer.Data.Offset;
Str = CharArray->Val->Array.Data + NextArg->Val->Pointer.Offset;
PrintStr(Str, PlatformPutc);
break;
@ -161,9 +161,19 @@ void LibPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Valu
}
}
void LibGets(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
}
void LibGetc(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
}
/* list of all library functions and their prototypes */
struct LibraryFunction CLibrary[] =
{
{ LibPrintf, "void printf(char *, ...)" },
{ LibGets, "void gets(char *, int)" },
{ LibGetc, "int getc()" },
{ NULL, NULL }
};

View file

@ -70,7 +70,7 @@ int ExpressionParseValue(struct ParseState *Parser, struct Value **Result)
VariableStackPop(Parser, *Result);
*Result = VariableAllocValueFromType(Parser, TypeGetMatching(Parser, VType, TypePointer, 0, StrEmpty), FALSE, NULL);
(*Result)->Val->Pointer.Segment = LocalLValue;
(*Result)->Val->Pointer.Data.Offset = (void *)(*Result)->Val - (void *)(*Result)->LValueFrom;
(*Result)->Val->Pointer.Offset = (void *)(*Result)->Val - (void *)(*Result)->LValueFrom;
break;
case TokenIdentifier:

2
lex.c
View file

@ -280,7 +280,7 @@ enum LexToken LexGetStringConstant(struct LexState *Lexer, struct Value *Value)
/* create the the pointer for this char* */
Value->Typ = CharPtrType;
Value->Val->Pointer.Segment = ArrayValue;
Value->Val->Pointer.Data.Offset = 0;
Value->Val->Pointer.Offset = 0;
if (*Lexer->Pos == '"')
Lexer->Pos++;

View file

@ -1,31 +1,8 @@
#include "picoc.h"
void SayHello(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
PlatformPrintf("Hello\n");
}
void PrintInteger(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
PlatformPrintf("%d\n", Param[0]->Val->Integer);
}
#ifdef UNIX_HOST
void Random(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
ReturnValue->Val->Integer = rand();
}
#endif
static int SomeVar = 42;
static int SomeArray[4];
static int Blobcnt, Blobx1, Blobx2, Bloby1, Bloby2, Iy1, Iy2, Iu1, Iu2, Iv1, Iv2;
void PlatformLibraryInit()
{
struct ValueType *IntArrayType;
VariableDefinePlatformVar(NULL, "somevar", &IntType, (union AnyValue *)&SomeVar, TRUE);
VariableDefinePlatformVar(NULL, "blobcnt", &IntType, (union AnyValue *)&Blobcnt, FALSE);
VariableDefinePlatformVar(NULL, "blobx1", &IntType, (union AnyValue *)&Blobx1, FALSE);
VariableDefinePlatformVar(NULL, "blobx2", &IntType, (union AnyValue *)&Blobx2, FALSE);
@ -37,17 +14,8 @@ void PlatformLibraryInit()
VariableDefinePlatformVar(NULL, "u2", &IntType, (union AnyValue *)&Iu2, FALSE);
VariableDefinePlatformVar(NULL, "v1", &IntType, (union AnyValue *)&Iv1, FALSE);
VariableDefinePlatformVar(NULL, "v2", &IntType, (union AnyValue *)&Iv2, FALSE);
IntArrayType = TypeGetMatching(NULL, &IntType, TypeArray, 4, NULL);
SomeArray[0] = 12;
SomeArray[1] = 34;
SomeArray[2] = 56;
SomeArray[3] = 78;
VariableDefinePlatformVar(NULL, "somearray", IntArrayType, (union AnyValue *)&SomeArray, FALSE);
}
#ifdef SURVEYOR_HOST
void Csignal(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // check for kbhit, return t or nil
{
unsigned char ch;
@ -567,16 +535,4 @@ struct LibraryFunction PlatformLibrary[] =
{ Cnnlearnblob, "void nnlearnblob(int)" },
{ NULL, NULL }
};
#endif
#ifdef UNIX_HOST
/* list of all library functions and their prototypes */
struct LibraryFunction PlatformLibrary[] =
{
{ SayHello, "void sayhello()" },
{ PrintInteger, "void printint(int)" },
{ Random, "int random()" },
{ NULL, NULL }
};
#endif

12
library_unix.c Normal file
View file

@ -0,0 +1,12 @@
#include "picoc.h"
void PlatformLibraryInit()
{
}
/* list of all library functions and their prototypes */
struct LibraryFunction PlatformLibrary[] =
{
{ NULL, NULL }
};

49
picoc.h
View file

@ -108,15 +108,15 @@ enum BaseType
/* data type */
struct ValueType
{
enum BaseType Base; /* what kind of type this is */
int ArraySize; /* the size of an array type */
int Sizeof; /* the storage required */
const char *Identifier; /* the name of a struct or union */
struct ValueType *FromType; /* the type we're derived from (or NULL) */
enum BaseType Base; /* what kind of type this is */
int ArraySize; /* the size of an array type */
int Sizeof; /* the storage required */
const char *Identifier; /* the name of a struct or union */
struct ValueType *FromType; /* the type we're derived from (or NULL) */
struct ValueType *DerivedTypeList; /* first in a list of types derived from this one */
struct ValueType *Next; /* next item in the derived type list */
struct Table *Members; /* members of a struct or union */
int OnHeap; /* true if allocated on the heap */
struct ValueType *Next; /* next item in the derived type list */
struct Table *Members; /* members of a struct or union */
int OnHeap; /* true if allocated on the heap */
};
/* function definition */
@ -134,17 +134,14 @@ struct FuncDef
/* values */
struct ArrayValue
{
unsigned int Size; /* the number of elements in the array */
void *Data; /* pointer to the array data */
unsigned int Size; /* the number of elements in the array */
void *Data; /* pointer to the array data */
};
struct PointerValue
{
struct Value *Segment; /* array or basic value which this points to, NULL for machine memory access */
union s {
unsigned int Offset; /* index into an array */
void *Memory; /* machine memory pointer for raw memory access */
} Data;
struct Value *Segment; /* array or basic value which this points to, NULL for machine memory access */
unsigned int Offset; /* index into an array */
};
union AnyValue
@ -165,27 +162,27 @@ union AnyValue
struct Value
{
struct ValueType *Typ; /* the type of this value */
union AnyValue *Val; /* pointer to the AnyValue which holds the actual content */
struct Value *LValueFrom; /* if an LValue, this is a Value our LValue is contained within (or NULL) */
char ValOnHeap; /* the AnyValue is on the heap (but this Value is on the stack) */
char ValOnStack; /* the AnyValue is on the stack along with this Value */
char IsLValue; /* is modifiable and is allocated somewhere we can usefully modify it */
struct ValueType *Typ; /* the type of this value */
union AnyValue *Val; /* pointer to the AnyValue which holds the actual content */
struct Value *LValueFrom; /* if an LValue, this is a Value our LValue is contained within (or NULL) */
char ValOnHeap; /* the AnyValue is on the heap (but this Value is on the stack) */
char ValOnStack; /* the AnyValue is on the stack along with this Value */
char IsLValue; /* is modifiable and is allocated somewhere we can usefully modify it */
};
/* hash table data structure */
struct TableEntry
{
struct TableEntry *Next; /* next item in this hash chain */
struct TableEntry *Next; /* next item in this hash chain */
union TableEntryPayload
{
struct ValueEntry
{
char *Key; /* points to the shared string table */
struct Value *Val; /* the value we're storing */
} v; /* used for tables of values */
char *Key; /* points to the shared string table */
struct Value *Val; /* the value we're storing */
} v; /* used for tables of values */
char Key[1]; /* dummy size - used for the shared string table */
char Key[1]; /* dummy size - used for the shared string table */
} p;
};

64
platform.c Normal file
View file

@ -0,0 +1,64 @@
#include "picoc.h"
/* exit with a message */
void ProgramFail(struct ParseState *Parser, const char *Message, ...)
{
va_list Args;
if (Parser != NULL)
PlatformPrintf("%s:%d: ", Parser->FileName, Parser->Line);
va_start(Args, Message);
PlatformVPrintf(Message, Args);
PlatformPrintf("\n");
PlatformExit(1);
}
/* exit lexing with a message */
void LexFail(struct LexState *Lexer, const char *Message, ...)
{
va_list Args;
PlatformPrintf("%s:%d: ", Lexer->FileName, Lexer->Line);
va_start(Args, Message);
PlatformVPrintf(Message, Args);
PlatformPrintf("\n");
PlatformExit(1);
}
/* printf for compiler error reporting */
void PlatformPrintf(const char *Format, ...)
{
va_list Args;
va_start(Args, Format);
PlatformVPrintf(Format, Args);
va_end(Args);
}
void PlatformVPrintf(const char *Format, va_list Args)
{
const char *FPos;
for (FPos = Format; *FPos != '\0'; FPos++)
{
if (*FPos == '%')
{
FPos++;
switch (*FPos)
{
case 's': PrintStr(va_arg(Args, char *), PlatformPutc); break;
case 'd': PrintInt(va_arg(Args, int), PlatformPutc); break;
case 'c': PlatformPutc(va_arg(Args, int)); break;
#ifndef NO_FP
case 'f': PrintFP(va_arg(Args, double), PlatformPutc); break;
#endif
case '%': PlatformPutc('%'); break;
case '\0': FPos--; break;
}
}
else
PlatformPutc(*FPos);
}
}

View file

@ -1,199 +0,0 @@
#include "picoc.h"
#ifdef UNIX_HOST
/* a source file we need to clean up */
static char *CleanupText = NULL;
/* deallocate any storage */
void PlatformCleanup()
{
if (CleanupText != NULL)
HeapFree(CleanupText);
}
/* get a line of interactive input */
char *PlatformGetLine(char *Buf, int MaxLen)
{
fflush(stdout);
return fgets(Buf, MaxLen, stdin);
}
/* write a character to the console */
void PlatformPutc(unsigned char OutCh)
{
putchar(OutCh);
}
/* read a file into memory */
char *PlatformReadFile(const char *FileName)
{
struct stat FileInfo;
char *ReadText;
FILE *InFile;
int BytesRead;
if (stat(FileName, &FileInfo))
ProgramFail(NULL, "can't read file %s\n", FileName);
ReadText = malloc(FileInfo.st_size + 1);
if (ReadText == NULL)
ProgramFail(NULL, "out of memory\n");
InFile = fopen(FileName, "r");
if (InFile == NULL)
ProgramFail(NULL, "can't read file %s\n", FileName);
BytesRead = fread(ReadText, 1, FileInfo.st_size, InFile);
if (BytesRead == 0)
ProgramFail(NULL, "can't read file %s\n", FileName);
ReadText[BytesRead] = '\0';
fclose(InFile);
return ReadText;
}
/* read and scan a file for definitions */
void PlatformScanFile(const char *FileName)
{
char *SourceStr = PlatformReadFile(FileName);
char *OrigCleanupText = CleanupText;
if (CleanupText == NULL)
CleanupText = SourceStr;
Parse(FileName, SourceStr, strlen(SourceStr), TRUE);
free(SourceStr);
if (OrigCleanupText == NULL)
CleanupText = NULL;
}
/* mark where to end the program for platforms which require this */
static jmp_buf ExitBuf;
int PlatformSetExitPoint()
{
return setjmp(ExitBuf);
}
/* exit the program */
void PlatformExit()
{
longjmp(ExitBuf, 1);
}
#endif
#ifdef SURVEYOR_HOST
/* deallocate any storage */
void PlatformCleanup()
{
}
/* get a line of interactive input */
char *PlatformGetLine(char *Buf, int MaxLen)
{
int ix;
char ch, *cp;
ix = 0;
cp = Buf;
while (ix++ < MaxLen) {
ch = getch();
if (ch == 0x1B) { // ESC character - exit
printf("leaving picoC\n\r");
return NULL;
}
if (ch == '\n') {
*cp++ = '\n'; // if newline, send newline character followed by null
*cp = 0;
return Buf;
}
*cp++ = ch;
ix++;
}
return NULL;
}
/* write a character to the console */
void PlatformPutc(unsigned char OutCh)
{
putchar(OutCh);
}
/* mark where to end the program for platforms which require this */
int PlatformSetExitPoint()
{
return 0;
}
/* exit the program */
extern int errjmp[];
void PlatformExit()
{
errjmp[40] = 1;
longjmp(errjmp, 1);
}
#endif
/* exit with a message */
void ProgramFail(struct ParseState *Parser, const char *Message, ...)
{
va_list Args;
if (Parser != NULL)
PlatformPrintf("%s:%d: ", Parser->FileName, Parser->Line);
va_start(Args, Message);
PlatformVPrintf(Message, Args);
PlatformPrintf("\n");
PlatformExit(1);
}
/* exit lexing with a message */
void LexFail(struct LexState *Lexer, const char *Message, ...)
{
va_list Args;
PlatformPrintf("%s:%d: ", Lexer->FileName, Lexer->Line);
va_start(Args, Message);
PlatformVPrintf(Message, Args);
PlatformPrintf("\n");
PlatformExit(1);
}
/* printf for compiler error reporting */
void PlatformPrintf(const char *Format, ...)
{
va_list Args;
va_start(Args, Format);
PlatformVPrintf(Format, Args);
va_end(Args);
}
void PlatformVPrintf(const char *Format, va_list Args)
{
const char *FPos;
for (FPos = Format; *FPos != '\0'; FPos++)
{
if (*FPos == '%')
{
FPos++;
switch (*FPos)
{
case 's': PrintStr(va_arg(Args, char *), PlatformPutc); break;
case 'd': PrintInt(va_arg(Args, int), PlatformPutc); break;
case 'c': PlatformPutc(va_arg(Args, int)); break;
#ifndef NO_FP
case 'f': PrintFP(va_arg(Args, double), PlatformPutc); break;
#endif
case '%': PlatformPutc('%'); break;
case '\0': FPos--; break;
}
}
else
PlatformPutc(*FPos);
}
}

60
platform_surveyor.c Normal file
View file

@ -0,0 +1,60 @@
#include "picoc.h"
/* deallocate any storage */
void PlatformCleanup()
{
}
/* get a line of interactive input */
char *PlatformGetLine(char *Buf, int MaxLen)
{
int ix;
char ch, *cp;
ix = 0;
cp = Buf;
while (ix++ < MaxLen) {
ch = getch();
if (ch == 0x1B) { // ESC character - exit
printf("leaving picoC\n\r");
return NULL;
}
if (ch == '\n') {
*cp++ = '\n'; // if newline, send newline character followed by null
*cp = 0;
return Buf;
}
*cp++ = ch;
ix++;
}
return NULL;
}
/* write a character to the console */
void PlatformPutc(unsigned char OutCh)
{
putchar(OutCh);
}
/* write a character to the console */
int PlatformGetc()
{
return getch();
}
/* mark where to end the program for platforms which require this */
int PlatformSetExitPoint()
{
return 0;
}
/* exit the program */
extern int errjmp[];
void PlatformExit()
{
errjmp[40] = 1;
longjmp(errjmp, 1);
}

82
platform_unix.c Normal file
View file

@ -0,0 +1,82 @@
#include "picoc.h"
/* a source file we need to clean up */
static char *CleanupText = NULL;
/* deallocate any storage */
void PlatformCleanup()
{
if (CleanupText != NULL)
HeapFree(CleanupText);
}
/* get a line of interactive input */
char *PlatformGetLine(char *Buf, int MaxLen)
{
fflush(stdout);
return fgets(Buf, MaxLen, stdin);
}
/* write a character to the console */
void PlatformPutc(unsigned char OutCh)
{
putchar(OutCh);
}
/* read a file into memory */
char *PlatformReadFile(const char *FileName)
{
struct stat FileInfo;
char *ReadText;
FILE *InFile;
int BytesRead;
if (stat(FileName, &FileInfo))
ProgramFail(NULL, "can't read file %s\n", FileName);
ReadText = malloc(FileInfo.st_size + 1);
if (ReadText == NULL)
ProgramFail(NULL, "out of memory\n");
InFile = fopen(FileName, "r");
if (InFile == NULL)
ProgramFail(NULL, "can't read file %s\n", FileName);
BytesRead = fread(ReadText, 1, FileInfo.st_size, InFile);
if (BytesRead == 0)
ProgramFail(NULL, "can't read file %s\n", FileName);
ReadText[BytesRead] = '\0';
fclose(InFile);
return ReadText;
}
/* read and scan a file for definitions */
void PlatformScanFile(const char *FileName)
{
char *SourceStr = PlatformReadFile(FileName);
char *OrigCleanupText = CleanupText;
if (CleanupText == NULL)
CleanupText = SourceStr;
Parse(FileName, SourceStr, strlen(SourceStr), TRUE);
free(SourceStr);
if (OrigCleanupText == NULL)
CleanupText = NULL;
}
/* mark where to end the program for platforms which require this */
static jmp_buf ExitBuf;
int PlatformSetExitPoint()
{
return setjmp(ExitBuf);
}
/* exit the program */
void PlatformExit()
{
longjmp(ExitBuf, 1);
}