Added printf() and variants to stdio
git-svn-id: http://picoc.googlecode.com/svn/trunk@424 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
parent
8bd5cfa054
commit
40e338b823
83
clibrary.c
83
clibrary.c
|
@ -1,10 +1,5 @@
|
|||
#include "picoc.h"
|
||||
|
||||
struct OutputStream CStdOut;
|
||||
|
||||
static int TRUEValue = 1;
|
||||
static int ZeroValue = 0;
|
||||
|
||||
/* initialise a library */
|
||||
void LibraryInit(struct Table *GlobalTable, const char *LibraryName, struct LibraryFunction (*FuncList)[])
|
||||
{
|
||||
|
@ -16,8 +11,6 @@ void LibraryInit(struct Table *GlobalTable, const char *LibraryName, struct Libr
|
|||
void *Tokens;
|
||||
const char *IntrinsicName = TableStrRegister("c library");
|
||||
|
||||
CStdOut.Putch = &PlatformPutc;
|
||||
|
||||
for (Count = 0; (*FuncList)[Count].Prototype != NULL; Count++)
|
||||
{
|
||||
Tokens = LexAnalyse(IntrinsicName, (*FuncList)[Count].Prototype, strlen((char *)(*FuncList)[Count].Prototype), NULL);
|
||||
|
@ -29,6 +22,53 @@ void LibraryInit(struct Table *GlobalTable, const char *LibraryName, struct Libr
|
|||
}
|
||||
}
|
||||
|
||||
/* print a type to a stream without using printf/sprintf */
|
||||
void PrintType(struct ValueType *Typ, IOFILE *Stream)
|
||||
{
|
||||
switch (Typ->Base)
|
||||
{
|
||||
case TypeVoid: PrintStr("void", Stream); break;
|
||||
case TypeInt: PrintStr("int", Stream); break;
|
||||
case TypeShort: PrintStr("short", Stream); break;
|
||||
case TypeChar: PrintStr("char", Stream); break;
|
||||
case TypeLong: PrintStr("long", Stream); break;
|
||||
case TypeUnsignedInt: PrintStr("unsigned int", Stream); break;
|
||||
case TypeUnsignedShort: PrintStr("unsigned short", Stream); break;
|
||||
case TypeUnsignedLong: PrintStr("unsigned long", Stream); break;
|
||||
#ifndef NO_FP
|
||||
case TypeFP: PrintStr("double", Stream); break;
|
||||
#endif
|
||||
case TypeFunction: PrintStr("function", Stream); break;
|
||||
case TypeMacro: PrintStr("macro", Stream); break;
|
||||
case TypePointer: if (Typ->FromType) PrintType(Typ->FromType, Stream); PrintCh('*', Stream); break;
|
||||
case TypeArray: PrintType(Typ->FromType, Stream); PrintCh('[', Stream); if (Typ->ArraySize != 0) PrintSimpleInt(Typ->ArraySize, Stream); PrintCh(']', Stream); break;
|
||||
case TypeStruct: PrintStr("struct ", Stream); PrintStr(Typ->Identifier, Stream); break;
|
||||
case TypeUnion: PrintStr("union ", Stream); PrintStr(Typ->Identifier, Stream); break;
|
||||
case TypeEnum: PrintStr("enum ", Stream); PrintStr(Typ->Identifier, Stream); break;
|
||||
case Type_Type: PrintStr("type ", Stream); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef BUILTIN_MINI_STDLIB
|
||||
|
||||
/*
|
||||
* This is a simplified standard library for small embedded systems. It doesn't require
|
||||
* a system stdio library to operate.
|
||||
*
|
||||
* A more complete standard library for larger computers is in the library_XXX.c files.
|
||||
*/
|
||||
|
||||
struct OutputStream CStdOut;
|
||||
|
||||
static int TRUEValue = 1;
|
||||
static int ZeroValue = 0;
|
||||
|
||||
void BasicIOInit()
|
||||
{
|
||||
CStdOut.Putch = &PlatformPutc;
|
||||
}
|
||||
|
||||
/* initialise the C library */
|
||||
void CLibraryInit()
|
||||
{
|
||||
|
@ -148,33 +188,6 @@ void PrintFP(double Num, struct OutputStream *Stream)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* print a type to a stream without using printf/sprintf */
|
||||
void PrintType(struct ValueType *Typ, struct OutputStream *Stream)
|
||||
{
|
||||
switch (Typ->Base)
|
||||
{
|
||||
case TypeVoid: PrintStr("void", Stream); break;
|
||||
case TypeInt: PrintStr("int", Stream); break;
|
||||
case TypeShort: PrintStr("short", Stream); break;
|
||||
case TypeChar: PrintStr("char", Stream); break;
|
||||
case TypeLong: PrintStr("long", Stream); break;
|
||||
case TypeUnsignedInt: PrintStr("unsigned int", Stream); break;
|
||||
case TypeUnsignedShort: PrintStr("unsigned short", Stream); break;
|
||||
case TypeUnsignedLong: PrintStr("unsigned long", Stream); break;
|
||||
#ifndef NO_FP
|
||||
case TypeFP: PrintStr("double", Stream); break;
|
||||
#endif
|
||||
case TypeFunction: PrintStr("function", Stream); break;
|
||||
case TypeMacro: PrintStr("macro", Stream); break;
|
||||
case TypePointer: if (Typ->FromType) PrintType(Typ->FromType, Stream); PrintCh('*', Stream); break;
|
||||
case TypeArray: PrintType(Typ->FromType, Stream); PrintCh('[', Stream); if (Typ->ArraySize != 0) PrintInt(Typ->ArraySize, 0, FALSE, FALSE, Stream); PrintCh(']', Stream); break;
|
||||
case TypeStruct: PrintStr("struct ", Stream); PrintStr(Typ->Identifier, Stream); break;
|
||||
case TypeUnion: PrintStr("union ", Stream); PrintStr(Typ->Identifier, Stream); break;
|
||||
case TypeEnum: PrintStr("enum ", Stream); PrintStr(Typ->Identifier, Stream); break;
|
||||
case Type_Type: PrintStr("type ", Stream); break;
|
||||
}
|
||||
}
|
||||
|
||||
/* intrinsic functions made available to the language */
|
||||
void GenericPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs, struct OutputStream *Stream)
|
||||
{
|
||||
|
@ -626,3 +639,5 @@ struct LibraryFunction CLibrary[] =
|
|||
#endif
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
#endif /* BUILTIN_MINI_STDLIB */
|
||||
|
|
|
@ -40,7 +40,7 @@ void IncludeFile(char *FileName)
|
|||
if (LInclude->SetupFunction != NULL)
|
||||
(*LInclude->SetupFunction)();
|
||||
|
||||
/* parse the setup C source code - may define types etc. */
|
||||
/* run an extra startup function if there is one */
|
||||
if (LInclude->SetupCSource != NULL)
|
||||
Parse(FileName, LInclude->SetupCSource, strlen(LInclude->SetupCSource), TRUE);
|
||||
|
||||
|
|
281
library_stdio.c
281
library_stdio.c
|
@ -1,13 +1,172 @@
|
|||
/* stdio.h library */
|
||||
#include <errno.h>
|
||||
#include "picoc.h"
|
||||
|
||||
#ifndef NO_HASH_INCLUDE
|
||||
#ifndef BUILTIN_MINI_STDLIB
|
||||
|
||||
#define MAX_FORMAT 80
|
||||
|
||||
FILE *CStdOut;
|
||||
|
||||
static int EOFValue = EOF;
|
||||
static int SEEK_SETValue = SEEK_SET;
|
||||
static int SEEK_CURValue = SEEK_CUR;
|
||||
static int SEEK_ENDValue = SEEK_END;
|
||||
static int BUFSIZValue = BUFSIZ;
|
||||
static int FILENAME_MAXValue = FILENAME_MAX;
|
||||
static int _IOFBFValue = _IOFBF;
|
||||
static int _IOLBFValue = _IOLBF;
|
||||
static int _IONBFValue = _IONBF;
|
||||
static int L_tmpnamValue = L_tmpnam;
|
||||
static int GETS_MAXValue = 255; /* arbitrary maximum size of a gets() file */
|
||||
|
||||
struct StdVararg
|
||||
{
|
||||
struct Value **Param;
|
||||
int NumArgs;
|
||||
};
|
||||
|
||||
|
||||
void BasicIOInit()
|
||||
{
|
||||
CStdOut = stdout;
|
||||
}
|
||||
|
||||
int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *Format, struct StdVararg *Args)
|
||||
{
|
||||
struct Value **ArgPos = Args->Param;
|
||||
int ArgCount = 0;
|
||||
char *FPos = Format;
|
||||
char OneFormatBuf[MAX_FORMAT+1];
|
||||
int OneFormatCount;
|
||||
struct ValueType *ShowType;
|
||||
int TotalCharsPrinted = 0;
|
||||
|
||||
while (*FPos != '\0')
|
||||
{
|
||||
if (*FPos == '%')
|
||||
{
|
||||
/* work out what type we're printing */
|
||||
FPos++;
|
||||
ShowType = NULL;
|
||||
OneFormatBuf[OneFormatCount] = '%';
|
||||
OneFormatCount = 1;
|
||||
|
||||
do
|
||||
{
|
||||
switch (*FPos)
|
||||
{
|
||||
case 'd': case 'i': ShowType = &IntType; break; /* integer decimal */
|
||||
case 'o': case 'u': case 'x': case 'X': ShowType = &UnsignedIntType; break; /* integer base conversions */
|
||||
case 'e': case 'E': ShowType = &FPType; break; /* double, exponent form */
|
||||
case 'f': case 'F': ShowType = &FPType; break; /* double, fixed-point */
|
||||
case 'g': case 'G': ShowType = &FPType; break; /* double, flexible format */
|
||||
case 'a': case 'A': ShowType = &UnsignedIntType; break; /* hexadecimal, 0x- format */
|
||||
case 'c': ShowType = &UnsignedIntType; break; /* character */
|
||||
case 's': ShowType = CharPtrType; break; /* string */
|
||||
case 'p': ShowType = VoidPtrType; break; /* pointer */
|
||||
case 'n': ShowType = &VoidType; break; /* number of characters written */
|
||||
case 'm': ShowType = &VoidType; break; /* strerror(errno) */
|
||||
case '%': ShowType = &VoidType; break; /* just a '%' character */
|
||||
case '\0': ShowType = &VoidType; break; /* end of format string */
|
||||
}
|
||||
|
||||
/* copy one character of format across to the OneFormatBuf */
|
||||
OneFormatBuf[OneFormatCount] = *FPos;
|
||||
OneFormatCount++;
|
||||
|
||||
/* do special actions depending on the conversion type */
|
||||
if (ShowType == &VoidType)
|
||||
{
|
||||
switch (*FPos)
|
||||
{
|
||||
case 'm': fputs(strerror(errno), Stream); break;
|
||||
case '%': fputc(*FPos, Stream); break;
|
||||
case '\0': OneFormatBuf[OneFormatCount] = '\0'; fputc(*FPos, Stream); break;
|
||||
case 'n':
|
||||
if ((*ArgPos)->Typ->Base == TypeArray && (*ArgPos)->Typ->FromType->Base == TypeInt)
|
||||
*(int *)(*ArgPos)->Val->Integer = TotalCharsPrinted;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} while (ShowType == NULL && OneFormatCount < MAX_FORMAT);
|
||||
|
||||
if (ShowType != &VoidType)
|
||||
{
|
||||
if (ArgCount >= Args->NumArgs)
|
||||
fputs("XXX", Stream);
|
||||
else
|
||||
{
|
||||
/* null-terminate the buffer */
|
||||
OneFormatBuf[OneFormatCount] = '\0';
|
||||
|
||||
if (ShowType == &IntType)
|
||||
{
|
||||
/* show a signed integer */
|
||||
if (IS_INTEGER_NUMERIC(*ArgPos))
|
||||
fprintf(Stream, OneFormatBuf, ExpressionCoerceInteger(*ArgPos));
|
||||
else
|
||||
fputs("XXX", Stream);
|
||||
}
|
||||
else if (ShowType == &UnsignedIntType)
|
||||
{
|
||||
/* show an unsigned integer */
|
||||
if (IS_INTEGER_NUMERIC(*ArgPos))
|
||||
fprintf(Stream, OneFormatBuf, ExpressionCoerceUnsignedInteger(*ArgPos));
|
||||
else
|
||||
fputs("XXX", Stream);
|
||||
}
|
||||
else if (ShowType == &FPType)
|
||||
{
|
||||
/* show a floating point number */
|
||||
if (IS_FP(*ArgPos))
|
||||
fprintf(Stream, OneFormatBuf, ExpressionCoerceFP(*ArgPos));
|
||||
else
|
||||
fputs("XXX", Stream);
|
||||
}
|
||||
else if (ShowType == CharPtrType)
|
||||
{
|
||||
if ((*ArgPos)->Typ->Base == TypePointer)
|
||||
fprintf(Stream, OneFormatBuf, (*ArgPos)->Val->NativePointer);
|
||||
|
||||
else if ((*ArgPos)->Typ->Base == TypeArray && (*ArgPos)->Typ->FromType->Base == TypeChar)
|
||||
fprintf(Stream, OneFormatBuf, &(*ArgPos)->Val->ArrayMem[0]);
|
||||
|
||||
else
|
||||
fputs("XXX", Stream);
|
||||
}
|
||||
else if (ShowType == VoidPtrType)
|
||||
{
|
||||
if ((*ArgPos)->Typ->Base == TypePointer)
|
||||
fprintf(Stream, OneFormatBuf, (*ArgPos)->Val->NativePointer);
|
||||
|
||||
else if ((*ArgPos)->Typ->Base == TypeArray)
|
||||
fprintf(Stream, OneFormatBuf, &(*ArgPos)->Val->ArrayMem[0]);
|
||||
|
||||
else
|
||||
fputs("XXX", Stream);
|
||||
}
|
||||
|
||||
ArgPos++;
|
||||
ArgCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* just output a normal character */
|
||||
putc(*FPos, Stream);
|
||||
}
|
||||
}
|
||||
|
||||
return TotalCharsPrinted;
|
||||
}
|
||||
|
||||
int StdioBaseSprintf(struct ParseState *Parser, char *Str, int MaxStrSize, char *Format, struct StdVararg *Args)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void StdioFopen(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
|
||||
{
|
||||
|
@ -154,9 +313,76 @@ void StdioPuts(struct ParseState *Parser, struct Value *ReturnValue, struct Valu
|
|||
ReturnValue->Val->Integer = puts(Param[0]->Val->NativePointer);
|
||||
}
|
||||
|
||||
void StdioGets(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
|
||||
{
|
||||
ReturnValue->Val->NativePointer = fgets(Param[0]->Val->NativePointer, GETS_MAXValue, stdin);
|
||||
}
|
||||
|
||||
void StdioGetchar(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
|
||||
{
|
||||
ReturnValue->Val->Integer = getchar();
|
||||
}
|
||||
|
||||
void StdioPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
|
||||
{
|
||||
struct StdVararg PrintfArgs;
|
||||
|
||||
PrintfArgs.Param = Param+1;
|
||||
PrintfArgs.NumArgs = NumArgs;
|
||||
ReturnValue->Val->Integer = StdioBasePrintf(Parser, stdout, Param[0]->Val->NativePointer, &PrintfArgs);
|
||||
}
|
||||
|
||||
void StdioVprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
|
||||
{
|
||||
ReturnValue->Val->Integer = StdioBasePrintf(Parser, stdout, Param[0]->Val->NativePointer, Param[1]->Val->NativePointer);
|
||||
}
|
||||
|
||||
void StdioFprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
|
||||
{
|
||||
struct StdVararg PrintfArgs;
|
||||
|
||||
PrintfArgs.Param = Param+1;
|
||||
PrintfArgs.NumArgs = NumArgs;
|
||||
ReturnValue->Val->Integer = StdioBasePrintf(Parser, Param[0]->Val->NativePointer, Param[1]->Val->NativePointer, &PrintfArgs);
|
||||
}
|
||||
|
||||
void StdioVfprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
|
||||
{
|
||||
ReturnValue->Val->Integer = StdioBasePrintf(Parser, Param[0]->Val->NativePointer, Param[1]->Val->NativePointer, Param[2]->Val->NativePointer);
|
||||
}
|
||||
|
||||
void StdioSprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
|
||||
{
|
||||
struct StdVararg PrintfArgs;
|
||||
|
||||
PrintfArgs.Param = Param+2;
|
||||
PrintfArgs.NumArgs = NumArgs;
|
||||
ReturnValue->Val->Integer = StdioBaseSprintf(Parser, Param[0]->Val->NativePointer, -1, Param[1]->Val->NativePointer, &PrintfArgs);
|
||||
}
|
||||
|
||||
void StdioSnprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
|
||||
{
|
||||
struct StdVararg PrintfArgs;
|
||||
|
||||
PrintfArgs.Param = Param+3;
|
||||
PrintfArgs.NumArgs = NumArgs;
|
||||
ReturnValue->Val->Integer = StdioBaseSprintf(Parser, Param[0]->Val->NativePointer, Param[1]->Val->Integer, Param[2]->Val->NativePointer, &PrintfArgs);
|
||||
}
|
||||
|
||||
void StdioVsprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
|
||||
{
|
||||
ReturnValue->Val->Integer = StdioBaseSprintf(Parser, Param[0]->Val->NativePointer, -1, Param[1]->Val->NativePointer, Param[2]->Val->NativePointer);
|
||||
}
|
||||
|
||||
void StdioVsnprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
|
||||
{
|
||||
ReturnValue->Val->Integer = StdioBaseSprintf(Parser, Param[0]->Val->NativePointer, Param[1]->Val->Integer, Param[2]->Val->NativePointer, Param[3]->Val->NativePointer);
|
||||
}
|
||||
|
||||
|
||||
const char StdioDefs[] = "\
|
||||
typedef struct FILEStruct FILE; \
|
||||
typedef struct __FILEStruct FILE; \
|
||||
typedef struct __va_listStruct va_list; \
|
||||
";
|
||||
|
||||
struct LibraryFunction StdioFunctions[] =
|
||||
|
@ -193,28 +419,67 @@ struct LibraryFunction StdioFunctions[] =
|
|||
{ StdioSetvbuf, "void setvbuf(FILE *, char *, int, int);" },
|
||||
{ StdioUngetc, "int ungetc(int, FILE *);" },
|
||||
{ StdioPuts, "int puts(char *);" },
|
||||
{ StdioPrintf, "void printf(char *, ...);" },
|
||||
{ StdioSprintf, "char *sprintf(char *, char *, ...);" },
|
||||
{ StdioGets, "char *gets(char *);" },
|
||||
{ StdioGetchar, "int getchar();" },
|
||||
{ StdioGetchar, "int printf(char *format, ...);" },
|
||||
{ StdioGetchar, "int fprintf(FILE *stream, char *format, ...);" },
|
||||
{ StdioGetchar, "int sprintf(char *str, char *format, ...);" },
|
||||
{ StdioGetchar, "int snprintf(char *str, size_t size, char *format, ...);" },
|
||||
{ StdioGetchar, "int vprintf(const char *format, va_list ap);" },
|
||||
{ StdioGetchar, "int vfprintf(FILE *stream, char *format, va_list ap);" },
|
||||
{ StdioGetchar, "int vsprintf(char *str, char *format, va_list ap);" },
|
||||
{ StdioGetchar, "int vsnprintf(char *str, size_t size, char *format, va_list ap);" },
|
||||
{ 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));
|
||||
/* make a "struct __FILEStruct" which is the same size as a native FILE structure */
|
||||
TypeCreateOpaqueStruct(NULL, TableStrRegister("__FILEStruct"), sizeof(FILE));
|
||||
|
||||
/* make a "struct __va_listStruct" which is the same size as our struct StdVararg */
|
||||
TypeCreateOpaqueStruct(NULL, TableStrRegister("__va_listStruct"), sizeof(FILE));
|
||||
|
||||
/* define EOF equal to the system EOF */
|
||||
VariableDefinePlatformVar(NULL, "EOF", &IntType, (union AnyValue *)&EOFValue, FALSE);
|
||||
VariableDefinePlatformVar(NULL, "SEEK_SET", &IntType, (union AnyValue *)&SEEK_SETValue, FALSE);
|
||||
VariableDefinePlatformVar(NULL, "SEEK_CUR", &IntType, (union AnyValue *)&SEEK_CURValue, FALSE);
|
||||
VariableDefinePlatformVar(NULL, "SEEK_END", &IntType, (union AnyValue *)&SEEK_ENDValue, FALSE);
|
||||
VariableDefinePlatformVar(NULL, "BUFSIZ", &IntType, (union AnyValue *)&BUFSIZValue, FALSE);
|
||||
VariableDefinePlatformVar(NULL, "FILENAME_MAX", &IntType, (union AnyValue *)&FILENAME_MAXValue, FALSE);
|
||||
VariableDefinePlatformVar(NULL, "_IOFBF", &IntType, (union AnyValue *)&_IOFBFValue, FALSE);
|
||||
VariableDefinePlatformVar(NULL, "_IOLBF", &IntType, (union AnyValue *)&_IOLBFValue, FALSE);
|
||||
VariableDefinePlatformVar(NULL, "_IONBF", &IntType, (union AnyValue *)&_IONBFValue, FALSE);
|
||||
VariableDefinePlatformVar(NULL, "L_tmpnam", &IntType, (union AnyValue *)&L_tmpnamValue, FALSE);
|
||||
VariableDefinePlatformVar(NULL, "GETS_MAX", &IntType, (union AnyValue *)&GETS_MAXValue, FALSE);
|
||||
}
|
||||
|
||||
#endif /* NO_HASH_INCLUDE */
|
||||
void PrintCh(char OutCh, FILE *Stream)
|
||||
{
|
||||
putc(OutCh, Stream);
|
||||
}
|
||||
|
||||
void PrintSimpleInt(long Num, FILE *Stream)
|
||||
{
|
||||
fprintf(Stream, "%ld", Num);
|
||||
}
|
||||
|
||||
void PrintStr(const char *Str, FILE *Stream)
|
||||
{
|
||||
fputs(Str, Stream);
|
||||
}
|
||||
|
||||
void PrintFP(double Num, FILE *Stream)
|
||||
{
|
||||
fprintf(Stream, "%f", Num);
|
||||
}
|
||||
|
||||
#endif /* !BUILTIN_MINI_STDLIB */
|
||||
|
||||
/*
|
||||
TODO:
|
||||
vprintf used to print to the standard output stream
|
||||
fprintf, vfprintf used to print to a file
|
||||
snprintf, vsprintf, vsnprintf used to print to a char array (C string)
|
||||
scanf, vscanf used to input from the standard input stream
|
||||
fscanf, vfscanf used to input from a file
|
||||
sscanf, vsscanf used to input from a char array (e.g., a C string)
|
||||
|
|
|
@ -15,18 +15,11 @@ void Clineno (struct ParseState *Parser, struct Value *ReturnValue, struct Value
|
|||
ReturnValue->Val->Integer = Parser->Line;
|
||||
}
|
||||
|
||||
void Cerrormsg (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
|
||||
{
|
||||
PlatformErrorPrefix(Parser);
|
||||
LibPrintf(Parser, ReturnValue, Param, NumArgs);
|
||||
}
|
||||
|
||||
/* list of all library functions and their prototypes */
|
||||
struct LibraryFunction PlatformLibrary[] =
|
||||
{
|
||||
{ Ctest, "void test(int);" },
|
||||
{ Clineno, "int lineno();" },
|
||||
{ Cerrormsg, "void errorprintf(char *,...);" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
3
picoc.c
3
picoc.c
|
@ -3,13 +3,16 @@
|
|||
/* initialise everything */
|
||||
void Initialise()
|
||||
{
|
||||
BasicIOInit();
|
||||
HeapInit();
|
||||
TableInit();
|
||||
VariableInit();
|
||||
LexInit();
|
||||
TypeInit();
|
||||
#ifdef BUILTIN_MINI_STDLIB
|
||||
LibraryInit(&GlobalTable, "c library", &CLibrary);
|
||||
CLibraryInit();
|
||||
#endif
|
||||
PlatformLibraryInit();
|
||||
LibraryInit(&GlobalTable, "platform library", &PlatformLibrary);
|
||||
}
|
||||
|
|
22
picoc.h
22
picoc.h
|
@ -21,6 +21,13 @@
|
|||
|
||||
#define GETS_BUF_MAX 256
|
||||
|
||||
/* small processors use a simplified FILE * for stdio, otherwise use the system FILE * */
|
||||
#ifdef BUILTIN_MINI_STDLIB
|
||||
typedef struct OutputStream IOFILE;
|
||||
#else
|
||||
typedef FILE IOFILE;
|
||||
#endif
|
||||
|
||||
/* coercion of numeric types to other numeric types */
|
||||
#ifndef NO_FP
|
||||
#define IS_FP(v) ((v)->Typ->Base == TypeFP)
|
||||
|
@ -270,6 +277,7 @@ extern struct Table GlobalTable;
|
|||
extern struct StackFrame *TopStackFrame;
|
||||
extern struct ValueType UberType;
|
||||
extern struct ValueType IntType;
|
||||
extern struct ValueType UnsignedIntType;
|
||||
extern struct ValueType CharType;
|
||||
#ifndef NO_FP
|
||||
extern struct ValueType FPType;
|
||||
|
@ -285,7 +293,7 @@ extern char *StrEmpty;
|
|||
extern struct PointerValue NULLPointer;
|
||||
extern struct LibraryFunction CLibrary[];
|
||||
extern struct LibraryFunction PlatformLibrary[];
|
||||
extern struct OutputStream CStdOut;
|
||||
extern IOFILE *CStdOut;
|
||||
|
||||
/* table.c */
|
||||
void TableInit();
|
||||
|
@ -374,13 +382,15 @@ void VariableStringLiteralDefine(char *Ident, struct Value *Val);
|
|||
void *VariableDereferencePointer(struct ParseState *Parser, struct Value *PointerValue, struct Value **DerefVal, int *DerefOffset, struct ValueType **DerefType, int *DerefIsLValue);
|
||||
|
||||
/* clibrary.c */
|
||||
void BasicIOInit();
|
||||
void LibraryInit(struct Table *GlobalTable, const char *LibraryName, struct LibraryFunction (*FuncList)[]);
|
||||
void CLibraryInit();
|
||||
void PrintCh(char OutCh, struct OutputStream *Stream);
|
||||
void PrintInt(long Num, int FieldWidth, int ZeroPad, int LeftJustify, struct OutputStream *Stream);
|
||||
void PrintStr(const char *Str, struct OutputStream *Stream);
|
||||
void PrintFP(double Num, struct OutputStream *Stream);
|
||||
void PrintType(struct ValueType *Typ, struct OutputStream *Stream);
|
||||
void PrintCh(char OutCh, IOFILE *Stream);
|
||||
void PrintSimpleInt(long Num, FILE *Stream);
|
||||
void PrintInt(long Num, int FieldWidth, int ZeroPad, int LeftJustify, IOFILE *Stream);
|
||||
void PrintStr(const char *Str, IOFILE *Stream);
|
||||
void PrintFP(double Num, IOFILE *Stream);
|
||||
void PrintType(struct ValueType *Typ, IOFILE *Stream);
|
||||
void LibPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs);
|
||||
|
||||
/* platform.c */
|
||||
|
|
24
platform.c
24
platform.c
|
@ -19,23 +19,23 @@ void PrintSourceTextErrorLine(const char *FileName, const char *SourceText, int
|
|||
|
||||
/* display the line */
|
||||
for (CPos = LinePos; *CPos != '\n' && *CPos != '\0'; CPos++)
|
||||
PrintCh(*CPos, &CStdOut);
|
||||
PrintCh('\n', &CStdOut);
|
||||
PrintCh(*CPos, CStdOut);
|
||||
PrintCh('\n', CStdOut);
|
||||
|
||||
/* display the error position */
|
||||
for (CPos = LinePos, CCount = 0; *CPos != '\n' && *CPos != '\0' && (CCount < CharacterPos || *CPos == ' '); CPos++, CCount++)
|
||||
{
|
||||
if (*CPos == '\t')
|
||||
PrintCh('\t', &CStdOut);
|
||||
PrintCh('\t', CStdOut);
|
||||
else
|
||||
PrintCh(' ', &CStdOut);
|
||||
PrintCh(' ', CStdOut);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* assume we're in interactive mode - try to make the arrow match up with the input text */
|
||||
for (CCount = 0; CCount < CharacterPos + strlen(INTERACTIVE_PROMPT_STATEMENT); CCount++)
|
||||
PrintCh(' ', &CStdOut);
|
||||
PrintCh(' ', CStdOut);
|
||||
}
|
||||
PlatformPrintf("^\n%s:%d: ", FileName, Line, CharacterPos);
|
||||
|
||||
|
@ -122,18 +122,18 @@ void PlatformVPrintf(const char *Format, va_list Args)
|
|||
FPos++;
|
||||
switch (*FPos)
|
||||
{
|
||||
case 's': PrintStr(va_arg(Args, char *), &CStdOut); break;
|
||||
case 'd': PrintInt(va_arg(Args, int), 0, FALSE, FALSE, &CStdOut); break;
|
||||
case 'c': PrintCh(va_arg(Args, int), &CStdOut); break;
|
||||
case 't': PrintType(va_arg(Args, struct ValueType *), &CStdOut); break;
|
||||
case 's': PrintStr(va_arg(Args, char *), CStdOut); break;
|
||||
case 'd': PrintSimpleInt(va_arg(Args, int), CStdOut); break;
|
||||
case 'c': PrintCh(va_arg(Args, int), CStdOut); break;
|
||||
case 't': PrintType(va_arg(Args, struct ValueType *), CStdOut); break;
|
||||
#ifndef NO_FP
|
||||
case 'f': PrintFP(va_arg(Args, double), &CStdOut); break;
|
||||
case 'f': PrintFP(va_arg(Args, double), CStdOut); break;
|
||||
#endif
|
||||
case '%': PrintCh('%', &CStdOut); break;
|
||||
case '%': PrintCh('%', CStdOut); break;
|
||||
case '\0': FPos--; break;
|
||||
}
|
||||
}
|
||||
else
|
||||
PrintCh(*FPos, &CStdOut);
|
||||
PrintCh(*FPos, CStdOut);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,6 +73,7 @@ extern jmp_buf ExitBuf;
|
|||
# include <setjmp.h>
|
||||
# include <math.h>
|
||||
# define assert(x)
|
||||
# define BUILTIN_MINI_STDLIB
|
||||
# undef BIG_ENDIAN
|
||||
# undef FANCY_ERROR_REPORTING
|
||||
|
||||
|
@ -103,10 +104,12 @@ extern jmp_buf ExitBuf;
|
|||
# define NO_CALLOC
|
||||
# define NO_REALLOC
|
||||
# define BROKEN_FLOAT_CASTS
|
||||
# define BUILTIN_MINI_STDLIB
|
||||
# else
|
||||
# ifdef UMON_HOST
|
||||
# define HEAP_SIZE (128*1024) /* space for the heap and the stack */
|
||||
# define NO_FP
|
||||
# define BUILTIN_MINI_STDLIB
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <ctype.h>
|
||||
|
|
Loading…
Reference in a new issue