[DEV] some other rework unneeded elements
This commit is contained in:
parent
3f5c4725f9
commit
177d1ba8c0
628
eci/clibrary.c
628
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 "picoc.h"
|
||||||
#include "interpreter.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 */
|
/* print a type to a stream without using printf/sprintf */
|
||||||
void PrintType(struct ValueType *Typ, IOFILE *Stream) {
|
void PrintType(struct ValueType *Typ, IOFILE *Stream) {
|
||||||
switch (Typ->Base) {
|
switch (Typ->Base) {
|
||||||
case TypeVoid: PrintStr("void", Stream); break;
|
case TypeVoid:
|
||||||
case TypeInt: PrintStr("int", Stream); break;
|
PrintStr("void", Stream);
|
||||||
case TypeShort: PrintStr("short", Stream); break;
|
break;
|
||||||
case TypeChar: PrintStr("char", Stream); break;
|
case TypeInt:
|
||||||
case TypeLong: PrintStr("long", Stream); break;
|
PrintStr("int", Stream);
|
||||||
case TypeUnsignedInt: PrintStr("unsigned int", Stream); break;
|
break;
|
||||||
case TypeUnsignedShort: PrintStr("unsigned short", Stream); break;
|
case TypeShort:
|
||||||
case TypeUnsignedLong: PrintStr("unsigned long", Stream); break;
|
PrintStr("short", Stream);
|
||||||
#ifndef NO_FP
|
break;
|
||||||
case TypeFP: PrintStr("double", Stream); break;
|
case TypeChar:
|
||||||
#endif
|
PrintStr("char", Stream);
|
||||||
case TypeFunction: PrintStr("function", Stream); break;
|
break;
|
||||||
case TypeMacro: PrintStr("macro", Stream); break;
|
case TypeLong:
|
||||||
case TypePointer: if (Typ->FromType) PrintType(Typ->FromType, Stream); PrintCh('*', Stream); break;
|
PrintStr("long", Stream);
|
||||||
case TypeArray: PrintType(Typ->FromType, Stream); PrintCh('[', Stream); if (Typ->ArraySize != 0) PrintSimpleInt(Typ->ArraySize, Stream); PrintCh(']', Stream); break;
|
break;
|
||||||
case TypeStruct: PrintStr("struct ", Stream); PrintStr(Typ->Identifier, Stream); break;
|
case TypeUnsignedInt:
|
||||||
case TypeUnion: PrintStr("union ", Stream); PrintStr(Typ->Identifier, Stream); break;
|
PrintStr("unsigned int", Stream);
|
||||||
case TypeEnum: PrintStr("enum ", Stream); PrintStr(Typ->Identifier, Stream); break;
|
break;
|
||||||
case TypeGotoLabel: PrintStr("goto label ", Stream); break;
|
case TypeUnsignedShort:
|
||||||
case Type_Type: PrintStr("type ", Stream); break;
|
PrintStr("unsigned short", Stream);
|
||||||
}
|
break;
|
||||||
}
|
case TypeUnsignedLong:
|
||||||
|
PrintStr("unsigned long", Stream);
|
||||||
|
break;
|
||||||
#ifdef BUILTIN_MINI_STDLIB
|
case TypeFP:
|
||||||
|
PrintStr("double", Stream);
|
||||||
/*
|
break;
|
||||||
* This is a simplified standard library for small embedded systems. It doesn't require
|
case TypeFunction:
|
||||||
* a system stdio library to operate.
|
PrintStr("function", Stream);
|
||||||
*
|
break;
|
||||||
* A more complete standard library for larger computers is in the library_XXX.c files.
|
case TypeMacro:
|
||||||
*/
|
PrintStr("macro", Stream);
|
||||||
IOFILE *CStdOut;
|
break;
|
||||||
IOFILE CStdOutBase;
|
case TypePointer:
|
||||||
|
if (Typ->FromType) {
|
||||||
static int TRUEValue = 1;
|
PrintType(Typ->FromType, Stream);
|
||||||
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++;
|
|
||||||
}
|
}
|
||||||
|
PrintCh('*', Stream);
|
||||||
if (*FPos == '0') {
|
break;
|
||||||
/* a leading zero means zero pad a decimal number */
|
case TypeArray:
|
||||||
ZeroPad = TRUE;
|
PrintType(Typ->FromType, Stream);
|
||||||
FPos++;
|
PrintCh('[', Stream);
|
||||||
|
if (Typ->ArraySize != 0) {
|
||||||
|
PrintSimpleInt(Typ->ArraySize, Stream);
|
||||||
}
|
}
|
||||||
|
PrintCh(']', Stream);
|
||||||
/* get any field width in the format */
|
break;
|
||||||
while (isdigit((int)*FPos)) {
|
case TypeStruct:
|
||||||
FieldWidth = FieldWidth * 10 + (*FPos++ - '0');
|
PrintStr("struct ", Stream);
|
||||||
}
|
PrintStr(Typ->Identifier, Stream);
|
||||||
/* now check the format type */
|
break;
|
||||||
switch (*FPos) {
|
case TypeUnion:
|
||||||
case 's': FormatType = CharPtrType; break;
|
PrintStr("union ", Stream);
|
||||||
case 'd': case 'u': case 'x': case 'b': case 'c': FormatType = &IntType; break;
|
PrintStr(Typ->Identifier, Stream);
|
||||||
#ifndef NO_FP
|
break;
|
||||||
case 'f': FormatType = &FPType; break;
|
case TypeEnum:
|
||||||
#endif
|
PrintStr("enum ", Stream);
|
||||||
case '%': PrintCh('%', Stream); FormatType = NULL; break;
|
PrintStr(Typ->Identifier, Stream);
|
||||||
case '\0': FPos--; FormatType = NULL; break;
|
break;
|
||||||
default: PrintCh(*FPos, Stream); FormatType = NULL; break;
|
case TypeGotoLabel:
|
||||||
}
|
PrintStr("goto label ", Stream);
|
||||||
|
break;
|
||||||
if (FormatType != NULL) {
|
case Type_Type:
|
||||||
/* we have to format something */
|
PrintStr("type ", Stream);
|
||||||
if (ArgCount >= NumArgs) {
|
break;
|
||||||
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);
|
|
||||||
}
|
|
||||||
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 */
|
/* string.h library for large systems - small embedded systems use clibrary.c instead */
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "../interpreter.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 */
|
/* string.h library for large systems - small embedded systems use clibrary.c instead */
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "../interpreter.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 */
|
/* stdio.h library for large systems - small embedded systems use clibrary.c instead */
|
||||||
#include "../interpreter.h"
|
#include "../interpreter.h"
|
||||||
|
|
||||||
#ifndef BUILTIN_MINI_STDLIB
|
#ifndef BUILTIN_MINI_STDLIB
|
||||||
#ifndef NO_FP
|
|
||||||
|
|
||||||
static double M_EValue = 2.7182818284590452354; /* e */
|
static double M_EValue = 2.7182818284590452354; /* e */
|
||||||
static double M_LOG2EValue = 1.4426950408889634074; /* log_2 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);
|
VariableDefinePlatformVar(NULL, "M_SQRT1_2", &FPType, (union AnyValue *)&M_SQRT1_2Value, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !NO_FP */
|
|
||||||
#endif /* !BUILTIN_MINI_STDLIB */
|
#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 */
|
/* string.h library for large systems - small embedded systems use clibrary.c instead */
|
||||||
#include "../interpreter.h"
|
#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 */
|
/* stdio.h library for large systems - small embedded systems use clibrary.c instead */
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "../interpreter.h"
|
#include "../interpreter.h"
|
||||||
@ -174,7 +182,6 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, int S
|
|||||||
ShowType = &IntType;
|
ShowType = &IntType;
|
||||||
break;
|
break;
|
||||||
/* integer base conversions */
|
/* integer base conversions */
|
||||||
#ifndef NO_FP
|
|
||||||
case 'e':
|
case 'e':
|
||||||
case 'E':
|
case 'E':
|
||||||
ShowType = &FPType;
|
ShowType = &FPType;
|
||||||
@ -190,7 +197,6 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, int S
|
|||||||
ShowType = &FPType;
|
ShowType = &FPType;
|
||||||
break;
|
break;
|
||||||
/* double, flexible format */
|
/* double, flexible format */
|
||||||
#endif
|
|
||||||
case 'a':
|
case 'a':
|
||||||
case 'A':
|
case 'A':
|
||||||
ShowType = &IntType;
|
ShowType = &IntType;
|
||||||
@ -268,18 +274,14 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, int S
|
|||||||
} else {
|
} else {
|
||||||
StdioOutPuts("XXX", &SOStream);
|
StdioOutPuts("XXX", &SOStream);
|
||||||
}
|
}
|
||||||
}
|
} else if (ShowType == &FPType) {
|
||||||
#ifndef NO_FP
|
|
||||||
else if (ShowType == &FPType) {
|
|
||||||
/* show a floating point number */
|
/* show a floating point number */
|
||||||
if (IS_NUMERIC_COERCIBLE(ThisArg)) {
|
if (IS_NUMERIC_COERCIBLE(ThisArg)) {
|
||||||
StdioFprintfFP(&SOStream, OneFormatBuf, ExpressionCoerceFP(ThisArg));
|
StdioFprintfFP(&SOStream, OneFormatBuf, ExpressionCoerceFP(ThisArg));
|
||||||
} else {
|
} else {
|
||||||
StdioOutPuts("XXX", &SOStream);
|
StdioOutPuts("XXX", &SOStream);
|
||||||
}
|
}
|
||||||
}
|
} else if (ShowType == CharPtrType) {
|
||||||
#endif
|
|
||||||
else if (ShowType == CharPtrType) {
|
|
||||||
if (ThisArg->Typ->Base == TypePointer) {
|
if (ThisArg->Typ->Base == TypePointer) {
|
||||||
StdioFprintfPointer(&SOStream, OneFormatBuf, ThisArg->Val->Pointer);
|
StdioFprintfPointer(&SOStream, OneFormatBuf, ThisArg->Val->Pointer);
|
||||||
} else if ( ThisArg->Typ->Base == TypeArray
|
} 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 */
|
/* stdlib.h library for large systems - small embedded systems use clibrary.c instead */
|
||||||
#include "../interpreter.h"
|
#include "../interpreter.h"
|
||||||
|
|
||||||
@ -5,11 +13,9 @@
|
|||||||
|
|
||||||
static int ZeroValue = 0;
|
static int ZeroValue = 0;
|
||||||
|
|
||||||
#ifndef NO_FP
|
|
||||||
void StdlibAtof(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
void StdlibAtof(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||||
ReturnValue->Val->FP = atof(Param[0]->Val->Pointer);
|
ReturnValue->Val->FP = atof(Param[0]->Val->Pointer);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void StdlibAtoi(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
void StdlibAtoi(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||||
ReturnValue->Val->Integer = atoi(Param[0]->Val->Pointer);
|
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);
|
ReturnValue->Val->Integer = atol(Param[0]->Val->Pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_FP
|
|
||||||
void StdlibStrtod(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
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);
|
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) {
|
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);
|
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 */
|
/* all stdlib.h functions */
|
||||||
struct LibraryFunction StdlibFunctions[] =
|
struct LibraryFunction StdlibFunctions[] =
|
||||||
{
|
{
|
||||||
#ifndef NO_FP
|
|
||||||
{ StdlibAtof, "float atof(char *);" },
|
{ StdlibAtof, "float atof(char *);" },
|
||||||
{ StdlibStrtod, "float strtod(char *,char **);" },
|
{ StdlibStrtod, "float strtod(char *,char **);" },
|
||||||
#endif
|
|
||||||
{ StdlibAtoi, "int atoi(char *);" },
|
{ StdlibAtoi, "int atoi(char *);" },
|
||||||
{ StdlibAtol, "int atol(char *);" },
|
{ StdlibAtol, "int atol(char *);" },
|
||||||
{ StdlibStrtol, "int strtol(char *,char **,int);" },
|
{ 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 */
|
/* string.h library for large systems - small embedded systems use clibrary.c instead */
|
||||||
#include "../interpreter.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 */
|
/* string.h library for large systems - small embedded systems use clibrary.c instead */
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "../interpreter.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);
|
ReturnValue->Val->Pointer = ctime(Param[0]->Val->Pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_FP
|
|
||||||
void StdDifftime(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
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);
|
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) {
|
void StdGmtime(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) {
|
||||||
ReturnValue->Val->Pointer = gmtime(Param[0]->Val->Pointer);
|
ReturnValue->Val->Pointer = gmtime(Param[0]->Val->Pointer);
|
||||||
@ -76,9 +82,7 @@ struct LibraryFunction StdTimeFunctions[] = {
|
|||||||
{ StdAsctime, "char *asctime(struct tm *);" },
|
{ StdAsctime, "char *asctime(struct tm *);" },
|
||||||
{ StdClock, "time_t clock();" },
|
{ StdClock, "time_t clock();" },
|
||||||
{ StdCtime, "char *ctime(int *);" },
|
{ StdCtime, "char *ctime(int *);" },
|
||||||
#ifndef NO_FP
|
|
||||||
{ StdDifftime, "double difftime(int, int);" },
|
{ StdDifftime, "double difftime(int, int);" },
|
||||||
#endif
|
|
||||||
{ StdGmtime, "struct tm *gmtime(int *);" },
|
{ StdGmtime, "struct tm *gmtime(int *);" },
|
||||||
{ StdGmtime_r, "struct tm *gmtime_r(int *, struct tm *);" },
|
{ StdGmtime_r, "struct tm *gmtime_r(int *, struct tm *);" },
|
||||||
{ StdLocaltime, "struct tm *localtime(int *);" },
|
{ 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 */
|
/* stdlib.h library for large systems - small embedded systems use clibrary.c instead */
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.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"
|
#include "interpreter.h"
|
||||||
|
|
||||||
|
|
||||||
@ -168,10 +176,8 @@ long ExpressionCoerceInteger(struct Value *Val) {
|
|||||||
return (long)Val->Val->UnsignedLongInteger;
|
return (long)Val->Val->UnsignedLongInteger;
|
||||||
case TypePointer:
|
case TypePointer:
|
||||||
return (long)Val->Val->Pointer;
|
return (long)Val->Val->Pointer;
|
||||||
#ifndef NO_FP
|
|
||||||
case TypeFP:
|
case TypeFP:
|
||||||
return (long)Val->Val->FP;
|
return (long)Val->Val->FP;
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -195,16 +201,13 @@ unsigned long ExpressionCoerceUnsignedInteger(struct Value *Val) {
|
|||||||
return (unsigned long)Val->Val->UnsignedLongInteger;
|
return (unsigned long)Val->Val->UnsignedLongInteger;
|
||||||
case TypePointer:
|
case TypePointer:
|
||||||
return (unsigned long)Val->Val->Pointer;
|
return (unsigned long)Val->Val->Pointer;
|
||||||
#ifndef NO_FP
|
|
||||||
case TypeFP:
|
case TypeFP:
|
||||||
return (unsigned long)Val->Val->FP;
|
return (unsigned long)Val->Val->FP;
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_FP
|
|
||||||
double ExpressionCoerceFP(struct Value *Val) {
|
double ExpressionCoerceFP(struct Value *Val) {
|
||||||
#ifndef BROKEN_FLOAT_CASTS
|
#ifndef BROKEN_FLOAT_CASTS
|
||||||
int IntVal;
|
int IntVal;
|
||||||
@ -259,7 +262,6 @@ double ExpressionCoerceFP(struct Value *Val) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* assign an integer value */
|
/* assign an integer value */
|
||||||
long ExpressionAssignInt(struct ParseState *_parser, struct Value *DestValue, long FromInt, int After) {
|
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;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_FP
|
|
||||||
/* assign a floating point value */
|
/* assign a floating point value */
|
||||||
double ExpressionAssignFP(struct ParseState *_parser, struct Value *DestValue, double FromFP) {
|
double ExpressionAssignFP(struct ParseState *_parser, struct Value *DestValue, double FromFP) {
|
||||||
if (!DestValue->IsLValue) {
|
if (!DestValue->IsLValue) {
|
||||||
@ -309,7 +310,6 @@ double ExpressionAssignFP(struct ParseState *_parser, struct Value *DestValue, d
|
|||||||
DestValue->Val->FP = FromFP;
|
DestValue->Val->FP = FromFP;
|
||||||
return FromFP;
|
return FromFP;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* push a node on to the expression stack */
|
/* push a node on to the expression stack */
|
||||||
void ExpressionStackPushValueNode(struct ParseState *_parser, struct ExpressionStack **StackTop, struct Value *ValueLoc) {
|
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);
|
ExpressionStackPushValueNode(_parser, StackTop, ValueLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_FP
|
|
||||||
void ExpressionPushFP(struct ParseState *_parser, struct ExpressionStack **StackTop, double FPValue) {
|
void ExpressionPushFP(struct ParseState *_parser, struct ExpressionStack **StackTop, double FPValue) {
|
||||||
struct Value *ValueLoc = VariableAllocValueFromType(_parser, &FPType, FALSE, NULL, FALSE);
|
struct Value *ValueLoc = VariableAllocValueFromType(_parser, &FPType, FALSE, NULL, FALSE);
|
||||||
ValueLoc->Val->FP = FPValue;
|
ValueLoc->Val->FP = FPValue;
|
||||||
ExpressionStackPushValueNode(_parser, StackTop, ValueLoc);
|
ExpressionStackPushValueNode(_parser, StackTop, ValueLoc);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* assign to a pointer */
|
/* assign to a pointer */
|
||||||
void ExpressionAssignToPointer(struct ParseState *_parser, struct Value *ToValue, struct Value *FromValue, const char *FuncName, int ParamNo, int AllowPointerCoercion) {
|
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:
|
case TypeUnsignedLong:
|
||||||
DestValue->Val->UnsignedLongInteger = ExpressionCoerceUnsignedInteger(SourceValue);
|
DestValue->Val->UnsignedLongInteger = ExpressionCoerceUnsignedInteger(SourceValue);
|
||||||
break;
|
break;
|
||||||
#ifndef NO_FP
|
|
||||||
case TypeFP:
|
case TypeFP:
|
||||||
if (!IS_NUMERIC_COERCIBLE_PLUS_POINTERS(SourceValue, AllowPointerCoercion)) {
|
if (!IS_NUMERIC_COERCIBLE_PLUS_POINTERS(SourceValue, AllowPointerCoercion)) {
|
||||||
AssignFail(_parser, "%t from %t", DestValue->Typ, SourceValue->Typ, 0, 0, FuncName, ParamNo);
|
AssignFail(_parser, "%t from %t", DestValue->Typ, SourceValue->Typ, 0, 0, FuncName, ParamNo);
|
||||||
}
|
}
|
||||||
DestValue->Val->FP = ExpressionCoerceFP(SourceValue);
|
DestValue->Val->FP = ExpressionCoerceFP(SourceValue);
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
case TypePointer:
|
case TypePointer:
|
||||||
ExpressionAssignToPointer(_parser, DestValue, SourceValue, FuncName, ParamNo, AllowPointerCoercion);
|
ExpressionAssignToPointer(_parser, DestValue, SourceValue, FuncName, ParamNo, AllowPointerCoercion);
|
||||||
break;
|
break;
|
||||||
@ -527,7 +523,6 @@ void ExpressionPrefixOperator(struct ParseState *_parser, struct ExpressionStack
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* an arithmetic operator */
|
/* an arithmetic operator */
|
||||||
#ifndef NO_FP
|
|
||||||
if (TopValue->Typ == &FPType) {
|
if (TopValue->Typ == &FPType) {
|
||||||
/* floating point prefix arithmetic */
|
/* floating point prefix arithmetic */
|
||||||
double ResultFP = 0.0;
|
double ResultFP = 0.0;
|
||||||
@ -543,9 +538,7 @@ void ExpressionPrefixOperator(struct ParseState *_parser, struct ExpressionStack
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ExpressionPushFP(_parser, StackTop, ResultFP);
|
ExpressionPushFP(_parser, StackTop, ResultFP);
|
||||||
} else
|
} else if (IS_NUMERIC_COERCIBLE(TopValue)) {
|
||||||
#endif
|
|
||||||
if (IS_NUMERIC_COERCIBLE(TopValue)) {
|
|
||||||
/* integer prefix arithmetic */
|
/* integer prefix arithmetic */
|
||||||
long ResultInt = 0;
|
long ResultInt = 0;
|
||||||
long TopInt = ExpressionCoerceInteger(TopValue);
|
long TopInt = ExpressionCoerceInteger(TopValue);
|
||||||
@ -694,11 +687,9 @@ void ExpressionInfixOperator(struct ParseState *_parser, struct ExpressionStack
|
|||||||
ExpressionQuestionMarkOperator(_parser, StackTop, TopValue, BottomValue);
|
ExpressionQuestionMarkOperator(_parser, StackTop, TopValue, BottomValue);
|
||||||
} else if (Op == TokenColon) {
|
} else if (Op == TokenColon) {
|
||||||
ExpressionColonOperator(_parser, StackTop, TopValue, BottomValue);
|
ExpressionColonOperator(_parser, StackTop, TopValue, BottomValue);
|
||||||
}
|
} else if ( (TopValue->Typ == &FPType && BottomValue->Typ == &FPType)
|
||||||
#ifndef NO_FP
|
|| (TopValue->Typ == &FPType && IS_NUMERIC_COERCIBLE(BottomValue))
|
||||||
else if ( (TopValue->Typ == &FPType && BottomValue->Typ == &FPType)
|
|| (IS_NUMERIC_COERCIBLE(TopValue) && BottomValue->Typ == &FPType) ) {
|
||||||
|| (TopValue->Typ == &FPType && IS_NUMERIC_COERCIBLE(BottomValue))
|
|
||||||
|| (IS_NUMERIC_COERCIBLE(TopValue) && BottomValue->Typ == &FPType) ) {
|
|
||||||
/* floating point infix arithmetic */
|
/* floating point infix arithmetic */
|
||||||
int ResultIsInt = FALSE;
|
int ResultIsInt = FALSE;
|
||||||
double ResultFP = 0.0;
|
double ResultFP = 0.0;
|
||||||
@ -765,9 +756,7 @@ void ExpressionInfixOperator(struct ParseState *_parser, struct ExpressionStack
|
|||||||
} else {
|
} else {
|
||||||
ExpressionPushFP(_parser, StackTop, ResultFP);
|
ExpressionPushFP(_parser, StackTop, ResultFP);
|
||||||
}
|
}
|
||||||
}
|
} else if (IS_NUMERIC_COERCIBLE(TopValue) && IS_NUMERIC_COERCIBLE(BottomValue)) {
|
||||||
#endif
|
|
||||||
else if (IS_NUMERIC_COERCIBLE(TopValue) && IS_NUMERIC_COERCIBLE(BottomValue)) {
|
|
||||||
/* integer operation */
|
/* integer operation */
|
||||||
long TopInt = ExpressionCoerceInteger(TopValue);
|
long TopInt = ExpressionCoerceInteger(TopValue);
|
||||||
long BottomInt = ExpressionCoerceInteger(BottomValue);
|
long BottomInt = ExpressionCoerceInteger(BottomValue);
|
||||||
@ -1348,11 +1337,7 @@ void ExpressionParseMacroCall(struct ParseState *_parser, struct ExpressionStack
|
|||||||
enum LexToken Token;
|
enum LexToken Token;
|
||||||
if (_parser->Mode == RunModeRun) {
|
if (_parser->Mode == RunModeRun) {
|
||||||
/* create a stack frame for this macro */
|
/* create a stack frame for this macro */
|
||||||
#ifndef NO_FP
|
|
||||||
ExpressionStackPushValueByType(_parser, StackTop, &FPType); /* largest return type there is */
|
ExpressionStackPushValueByType(_parser, StackTop, &FPType); /* largest return type there is */
|
||||||
#else
|
|
||||||
ExpressionStackPushValueByType(_parser, StackTop, &IntType); /* largest return type there is */
|
|
||||||
#endif
|
|
||||||
ReturnValue = (*StackTop)->Val;
|
ReturnValue = (*StackTop)->Val;
|
||||||
HeapPushStackFrame();
|
HeapPushStackFrame();
|
||||||
ParamArray = HeapAllocStack(sizeof(struct Value *) * MDef->NumParams);
|
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 */
|
/* stack grows up from the bottom and heap grows down from the top of heap space */
|
||||||
#include "interpreter.h"
|
#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 "picoc.h"
|
||||||
#include "interpreter.h"
|
#include "interpreter.h"
|
||||||
|
|
||||||
@ -19,9 +27,7 @@ void IncludeInit() {
|
|||||||
#ifndef BUILTIN_MINI_STDLIB
|
#ifndef BUILTIN_MINI_STDLIB
|
||||||
IncludeRegister("ctype.h", NULL, &StdCtypeFunctions[0], NULL);
|
IncludeRegister("ctype.h", NULL, &StdCtypeFunctions[0], NULL);
|
||||||
IncludeRegister("errno.h", &StdErrnoSetupFunc, NULL, NULL);
|
IncludeRegister("errno.h", &StdErrnoSetupFunc, NULL, NULL);
|
||||||
#ifndef NO_FP
|
|
||||||
IncludeRegister("math.h", &MathSetupFunc, &MathFunctions[0], NULL);
|
IncludeRegister("math.h", &MathSetupFunc, &MathFunctions[0], NULL);
|
||||||
#endif
|
|
||||||
IncludeRegister("stdbool.h", &StdboolSetupFunc, NULL, StdboolDefs);
|
IncludeRegister("stdbool.h", &StdboolSetupFunc, NULL, StdboolDefs);
|
||||||
IncludeRegister("stdio.h", &StdioSetupFunc, &StdioFunctions[0], StdioDefs);
|
IncludeRegister("stdio.h", &StdioSetupFunc, &StdioFunctions[0], StdioDefs);
|
||||||
IncludeRegister("stdlib.h", &StdlibSetupFunc, &StdlibFunctions[0], NULL);
|
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"
|
#include "platform.h"
|
||||||
|
|
||||||
@ -30,13 +38,8 @@ typedef FILE IOFILE;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* coercion of numeric types to other numeric types */
|
/* coercion of numeric types to other numeric types */
|
||||||
#ifndef NO_FP
|
|
||||||
#define IS_FP(v) ((v)->Typ->Base == TypeFP)
|
#define IS_FP(v) ((v)->Typ->Base == TypeFP)
|
||||||
#define FP_VAL(v) ((v)->Val->FP)
|
#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 IS_POINTER_COERCIBLE(v, ap) ((ap) ? ((v)->Typ->Base == TypePointer) : 0)
|
||||||
#define POINTER_COERCE(v) ((int)(v)->Val->Pointer)
|
#define POINTER_COERCE(v) ((int)(v)->Val->Pointer)
|
||||||
@ -122,9 +125,7 @@ enum BaseType {
|
|||||||
TypeUnsignedInt, //!< unsigned integer
|
TypeUnsignedInt, //!< unsigned integer
|
||||||
TypeUnsignedShort, //!< unsigned short integer
|
TypeUnsignedShort, //!< unsigned short integer
|
||||||
TypeUnsignedLong, //!< unsigned long integer
|
TypeUnsignedLong, //!< unsigned long integer
|
||||||
#ifndef NO_FP
|
|
||||||
TypeFP, //!< floating point
|
TypeFP, //!< floating point
|
||||||
#endif
|
|
||||||
TypeFunction, //!< a function
|
TypeFunction, //!< a function
|
||||||
TypeMacro, //!< a macro
|
TypeMacro, //!< a macro
|
||||||
TypePointer, //!< a pointer
|
TypePointer, //!< a pointer
|
||||||
@ -183,9 +184,7 @@ union AnyValue {
|
|||||||
struct ValueType *Typ;
|
struct ValueType *Typ;
|
||||||
struct FuncDef FuncDef;
|
struct FuncDef FuncDef;
|
||||||
struct MacroDef MacroDef;
|
struct MacroDef MacroDef;
|
||||||
#ifndef NO_FP
|
|
||||||
double FP;
|
double FP;
|
||||||
#endif
|
|
||||||
void *Pointer; //!< unsafe native pointers
|
void *Pointer; //!< unsafe native pointers
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -289,9 +288,7 @@ extern struct StackFrame *TopStackFrame;
|
|||||||
extern struct ValueType UberType;
|
extern struct ValueType UberType;
|
||||||
extern struct ValueType IntType;
|
extern struct ValueType IntType;
|
||||||
extern struct ValueType CharType;
|
extern struct ValueType CharType;
|
||||||
#ifndef NO_FP
|
|
||||||
extern struct ValueType FPType;
|
extern struct ValueType FPType;
|
||||||
#endif
|
|
||||||
extern struct ValueType VoidType;
|
extern struct ValueType VoidType;
|
||||||
extern struct ValueType TypeType;
|
extern struct ValueType TypeType;
|
||||||
extern struct ValueType FunctionType;
|
extern struct ValueType FunctionType;
|
||||||
@ -307,111 +304,31 @@ extern struct LibraryFunction CLibrary[];
|
|||||||
extern struct LibraryFunction PlatformLibrary[];
|
extern struct LibraryFunction PlatformLibrary[];
|
||||||
extern IOFILE *CStdOut;
|
extern IOFILE *CStdOut;
|
||||||
|
|
||||||
/* table.c */
|
#include <eci/lex.h>
|
||||||
void TableInit();
|
#include <eci/parse.h>
|
||||||
char *TableStrRegister(const char *_str);
|
#include <eci/expression.h>
|
||||||
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();
|
|
||||||
|
|
||||||
/* lex.c */
|
#include <eci/heap.h>
|
||||||
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();
|
|
||||||
|
|
||||||
/* parse.c */
|
#include <eci/table.h>
|
||||||
/* the following are defined in picoc.h:
|
#include <eci/type.h>
|
||||||
* void PicocParse(const char *FileName, const char *Source, int SourceLen, int RunIt, int CleanupNow, int CleanupSource);
|
#include <eci/variable.h>
|
||||||
* void PicocParseInteractive(); */
|
#include <eci/include.h>
|
||||||
enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemicolon);
|
#include <eci/clibrary.h>
|
||||||
struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, char *Identifier);
|
#include <eci/platform.h>
|
||||||
void ParseCleanup();
|
#include <eci/cstdlib/ctype.h>
|
||||||
void ParserCopyPos(struct ParseState *To, struct ParseState *From);
|
#include <eci/cstdlib/errno.h>
|
||||||
void ParserCopy(struct ParseState *To, struct ParseState *From);
|
#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 */
|
// TODO : Move this ... platform.h:
|
||||||
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);
|
|
||||||
|
|
||||||
/* 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:
|
/* the following are defined in picoc.h:
|
||||||
* void PicocCallMain(int argc, char **argv);
|
* void PicocCallMain(int argc, char **argv);
|
||||||
* int PicocPlatformSetExitPoint();
|
* int PicocPlatformSetExitPoint();
|
||||||
@ -433,49 +350,5 @@ void PlatformExit(int ExitVal);
|
|||||||
char *PlatformMakeTempName(char *TempNameBuffer);
|
char *PlatformMakeTempName(char *TempNameBuffer);
|
||||||
void PlatformLibraryInit();
|
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 */
|
#endif
|
||||||
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 */
|
|
||||||
|
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"
|
#include "interpreter.h"
|
||||||
|
|
||||||
#ifdef NO_CTYPE
|
#ifdef NO_CTYPE
|
||||||
@ -50,15 +58,11 @@ static struct ReservedWord ReservedWords[] = {
|
|||||||
{ "default", TokenDefault, NULL },
|
{ "default", TokenDefault, NULL },
|
||||||
{ "delete", TokenDelete, NULL },
|
{ "delete", TokenDelete, NULL },
|
||||||
{ "do", TokenDo, NULL },
|
{ "do", TokenDo, NULL },
|
||||||
#ifndef NO_FP
|
|
||||||
{ "double", TokenDoubleType, NULL },
|
{ "double", TokenDoubleType, NULL },
|
||||||
#endif
|
|
||||||
{ "else", TokenElse, NULL },
|
{ "else", TokenElse, NULL },
|
||||||
{ "enum", TokenEnumType, NULL },
|
{ "enum", TokenEnumType, NULL },
|
||||||
{ "extern", TokenExternType, NULL },
|
{ "extern", TokenExternType, NULL },
|
||||||
#ifndef NO_FP
|
|
||||||
{ "float", TokenFloatType, NULL },
|
{ "float", TokenFloatType, NULL },
|
||||||
#endif
|
|
||||||
{ "for", TokenFor, NULL },
|
{ "for", TokenFor, NULL },
|
||||||
{ "goto", TokenGoto, NULL },
|
{ "goto", TokenGoto, NULL },
|
||||||
{ "if", TokenIf, NULL },
|
{ "if", TokenIf, NULL },
|
||||||
@ -122,10 +126,8 @@ enum LexToken LexGetNumber(struct LexState *Lexer, struct Value *Value) {
|
|||||||
int Result = 0;
|
int Result = 0;
|
||||||
int Base = 10;
|
int Base = 10;
|
||||||
enum LexToken ResultToken;
|
enum LexToken ResultToken;
|
||||||
#ifndef NO_FP
|
|
||||||
double FPResult;
|
double FPResult;
|
||||||
double FPDiv;
|
double FPDiv;
|
||||||
#endif
|
|
||||||
if (*Lexer->Pos == '0') {
|
if (*Lexer->Pos == '0') {
|
||||||
/* a binary, octal or hex literal */
|
/* a binary, octal or hex literal */
|
||||||
LEXER_INC(Lexer);
|
LEXER_INC(Lexer);
|
||||||
@ -163,7 +165,6 @@ enum LexToken LexGetNumber(struct LexState *Lexer, struct Value *Value) {
|
|||||||
LEXER_INC(Lexer);
|
LEXER_INC(Lexer);
|
||||||
return ResultToken;
|
return ResultToken;
|
||||||
}
|
}
|
||||||
#ifndef NO_FP
|
|
||||||
if ( Lexer->Pos == Lexer->End
|
if ( Lexer->Pos == Lexer->End
|
||||||
|| *Lexer->Pos != '.') {
|
|| *Lexer->Pos != '.') {
|
||||||
return ResultToken;
|
return ResultToken;
|
||||||
@ -190,9 +191,6 @@ enum LexToken LexGetNumber(struct LexState *Lexer, struct Value *Value) {
|
|||||||
}
|
}
|
||||||
Value->Val->FP = FPResult;
|
Value->Val->FP = FPResult;
|
||||||
return TokenFPConstant;
|
return TokenFPConstant;
|
||||||
#else
|
|
||||||
return ResultToken;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get a reserved word or identifier - used while scanning */
|
/* 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:
|
case TokenCharacterConstant:
|
||||||
LexValue.Typ = &CharType;
|
LexValue.Typ = &CharType;
|
||||||
break;
|
break;
|
||||||
#ifndef NO_FP
|
|
||||||
case TokenFPConstant:
|
case TokenFPConstant:
|
||||||
LexValue.Typ = &FPType;
|
LexValue.Typ = &FPType;
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
break;
|
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 "picoc.h"
|
||||||
#include "interpreter.h"
|
#include "interpreter.h"
|
||||||
|
|
||||||
@ -742,7 +750,7 @@ void PicocParse(const char *FileName, const char *Source, int SourceLen, int Run
|
|||||||
void PicocParseInteractive() {
|
void PicocParseInteractive() {
|
||||||
struct ParseState Parser;
|
struct ParseState Parser;
|
||||||
enum ParseResult Ok;
|
enum ParseResult Ok;
|
||||||
PlatformPrintf(INTERACTIVE_PROMPT_START);
|
PlatformPrintf("Starting eci " ECI_VERSION "\n");
|
||||||
LexInitParser(&Parser, NULL, NULL, StrEmpty, TRUE);
|
LexInitParser(&Parser, NULL, NULL, StrEmpty, TRUE);
|
||||||
PicocPlatformSetExitPoint();
|
PicocPlatformSetExitPoint();
|
||||||
LexInteractiveClear(&Parser);
|
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 only picoc.h here - should be able to use it with only the external interfaces, no internals from interpreter.h */
|
||||||
#include "picoc.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 */
|
#ifndef __ECI_H__
|
||||||
#define PICOC_VERSION "v2.1"
|
#define __ECI_H__
|
||||||
|
|
||||||
|
/* eci version number */
|
||||||
|
#define ECI_VERSION "v0.1"
|
||||||
|
|
||||||
/* handy definitions */
|
/* handy definitions */
|
||||||
#ifndef TRUE
|
#ifndef TRUE
|
||||||
@ -34,4 +42,4 @@ extern int PicocExitValue;
|
|||||||
/* include.c */
|
/* include.c */
|
||||||
void PicocIncludeAllSystemHeaders();
|
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 "picoc.h"
|
||||||
#include "interpreter.h"
|
#include "interpreter.h"
|
||||||
|
|
||||||
@ -180,11 +188,9 @@ void PlatformVPrintf(const char *Format, va_list Args) {
|
|||||||
case 't':
|
case 't':
|
||||||
PrintType(va_arg(Args, struct ValueType *), CStdOut);
|
PrintType(va_arg(Args, struct ValueType *), CStdOut);
|
||||||
break;
|
break;
|
||||||
#ifndef NO_FP
|
|
||||||
case 'f':
|
case 'f':
|
||||||
PrintFP(va_arg(Args, double), CStdOut);
|
PrintFP(va_arg(Args, double), CStdOut);
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
case '%':
|
case '%':
|
||||||
PrintCh('%', CStdOut);
|
PrintCh('%', CStdOut);
|
||||||
break;
|
break;
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
/* all platform-specific includes and defines go in this file */
|
/**
|
||||||
#ifndef PLATFORM_H
|
* @author Edouard DUPIN
|
||||||
#define PLATFORM_H
|
*
|
||||||
|
* @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 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 */
|
#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 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 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 "eci> "
|
||||||
#define INTERACTIVE_PROMPT_STATEMENT "picoc> "
|
|
||||||
#define INTERACTIVE_PROMPT_LINE " > "
|
#define INTERACTIVE_PROMPT_LINE " > "
|
||||||
|
|
||||||
/* host platform includes */
|
/* host platform includes */
|
||||||
@ -28,16 +34,9 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#ifndef NO_FP
|
#include <math.h>
|
||||||
# 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
|
|
||||||
|
|
||||||
extern jmp_buf ExitBuf;
|
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"
|
#include "../interpreter.h"
|
||||||
|
|
||||||
void UnixSetupFunc() {
|
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 "../picoc.h"
|
||||||
#include "../interpreter.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 */
|
/* mark where to end the program for platforms which require this */
|
||||||
jmp_buf PicocExitBuf;
|
jmp_buf PicocExitBuf;
|
||||||
|
|
||||||
@ -15,23 +18,6 @@ void PlatformCleanup() {
|
|||||||
|
|
||||||
/* get a line of interactive input */
|
/* get a line of interactive input */
|
||||||
char *PlatformGetLine(char *Buf, int MaxLen, const char *Prompt) {
|
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) {
|
if (Prompt != NULL) {
|
||||||
printf("%s", Prompt);
|
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"
|
#include "interpreter.h"
|
||||||
|
|
||||||
struct Table StringTable;
|
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"
|
#include "interpreter.h"
|
||||||
|
|
||||||
/* some basic types */
|
/* some basic types */
|
||||||
@ -9,9 +17,7 @@ struct ValueType LongType;
|
|||||||
struct ValueType UnsignedIntType;
|
struct ValueType UnsignedIntType;
|
||||||
struct ValueType UnsignedShortType;
|
struct ValueType UnsignedShortType;
|
||||||
struct ValueType UnsignedLongType;
|
struct ValueType UnsignedLongType;
|
||||||
#ifndef NO_FP
|
|
||||||
struct ValueType FPType;
|
struct ValueType FPType;
|
||||||
#endif
|
|
||||||
struct ValueType VoidType;
|
struct ValueType VoidType;
|
||||||
struct ValueType TypeType;
|
struct ValueType TypeType;
|
||||||
struct ValueType FunctionType;
|
struct ValueType FunctionType;
|
||||||
@ -148,12 +154,10 @@ void TypeInit() {
|
|||||||
char x;
|
char x;
|
||||||
long y;
|
long y;
|
||||||
} la;
|
} la;
|
||||||
#ifndef NO_FP
|
|
||||||
struct DoubleAlign {
|
struct DoubleAlign {
|
||||||
char x;
|
char x;
|
||||||
double y;
|
double y;
|
||||||
} da;
|
} da;
|
||||||
#endif
|
|
||||||
struct PointerAlign {
|
struct PointerAlign {
|
||||||
char x;
|
char x;
|
||||||
void *y;
|
void *y;
|
||||||
@ -174,12 +178,8 @@ void TypeInit() {
|
|||||||
TypeAddBaseType(&FunctionType, TypeFunction, sizeof(int), IntAlignBytes);
|
TypeAddBaseType(&FunctionType, TypeFunction, sizeof(int), IntAlignBytes);
|
||||||
TypeAddBaseType(&MacroType, TypeMacro, sizeof(int), IntAlignBytes);
|
TypeAddBaseType(&MacroType, TypeMacro, sizeof(int), IntAlignBytes);
|
||||||
TypeAddBaseType(&GotoLabelType, TypeGotoLabel, 0, 1);
|
TypeAddBaseType(&GotoLabelType, TypeGotoLabel, 0, 1);
|
||||||
#ifndef NO_FP
|
|
||||||
TypeAddBaseType(&FPType, TypeFP, sizeof(double), (char *)&da.y - &da.x);
|
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 */
|
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);
|
CharArrayType = TypeAdd(NULL, &CharType, TypeArray, 0, StrEmpty, sizeof(char), (char *)&ca.y - &ca.x);
|
||||||
CharPtrType = TypeAdd(NULL, &CharType, TypePointer, 0, StrEmpty, sizeof(void *), PointerAlignBytes);
|
CharPtrType = TypeAdd(NULL, &CharType, TypePointer, 0, StrEmpty, sizeof(void *), PointerAlignBytes);
|
||||||
CharPtrPtrType = TypeAdd(NULL, CharPtrType, 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:
|
case TokenLongType:
|
||||||
*Typ = Unsigned ? &UnsignedLongType : &LongType;
|
*Typ = Unsigned ? &UnsignedLongType : &LongType;
|
||||||
break;
|
break;
|
||||||
#ifndef NO_FP
|
|
||||||
case TokenFloatType:
|
case TokenFloatType:
|
||||||
case TokenDoubleType:
|
case TokenDoubleType:
|
||||||
*Typ = &FPType;
|
*Typ = &FPType;
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
case TokenVoidType:
|
case TokenVoidType:
|
||||||
*Typ = &VoidType;
|
*Typ = &VoidType;
|
||||||
break;
|
break;
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
*
|
||||||
|
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||||
|
*
|
||||||
|
* @license APACHE-2 (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
#include "interpreter.h"
|
#include "interpreter.h"
|
||||||
|
|
||||||
/* maximum size of a value to temporarily copy while we create a variable */
|
/* maximum size of a value to temporarily copy while we create a variable */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user