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:
parent
436b0cafc0
commit
207549bf17
2
Makefile
2
Makefile
|
@ -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
2
TODO
|
@ -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
|
||||
|
|
18
clibrary.c
18
clibrary.c
|
@ -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 }
|
||||
};
|
||||
|
|
|
@ -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
2
lex.c
|
@ -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++;
|
||||
|
|
|
@ -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
12
library_unix.c
Normal 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
49
picoc.h
|
@ -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
64
platform.c
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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
60
platform_surveyor.c
Normal 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
82
platform_unix.c
Normal 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);
|
||||
}
|
||||
|
Loading…
Reference in a new issue