[DEV] some other rework unneeded elements
This commit is contained in:
parent
3f5c4725f9
commit
177d1ba8c0
626
eci/clibrary.c
626
eci/clibrary.c
@ -1,3 +1,11 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
#include "picoc.h"
|
||||
#include "interpreter.h"
|
||||
|
||||
@ -46,565 +54,71 @@ void LibraryAdd(struct Table *GlobalTable, const char *LibraryName, struct Libra
|
||||
/* 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 TypeGotoLabel: PrintStr("goto label ", Stream); break;
|
||||
case Type_Type: PrintStr("type ", Stream); break;
|
||||
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;
|
||||
case TypeFP:
|
||||
PrintStr("double", Stream);
|
||||
break;
|
||||
case TypeFunction:
|
||||
PrintStr("function", Stream);
|
||||
break;
|
||||
case TypeMacro:
|
||||
PrintStr("macro", Stream);
|
||||
break;
|
||||
case TypePointer:
|
||||
if (Typ->FromType) {
|
||||
PrintType(Typ->FromType, Stream);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#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.
|
||||
*/
|
||||
IOFILE *CStdOut;
|
||||
IOFILE CStdOutBase;
|
||||
|
||||
static int TRUEValue = 1;
|
||||
static int ZeroValue = 0;
|
||||
|
||||
void BasicIOInit() {
|
||||
CStdOutBase.Putch = &PlatformPutc;
|
||||
CStdOut = &CStdOutBase;
|
||||
}
|
||||
|
||||
/* initialise the C library */
|
||||
void CLibraryInit() {
|
||||
/* define some constants */
|
||||
VariableDefinePlatformVar(NULL, "NULL", &IntType, (union AnyValue *)&ZeroValue, FALSE);
|
||||
VariableDefinePlatformVar(NULL, "TRUE", &IntType, (union AnyValue *)&TRUEValue, FALSE);
|
||||
VariableDefinePlatformVar(NULL, "FALSE", &IntType, (union AnyValue *)&ZeroValue, FALSE);
|
||||
}
|
||||
|
||||
/* stream for writing into strings */
|
||||
void SPutc(unsigned char Ch, union OutputStreamInfo *Stream) {
|
||||
struct StringOutputStream *Out = &Stream->Str;
|
||||
*Out->WritePos++ = Ch;
|
||||
}
|
||||
|
||||
/* print a character to a stream without using printf/sprintf */
|
||||
void PrintCh(char OutCh, struct OutputStream *Stream) {
|
||||
(*Stream->Putch)(OutCh, &Stream->i);
|
||||
}
|
||||
|
||||
/* print a string to a stream without using printf/sprintf */
|
||||
void PrintStr(const char *Str, struct OutputStream *Stream) {
|
||||
while (*Str != 0) {
|
||||
PrintCh(*Str++, Stream);
|
||||
}
|
||||
}
|
||||
|
||||
/* print a single character a given number of times */
|
||||
void PrintRepeatedChar(char ShowChar, int Length, struct OutputStream *Stream) {
|
||||
while (Length-- > 0) {
|
||||
PrintCh(ShowChar, Stream);
|
||||
}
|
||||
}
|
||||
|
||||
/* print an unsigned integer to a stream without using printf/sprintf */
|
||||
void PrintUnsigned(unsigned long Num, unsigned int Base, int FieldWidth, int ZeroPad, int LeftJustify, struct OutputStream *Stream) {
|
||||
char Result[33];
|
||||
int ResPos = sizeof(Result);
|
||||
|
||||
Result[--ResPos] = '\0';
|
||||
if (Num == 0) {
|
||||
Result[--ResPos] = '0';
|
||||
}
|
||||
|
||||
while (Num > 0) {
|
||||
unsigned long NextNum = Num / Base;
|
||||
unsigned long Digit = Num - NextNum * Base;
|
||||
if (Digit < 10) {
|
||||
Result[--ResPos] = '0' + Digit;
|
||||
} else {
|
||||
Result[--ResPos] = 'a' + Digit - 10;
|
||||
}
|
||||
Num = NextNum;
|
||||
}
|
||||
|
||||
if (FieldWidth > 0 && !LeftJustify) {
|
||||
PrintRepeatedChar(ZeroPad ? '0' : ' ', FieldWidth - (sizeof(Result) - 1 - ResPos), Stream);
|
||||
}
|
||||
PrintStr(&Result[ResPos], Stream);
|
||||
if (FieldWidth > 0 && LeftJustify) {
|
||||
PrintRepeatedChar(' ', FieldWidth - (sizeof(Result) - 1 - ResPos), Stream);
|
||||
}
|
||||
}
|
||||
|
||||
/* print an integer to a stream without using printf/sprintf */
|
||||
void PrintSimpleInt(long Num, struct OutputStream *Stream) {
|
||||
PrintInt(Num, -1, FALSE, FALSE, Stream);
|
||||
}
|
||||
|
||||
/* print an integer to a stream without using printf/sprintf */
|
||||
void PrintInt(long Num, int FieldWidth, int ZeroPad, int LeftJustify, struct OutputStream *Stream) {
|
||||
if (Num < 0) {
|
||||
PrintCh('-', Stream);
|
||||
Num = -Num;
|
||||
if (FieldWidth != 0) {
|
||||
FieldWidth--;
|
||||
}
|
||||
}
|
||||
PrintUnsigned((unsigned long)Num, 10, FieldWidth, ZeroPad, LeftJustify, Stream);
|
||||
}
|
||||
|
||||
#ifndef NO_FP
|
||||
/* print a double to a stream without using printf/sprintf */
|
||||
void PrintFP(double Num, struct OutputStream *Stream) {
|
||||
int Exponent = 0;
|
||||
int MaxDecimal;
|
||||
if (Num < 0) {
|
||||
PrintCh('-', Stream);
|
||||
Num = -Num;
|
||||
}
|
||||
|
||||
if (Num >= 1e7) {
|
||||
Exponent = log10(Num);
|
||||
} else if (Num <= 1e-7 && Num != 0.0) {
|
||||
Exponent = log10(Num) - 0.999999999;
|
||||
}
|
||||
Num /= pow(10.0, Exponent);
|
||||
PrintInt((long)Num, 0, FALSE, FALSE, Stream);
|
||||
PrintCh('.', Stream);
|
||||
Num = (Num - (long)Num) * 10;
|
||||
if (abs(Num) >= 1e-7) {
|
||||
for (MaxDecimal = 6; MaxDecimal > 0 && abs(Num) >= 1e-7; Num = (Num - (long)(Num + 1e-7)) * 10, MaxDecimal--) {
|
||||
PrintCh('0' + (long)(Num + 1e-7), Stream);
|
||||
}
|
||||
} else {
|
||||
PrintCh('0', Stream);
|
||||
}
|
||||
if (Exponent != 0) {
|
||||
PrintCh('e', Stream);
|
||||
PrintInt(Exponent, 0, FALSE, FALSE, Stream);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* intrinsic functions made available to the language */
|
||||
void GenericPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs, struct OutputStream *Stream) {
|
||||
char *FPos;
|
||||
struct Value *NextArg = Param[0];
|
||||
struct ValueType *FormatType;
|
||||
int ArgCount = 1;
|
||||
int LeftJustify = FALSE;
|
||||
int ZeroPad = FALSE;
|
||||
int FieldWidth = 0;
|
||||
char *Format = Param[0]->Val->Pointer;
|
||||
|
||||
for (FPos = Format; *FPos != '\0'; FPos++) {
|
||||
if (*FPos == '%') {
|
||||
FPos++;
|
||||
if (*FPos == '-') {
|
||||
/* a leading '-' means left justify */
|
||||
LeftJustify = TRUE;
|
||||
FPos++;
|
||||
}
|
||||
|
||||
if (*FPos == '0') {
|
||||
/* a leading zero means zero pad a decimal number */
|
||||
ZeroPad = TRUE;
|
||||
FPos++;
|
||||
}
|
||||
|
||||
/* get any field width in the format */
|
||||
while (isdigit((int)*FPos)) {
|
||||
FieldWidth = FieldWidth * 10 + (*FPos++ - '0');
|
||||
}
|
||||
/* now check the format type */
|
||||
switch (*FPos) {
|
||||
case 's': FormatType = CharPtrType; break;
|
||||
case 'd': case 'u': case 'x': case 'b': case 'c': FormatType = &IntType; break;
|
||||
#ifndef NO_FP
|
||||
case 'f': FormatType = &FPType; break;
|
||||
#endif
|
||||
case '%': PrintCh('%', Stream); FormatType = NULL; break;
|
||||
case '\0': FPos--; FormatType = NULL; break;
|
||||
default: PrintCh(*FPos, Stream); FormatType = NULL; break;
|
||||
}
|
||||
|
||||
if (FormatType != NULL) {
|
||||
/* we have to format something */
|
||||
if (ArgCount >= NumArgs) {
|
||||
PrintStr("XXX", Stream); /* not enough parameters for format */
|
||||
} else {
|
||||
NextArg = (struct Value *)((char *)NextArg + MEM_ALIGN(sizeof(struct Value) + TypeStackSizeValue(NextArg)));
|
||||
if (NextArg->Typ != FormatType &&
|
||||
!((FormatType == &IntType || *FPos == 'f') && IS_NUMERIC_COERCIBLE(NextArg)) &&
|
||||
!(FormatType == CharPtrType && (NextArg->Typ->Base == TypePointer ||
|
||||
(NextArg->Typ->Base == TypeArray && NextArg->Typ->FromType->Base == TypeChar) ) ) ) {
|
||||
PrintStr("XXX", Stream); /* bad type for format */
|
||||
} else {
|
||||
switch (*FPos) {
|
||||
case 's':
|
||||
{
|
||||
char *Str;
|
||||
|
||||
if (NextArg->Typ->Base == TypePointer) {
|
||||
Str = NextArg->Val->Pointer;
|
||||
}else {
|
||||
Str = &NextArg->Val->ArrayMem[0];
|
||||
}
|
||||
if (Str == NULL) {
|
||||
PrintStr("NULL", Stream);
|
||||
} else {
|
||||
PrintStr(Str, 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 TypeGotoLabel:
|
||||
PrintStr("goto label ", Stream);
|
||||
break;
|
||||
case Type_Type:
|
||||
PrintStr("type ", Stream);
|
||||
break;
|
||||
}
|
||||
case 'd': PrintInt(ExpressionCoerceInteger(NextArg), FieldWidth, ZeroPad, LeftJustify, Stream); break;
|
||||
case 'u': PrintUnsigned(ExpressionCoerceUnsignedInteger(NextArg), 10, FieldWidth, ZeroPad, LeftJustify, Stream); break;
|
||||
case 'x': PrintUnsigned(ExpressionCoerceUnsignedInteger(NextArg), 16, FieldWidth, ZeroPad, LeftJustify, Stream); break;
|
||||
case 'b': PrintUnsigned(ExpressionCoerceUnsignedInteger(NextArg), 2, FieldWidth, ZeroPad, LeftJustify, Stream); break;
|
||||
case 'c': PrintCh(ExpressionCoerceUnsignedInteger(NextArg), Stream); break;
|
||||
#ifndef NO_FP
|
||||
case 'f': PrintFP(ExpressionCoerceFP(NextArg), Stream); break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
ArgCount++;
|
||||
}
|
||||
} else {
|
||||
PrintCh(*FPos, Stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* printf(): print to console output */
|
||||
void LibPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
struct OutputStream ConsoleStream;
|
||||
ConsoleStream.Putch = &PlatformPutc;
|
||||
GenericPrintf(Parser, ReturnValue, Param, NumArgs, &ConsoleStream);
|
||||
}
|
||||
|
||||
/* sprintf(): print to a string */
|
||||
void LibSPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
struct OutputStream StrStream;
|
||||
StrStream.Putch = &SPutc;
|
||||
StrStream.i.Str.Parser = Parser;
|
||||
StrStream.i.Str.WritePos = Param[0]->Val->Pointer;
|
||||
GenericPrintf(Parser, ReturnValue, Param+1, NumArgs-1, &StrStream);
|
||||
PrintCh(0, &StrStream);
|
||||
ReturnValue->Val->Pointer = *Param;
|
||||
}
|
||||
|
||||
/* get a line of input. protected from buffer overrun */
|
||||
void LibGets(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->Pointer = PlatformGetLine(Param[0]->Val->Pointer, GETS_BUF_MAX, NULL);
|
||||
if (ReturnValue->Val->Pointer != NULL) {
|
||||
char *EOLPos = strchr(Param[0]->Val->Pointer, '\n');
|
||||
if (EOLPos != NULL) {
|
||||
*EOLPos = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LibGetc(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->Integer = PlatformGetCharacter();
|
||||
}
|
||||
|
||||
void LibExit(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
PlatformExit(Param[0]->Val->Integer);
|
||||
}
|
||||
|
||||
#ifdef PICOC_LIBRARY
|
||||
void LibSin(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->FP = sin(Param[0]->Val->FP);
|
||||
}
|
||||
|
||||
void LibCos(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->FP = cos(Param[0]->Val->FP);
|
||||
}
|
||||
|
||||
void LibTan(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->FP = tan(Param[0]->Val->FP);
|
||||
}
|
||||
|
||||
void LibAsin(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->FP = asin(Param[0]->Val->FP);
|
||||
}
|
||||
|
||||
void LibAcos(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->FP = acos(Param[0]->Val->FP);
|
||||
}
|
||||
|
||||
void LibAtan(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->FP = atan(Param[0]->Val->FP);
|
||||
}
|
||||
|
||||
void LibSinh(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->FP = sinh(Param[0]->Val->FP);
|
||||
}
|
||||
|
||||
void LibCosh(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->FP = cosh(Param[0]->Val->FP);
|
||||
}
|
||||
|
||||
void LibTanh(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->FP = tanh(Param[0]->Val->FP);
|
||||
}
|
||||
|
||||
void LibExp(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->FP = exp(Param[0]->Val->FP);
|
||||
}
|
||||
|
||||
void LibFabs(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->FP = fabs(Param[0]->Val->FP);
|
||||
}
|
||||
|
||||
void LibLog(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->FP = log(Param[0]->Val->FP);
|
||||
}
|
||||
|
||||
void LibLog10(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->FP = log10(Param[0]->Val->FP);
|
||||
}
|
||||
|
||||
void LibPow(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->FP = pow(Param[0]->Val->FP, Param[1]->Val->FP);
|
||||
}
|
||||
|
||||
void LibSqrt(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->FP = sqrt(Param[0]->Val->FP);
|
||||
}
|
||||
|
||||
void LibRound(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->FP = floor(Param[0]->Val->FP + 0.5); /* XXX - fix for soft float */
|
||||
}
|
||||
|
||||
void LibCeil(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->FP = ceil(Param[0]->Val->FP);
|
||||
}
|
||||
|
||||
void LibFloor(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->FP = floor(Param[0]->Val->FP);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NO_STRING_FUNCTIONS
|
||||
void LibMalloc(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->Pointer = malloc(Param[0]->Val->Integer);
|
||||
}
|
||||
|
||||
#ifndef NO_CALLOC
|
||||
void LibCalloc(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->Pointer = calloc(Param[0]->Val->Integer, Param[1]->Val->Integer);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NO_REALLOC
|
||||
void LibRealloc(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->Pointer = realloc(Param[0]->Val->Pointer, Param[1]->Val->Integer);
|
||||
}
|
||||
#endif
|
||||
|
||||
void LibFree(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
free(Param[0]->Val->Pointer);
|
||||
}
|
||||
|
||||
void LibStrcpy(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
char *To = (char *)Param[0]->Val->Pointer;
|
||||
char *From = (char *)Param[1]->Val->Pointer;
|
||||
|
||||
while (*From != '\0') {
|
||||
*To++ = *From++;
|
||||
}
|
||||
|
||||
*To = '\0';
|
||||
}
|
||||
|
||||
void LibStrncpy(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
char *To = (char *)Param[0]->Val->Pointer;
|
||||
char *From = (char *)Param[1]->Val->Pointer;
|
||||
int Len = Param[2]->Val->Integer;
|
||||
|
||||
for (; *From != '\0' && Len > 0; Len--) {
|
||||
*To++ = *From++;
|
||||
}
|
||||
if (Len > 0) {
|
||||
*To = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void LibStrcmp(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
char *Str1 = (char *)Param[0]->Val->Pointer;
|
||||
char *Str2 = (char *)Param[1]->Val->Pointer;
|
||||
int StrEnded;
|
||||
|
||||
for (StrEnded = FALSE; !StrEnded; StrEnded = (*Str1 == '\0' || *Str2 == '\0'), Str1++, Str2++) {
|
||||
if (*Str1 < *Str2) {
|
||||
ReturnValue->Val->Integer = -1;
|
||||
return;
|
||||
} else if (*Str1 > *Str2) {
|
||||
ReturnValue->Val->Integer = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
ReturnValue->Val->Integer = 0;
|
||||
}
|
||||
|
||||
void LibStrncmp(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
char *Str1 = (char *)Param[0]->Val->Pointer;
|
||||
char *Str2 = (char *)Param[1]->Val->Pointer;
|
||||
int Len = Param[2]->Val->Integer;
|
||||
int StrEnded;
|
||||
|
||||
for (StrEnded = FALSE; !StrEnded && Len > 0; StrEnded = (*Str1 == '\0' || *Str2 == '\0'), Str1++, Str2++, Len--) {
|
||||
if (*Str1 < *Str2) {
|
||||
ReturnValue->Val->Integer = -1;
|
||||
return;
|
||||
} else if (*Str1 > *Str2) {
|
||||
ReturnValue->Val->Integer = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
ReturnValue->Val->Integer = 0;
|
||||
}
|
||||
|
||||
void LibStrcat(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
char *To = (char *)Param[0]->Val->Pointer;
|
||||
char *From = (char *)Param[1]->Val->Pointer;
|
||||
while (*To != '\0') {
|
||||
To++;
|
||||
}
|
||||
while (*From != '\0') {
|
||||
*To++ = *From++;
|
||||
}
|
||||
*To = '\0';
|
||||
}
|
||||
|
||||
void LibIndex(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
char *Pos = (char *)Param[0]->Val->Pointer;
|
||||
int SearchChar = Param[1]->Val->Integer;
|
||||
while (*Pos != '\0' && *Pos != SearchChar) {
|
||||
Pos++;
|
||||
}
|
||||
if (*Pos != SearchChar) {
|
||||
ReturnValue->Val->Pointer = NULL;
|
||||
} else {
|
||||
ReturnValue->Val->Pointer = Pos;
|
||||
}
|
||||
}
|
||||
|
||||
void LibRindex(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
char *Pos = (char *)Param[0]->Val->Pointer;
|
||||
int SearchChar = Param[1]->Val->Integer;
|
||||
ReturnValue->Val->Pointer = NULL;
|
||||
for (; *Pos != '\0'; Pos++) {
|
||||
if (*Pos == SearchChar) {
|
||||
ReturnValue->Val->Pointer = Pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LibStrlen(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
char *Pos = (char *)Param[0]->Val->Pointer;
|
||||
int Len;
|
||||
for (Len = 0; *Pos != '\0'; Pos++) {
|
||||
Len++;
|
||||
}
|
||||
ReturnValue->Val->Integer = Len;
|
||||
}
|
||||
|
||||
void LibMemset(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
/* we can use the system memset() */
|
||||
memset(Param[0]->Val->Pointer, Param[1]->Val->Integer, Param[2]->Val->Integer);
|
||||
}
|
||||
|
||||
void LibMemcpy(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
/* we can use the system memcpy() */
|
||||
memcpy(Param[0]->Val->Pointer, Param[1]->Val->Pointer, Param[2]->Val->Integer);
|
||||
}
|
||||
|
||||
void LibMemcmp(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
unsigned char *Mem1 = (unsigned char *)Param[0]->Val->Pointer;
|
||||
unsigned char *Mem2 = (unsigned char *)Param[1]->Val->Pointer;
|
||||
int Len = Param[2]->Val->Integer;
|
||||
|
||||
for (; Len > 0; Mem1++, Mem2++, Len--) {
|
||||
if (*Mem1 < *Mem2) {
|
||||
ReturnValue->Val->Integer = -1;
|
||||
return;
|
||||
} else if (*Mem1 > *Mem2) {
|
||||
ReturnValue->Val->Integer = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
ReturnValue->Val->Integer = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* list of all library functions and their prototypes */
|
||||
struct LibraryFunction CLibrary[] = {
|
||||
{ LibPrintf, "void printf(char *, ...);" },
|
||||
{ LibSPrintf, "char *sprintf(char *, char *, ...);" },
|
||||
{ LibGets, "char *gets(char *);" },
|
||||
{ LibGetc, "int getchar();" },
|
||||
{ LibExit, "void exit(int);" },
|
||||
#ifdef PICOC_LIBRARY
|
||||
{ LibSin, "float sin(float);" },
|
||||
{ LibCos, "float cos(float);" },
|
||||
{ LibTan, "float tan(float);" },
|
||||
{ LibAsin, "float asin(float);" },
|
||||
{ LibAcos, "float acos(float);" },
|
||||
{ LibAtan, "float atan(float);" },
|
||||
{ LibSinh, "float sinh(float);" },
|
||||
{ LibCosh, "float cosh(float);" },
|
||||
{ LibTanh, "float tanh(float);" },
|
||||
{ LibExp, "float exp(float);" },
|
||||
{ LibFabs, "float fabs(float);" },
|
||||
{ LibLog, "float log(float);" },
|
||||
{ LibLog10, "float log10(float);" },
|
||||
{ LibPow, "float pow(float,float);" },
|
||||
{ LibSqrt, "float sqrt(float);" },
|
||||
{ LibRound, "float round(float);" },
|
||||
{ LibCeil, "float ceil(float);" },
|
||||
{ LibFloor, "float floor(float);" },
|
||||
#endif
|
||||
{ LibMalloc, "void *malloc(int);" },
|
||||
#ifndef NO_CALLOC
|
||||
{ LibCalloc, "void *calloc(int,int);" },
|
||||
#endif
|
||||
#ifndef NO_REALLOC
|
||||
{ LibRealloc, "void *realloc(void *,int);" },
|
||||
#endif
|
||||
{ LibFree, "void free(void *);" },
|
||||
#ifndef NO_STRING_FUNCTIONS
|
||||
{ LibStrcpy, "void strcpy(char *,char *);" },
|
||||
{ LibStrncpy, "void strncpy(char *,char *,int);" },
|
||||
{ LibStrcmp, "int strcmp(char *,char *);" },
|
||||
{ LibStrncmp, "int strncmp(char *,char *,int);" },
|
||||
{ LibStrcat, "void strcat(char *,char *);" },
|
||||
{ LibIndex, "char *index(char *,int);" },
|
||||
{ LibRindex, "char *rindex(char *,int);" },
|
||||
{ LibStrlen, "int strlen(char *);" },
|
||||
{ LibMemset, "void memset(void *,int,int);" },
|
||||
{ LibMemcpy, "void memcpy(void *,void *,int);" },
|
||||
{ LibMemcmp, "int memcmp(void *,void *,int);" },
|
||||
#endif
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
#endif /* BUILTIN_MINI_STDLIB */
|
||||
|
@ -1,3 +1,11 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
/* string.h library for large systems - small embedded systems use clibrary.c instead */
|
||||
#include <ctype.h>
|
||||
#include "../interpreter.h"
|
||||
|
@ -1,3 +1,11 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
/* string.h library for large systems - small embedded systems use clibrary.c instead */
|
||||
#include <errno.h>
|
||||
#include "../interpreter.h"
|
||||
|
@ -1,8 +1,15 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
/* stdio.h library for large systems - small embedded systems use clibrary.c instead */
|
||||
#include "../interpreter.h"
|
||||
|
||||
#ifndef BUILTIN_MINI_STDLIB
|
||||
#ifndef NO_FP
|
||||
|
||||
static double M_EValue = 2.7182818284590452354; /* e */
|
||||
static double M_LOG2EValue = 1.4426950408889634074; /* log_2 e */
|
||||
@ -158,5 +165,4 @@ void MathSetupFunc() {
|
||||
VariableDefinePlatformVar(NULL, "M_SQRT1_2", &FPType, (union AnyValue *)&M_SQRT1_2Value, FALSE);
|
||||
}
|
||||
|
||||
#endif /* !NO_FP */
|
||||
#endif /* !BUILTIN_MINI_STDLIB */
|
||||
|
@ -1,3 +1,11 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
/* string.h library for large systems - small embedded systems use clibrary.c instead */
|
||||
#include "../interpreter.h"
|
||||
|
||||
|
@ -1,3 +1,11 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
/* stdio.h library for large systems - small embedded systems use clibrary.c instead */
|
||||
#include <errno.h>
|
||||
#include "../interpreter.h"
|
||||
@ -174,7 +182,6 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, int S
|
||||
ShowType = &IntType;
|
||||
break;
|
||||
/* integer base conversions */
|
||||
#ifndef NO_FP
|
||||
case 'e':
|
||||
case 'E':
|
||||
ShowType = &FPType;
|
||||
@ -190,7 +197,6 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, int S
|
||||
ShowType = &FPType;
|
||||
break;
|
||||
/* double, flexible format */
|
||||
#endif
|
||||
case 'a':
|
||||
case 'A':
|
||||
ShowType = &IntType;
|
||||
@ -268,18 +274,14 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, int S
|
||||
} else {
|
||||
StdioOutPuts("XXX", &SOStream);
|
||||
}
|
||||
}
|
||||
#ifndef NO_FP
|
||||
else if (ShowType == &FPType) {
|
||||
} else if (ShowType == &FPType) {
|
||||
/* show a floating point number */
|
||||
if (IS_NUMERIC_COERCIBLE(ThisArg)) {
|
||||
StdioFprintfFP(&SOStream, OneFormatBuf, ExpressionCoerceFP(ThisArg));
|
||||
} else {
|
||||
StdioOutPuts("XXX", &SOStream);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if (ShowType == CharPtrType) {
|
||||
} else if (ShowType == CharPtrType) {
|
||||
if (ThisArg->Typ->Base == TypePointer) {
|
||||
StdioFprintfPointer(&SOStream, OneFormatBuf, ThisArg->Val->Pointer);
|
||||
} else if ( ThisArg->Typ->Base == TypeArray
|
||||
|
@ -1,3 +1,11 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
/* stdlib.h library for large systems - small embedded systems use clibrary.c instead */
|
||||
#include "../interpreter.h"
|
||||
|
||||
@ -5,11 +13,9 @@
|
||||
|
||||
static int ZeroValue = 0;
|
||||
|
||||
#ifndef NO_FP
|
||||
void StdlibAtof(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->FP = atof(Param[0]->Val->Pointer);
|
||||
}
|
||||
#endif
|
||||
|
||||
void StdlibAtoi(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->Integer = atoi(Param[0]->Val->Pointer);
|
||||
@ -19,11 +25,9 @@ void StdlibAtol(struct ParseState *Parser, struct Value *ReturnValue, struct Val
|
||||
ReturnValue->Val->Integer = atol(Param[0]->Val->Pointer);
|
||||
}
|
||||
|
||||
#ifndef NO_FP
|
||||
void StdlibStrtod(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->FP = strtod(Param[0]->Val->Pointer, Param[1]->Val->Pointer);
|
||||
}
|
||||
#endif
|
||||
|
||||
void StdlibStrtol(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->Integer = strtol(Param[0]->Val->Pointer, Param[1]->Val->Pointer, Param[2]->Val->Integer);
|
||||
@ -84,10 +88,8 @@ void StdlibLabs(struct ParseState *Parser, struct Value *ReturnValue, struct Val
|
||||
/* all stdlib.h functions */
|
||||
struct LibraryFunction StdlibFunctions[] =
|
||||
{
|
||||
#ifndef NO_FP
|
||||
{ StdlibAtof, "float atof(char *);" },
|
||||
{ StdlibStrtod, "float strtod(char *,char **);" },
|
||||
#endif
|
||||
{ StdlibAtoi, "int atoi(char *);" },
|
||||
{ StdlibAtol, "int atol(char *);" },
|
||||
{ StdlibStrtol, "int strtol(char *,char **,int);" },
|
||||
@ -115,4 +117,4 @@ void StdlibSetupFunc() {
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !BUILTIN_MINI_STDLIB */
|
||||
#endif
|
||||
|
@ -1,3 +1,11 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
/* string.h library for large systems - small embedded systems use clibrary.c instead */
|
||||
#include "../interpreter.h"
|
||||
|
||||
|
@ -1,3 +1,11 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
/* string.h library for large systems - small embedded systems use clibrary.c instead */
|
||||
#include <time.h>
|
||||
#include "../interpreter.h"
|
||||
@ -26,11 +34,9 @@ void StdCtime(struct ParseState *Parser, struct Value *ReturnValue, struct Value
|
||||
ReturnValue->Val->Pointer = ctime(Param[0]->Val->Pointer);
|
||||
}
|
||||
|
||||
#ifndef NO_FP
|
||||
void StdDifftime(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->FP = difftime((time_t)Param[0]->Val->Integer, Param[1]->Val->Integer);
|
||||
}
|
||||
#endif
|
||||
|
||||
void StdGmtime(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||
ReturnValue->Val->Pointer = gmtime(Param[0]->Val->Pointer);
|
||||
@ -76,9 +82,7 @@ struct LibraryFunction StdTimeFunctions[] = {
|
||||
{ StdAsctime, "char *asctime(struct tm *);" },
|
||||
{ StdClock, "time_t clock();" },
|
||||
{ StdCtime, "char *ctime(int *);" },
|
||||
#ifndef NO_FP
|
||||
{ StdDifftime, "double difftime(int, int);" },
|
||||
#endif
|
||||
{ StdGmtime, "struct tm *gmtime(int *);" },
|
||||
{ StdGmtime_r, "struct tm *gmtime_r(int *, struct tm *);" },
|
||||
{ StdLocaltime, "struct tm *localtime(int *);" },
|
||||
|
@ -1,3 +1,11 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
/* stdlib.h library for large systems - small embedded systems use clibrary.c instead */
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
@ -1,3 +1,11 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
#include "interpreter.h"
|
||||
|
||||
|
||||
@ -168,10 +176,8 @@ long ExpressionCoerceInteger(struct Value *Val) {
|
||||
return (long)Val->Val->UnsignedLongInteger;
|
||||
case TypePointer:
|
||||
return (long)Val->Val->Pointer;
|
||||
#ifndef NO_FP
|
||||
case TypeFP:
|
||||
return (long)Val->Val->FP;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -195,16 +201,13 @@ unsigned long ExpressionCoerceUnsignedInteger(struct Value *Val) {
|
||||
return (unsigned long)Val->Val->UnsignedLongInteger;
|
||||
case TypePointer:
|
||||
return (unsigned long)Val->Val->Pointer;
|
||||
#ifndef NO_FP
|
||||
case TypeFP:
|
||||
return (unsigned long)Val->Val->FP;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NO_FP
|
||||
double ExpressionCoerceFP(struct Value *Val) {
|
||||
#ifndef BROKEN_FLOAT_CASTS
|
||||
int IntVal;
|
||||
@ -259,7 +262,6 @@ double ExpressionCoerceFP(struct Value *Val) {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* assign an integer value */
|
||||
long ExpressionAssignInt(struct ParseState *_parser, struct Value *DestValue, long FromInt, int After) {
|
||||
@ -300,7 +302,6 @@ long ExpressionAssignInt(struct ParseState *_parser, struct Value *DestValue, lo
|
||||
return Result;
|
||||
}
|
||||
|
||||
#ifndef NO_FP
|
||||
/* assign a floating point value */
|
||||
double ExpressionAssignFP(struct ParseState *_parser, struct Value *DestValue, double FromFP) {
|
||||
if (!DestValue->IsLValue) {
|
||||
@ -309,7 +310,6 @@ double ExpressionAssignFP(struct ParseState *_parser, struct Value *DestValue, d
|
||||
DestValue->Val->FP = FromFP;
|
||||
return FromFP;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* push a node on to the expression stack */
|
||||
void ExpressionStackPushValueNode(struct ParseState *_parser, struct ExpressionStack **StackTop, struct Value *ValueLoc) {
|
||||
@ -365,13 +365,11 @@ void ExpressionPushInt(struct ParseState *_parser, struct ExpressionStack **Stac
|
||||
ExpressionStackPushValueNode(_parser, StackTop, ValueLoc);
|
||||
}
|
||||
|
||||
#ifndef NO_FP
|
||||
void ExpressionPushFP(struct ParseState *_parser, struct ExpressionStack **StackTop, double FPValue) {
|
||||
struct Value *ValueLoc = VariableAllocValueFromType(_parser, &FPType, FALSE, NULL, FALSE);
|
||||
ValueLoc->Val->FP = FPValue;
|
||||
ExpressionStackPushValueNode(_parser, StackTop, ValueLoc);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* assign to a pointer */
|
||||
void ExpressionAssignToPointer(struct ParseState *_parser, struct Value *ToValue, struct Value *FromValue, const char *FuncName, int ParamNo, int AllowPointerCoercion) {
|
||||
@ -441,14 +439,12 @@ void ExpressionAssign(struct ParseState *_parser, struct Value *DestValue, struc
|
||||
case TypeUnsignedLong:
|
||||
DestValue->Val->UnsignedLongInteger = ExpressionCoerceUnsignedInteger(SourceValue);
|
||||
break;
|
||||
#ifndef NO_FP
|
||||
case TypeFP:
|
||||
if (!IS_NUMERIC_COERCIBLE_PLUS_POINTERS(SourceValue, AllowPointerCoercion)) {
|
||||
AssignFail(_parser, "%t from %t", DestValue->Typ, SourceValue->Typ, 0, 0, FuncName, ParamNo);
|
||||
}
|
||||
DestValue->Val->FP = ExpressionCoerceFP(SourceValue);
|
||||
break;
|
||||
#endif
|
||||
case TypePointer:
|
||||
ExpressionAssignToPointer(_parser, DestValue, SourceValue, FuncName, ParamNo, AllowPointerCoercion);
|
||||
break;
|
||||
@ -527,7 +523,6 @@ void ExpressionPrefixOperator(struct ParseState *_parser, struct ExpressionStack
|
||||
break;
|
||||
default:
|
||||
/* an arithmetic operator */
|
||||
#ifndef NO_FP
|
||||
if (TopValue->Typ == &FPType) {
|
||||
/* floating point prefix arithmetic */
|
||||
double ResultFP = 0.0;
|
||||
@ -543,9 +538,7 @@ void ExpressionPrefixOperator(struct ParseState *_parser, struct ExpressionStack
|
||||
break;
|
||||
}
|
||||
ExpressionPushFP(_parser, StackTop, ResultFP);
|
||||
} else
|
||||
#endif
|
||||
if (IS_NUMERIC_COERCIBLE(TopValue)) {
|
||||
} else if (IS_NUMERIC_COERCIBLE(TopValue)) {
|
||||
/* integer prefix arithmetic */
|
||||
long ResultInt = 0;
|
||||
long TopInt = ExpressionCoerceInteger(TopValue);
|
||||
@ -694,9 +687,7 @@ void ExpressionInfixOperator(struct ParseState *_parser, struct ExpressionStack
|
||||
ExpressionQuestionMarkOperator(_parser, StackTop, TopValue, BottomValue);
|
||||
} else if (Op == TokenColon) {
|
||||
ExpressionColonOperator(_parser, StackTop, TopValue, BottomValue);
|
||||
}
|
||||
#ifndef NO_FP
|
||||
else if ( (TopValue->Typ == &FPType && BottomValue->Typ == &FPType)
|
||||
} else if ( (TopValue->Typ == &FPType && BottomValue->Typ == &FPType)
|
||||
|| (TopValue->Typ == &FPType && IS_NUMERIC_COERCIBLE(BottomValue))
|
||||
|| (IS_NUMERIC_COERCIBLE(TopValue) && BottomValue->Typ == &FPType) ) {
|
||||
/* floating point infix arithmetic */
|
||||
@ -765,9 +756,7 @@ void ExpressionInfixOperator(struct ParseState *_parser, struct ExpressionStack
|
||||
} else {
|
||||
ExpressionPushFP(_parser, StackTop, ResultFP);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if (IS_NUMERIC_COERCIBLE(TopValue) && IS_NUMERIC_COERCIBLE(BottomValue)) {
|
||||
} else if (IS_NUMERIC_COERCIBLE(TopValue) && IS_NUMERIC_COERCIBLE(BottomValue)) {
|
||||
/* integer operation */
|
||||
long TopInt = ExpressionCoerceInteger(TopValue);
|
||||
long BottomInt = ExpressionCoerceInteger(BottomValue);
|
||||
@ -1348,11 +1337,7 @@ void ExpressionParseMacroCall(struct ParseState *_parser, struct ExpressionStack
|
||||
enum LexToken Token;
|
||||
if (_parser->Mode == RunModeRun) {
|
||||
/* create a stack frame for this macro */
|
||||
#ifndef NO_FP
|
||||
ExpressionStackPushValueByType(_parser, StackTop, &FPType); /* largest return type there is */
|
||||
#else
|
||||
ExpressionStackPushValueByType(_parser, StackTop, &IntType); /* largest return type there is */
|
||||
#endif
|
||||
ReturnValue = (*StackTop)->Val;
|
||||
HeapPushStackFrame();
|
||||
ParamArray = HeapAllocStack(sizeof(struct Value *) * MDef->NumParams);
|
||||
|
@ -1,3 +1,11 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
/* stack grows up from the bottom and heap grows down from the top of heap space */
|
||||
#include "interpreter.h"
|
||||
|
||||
|
@ -1,3 +1,11 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
#include "picoc.h"
|
||||
#include "interpreter.h"
|
||||
|
||||
@ -19,9 +27,7 @@ void IncludeInit() {
|
||||
#ifndef BUILTIN_MINI_STDLIB
|
||||
IncludeRegister("ctype.h", NULL, &StdCtypeFunctions[0], NULL);
|
||||
IncludeRegister("errno.h", &StdErrnoSetupFunc, NULL, NULL);
|
||||
#ifndef NO_FP
|
||||
IncludeRegister("math.h", &MathSetupFunc, &MathFunctions[0], NULL);
|
||||
#endif
|
||||
IncludeRegister("stdbool.h", &StdboolSetupFunc, NULL, StdboolDefs);
|
||||
IncludeRegister("stdio.h", &StdioSetupFunc, &StdioFunctions[0], StdioDefs);
|
||||
IncludeRegister("stdlib.h", &StdlibSetupFunc, &StdlibFunctions[0], NULL);
|
||||
|
@ -1,5 +1,13 @@
|
||||
#ifndef INTERPRETER_H
|
||||
#define INTERPRETER_H
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
#ifndef __ECI_INTERPRETER_H__
|
||||
#define __ECI_INTERPRETER_H__
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
@ -30,13 +38,8 @@ typedef FILE IOFILE;
|
||||
#endif
|
||||
|
||||
/* coercion of numeric types to other numeric types */
|
||||
#ifndef NO_FP
|
||||
#define IS_FP(v) ((v)->Typ->Base == TypeFP)
|
||||
#define FP_VAL(v) ((v)->Val->FP)
|
||||
#else
|
||||
#define IS_FP(v) 0
|
||||
#define FP_VAL(v) 0
|
||||
#endif
|
||||
|
||||
#define IS_POINTER_COERCIBLE(v, ap) ((ap) ? ((v)->Typ->Base == TypePointer) : 0)
|
||||
#define POINTER_COERCE(v) ((int)(v)->Val->Pointer)
|
||||
@ -122,9 +125,7 @@ enum BaseType {
|
||||
TypeUnsignedInt, //!< unsigned integer
|
||||
TypeUnsignedShort, //!< unsigned short integer
|
||||
TypeUnsignedLong, //!< unsigned long integer
|
||||
#ifndef NO_FP
|
||||
TypeFP, //!< floating point
|
||||
#endif
|
||||
TypeFunction, //!< a function
|
||||
TypeMacro, //!< a macro
|
||||
TypePointer, //!< a pointer
|
||||
@ -183,9 +184,7 @@ union AnyValue {
|
||||
struct ValueType *Typ;
|
||||
struct FuncDef FuncDef;
|
||||
struct MacroDef MacroDef;
|
||||
#ifndef NO_FP
|
||||
double FP;
|
||||
#endif
|
||||
void *Pointer; //!< unsafe native pointers
|
||||
};
|
||||
|
||||
@ -289,9 +288,7 @@ extern struct StackFrame *TopStackFrame;
|
||||
extern struct ValueType UberType;
|
||||
extern struct ValueType IntType;
|
||||
extern struct ValueType CharType;
|
||||
#ifndef NO_FP
|
||||
extern struct ValueType FPType;
|
||||
#endif
|
||||
extern struct ValueType VoidType;
|
||||
extern struct ValueType TypeType;
|
||||
extern struct ValueType FunctionType;
|
||||
@ -307,111 +304,31 @@ extern struct LibraryFunction CLibrary[];
|
||||
extern struct LibraryFunction PlatformLibrary[];
|
||||
extern IOFILE *CStdOut;
|
||||
|
||||
/* table.c */
|
||||
void TableInit();
|
||||
char *TableStrRegister(const char *_str);
|
||||
char *TableStrRegister2(const char *_str, int Len);
|
||||
void TableInitTable(struct Table *_table, struct TableEntry **_hashTable, int _size, int _onHeap);
|
||||
int TableSet(struct Table *Tbl, char *Key, struct Value *Val, const char *DeclFileName, int DeclLine, int DeclColumn);
|
||||
int TableGet(struct Table *Tbl, const char *Key, struct Value **Val, const char **DeclFileName, int *DeclLine, int *DeclColumn);
|
||||
struct Value *TableDelete(struct Table *Tbl, const char *Key);
|
||||
char *TableSetIdentifier(struct Table *Tbl, const char *Ident, int IdentLen);
|
||||
void TableStrFree();
|
||||
#include <eci/lex.h>
|
||||
#include <eci/parse.h>
|
||||
#include <eci/expression.h>
|
||||
|
||||
/* lex.c */
|
||||
void LexInit();
|
||||
void LexCleanup();
|
||||
void *LexAnalyse(const char *FileName, const char *Source, int SourceLen, int *TokenLen);
|
||||
void LexInitParser(struct ParseState *Parser, const char *SourceText, void *TokenSource, const char *FileName, int RunIt);
|
||||
enum LexToken LexGetToken(struct ParseState *Parser, struct Value **Value, int IncPos);
|
||||
enum LexToken LexRawPeekToken(struct ParseState *Parser);
|
||||
void LexToEndOfLine(struct ParseState *Parser);
|
||||
void *LexCopyTokens(struct ParseState *StartParser, struct ParseState *EndParser);
|
||||
void LexInteractiveClear(struct ParseState *Parser);
|
||||
void LexInteractiveCompleted(struct ParseState *Parser);
|
||||
void LexInteractiveStatementPrompt();
|
||||
#include <eci/heap.h>
|
||||
|
||||
/* parse.c */
|
||||
/* the following are defined in picoc.h:
|
||||
* void PicocParse(const char *FileName, const char *Source, int SourceLen, int RunIt, int CleanupNow, int CleanupSource);
|
||||
* void PicocParseInteractive(); */
|
||||
enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemicolon);
|
||||
struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, char *Identifier);
|
||||
void ParseCleanup();
|
||||
void ParserCopyPos(struct ParseState *To, struct ParseState *From);
|
||||
void ParserCopy(struct ParseState *To, struct ParseState *From);
|
||||
#include <eci/table.h>
|
||||
#include <eci/type.h>
|
||||
#include <eci/variable.h>
|
||||
#include <eci/include.h>
|
||||
#include <eci/clibrary.h>
|
||||
#include <eci/platform.h>
|
||||
#include <eci/cstdlib/ctype.h>
|
||||
#include <eci/cstdlib/errno.h>
|
||||
#include <eci/cstdlib/math.h>
|
||||
#include <eci/cstdlib/stdbool.h>
|
||||
#include <eci/cstdlib/stdio.h>
|
||||
#include <eci/cstdlib/stdlib.h>
|
||||
#include <eci/cstdlib/string.h>
|
||||
#include <eci/cstdlib/time.h>
|
||||
#include <eci/cstdlib/unistd.h>
|
||||
|
||||
/* expression.c */
|
||||
int ExpressionParse(struct ParseState *Parser, struct Value **Result);
|
||||
long ExpressionParseInt(struct ParseState *Parser);
|
||||
void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, struct Value *SourceValue, int Force, const char *FuncName, int ParamNo, int AllowPointerCoercion);
|
||||
long ExpressionCoerceInteger(struct Value *Val);
|
||||
unsigned long ExpressionCoerceUnsignedInteger(struct Value *Val);
|
||||
#ifndef NO_FP
|
||||
double ExpressionCoerceFP(struct Value *Val);
|
||||
#endif
|
||||
|
||||
/* type.c */
|
||||
void TypeInit();
|
||||
void TypeCleanup();
|
||||
int TypeSize(struct ValueType *Typ, int ArraySize, int Compact);
|
||||
int TypeSizeValue(struct Value *Val, int Compact);
|
||||
int TypeStackSizeValue(struct Value *Val);
|
||||
int TypeLastAccessibleOffset(struct Value *Val);
|
||||
int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ, int *IsStatic);
|
||||
void TypeParseIdentPart(struct ParseState *Parser, struct ValueType *BasicTyp, struct ValueType **Typ, char **Identifier);
|
||||
void TypeParse(struct ParseState *Parser, struct ValueType **Typ, char **Identifier, int *IsStatic);
|
||||
struct ValueType *TypeGetMatching(struct ParseState *Parser, struct ValueType *ParentType, enum BaseType Base, int ArraySize, const char *Identifier, int AllowDuplicates);
|
||||
struct ValueType *TypeCreateOpaqueStruct(struct ParseState *Parser, const char *StructName, int Size);
|
||||
// TODO : Move this ... platform.h:
|
||||
|
||||
/* heap.c */
|
||||
void HeapInit(int StackSize);
|
||||
void HeapCleanup();
|
||||
void *HeapAllocStack(int Size);
|
||||
int HeapPopStack(void *Addr, int Size);
|
||||
void HeapUnpopStack(int Size);
|
||||
void HeapPushStackFrame();
|
||||
int HeapPopStackFrame();
|
||||
void *HeapAllocMem(int Size);
|
||||
void HeapFreeMem(void *Mem);
|
||||
|
||||
/* variable.c */
|
||||
void VariableInit();
|
||||
void VariableCleanup();
|
||||
void VariableFree(struct Value *Val);
|
||||
void VariableTableCleanup(struct Table *HashTable);
|
||||
void *VariableAlloc(struct ParseState *Parser, int Size, int OnHeap);
|
||||
void VariableStackPop(struct ParseState *Parser, struct Value *Var);
|
||||
struct Value *VariableAllocValueAndData(struct ParseState *Parser, int DataSize, int IsLValue, struct Value *LValueFrom, int OnHeap);
|
||||
struct Value *VariableAllocValueAndCopy(struct ParseState *Parser, struct Value *FromValue, int OnHeap);
|
||||
struct Value *VariableAllocValueFromType(struct ParseState *Parser, struct ValueType *Typ, int IsLValue, struct Value *LValueFrom, int OnHeap);
|
||||
struct Value *VariableAllocValueFromExistingData(struct ParseState *Parser, struct ValueType *Typ, union AnyValue *FromValue, int IsLValue, struct Value *LValueFrom);
|
||||
struct Value *VariableAllocValueShared(struct ParseState *Parser, struct Value *FromValue);
|
||||
struct Value *VariableDefine(struct ParseState *Parser, char *Ident, struct Value *InitValue, struct ValueType *Typ, int MakeWritable);
|
||||
struct Value *VariableDefineButIgnoreIdentical(struct ParseState *Parser, char *Ident, struct ValueType *Typ, int IsStatic, int *FirstVisit);
|
||||
int VariableDefined(const char *Ident);
|
||||
void VariableGet(struct ParseState *Parser, const char *Ident, struct Value **LVal);
|
||||
void VariableDefinePlatformVar(struct ParseState *Parser, char *Ident, struct ValueType *Typ, union AnyValue *FromValue, int IsWritable);
|
||||
void VariableStackFrameAdd(struct ParseState *Parser, const char *FuncName, int NumParams);
|
||||
void VariableStackFramePop(struct ParseState *Parser);
|
||||
struct Value *VariableStringLiteralGet(char *Ident);
|
||||
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();
|
||||
void LibraryAdd(struct Table *GlobalTable, const char *LibraryName, struct LibraryFunction *FuncList);
|
||||
void CLibraryInit();
|
||||
void PrintCh(char OutCh, IOFILE *Stream);
|
||||
void PrintSimpleInt(long Num, IOFILE *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 */
|
||||
/* the following are defined in picoc.h:
|
||||
* void PicocCallMain(int argc, char **argv);
|
||||
* int PicocPlatformSetExitPoint();
|
||||
@ -433,49 +350,5 @@ void PlatformExit(int ExitVal);
|
||||
char *PlatformMakeTempName(char *TempNameBuffer);
|
||||
void PlatformLibraryInit();
|
||||
|
||||
/* include.c */
|
||||
void IncludeInit();
|
||||
void IncludeCleanup();
|
||||
void IncludeRegister(const char *IncludeName, void (*SetupFunction)(void), struct LibraryFunction *FuncList, const char *SetupCSource);
|
||||
void IncludeFile(char *Filename);
|
||||
/* the following is defined in picoc.h:
|
||||
* void PicocIncludeAllSystemHeaders(); */
|
||||
|
||||
/* stdio.c */
|
||||
extern const char StdioDefs[];
|
||||
extern struct LibraryFunction StdioFunctions[];
|
||||
void StdioSetupFunc(void);
|
||||
|
||||
/* math.c */
|
||||
extern struct LibraryFunction MathFunctions[];
|
||||
void MathSetupFunc(void);
|
||||
|
||||
/* string.c */
|
||||
extern struct LibraryFunction StringFunctions[];
|
||||
void StringSetupFunc(void);
|
||||
|
||||
/* stdlib.c */
|
||||
extern struct LibraryFunction StdlibFunctions[];
|
||||
void StdlibSetupFunc(void);
|
||||
|
||||
/* time.c */
|
||||
extern const char StdTimeDefs[];
|
||||
extern struct LibraryFunction StdTimeFunctions[];
|
||||
void StdTimeSetupFunc(void);
|
||||
|
||||
/* errno.c */
|
||||
void StdErrnoSetupFunc(void);
|
||||
|
||||
/* ctype.c */
|
||||
extern struct LibraryFunction StdCtypeFunctions[];
|
||||
|
||||
/* stdbool.c */
|
||||
extern const char StdboolDefs[];
|
||||
void StdboolSetupFunc(void);
|
||||
|
||||
/* unistd.c */
|
||||
extern const char UnistdDefs[];
|
||||
extern struct LibraryFunction UnistdFunctions[];
|
||||
void UnistdSetupFunc(void);
|
||||
|
||||
#endif /* INTERPRETER_H */
|
||||
#endif
|
||||
|
20
eci/lex.c
20
eci/lex.c
@ -1,3 +1,11 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
#include "interpreter.h"
|
||||
|
||||
#ifdef NO_CTYPE
|
||||
@ -50,15 +58,11 @@ static struct ReservedWord ReservedWords[] = {
|
||||
{ "default", TokenDefault, NULL },
|
||||
{ "delete", TokenDelete, NULL },
|
||||
{ "do", TokenDo, NULL },
|
||||
#ifndef NO_FP
|
||||
{ "double", TokenDoubleType, NULL },
|
||||
#endif
|
||||
{ "else", TokenElse, NULL },
|
||||
{ "enum", TokenEnumType, NULL },
|
||||
{ "extern", TokenExternType, NULL },
|
||||
#ifndef NO_FP
|
||||
{ "float", TokenFloatType, NULL },
|
||||
#endif
|
||||
{ "for", TokenFor, NULL },
|
||||
{ "goto", TokenGoto, NULL },
|
||||
{ "if", TokenIf, NULL },
|
||||
@ -122,10 +126,8 @@ enum LexToken LexGetNumber(struct LexState *Lexer, struct Value *Value) {
|
||||
int Result = 0;
|
||||
int Base = 10;
|
||||
enum LexToken ResultToken;
|
||||
#ifndef NO_FP
|
||||
double FPResult;
|
||||
double FPDiv;
|
||||
#endif
|
||||
if (*Lexer->Pos == '0') {
|
||||
/* a binary, octal or hex literal */
|
||||
LEXER_INC(Lexer);
|
||||
@ -163,7 +165,6 @@ enum LexToken LexGetNumber(struct LexState *Lexer, struct Value *Value) {
|
||||
LEXER_INC(Lexer);
|
||||
return ResultToken;
|
||||
}
|
||||
#ifndef NO_FP
|
||||
if ( Lexer->Pos == Lexer->End
|
||||
|| *Lexer->Pos != '.') {
|
||||
return ResultToken;
|
||||
@ -190,9 +191,6 @@ enum LexToken LexGetNumber(struct LexState *Lexer, struct Value *Value) {
|
||||
}
|
||||
Value->Val->FP = FPResult;
|
||||
return TokenFPConstant;
|
||||
#else
|
||||
return ResultToken;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* get a reserved word or identifier - used while scanning */
|
||||
@ -724,11 +722,9 @@ enum LexToken LexGetRawToken(struct ParseState *Parser, struct Value **Value, in
|
||||
case TokenCharacterConstant:
|
||||
LexValue.Typ = &CharType;
|
||||
break;
|
||||
#ifndef NO_FP
|
||||
case TokenFPConstant:
|
||||
LexValue.Typ = &FPType;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
10
eci/parse.c
10
eci/parse.c
@ -1,3 +1,11 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
#include "picoc.h"
|
||||
#include "interpreter.h"
|
||||
|
||||
@ -742,7 +750,7 @@ void PicocParse(const char *FileName, const char *Source, int SourceLen, int Run
|
||||
void PicocParseInteractive() {
|
||||
struct ParseState Parser;
|
||||
enum ParseResult Ok;
|
||||
PlatformPrintf(INTERACTIVE_PROMPT_START);
|
||||
PlatformPrintf("Starting eci " ECI_VERSION "\n");
|
||||
LexInitParser(&Parser, NULL, NULL, StrEmpty, TRUE);
|
||||
PicocPlatformSetExitPoint();
|
||||
LexInteractiveClear(&Parser);
|
||||
|
@ -1,3 +1,11 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
/* include only picoc.h here - should be able to use it with only the external interfaces, no internals from interpreter.h */
|
||||
#include "picoc.h"
|
||||
|
||||
|
18
eci/picoc.h
18
eci/picoc.h
@ -1,8 +1,16 @@
|
||||
#ifndef PICOC_H
|
||||
#define PICOC_H
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
/* picoc version number */
|
||||
#define PICOC_VERSION "v2.1"
|
||||
#ifndef __ECI_H__
|
||||
#define __ECI_H__
|
||||
|
||||
/* eci version number */
|
||||
#define ECI_VERSION "v0.1"
|
||||
|
||||
/* handy definitions */
|
||||
#ifndef TRUE
|
||||
@ -34,4 +42,4 @@ extern int PicocExitValue;
|
||||
/* include.c */
|
||||
void PicocIncludeAllSystemHeaders();
|
||||
|
||||
#endif /* PICOC_H */
|
||||
#endif
|
||||
|
@ -1,3 +1,11 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
#include "picoc.h"
|
||||
#include "interpreter.h"
|
||||
|
||||
@ -180,11 +188,9 @@ void PlatformVPrintf(const char *Format, va_list Args) {
|
||||
case 't':
|
||||
PrintType(va_arg(Args, struct ValueType *), CStdOut);
|
||||
break;
|
||||
#ifndef NO_FP
|
||||
case 'f':
|
||||
PrintFP(va_arg(Args, double), CStdOut);
|
||||
break;
|
||||
#endif
|
||||
case '%':
|
||||
PrintCh('%', CStdOut);
|
||||
break;
|
||||
|
@ -1,6 +1,13 @@
|
||||
/* all platform-specific includes and defines go in this file */
|
||||
#ifndef PLATFORM_H
|
||||
#define PLATFORM_H
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
#ifndef __ECI_PLATFORM_H__
|
||||
#define __ECI_PLATFORM_H__
|
||||
|
||||
#define LARGE_INT_POWER_OF_TEN 1000000000 /* the largest power of ten which fits in an int on this architecture */
|
||||
#define ALIGN_TYPE void * /* the default data type to use for alignment */
|
||||
@ -13,8 +20,7 @@
|
||||
#define LOCAL_TABLE_SIZE 11 /* size of local variable table (can expand) */
|
||||
#define STRUCT_TABLE_SIZE 11 /* size of struct/union member table (can expand) */
|
||||
|
||||
#define INTERACTIVE_PROMPT_START "starting picoc " PICOC_VERSION "\n"
|
||||
#define INTERACTIVE_PROMPT_STATEMENT "picoc> "
|
||||
#define INTERACTIVE_PROMPT_STATEMENT "eci> "
|
||||
#define INTERACTIVE_PROMPT_LINE " > "
|
||||
|
||||
/* host platform includes */
|
||||
@ -28,16 +34,9 @@
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <setjmp.h>
|
||||
#ifndef NO_FP
|
||||
# include <math.h>
|
||||
# define PICOC_MATH_LIBRARY
|
||||
/*# define USE_READLINE*/
|
||||
# undef BIG_ENDIAN
|
||||
# if defined(__powerpc__) || defined(__hppa__) || defined(__sparc__)
|
||||
# define BIG_ENDIAN
|
||||
# endif
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
extern jmp_buf ExitBuf;
|
||||
|
||||
#endif /* PLATFORM_H */
|
||||
|
||||
#endif
|
||||
|
@ -1,3 +1,11 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
#include "../interpreter.h"
|
||||
|
||||
void UnixSetupFunc() {
|
||||
|
@ -1,11 +1,14 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
#include "../picoc.h"
|
||||
#include "../interpreter.h"
|
||||
|
||||
#ifdef USE_READLINE
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#endif
|
||||
|
||||
/* mark where to end the program for platforms which require this */
|
||||
jmp_buf PicocExitBuf;
|
||||
|
||||
@ -15,23 +18,6 @@ void PlatformCleanup() {
|
||||
|
||||
/* get a line of interactive input */
|
||||
char *PlatformGetLine(char *Buf, int MaxLen, const char *Prompt) {
|
||||
#ifdef USE_READLINE
|
||||
if (Prompt != NULL) {
|
||||
/* use GNU readline to read the line */
|
||||
char *InLine = readline(Prompt);
|
||||
if (InLine == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
Buf[MaxLen] = '\0';
|
||||
strncpy(Buf, InLine, MaxLen-1);
|
||||
strncat(Buf, "\n", MaxLen-1);
|
||||
if (InLine[0] != '\0') {
|
||||
add_history(InLine);
|
||||
}
|
||||
free(InLine);
|
||||
return Buf;
|
||||
}
|
||||
#endif
|
||||
if (Prompt != NULL) {
|
||||
printf("%s", Prompt);
|
||||
}
|
||||
|
@ -1,3 +1,11 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
#include "interpreter.h"
|
||||
|
||||
struct Table StringTable;
|
||||
|
18
eci/type.c
18
eci/type.c
@ -1,3 +1,11 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
#include "interpreter.h"
|
||||
|
||||
/* some basic types */
|
||||
@ -9,9 +17,7 @@ struct ValueType LongType;
|
||||
struct ValueType UnsignedIntType;
|
||||
struct ValueType UnsignedShortType;
|
||||
struct ValueType UnsignedLongType;
|
||||
#ifndef NO_FP
|
||||
struct ValueType FPType;
|
||||
#endif
|
||||
struct ValueType VoidType;
|
||||
struct ValueType TypeType;
|
||||
struct ValueType FunctionType;
|
||||
@ -148,12 +154,10 @@ void TypeInit() {
|
||||
char x;
|
||||
long y;
|
||||
} la;
|
||||
#ifndef NO_FP
|
||||
struct DoubleAlign {
|
||||
char x;
|
||||
double y;
|
||||
} da;
|
||||
#endif
|
||||
struct PointerAlign {
|
||||
char x;
|
||||
void *y;
|
||||
@ -174,12 +178,8 @@ void TypeInit() {
|
||||
TypeAddBaseType(&FunctionType, TypeFunction, sizeof(int), IntAlignBytes);
|
||||
TypeAddBaseType(&MacroType, TypeMacro, sizeof(int), IntAlignBytes);
|
||||
TypeAddBaseType(&GotoLabelType, TypeGotoLabel, 0, 1);
|
||||
#ifndef NO_FP
|
||||
TypeAddBaseType(&FPType, TypeFP, sizeof(double), (char *)&da.y - &da.x);
|
||||
TypeAddBaseType(&TypeType, Type_Type, sizeof(double), (char *)&da.y - &da.x); /* must be large enough to cast to a double */
|
||||
#else
|
||||
TypeAddBaseType(&TypeType, Type_Type, sizeof(struct ValueType *), PointerAlignBytes);
|
||||
#endif
|
||||
CharArrayType = TypeAdd(NULL, &CharType, TypeArray, 0, StrEmpty, sizeof(char), (char *)&ca.y - &ca.x);
|
||||
CharPtrType = TypeAdd(NULL, &CharType, TypePointer, 0, StrEmpty, sizeof(void *), PointerAlignBytes);
|
||||
CharPtrPtrType = TypeAdd(NULL, CharPtrType, TypePointer, 0, StrEmpty, sizeof(void *), PointerAlignBytes);
|
||||
@ -404,12 +404,10 @@ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ, int *IsSta
|
||||
case TokenLongType:
|
||||
*Typ = Unsigned ? &UnsignedLongType : &LongType;
|
||||
break;
|
||||
#ifndef NO_FP
|
||||
case TokenFloatType:
|
||||
case TokenDoubleType:
|
||||
*Typ = &FPType;
|
||||
break;
|
||||
#endif
|
||||
case TokenVoidType:
|
||||
*Typ = &VoidType;
|
||||
break;
|
||||
|
@ -1,3 +1,11 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license APACHE-2 (see license file)
|
||||
*/
|
||||
|
||||
#include "interpreter.h"
|
||||
|
||||
/* maximum size of a value to temporarily copy while we create a variable */
|
||||
|
Loading…
Reference in New Issue
Block a user