respect 80 col mark when it makes sense

This commit is contained in:
Joseph Poirier 2015-06-10 18:49:09 -05:00
parent ab118b0913
commit e52188dcda
25 changed files with 1608 additions and 745 deletions

View file

@ -1,8 +1,8 @@
CC=gcc CC=gcc
# -O3 # -O3 -g
# -std=gnu11 # -std=gnu11
CFLAGS=-Wall -O3 -g -std=gnu11 -pedantic -DUNIX_HOST -DVER=\"`git show-ref --abbrev=8 --head --hash head`\" -DTAG=\"`git describe --abbrev=0 --tags`\" CFLAGS=-Wall -pg -std=gnu11 -pedantic -DUNIX_HOST -DVER=\"`git show-ref --abbrev=8 --head --hash head`\" -DTAG=\"`git describe --abbrev=0 --tags`\"
LIBS=-lm -lreadline LIBS=-lm -lreadline
TARGET = picoc TARGET = picoc

View file

@ -15,14 +15,17 @@ void LibraryInit(Picoc *pc)
/* define the version number macro */ /* define the version number macro */
pc->VersionString = TableStrRegister(pc, PICOC_VERSION); pc->VersionString = TableStrRegister(pc, PICOC_VERSION);
VariableDefinePlatformVar(pc, NULL, "PICOC_VERSION", pc->CharPtrType, (union AnyValue*)&pc->VersionString, false); VariableDefinePlatformVar(pc, NULL, "PICOC_VERSION", pc->CharPtrType,
(union AnyValue*)&pc->VersionString, false);
/* define endian-ness macros */ /* define endian-ness macros */
BigEndian = ((*(char*)&__ENDIAN_CHECK__) == 0); BigEndian = ((*(char*)&__ENDIAN_CHECK__) == 0);
LittleEndian = ((*(char*)&__ENDIAN_CHECK__) == 1); LittleEndian = ((*(char*)&__ENDIAN_CHECK__) == 1);
VariableDefinePlatformVar(pc, NULL, "BIG_ENDIAN", &pc->IntType, (union AnyValue*)&BigEndian, false); VariableDefinePlatformVar(pc, NULL, "BIG_ENDIAN", &pc->IntType,
VariableDefinePlatformVar(pc, NULL, "LITTLE_ENDIAN", &pc->IntType, (union AnyValue*)&LittleEndian, false); (union AnyValue*)&BigEndian, false);
VariableDefinePlatformVar(pc, NULL, "LITTLE_ENDIAN", &pc->IntType,
(union AnyValue*)&LittleEndian, false);
} }
/* add a library */ /* add a library */
@ -38,8 +41,11 @@ void LibraryAdd(Picoc *pc, struct Table *GlobalTable, struct LibraryFunction *Fu
/* read all the library definitions */ /* read all the library definitions */
for (Count = 0; FuncList[Count].Prototype != NULL; Count++) { for (Count = 0; FuncList[Count].Prototype != NULL; Count++) {
Tokens = LexAnalyse(pc, (const char*)IntrinsicName, FuncList[Count].Prototype, strlen((char*)FuncList[Count].Prototype), NULL); Tokens = LexAnalyse(pc,
LexInitParser(&Parser, pc, FuncList[Count].Prototype, Tokens, IntrinsicName, true, false); (const char*)IntrinsicName, FuncList[Count].Prototype,
strlen((char*)FuncList[Count].Prototype), NULL);
LexInitParser(&Parser, pc, FuncList[Count].Prototype, Tokens,
IntrinsicName, true, false);
TypeParse(&Parser, &ReturnType, &Identifier, NULL); TypeParse(&Parser, &ReturnType, &Identifier, NULL);
NewValue = ParseFunctionDefinition(&Parser, ReturnType, Identifier); NewValue = ParseFunctionDefinition(&Parser, ReturnType, Identifier);
NewValue->Val->FuncDef.Intrinsic = FuncList[Count].Func; NewValue->Val->FuncDef.Intrinsic = FuncList[Count].Func;
@ -63,11 +69,29 @@ void PrintType(struct ValueType *Typ, IOFILE *Stream)
case TypeFP: PrintStr("double", Stream); break; case TypeFP: PrintStr("double", Stream); break;
case TypeFunction: PrintStr("function", Stream); break; case TypeFunction: PrintStr("function", Stream); break;
case TypeMacro: PrintStr("macro", Stream); break; case TypeMacro: PrintStr("macro", Stream); break;
case TypePointer: if (Typ->FromType) PrintType(Typ->FromType, Stream); PrintCh('*', Stream); break; case TypePointer:
case TypeArray: PrintType(Typ->FromType, Stream); PrintCh('[', Stream); if (Typ->ArraySize != 0) PrintSimpleInt(Typ->ArraySize, Stream); PrintCh(']', Stream); break; if (Typ->FromType)
case TypeStruct: PrintStr("struct ", Stream); PrintStr( Typ->Identifier, Stream); break; PrintType(Typ->FromType, Stream);
case TypeUnion: PrintStr("union ", Stream); PrintStr(Typ->Identifier, Stream); break; PrintCh('*', Stream); break;
case TypeEnum: PrintStr("enum ", Stream); PrintStr(Typ->Identifier, 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 TypeGotoLabel: PrintStr("goto label ", Stream); break;
case Type_Type: PrintStr("type ", Stream); break; case Type_Type: PrintStr("type ", Stream); break;
} }

View file

@ -3,83 +3,99 @@
#include "../interpreter.h" #include "../interpreter.h"
void StdIsalnum(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdIsalnum(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = isalnum(Param[0]->Val->Integer); ReturnValue->Val->Integer = isalnum(Param[0]->Val->Integer);
} }
void StdIsalpha(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdIsalpha(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = isalpha(Param[0]->Val->Integer); ReturnValue->Val->Integer = isalpha(Param[0]->Val->Integer);
} }
void StdIsblank(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdIsblank(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
int ch = Param[0]->Val->Integer; int ch = Param[0]->Val->Integer;
ReturnValue->Val->Integer = (ch == ' ') | (ch == '\t'); ReturnValue->Val->Integer = (ch == ' ') | (ch == '\t');
} }
void StdIscntrl(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdIscntrl(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = iscntrl(Param[0]->Val->Integer); ReturnValue->Val->Integer = iscntrl(Param[0]->Val->Integer);
} }
void StdIsdigit(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdIsdigit(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = isdigit(Param[0]->Val->Integer); ReturnValue->Val->Integer = isdigit(Param[0]->Val->Integer);
} }
void StdIsgraph(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdIsgraph(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = isgraph(Param[0]->Val->Integer); ReturnValue->Val->Integer = isgraph(Param[0]->Val->Integer);
} }
void StdIslower(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdIslower(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = islower(Param[0]->Val->Integer); ReturnValue->Val->Integer = islower(Param[0]->Val->Integer);
} }
void StdIsprint(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdIsprint(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = isprint(Param[0]->Val->Integer); ReturnValue->Val->Integer = isprint(Param[0]->Val->Integer);
} }
void StdIspunct(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdIspunct(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = ispunct(Param[0]->Val->Integer); ReturnValue->Val->Integer = ispunct(Param[0]->Val->Integer);
} }
void StdIsspace(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdIsspace(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = isspace(Param[0]->Val->Integer); ReturnValue->Val->Integer = isspace(Param[0]->Val->Integer);
} }
void StdIsupper(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdIsupper(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = isupper(Param[0]->Val->Integer); ReturnValue->Val->Integer = isupper(Param[0]->Val->Integer);
} }
void StdIsxdigit(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdIsxdigit(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = isxdigit(Param[0]->Val->Integer); ReturnValue->Val->Integer = isxdigit(Param[0]->Val->Integer);
} }
void StdTolower(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdTolower(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = tolower(Param[0]->Val->Integer); ReturnValue->Val->Integer = tolower(Param[0]->Val->Integer);
} }
void StdToupper(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdToupper(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = toupper(Param[0]->Val->Integer); ReturnValue->Val->Integer = toupper(Param[0]->Val->Integer);
} }
void StdIsascii(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdIsascii(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = isascii(Param[0]->Val->Integer); ReturnValue->Val->Integer = isascii(Param[0]->Val->Integer);
} }
void StdToascii(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdToascii(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = toascii(Param[0]->Val->Integer); ReturnValue->Val->Integer = toascii(Param[0]->Val->Integer);
} }

View file

@ -329,325 +329,406 @@ void StdErrnoSetupFunc(Picoc *pc)
{ {
/* defines */ /* defines */
#ifdef EACCES #ifdef EACCES
VariableDefinePlatformVar(pc, NULL, "EACCES", &pc->IntType, (union AnyValue *)&EACCESValue, false); VariableDefinePlatformVar(pc, NULL, "EACCES", &pc->IntType,
(union AnyValue*)&EACCESValue, false);
#endif #endif
#ifdef EADDRINUSE #ifdef EADDRINUSE
VariableDefinePlatformVar(pc, NULL, "EADDRINUSE", &pc->IntType, (union AnyValue *)&EADDRINUSEValue, false); VariableDefinePlatformVar(pc, NULL, "EADDRINUSE", &pc->IntType,
(union AnyValue*)&EADDRINUSEValue, false);
#endif #endif
#ifdef EADDRNOTAVAIL #ifdef EADDRNOTAVAIL
VariableDefinePlatformVar(pc, NULL, "EADDRNOTAVAIL", &pc->IntType, (union AnyValue *)&EADDRNOTAVAILValue, false); VariableDefinePlatformVar(pc, NULL, "EADDRNOTAVAIL", &pc->IntType,
(union AnyValue*)&EADDRNOTAVAILValue, false);
#endif #endif
#ifdef EAFNOSUPPORT #ifdef EAFNOSUPPORT
VariableDefinePlatformVar(pc, NULL, "EAFNOSUPPORT", &pc->IntType, (union AnyValue *)&EAFNOSUPPORTValue, false); VariableDefinePlatformVar(pc, NULL, "EAFNOSUPPORT", &pc->IntType,
(union AnyValue*)&EAFNOSUPPORTValue, false);
#endif #endif
#ifdef EAGAIN #ifdef EAGAIN
VariableDefinePlatformVar(pc, NULL, "EAGAIN", &pc->IntType, (union AnyValue *)&EAGAINValue, false); VariableDefinePlatformVar(pc, NULL, "EAGAIN", &pc->IntType,
(union AnyValue*)&EAGAINValue, false);
#endif #endif
#ifdef EALREADY #ifdef EALREADY
VariableDefinePlatformVar(pc, NULL, "EALREADY", &pc->IntType, (union AnyValue *)&EALREADYValue, false); VariableDefinePlatformVar(pc, NULL, "EALREADY", &pc->IntType,
(union AnyValue*)&EALREADYValue, false);
#endif #endif
#ifdef EBADF #ifdef EBADF
VariableDefinePlatformVar(pc, NULL, "EBADF", &pc->IntType, (union AnyValue *)&EBADFValue, false); VariableDefinePlatformVar(pc, NULL, "EBADF", &pc->IntType,
(union AnyValue*)&EBADFValue, false);
#endif #endif
#ifdef EBADMSG #ifdef EBADMSG
VariableDefinePlatformVar(pc, NULL, "EBADMSG", &pc->IntType, (union AnyValue *)&EBADMSGValue, false); VariableDefinePlatformVar(pc, NULL, "EBADMSG", &pc->IntType,
(union AnyValue*)&EBADMSGValue, false);
#endif #endif
#ifdef EBUSY #ifdef EBUSY
VariableDefinePlatformVar(pc, NULL, "EBUSY", &pc->IntType, (union AnyValue *)&EBUSYValue, false); VariableDefinePlatformVar(pc, NULL, "EBUSY", &pc->IntType,
(union AnyValue*)&EBUSYValue, false);
#endif #endif
#ifdef ECANCELED #ifdef ECANCELED
VariableDefinePlatformVar(pc, NULL, "ECANCELED", &pc->IntType, (union AnyValue *)&ECANCELEDValue, false); VariableDefinePlatformVar(pc, NULL, "ECANCELED", &pc->IntType,
(union AnyValue*)&ECANCELEDValue, false);
#endif #endif
#ifdef ECHILD #ifdef ECHILD
VariableDefinePlatformVar(pc, NULL, "ECHILD", &pc->IntType, (union AnyValue *)&ECHILDValue, false); VariableDefinePlatformVar(pc, NULL, "ECHILD", &pc->IntType,
(union AnyValue*)&ECHILDValue, false);
#endif #endif
#ifdef ECONNABORTED #ifdef ECONNABORTED
VariableDefinePlatformVar(pc, NULL, "ECONNABORTED", &pc->IntType, (union AnyValue *)&ECONNABORTEDValue, false); VariableDefinePlatformVar(pc, NULL, "ECONNABORTED", &pc->IntType,
(union AnyValue*)&ECONNABORTEDValue, false);
#endif #endif
#ifdef ECONNREFUSED #ifdef ECONNREFUSED
VariableDefinePlatformVar(pc, NULL, "ECONNREFUSED", &pc->IntType, (union AnyValue *)&ECONNREFUSEDValue, false); VariableDefinePlatformVar(pc, NULL, "ECONNREFUSED", &pc->IntType,
(union AnyValue*)&ECONNREFUSEDValue, false);
#endif #endif
#ifdef ECONNRESET #ifdef ECONNRESET
VariableDefinePlatformVar(pc, NULL, "ECONNRESET", &pc->IntType, (union AnyValue *)&ECONNRESETValue, false); VariableDefinePlatformVar(pc, NULL, "ECONNRESET", &pc->IntType,
(union AnyValue*)&ECONNRESETValue, false);
#endif #endif
#ifdef EDEADLK #ifdef EDEADLK
VariableDefinePlatformVar(pc, NULL, "EDEADLK", &pc->IntType, (union AnyValue *)&EDEADLKValue, false); VariableDefinePlatformVar(pc, NULL, "EDEADLK", &pc->IntType,
(union AnyValue*)&EDEADLKValue, false);
#endif #endif
#ifdef EDESTADDRREQ #ifdef EDESTADDRREQ
VariableDefinePlatformVar(pc, NULL, "EDESTADDRREQ", &pc->IntType, (union AnyValue *)&EDESTADDRREQValue, false); VariableDefinePlatformVar(pc, NULL, "EDESTADDRREQ", &pc->IntType,
(union AnyValue*)&EDESTADDRREQValue, false);
#endif #endif
#ifdef EDOM #ifdef EDOM
VariableDefinePlatformVar(pc, NULL, "EDOM", &pc->IntType, (union AnyValue *)&EDOMValue, false); VariableDefinePlatformVar(pc, NULL, "EDOM", &pc->IntType,
(union AnyValue*)&EDOMValue, false);
#endif #endif
#ifdef EDQUOT #ifdef EDQUOT
VariableDefinePlatformVar(pc, NULL, "EDQUOT", &pc->IntType, (union AnyValue *)&EDQUOTValue, false); VariableDefinePlatformVar(pc, NULL, "EDQUOT", &pc->IntType,
(union AnyValue*)&EDQUOTValue, false);
#endif #endif
#ifdef EEXIST #ifdef EEXIST
VariableDefinePlatformVar(pc, NULL, "EEXIST", &pc->IntType, (union AnyValue *)&EEXISTValue, false); VariableDefinePlatformVar(pc, NULL, "EEXIST", &pc->IntType,
(union AnyValue*)&EEXISTValue, false);
#endif #endif
#ifdef EFAULT #ifdef EFAULT
VariableDefinePlatformVar(pc, NULL, "EFAULT", &pc->IntType, (union AnyValue *)&EFAULTValue, false); VariableDefinePlatformVar(pc, NULL, "EFAULT", &pc->IntType,
(union AnyValue*)&EFAULTValue, false);
#endif #endif
#ifdef EFBIG #ifdef EFBIG
VariableDefinePlatformVar(pc, NULL, "EFBIG", &pc->IntType, (union AnyValue *)&EFBIGValue, false); VariableDefinePlatformVar(pc, NULL, "EFBIG", &pc->IntType,
(union AnyValue*)&EFBIGValue, false);
#endif #endif
#ifdef EHOSTUNREACH #ifdef EHOSTUNREACH
VariableDefinePlatformVar(pc, NULL, "EHOSTUNREACH", &pc->IntType, (union AnyValue *)&EHOSTUNREACHValue, false); VariableDefinePlatformVar(pc, NULL, "EHOSTUNREACH", &pc->IntType,
(union AnyValue*)&EHOSTUNREACHValue, false);
#endif #endif
#ifdef EIDRM #ifdef EIDRM
VariableDefinePlatformVar(pc, NULL, "EIDRM", &pc->IntType, (union AnyValue *)&EIDRMValue, false); VariableDefinePlatformVar(pc, NULL, "EIDRM", &pc->IntType,
(union AnyValue*)&EIDRMValue, false);
#endif #endif
#ifdef EILSEQ #ifdef EILSEQ
VariableDefinePlatformVar(pc, NULL, "EILSEQ", &pc->IntType, (union AnyValue *)&EILSEQValue, false); VariableDefinePlatformVar(pc, NULL, "EILSEQ", &pc->IntType,
(union AnyValue*)&EILSEQValue, false);
#endif #endif
#ifdef EINPROGRESS #ifdef EINPROGRESS
VariableDefinePlatformVar(pc, NULL, "EINPROGRESS", &pc->IntType, (union AnyValue *)&EINPROGRESSValue, false); VariableDefinePlatformVar(pc, NULL, "EINPROGRESS", &pc->IntType,
(union AnyValue*)&EINPROGRESSValue, false);
#endif #endif
#ifdef EINTR #ifdef EINTR
VariableDefinePlatformVar(pc, NULL, "EINTR", &pc->IntType, (union AnyValue *)&EINTRValue, false); VariableDefinePlatformVar(pc, NULL, "EINTR", &pc->IntType,
(union AnyValue*)&EINTRValue, false);
#endif #endif
#ifdef EINVAL #ifdef EINVAL
VariableDefinePlatformVar(pc, NULL, "EINVAL", &pc->IntType, (union AnyValue *)&EINVALValue, false); VariableDefinePlatformVar(pc, NULL, "EINVAL", &pc->IntType,
(union AnyValue*)&EINVALValue, false);
#endif #endif
#ifdef EIO #ifdef EIO
VariableDefinePlatformVar(pc, NULL, "EIO", &pc->IntType, (union AnyValue *)&EIOValue, false); VariableDefinePlatformVar(pc, NULL, "EIO", &pc->IntType,
(union AnyValue*)&EIOValue, false);
#endif #endif
#ifdef EISCONN #ifdef EISCONN
VariableDefinePlatformVar(pc, NULL, "EISCONN", &pc->IntType, (union AnyValue *)&EISCONNValue, false); VariableDefinePlatformVar(pc, NULL, "EISCONN", &pc->IntType,
(union AnyValue*)&EISCONNValue, false);
#endif #endif
#ifdef EISDIR #ifdef EISDIR
VariableDefinePlatformVar(pc, NULL, "EISDIR", &pc->IntType, (union AnyValue *)&EISDIRValue, false); VariableDefinePlatformVar(pc, NULL, "EISDIR", &pc->IntType,
(union AnyValue*)&EISDIRValue, false);
#endif #endif
#ifdef ELOOP #ifdef ELOOP
VariableDefinePlatformVar(pc, NULL, "ELOOP", &pc->IntType, (union AnyValue *)&ELOOPValue, false); VariableDefinePlatformVar(pc, NULL, "ELOOP", &pc->IntType,
(union AnyValue*)&ELOOPValue, false);
#endif #endif
#ifdef EMFILE #ifdef EMFILE
VariableDefinePlatformVar(pc, NULL, "EMFILE", &pc->IntType, (union AnyValue *)&EMFILEValue, false); VariableDefinePlatformVar(pc, NULL, "EMFILE", &pc->IntType,
(union AnyValue*)&EMFILEValue, false);
#endif #endif
#ifdef EMLINK #ifdef EMLINK
VariableDefinePlatformVar(pc, NULL, "EMLINK", &pc->IntType, (union AnyValue *)&EMLINKValue, false); VariableDefinePlatformVar(pc, NULL, "EMLINK", &pc->IntType,
(union AnyValue*)&EMLINKValue, false);
#endif #endif
#ifdef EMSGSIZE #ifdef EMSGSIZE
VariableDefinePlatformVar(pc, NULL, "EMSGSIZE", &pc->IntType, (union AnyValue *)&EMSGSIZEValue, false); VariableDefinePlatformVar(pc, NULL, "EMSGSIZE", &pc->IntType,
(union AnyValue*)&EMSGSIZEValue, false);
#endif #endif
#ifdef EMULTIHOP #ifdef EMULTIHOP
VariableDefinePlatformVar(pc, NULL, "EMULTIHOP", &pc->IntType, (union AnyValue *)&EMULTIHOPValue, false); VariableDefinePlatformVar(pc, NULL, "EMULTIHOP", &pc->IntType,
(union AnyValue*)&EMULTIHOPValue, false);
#endif #endif
#ifdef ENAMETOOLONG #ifdef ENAMETOOLONG
VariableDefinePlatformVar(pc, NULL, "ENAMETOOLONG", &pc->IntType, (union AnyValue *)&ENAMETOOLONGValue, false); VariableDefinePlatformVar(pc, NULL, "ENAMETOOLONG", &pc->IntType,
(union AnyValue*)&ENAMETOOLONGValue, false);
#endif #endif
#ifdef ENETDOWN #ifdef ENETDOWN
VariableDefinePlatformVar(pc, NULL, "ENETDOWN", &pc->IntType, (union AnyValue *)&ENETDOWNValue, false); VariableDefinePlatformVar(pc, NULL, "ENETDOWN", &pc->IntType,
(union AnyValue*)&ENETDOWNValue, false);
#endif #endif
#ifdef ENETRESET #ifdef ENETRESET
VariableDefinePlatformVar(pc, NULL, "ENETRESET", &pc->IntType, (union AnyValue *)&ENETRESETValue, false); VariableDefinePlatformVar(pc, NULL, "ENETRESET", &pc->IntType,
(union AnyValue*)&ENETRESETValue, false);
#endif #endif
#ifdef ENETUNREACH #ifdef ENETUNREACH
VariableDefinePlatformVar(pc, NULL, "ENETUNREACH", &pc->IntType, (union AnyValue *)&ENETUNREACHValue, false); VariableDefinePlatformVar(pc, NULL, "ENETUNREACH", &pc->IntType,
(union AnyValue*)&ENETUNREACHValue, false);
#endif #endif
#ifdef ENFILE #ifdef ENFILE
VariableDefinePlatformVar(pc, NULL, "ENFILE", &pc->IntType, (union AnyValue *)&ENFILEValue, false); VariableDefinePlatformVar(pc, NULL, "ENFILE", &pc->IntType,
(union AnyValue*)&ENFILEValue, false);
#endif #endif
#ifdef ENOBUFS #ifdef ENOBUFS
VariableDefinePlatformVar(pc, NULL, "ENOBUFS", &pc->IntType, (union AnyValue *)&ENOBUFSValue, false); VariableDefinePlatformVar(pc, NULL, "ENOBUFS", &pc->IntType,
(union AnyValue*)&ENOBUFSValue, false);
#endif #endif
#ifdef ENODATA #ifdef ENODATA
VariableDefinePlatformVar(pc, NULL, "ENODATA", &pc->IntType, (union AnyValue *)&ENODATAValue, false); VariableDefinePlatformVar(pc, NULL, "ENODATA", &pc->IntType,
(union AnyValue*)&ENODATAValue, false);
#endif #endif
#ifdef ENODEV #ifdef ENODEV
VariableDefinePlatformVar(pc, NULL, "ENODEV", &pc->IntType, (union AnyValue *)&ENODEVValue, false); VariableDefinePlatformVar(pc, NULL, "ENODEV", &pc->IntType,
(union AnyValue*)&ENODEVValue, false);
#endif #endif
#ifdef ENOENT #ifdef ENOENT
VariableDefinePlatformVar(pc, NULL, "ENOENT", &pc->IntType, (union AnyValue *)&ENOENTValue, false); VariableDefinePlatformVar(pc, NULL, "ENOENT", &pc->IntType,
(union AnyValue*)&ENOENTValue, false);
#endif #endif
#ifdef ENOEXEC #ifdef ENOEXEC
VariableDefinePlatformVar(pc, NULL, "ENOEXEC", &pc->IntType, (union AnyValue *)&ENOEXECValue, false); VariableDefinePlatformVar(pc, NULL, "ENOEXEC", &pc->IntType,
(union AnyValue*)&ENOEXECValue, false);
#endif #endif
#ifdef ENOLCK #ifdef ENOLCK
VariableDefinePlatformVar(pc, NULL, "ENOLCK", &pc->IntType, (union AnyValue *)&ENOLCKValue, false); VariableDefinePlatformVar(pc, NULL, "ENOLCK", &pc->IntType,
(union AnyValue*)&ENOLCKValue, false);
#endif #endif
#ifdef ENOLINK #ifdef ENOLINK
VariableDefinePlatformVar(pc, NULL, "ENOLINK", &pc->IntType, (union AnyValue *)&ENOLINKValue, false); VariableDefinePlatformVar(pc, NULL, "ENOLINK", &pc->IntType,
(union AnyValue*)&ENOLINKValue, false);
#endif #endif
#ifdef ENOMEM #ifdef ENOMEM
VariableDefinePlatformVar(pc, NULL, "ENOMEM", &pc->IntType, (union AnyValue *)&ENOMEMValue, false); VariableDefinePlatformVar(pc, NULL, "ENOMEM", &pc->IntType,
(union AnyValue*)&ENOMEMValue, false);
#endif #endif
#ifdef ENOMSG #ifdef ENOMSG
VariableDefinePlatformVar(pc, NULL, "ENOMSG", &pc->IntType, (union AnyValue *)&ENOMSGValue, false); VariableDefinePlatformVar(pc, NULL, "ENOMSG", &pc->IntType,
(union AnyValue*)&ENOMSGValue, false);
#endif #endif
#ifdef ENOPROTOOPT #ifdef ENOPROTOOPT
VariableDefinePlatformVar(pc, NULL, "ENOPROTOOPT", &pc->IntType, (union AnyValue *)&ENOPROTOOPTValue, false); VariableDefinePlatformVar(pc, NULL, "ENOPROTOOPT", &pc->IntType,
(union AnyValue*)&ENOPROTOOPTValue, false);
#endif #endif
#ifdef ENOSPC #ifdef ENOSPC
VariableDefinePlatformVar(pc, NULL, "ENOSPC", &pc->IntType, (union AnyValue *)&ENOSPCValue, false); VariableDefinePlatformVar(pc, NULL, "ENOSPC", &pc->IntType,
(union AnyValue*)&ENOSPCValue, false);
#endif #endif
#ifdef ENOSR #ifdef ENOSR
VariableDefinePlatformVar(pc, NULL, "ENOSR", &pc->IntType, (union AnyValue *)&ENOSRValue, false); VariableDefinePlatformVar(pc, NULL, "ENOSR", &pc->IntType,
(union AnyValue*)&ENOSRValue, false);
#endif #endif
#ifdef ENOSTR #ifdef ENOSTR
VariableDefinePlatformVar(pc, NULL, "ENOSTR", &pc->IntType, (union AnyValue *)&ENOSTRValue, false); VariableDefinePlatformVar(pc, NULL, "ENOSTR", &pc->IntType,
(union AnyValue*)&ENOSTRValue, false);
#endif #endif
#ifdef ENOSYS #ifdef ENOSYS
VariableDefinePlatformVar(pc, NULL, "ENOSYS", &pc->IntType, (union AnyValue *)&ENOSYSValue, false); VariableDefinePlatformVar(pc, NULL, "ENOSYS", &pc->IntType,
(union AnyValue*)&ENOSYSValue, false);
#endif #endif
#ifdef ENOTCONN #ifdef ENOTCONN
VariableDefinePlatformVar(pc, NULL, "ENOTCONN", &pc->IntType, (union AnyValue *)&ENOTCONNValue, false); VariableDefinePlatformVar(pc, NULL, "ENOTCONN", &pc->IntType,
(union AnyValue*)&ENOTCONNValue, false);
#endif #endif
#ifdef ENOTDIR #ifdef ENOTDIR
VariableDefinePlatformVar(pc, NULL, "ENOTDIR", &pc->IntType, (union AnyValue *)&ENOTDIRValue, false); VariableDefinePlatformVar(pc, NULL, "ENOTDIR", &pc->IntType,
(union AnyValue*)&ENOTDIRValue, false);
#endif #endif
#ifdef ENOTEMPTY #ifdef ENOTEMPTY
VariableDefinePlatformVar(pc, NULL, "ENOTEMPTY", &pc->IntType, (union AnyValue *)&ENOTEMPTYValue, false); VariableDefinePlatformVar(pc, NULL, "ENOTEMPTY", &pc->IntType,
(union AnyValue*)&ENOTEMPTYValue, false);
#endif #endif
#ifdef ENOTRECOVERABLE #ifdef ENOTRECOVERABLE
VariableDefinePlatformVar(pc, NULL, "ENOTRECOVERABLE", &pc->IntType, (union AnyValue *)&ENOTRECOVERABLEValue, false); VariableDefinePlatformVar(pc, NULL, "ENOTRECOVERABLE", &pc->IntType,
(union AnyValue*)&ENOTRECOVERABLEValue, false);
#endif #endif
#ifdef ENOTSOCK #ifdef ENOTSOCK
VariableDefinePlatformVar(pc, NULL, "ENOTSOCK", &pc->IntType, (union AnyValue *)&ENOTSOCKValue, false); VariableDefinePlatformVar(pc, NULL, "ENOTSOCK", &pc->IntType,
(union AnyValue*)&ENOTSOCKValue, false);
#endif #endif
#ifdef ENOTSUP #ifdef ENOTSUP
VariableDefinePlatformVar(pc, NULL, "ENOTSUP", &pc->IntType, (union AnyValue *)&ENOTSUPValue, false); VariableDefinePlatformVar(pc, NULL, "ENOTSUP", &pc->IntType,
(union AnyValue*)&ENOTSUPValue, false);
#endif #endif
#ifdef ENOTTY #ifdef ENOTTY
VariableDefinePlatformVar(pc, NULL, "ENOTTY", &pc->IntType, (union AnyValue *)&ENOTTYValue, false); VariableDefinePlatformVar(pc, NULL, "ENOTTY", &pc->IntType,
(union AnyValue*)&ENOTTYValue, false);
#endif #endif
#ifdef ENXIO #ifdef ENXIO
VariableDefinePlatformVar(pc, NULL, "ENXIO", &pc->IntType, (union AnyValue *)&ENXIOValue, false); VariableDefinePlatformVar(pc, NULL, "ENXIO", &pc->IntType,
(union AnyValue*)&ENXIOValue, false);
#endif #endif
#ifdef EOPNOTSUPP #ifdef EOPNOTSUPP
VariableDefinePlatformVar(pc, NULL, "EOPNOTSUPP", &pc->IntType, (union AnyValue *)&EOPNOTSUPPValue, false); VariableDefinePlatformVar(pc, NULL, "EOPNOTSUPP", &pc->IntType,
(union AnyValue*)&EOPNOTSUPPValue, false);
#endif #endif
#ifdef EOVERFLOW #ifdef EOVERFLOW
VariableDefinePlatformVar(pc, NULL, "EOVERFLOW", &pc->IntType, (union AnyValue *)&EOVERFLOWValue, false); VariableDefinePlatformVar(pc, NULL, "EOVERFLOW", &pc->IntType,
(union AnyValue*)&EOVERFLOWValue, false);
#endif #endif
#ifdef EOWNERDEAD #ifdef EOWNERDEAD
VariableDefinePlatformVar(pc, NULL, "EOWNERDEAD", &pc->IntType, (union AnyValue *)&EOWNERDEADValue, false); VariableDefinePlatformVar(pc, NULL, "EOWNERDEAD", &pc->IntType,
(union AnyValue*)&EOWNERDEADValue, false);
#endif #endif
#ifdef EPERM #ifdef EPERM
VariableDefinePlatformVar(pc, NULL, "EPERM", &pc->IntType, (union AnyValue *)&EPERMValue, false); VariableDefinePlatformVar(pc, NULL, "EPERM", &pc->IntType,
(union AnyValue*)&EPERMValue, false);
#endif #endif
#ifdef EPIPE #ifdef EPIPE
VariableDefinePlatformVar(pc, NULL, "EPIPE", &pc->IntType, (union AnyValue *)&EPIPEValue, false); VariableDefinePlatformVar(pc, NULL, "EPIPE", &pc->IntType,
(union AnyValue*)&EPIPEValue, false);
#endif #endif
#ifdef EPROTO #ifdef EPROTO
VariableDefinePlatformVar(pc, NULL, "EPROTO", &pc->IntType, (union AnyValue *)&EPROTOValue, false); VariableDefinePlatformVar(pc, NULL, "EPROTO", &pc->IntType,
(union AnyValue*)&EPROTOValue, false);
#endif #endif
#ifdef EPROTONOSUPPORT #ifdef EPROTONOSUPPORT
VariableDefinePlatformVar(pc, NULL, "EPROTONOSUPPORT", &pc->IntType, (union AnyValue *)&EPROTONOSUPPORTValue, false); VariableDefinePlatformVar(pc, NULL, "EPROTONOSUPPORT", &pc->IntType,
(union AnyValue*)&EPROTONOSUPPORTValue, false);
#endif #endif
#ifdef EPROTOTYPE #ifdef EPROTOTYPE
VariableDefinePlatformVar(pc, NULL, "EPROTOTYPE", &pc->IntType, (union AnyValue *)&EPROTOTYPEValue, false); VariableDefinePlatformVar(pc, NULL, "EPROTOTYPE", &pc->IntType,
(union AnyValue*)&EPROTOTYPEValue, false);
#endif #endif
#ifdef ERANGE #ifdef ERANGE
VariableDefinePlatformVar(pc, NULL, "ERANGE", &pc->IntType, (union AnyValue *)&ERANGEValue, false); VariableDefinePlatformVar(pc, NULL, "ERANGE", &pc->IntType,
(union AnyValue*)&ERANGEValue, false);
#endif #endif
#ifdef EROFS #ifdef EROFS
VariableDefinePlatformVar(pc, NULL, "EROFS", &pc->IntType, (union AnyValue *)&EROFSValue, false); VariableDefinePlatformVar(pc, NULL, "EROFS", &pc->IntType,
(union AnyValue*)&EROFSValue, false);
#endif #endif
#ifdef ESPIPE #ifdef ESPIPE
VariableDefinePlatformVar(pc, NULL, "ESPIPE", &pc->IntType, (union AnyValue *)&ESPIPEValue, false); VariableDefinePlatformVar(pc, NULL, "ESPIPE", &pc->IntType,
(union AnyValue*)&ESPIPEValue, false);
#endif #endif
#ifdef ESRCH #ifdef ESRCH
VariableDefinePlatformVar(pc, NULL, "ESRCH", &pc->IntType, (union AnyValue *)&ESRCHValue, false); VariableDefinePlatformVar(pc, NULL, "ESRCH", &pc->IntType,
(union AnyValue*)&ESRCHValue, false);
#endif #endif
#ifdef ESTALE #ifdef ESTALE
VariableDefinePlatformVar(pc, NULL, "ESTALE", &pc->IntType, (union AnyValue *)&ESTALEValue, false); VariableDefinePlatformVar(pc, NULL, "ESTALE", &pc->IntType,
(union AnyValue*)&ESTALEValue, false);
#endif #endif
#ifdef ETIME #ifdef ETIME
VariableDefinePlatformVar(pc, NULL, "ETIME", &pc->IntType, (union AnyValue *)&ETIMEValue, false); VariableDefinePlatformVar(pc, NULL, "ETIME", &pc->IntType,
(union AnyValue*)&ETIMEValue, false);
#endif #endif
#ifdef ETIMEDOUT #ifdef ETIMEDOUT
VariableDefinePlatformVar(pc, NULL, "ETIMEDOUT", &pc->IntType, (union AnyValue *)&ETIMEDOUTValue, false); VariableDefinePlatformVar(pc, NULL, "ETIMEDOUT", &pc->IntType,
(union AnyValue*)&ETIMEDOUTValue, false);
#endif #endif
#ifdef ETXTBSY #ifdef ETXTBSY
VariableDefinePlatformVar(pc, NULL, "ETXTBSY", &pc->IntType, (union AnyValue *)&ETXTBSYValue, false); VariableDefinePlatformVar(pc, NULL, "ETXTBSY", &pc->IntType,
(union AnyValue*)&ETXTBSYValue, false);
#endif #endif
#ifdef EWOULDBLOCK #ifdef EWOULDBLOCK
VariableDefinePlatformVar(pc, NULL, "EWOULDBLOCK", &pc->IntType, (union AnyValue *)&EWOULDBLOCKValue, false); VariableDefinePlatformVar(pc, NULL, "EWOULDBLOCK", &pc->IntType,
(union AnyValue*)&EWOULDBLOCKValue, false);
#endif #endif
#ifdef EXDEV #ifdef EXDEV
VariableDefinePlatformVar(pc, NULL, "EXDEV", &pc->IntType, (union AnyValue *)&EXDEVValue, false); VariableDefinePlatformVar(pc, NULL, "EXDEV", &pc->IntType,
(union AnyValue*)&EXDEVValue, false);
#endif #endif
VariableDefinePlatformVar(pc, NULL, "errno", &pc->IntType, (union AnyValue *)&errno, true); VariableDefinePlatformVar(pc, NULL, "errno", &pc->IntType,
(union AnyValue*)&errno, true);
} }

View file

@ -17,119 +17,142 @@ static double M_SQRT2Value = 1.41421356237309504880; /* sqrt(2) */
static double M_SQRT1_2Value = 0.70710678118654752440; /* 1/sqrt(2) */ static double M_SQRT1_2Value = 0.70710678118654752440; /* 1/sqrt(2) */
void MathSin(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void MathSin(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->FP = sin(Param[0]->Val->FP); ReturnValue->Val->FP = sin(Param[0]->Val->FP);
} }
void MathCos(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void MathCos(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->FP = cos(Param[0]->Val->FP); ReturnValue->Val->FP = cos(Param[0]->Val->FP);
} }
void MathTan(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void MathTan(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->FP = tan(Param[0]->Val->FP); ReturnValue->Val->FP = tan(Param[0]->Val->FP);
} }
void MathAsin(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void MathAsin(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->FP = asin(Param[0]->Val->FP); ReturnValue->Val->FP = asin(Param[0]->Val->FP);
} }
void MathAcos(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void MathAcos(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->FP = acos(Param[0]->Val->FP); ReturnValue->Val->FP = acos(Param[0]->Val->FP);
} }
void MathAtan(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void MathAtan(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->FP = atan(Param[0]->Val->FP); ReturnValue->Val->FP = atan(Param[0]->Val->FP);
} }
void MathAtan2(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void MathAtan2(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->FP = atan2(Param[0]->Val->FP, Param[1]->Val->FP); ReturnValue->Val->FP = atan2(Param[0]->Val->FP, Param[1]->Val->FP);
} }
void MathSinh(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void MathSinh(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->FP = sinh(Param[0]->Val->FP); ReturnValue->Val->FP = sinh(Param[0]->Val->FP);
} }
void MathCosh(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void MathCosh(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->FP = cosh(Param[0]->Val->FP); ReturnValue->Val->FP = cosh(Param[0]->Val->FP);
} }
void MathTanh(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void MathTanh(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->FP = tanh(Param[0]->Val->FP); ReturnValue->Val->FP = tanh(Param[0]->Val->FP);
} }
void MathExp(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void MathExp(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->FP = exp(Param[0]->Val->FP); ReturnValue->Val->FP = exp(Param[0]->Val->FP);
} }
void MathFabs(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void MathFabs(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->FP = fabs(Param[0]->Val->FP); ReturnValue->Val->FP = fabs(Param[0]->Val->FP);
} }
void MathFmod(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void MathFmod(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->FP = fmod(Param[0]->Val->FP, Param[1]->Val->FP); ReturnValue->Val->FP = fmod(Param[0]->Val->FP, Param[1]->Val->FP);
} }
void MathFrexp(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void MathFrexp(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->FP = frexp(Param[0]->Val->FP, Param[1]->Val->Pointer); ReturnValue->Val->FP = frexp(Param[0]->Val->FP, Param[1]->Val->Pointer);
} }
void MathLdexp(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void MathLdexp(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->FP = ldexp(Param[0]->Val->FP, Param[1]->Val->Integer); ReturnValue->Val->FP = ldexp(Param[0]->Val->FP, Param[1]->Val->Integer);
} }
void MathLog(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void MathLog(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->FP = log(Param[0]->Val->FP); ReturnValue->Val->FP = log(Param[0]->Val->FP);
} }
void MathLog10(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void MathLog10(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->FP = log10(Param[0]->Val->FP); ReturnValue->Val->FP = log10(Param[0]->Val->FP);
} }
void MathModf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void MathModf(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->FP = modf(Param[0]->Val->FP, Param[0]->Val->Pointer); ReturnValue->Val->FP = modf(Param[0]->Val->FP, Param[0]->Val->Pointer);
} }
void MathPow(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void MathPow(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->FP = pow(Param[0]->Val->FP, Param[1]->Val->FP); ReturnValue->Val->FP = pow(Param[0]->Val->FP, Param[1]->Val->FP);
} }
void MathSqrt(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void MathSqrt(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->FP = sqrt(Param[0]->Val->FP); ReturnValue->Val->FP = sqrt(Param[0]->Val->FP);
} }
void MathRound(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void MathRound(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
/* this awkward definition of "round()" due to it being inconsistently /* this awkward definition of "round()" due to it being inconsistently
* declared in math.h */ * declared in math.h */
ReturnValue->Val->FP = ceil(Param[0]->Val->FP - 0.5); ReturnValue->Val->FP = ceil(Param[0]->Val->FP - 0.5);
} }
void MathCeil(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void MathCeil(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->FP = ceil(Param[0]->Val->FP); ReturnValue->Val->FP = ceil(Param[0]->Val->FP);
} }
void MathFloor(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void MathFloor(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->FP = floor(Param[0]->Val->FP); ReturnValue->Val->FP = floor(Param[0]->Val->FP);
} }
@ -166,17 +189,30 @@ struct LibraryFunction MathFunctions[] =
/* creates various system-dependent definitions */ /* creates various system-dependent definitions */
void MathSetupFunc(Picoc *pc) void MathSetupFunc(Picoc *pc)
{ {
VariableDefinePlatformVar(pc, NULL, "M_E", &pc->FPType, (union AnyValue *)&M_EValue, false); VariableDefinePlatformVar(pc, NULL, "M_E", &pc->FPType,
VariableDefinePlatformVar(pc, NULL, "M_LOG2E", &pc->FPType, (union AnyValue *)&M_LOG2EValue, false); (union AnyValue*)&M_EValue, false);
VariableDefinePlatformVar(pc, NULL, "M_LOG10E", &pc->FPType, (union AnyValue *)&M_LOG10EValue, false); VariableDefinePlatformVar(pc, NULL, "M_LOG2E", &pc->FPType,
VariableDefinePlatformVar(pc, NULL, "M_LN2", &pc->FPType, (union AnyValue *)&M_LN2Value, false); (union AnyValue*)&M_LOG2EValue, false);
VariableDefinePlatformVar(pc, NULL, "M_LN10", &pc->FPType, (union AnyValue *)&M_LN10Value, false); VariableDefinePlatformVar(pc, NULL, "M_LOG10E", &pc->FPType,
VariableDefinePlatformVar(pc, NULL, "M_PI", &pc->FPType, (union AnyValue *)&M_PIValue, false); (union AnyValue*)&M_LOG10EValue, false);
VariableDefinePlatformVar(pc, NULL, "M_PI_2", &pc->FPType, (union AnyValue *)&M_PI_2Value, false); VariableDefinePlatformVar(pc, NULL, "M_LN2", &pc->FPType,
VariableDefinePlatformVar(pc, NULL, "M_PI_4", &pc->FPType, (union AnyValue *)&M_PI_4Value, false); (union AnyValue*)&M_LN2Value, false);
VariableDefinePlatformVar(pc, NULL, "M_1_PI", &pc->FPType, (union AnyValue *)&M_1_PIValue, false); VariableDefinePlatformVar(pc, NULL, "M_LN10", &pc->FPType,
VariableDefinePlatformVar(pc, NULL, "M_2_PI", &pc->FPType, (union AnyValue *)&M_2_PIValue, false); (union AnyValue*)&M_LN10Value, false);
VariableDefinePlatformVar(pc, NULL, "M_2_SQRTPI", &pc->FPType, (union AnyValue *)&M_2_SQRTPIValue, false); VariableDefinePlatformVar(pc, NULL, "M_PI", &pc->FPType,
VariableDefinePlatformVar(pc, NULL, "M_SQRT2", &pc->FPType, (union AnyValue *)&M_SQRT2Value, false); (union AnyValue*)&M_PIValue, false);
VariableDefinePlatformVar(pc, NULL, "M_SQRT1_2", &pc->FPType, (union AnyValue *)&M_SQRT1_2Value, false); VariableDefinePlatformVar(pc, NULL, "M_PI_2", &pc->FPType,
(union AnyValue*)&M_PI_2Value, false);
VariableDefinePlatformVar(pc, NULL, "M_PI_4", &pc->FPType,
(union AnyValue*)&M_PI_4Value, false);
VariableDefinePlatformVar(pc, NULL, "M_1_PI", &pc->FPType,
(union AnyValue*)&M_1_PIValue, false);
VariableDefinePlatformVar(pc, NULL, "M_2_PI", &pc->FPType,
(union AnyValue*)&M_2_PIValue, false);
VariableDefinePlatformVar(pc, NULL, "M_2_SQRTPI", &pc->FPType,
(union AnyValue*)&M_2_SQRTPIValue, false);
VariableDefinePlatformVar(pc, NULL, "M_SQRT2", &pc->FPType,
(union AnyValue*)&M_SQRT2Value, false);
VariableDefinePlatformVar(pc, NULL, "M_SQRT1_2", &pc->FPType,
(union AnyValue*)&M_SQRT1_2Value, false);
} }

View file

@ -13,7 +13,10 @@ const char StdboolDefs[] = "typedef int bool;";
void StdboolSetupFunc(Picoc *pc) void StdboolSetupFunc(Picoc *pc)
{ {
/* defines */ /* defines */
VariableDefinePlatformVar(pc, NULL, "true", &pc->IntType, (union AnyValue *)&trueValue, false); VariableDefinePlatformVar(pc, NULL, "true", &pc->IntType,
VariableDefinePlatformVar(pc, NULL, "false", &pc->IntType, (union AnyValue *)&falseValue, false); (union AnyValue*)&trueValue, false);
VariableDefinePlatformVar(pc, NULL, "__bool_true_false_are_defined", &pc->IntType, (union AnyValue *)&trueValue, false); VariableDefinePlatformVar(pc, NULL, "false", &pc->IntType,
(union AnyValue*)&falseValue, false);
VariableDefinePlatformVar(pc, NULL, "__bool_true_false_are_defined",
&pc->IntType, (union AnyValue*)&trueValue, false);
} }

View file

@ -94,15 +94,18 @@ void StdioOutPuts(const char *Str, StdOutStream *Stream)
} }
/* printf-style format of an int or other word-sized object */ /* printf-style format of an int or other word-sized object */
void StdioFprintfWord(StdOutStream *Stream, const char *Format, unsigned long Value) void StdioFprintfWord(StdOutStream *Stream, const char *Format,
unsigned long Value)
{ {
if (Stream->FilePtr != NULL) if (Stream->FilePtr != NULL)
Stream->CharCount += fprintf(Stream->FilePtr, Format, Value); Stream->CharCount += fprintf(Stream->FilePtr, Format, Value);
else if (Stream->StrOutLen >= 0) { else if (Stream->StrOutLen >= 0) {
#ifndef WIN32 #ifndef WIN32
int CCount = snprintf(Stream->StrOutPtr, Stream->StrOutLen, Format, Value); int CCount = snprintf(Stream->StrOutPtr, Stream->StrOutLen,
Format, Value);
#else #else
int CCount = _snprintf(Stream->StrOutPtr, Stream->StrOutLen, Format, Value); int CCount = _snprintf(Stream->StrOutPtr, Stream->StrOutLen,
Format, Value);
#endif #endif
Stream->StrOutPtr += CCount; Stream->StrOutPtr += CCount;
Stream->StrOutLen -= CCount; Stream->StrOutLen -= CCount;
@ -121,9 +124,11 @@ void StdioFprintfFP(StdOutStream *Stream, const char *Format, double Value)
Stream->CharCount += fprintf(Stream->FilePtr, Format, Value); Stream->CharCount += fprintf(Stream->FilePtr, Format, Value);
else if (Stream->StrOutLen >= 0) { else if (Stream->StrOutLen >= 0) {
#ifndef WIN32 #ifndef WIN32
int CCount = snprintf(Stream->StrOutPtr, Stream->StrOutLen, Format, Value); int CCount = snprintf(Stream->StrOutPtr, Stream->StrOutLen,
Format, Value);
#else #else
int CCount = _snprintf(Stream->StrOutPtr, Stream->StrOutLen, Format, Value); int CCount = _snprintf(Stream->StrOutPtr, Stream->StrOutLen,
Format, Value);
#endif #endif
Stream->StrOutPtr += CCount; Stream->StrOutPtr += CCount;
Stream->StrOutLen -= CCount; Stream->StrOutLen -= CCount;
@ -142,9 +147,11 @@ void StdioFprintfPointer(StdOutStream *Stream, const char *Format, void *Value)
Stream->CharCount += fprintf(Stream->FilePtr, Format, Value); Stream->CharCount += fprintf(Stream->FilePtr, Format, Value);
else if (Stream->StrOutLen >= 0) { else if (Stream->StrOutLen >= 0) {
#ifndef WIN32 #ifndef WIN32
int CCount = snprintf(Stream->StrOutPtr, Stream->StrOutLen, Format, Value); int CCount = snprintf(Stream->StrOutPtr, Stream->StrOutLen,
Format, Value);
#else #else
int CCount = _snprintf(Stream->StrOutPtr, Stream->StrOutLen, Format, Value); int CCount = _snprintf(Stream->StrOutPtr, Stream->StrOutLen,
Format, Value);
#endif #endif
Stream->StrOutPtr += CCount; Stream->StrOutPtr += CCount;
Stream->StrOutLen -= CCount; Stream->StrOutLen -= CCount;
@ -157,7 +164,8 @@ void StdioFprintfPointer(StdOutStream *Stream, const char *Format, void *Value)
} }
/* internal do-anything v[s][n]printf() formatting system with output to strings or FILE * */ /* internal do-anything v[s][n]printf() formatting system with output to strings or FILE * */
int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, int StrOutLen, char *Format, struct StdVararg *Args) int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut,
int StrOutLen, char *Format, struct StdVararg *Args)
{ {
struct Value *ThisArg = Args->Param[0]; struct Value *ThisArg = Args->Param[0];
int ArgCount = 0; int ArgCount = 0;
@ -187,19 +195,53 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, int S
do { do {
switch (*FPos) { switch (*FPos) {
case 'd': case 'i': ShowType = &pc->IntType; break; /* integer decimal */ case 'd':
case 'o': case 'u': case 'x': case 'X': ShowType = &pc->IntType; break; /* integer base conversions */ case 'i':
case 'e': case 'E': ShowType = &pc->FPType; break; /* double, exponent form */ ShowType = &pc->IntType;
case 'f': case 'F': ShowType = &pc->FPType; break; /* double, fixed-point */ break; /* integer decimal */
case 'g': case 'G': ShowType = &pc->FPType; break; /* double, flexible format */ case 'o':
case 'a': case 'A': ShowType = &pc->IntType; break; /* hexadecimal, 0x- format */ case 'u':
case 'c': ShowType = &pc->IntType; break; /* character */ case 'x':
case 's': ShowType = pc->CharPtrType; break; /* string */ case 'X':
case 'p': ShowType = pc->VoidPtrType; break; /* pointer */ ShowType = &pc->IntType;
case 'n': ShowType = &pc->VoidType; break; /* number of characters written */ break; /* integer base conversions */
case 'm': ShowType = &pc->VoidType; break; /* strerror(errno) */ case 'e':
case '%': ShowType = &pc->VoidType; break; /* just a '%' character */ case 'E':
case '\0': ShowType = &pc->VoidType; break; /* end of format string */ ShowType = &pc->FPType;
break; /* double, exponent form */
case 'f':
case 'F':
ShowType = &pc->FPType;
break; /* double, fixed-point */
case 'g':
case 'G':
ShowType = &pc->FPType;
break; /* double, flexible format */
case 'a':
case 'A':
ShowType = &pc->IntType;
break; /* hexadecimal, 0x- format */
case 'c':
ShowType = &pc->IntType;
break; /* character */
case 's':
ShowType = pc->CharPtrType;
break; /* string */
case 'p':
ShowType = pc->VoidPtrType;
break; /* pointer */
case 'n':
ShowType = &pc->VoidType;
break; /* number of characters written */
case 'm':
ShowType = &pc->VoidType;
break; /* strerror(errno) */
case '%':
ShowType = &pc->VoidType;
break; /* just a '%' character */
case '\0':
ShowType = &pc->VoidType;
break; /* end of format string */
} }
/* copy one character of format across to the OneFormatBuf */ /* copy one character of format across to the OneFormatBuf */
@ -209,11 +251,18 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, int S
/* do special actions depending on the conversion type */ /* do special actions depending on the conversion type */
if (ShowType == &pc->VoidType) { if (ShowType == &pc->VoidType) {
switch (*FPos) { switch (*FPos) {
case 'm': StdioOutPuts(strerror(errno), &SOStream); break; case 'm':
case '%': StdioOutPutc(*FPos, &SOStream); break; StdioOutPuts(strerror(errno), &SOStream);
case '\0': OneFormatBuf[OneFormatCount] = '\0'; StdioOutPutc(*FPos, &SOStream); break; break;
case '%':
StdioOutPutc(*FPos, &SOStream);
break;
case '\0':
OneFormatBuf[OneFormatCount] = '\0';
StdioOutPutc(*FPos, &SOStream);
break;
case 'n': case 'n':
ThisArg = (struct Value *)((char *)ThisArg + MEM_ALIGN(sizeof(struct Value) + TypeStackSizeValue(ThisArg))); ThisArg = (struct Value*)((char*)ThisArg+MEM_ALIGN(sizeof(struct Value)+TypeStackSizeValue(ThisArg)));
if (ThisArg->Typ->Base == TypeArray && ThisArg->Typ->FromType->Base == TypeInt) if (ThisArg->Typ->Base == TypeArray && ThisArg->Typ->FromType->Base == TypeInt)
*(int *)ThisArg->Val->Pointer = SOStream.CharCount; *(int *)ThisArg->Val->Pointer = SOStream.CharCount;
break; break;
@ -232,31 +281,37 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, int S
OneFormatBuf[OneFormatCount] = '\0'; OneFormatBuf[OneFormatCount] = '\0';
/* print this argument */ /* print this argument */
ThisArg = (struct Value *)((char *)ThisArg + MEM_ALIGN(sizeof(struct Value) + TypeStackSizeValue(ThisArg))); ThisArg = (struct Value*)((char*)ThisArg+MEM_ALIGN(sizeof(struct Value)+TypeStackSizeValue(ThisArg)));
if (ShowType == &pc->IntType) { if (ShowType == &pc->IntType) {
/* show a signed integer */ /* show a signed integer */
if (IS_NUMERIC_COERCIBLE(ThisArg)) if (IS_NUMERIC_COERCIBLE(ThisArg))
StdioFprintfWord(&SOStream, OneFormatBuf, ExpressionCoerceUnsignedInteger(ThisArg)); StdioFprintfWord(&SOStream, OneFormatBuf,
ExpressionCoerceUnsignedInteger(ThisArg));
else else
StdioOutPuts("XXX", &SOStream); StdioOutPuts("XXX", &SOStream);
} else if (ShowType == &pc->FPType) { } else if (ShowType == &pc->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 == pc->CharPtrType) { } else if (ShowType == pc->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 && ThisArg->Typ->FromType->Base == TypeChar) else if (ThisArg->Typ->Base == TypeArray && ThisArg->Typ->FromType->Base == TypeChar)
StdioFprintfPointer(&SOStream, OneFormatBuf, &ThisArg->Val->ArrayMem[0]); StdioFprintfPointer(&SOStream, OneFormatBuf,
&ThisArg->Val->ArrayMem[0]);
else else
StdioOutPuts("XXX", &SOStream); StdioOutPuts("XXX", &SOStream);
} else if (ShowType == pc->VoidPtrType) { } else if (ShowType == pc->VoidPtrType) {
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)
StdioFprintfPointer(&SOStream, OneFormatBuf, &ThisArg->Val->ArrayMem[0]); StdioFprintfPointer(&SOStream, OneFormatBuf,
&ThisArg->Val->ArrayMem[0]);
else else
StdioOutPuts("XXX", &SOStream); StdioOutPuts("XXX", &SOStream);
} }
@ -279,104 +334,133 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, int S
} }
/* internal do-anything v[s][n]scanf() formatting system with input from strings or FILE * */ /* internal do-anything v[s][n]scanf() formatting system with input from strings or FILE * */
int StdioBaseScanf(struct ParseState *Parser, FILE *Stream, char *StrIn, char *Format, struct StdVararg *Args) int StdioBaseScanf(struct ParseState *Parser, FILE *Stream, char *StrIn,
char *Format, struct StdVararg *Args)
{ {
struct Value *ThisArg = Args->Param[0]; struct Value *ThisArg = Args->Param[0];
int ArgCount = 0; int ArgCount = 0;
void *ScanfArg[MAX_SCANF_ARGS]; void *ScanfArg[MAX_SCANF_ARGS];
if (Args->NumArgs > MAX_SCANF_ARGS) if (Args->NumArgs > MAX_SCANF_ARGS)
ProgramFail(Parser, "too many arguments to scanf() - %d max", MAX_SCANF_ARGS); ProgramFail(Parser, "too many arguments to scanf() - %d max",
MAX_SCANF_ARGS);
for (ArgCount = 0; ArgCount < Args->NumArgs; ArgCount++) { for (ArgCount = 0; ArgCount < Args->NumArgs; ArgCount++) {
ThisArg = (struct Value *)((char *)ThisArg + MEM_ALIGN(sizeof(struct Value) + TypeStackSizeValue(ThisArg))); ThisArg = (struct Value*)((char*)ThisArg+MEM_ALIGN(sizeof(struct Value)+TypeStackSizeValue(ThisArg)));
if (ThisArg->Typ->Base == TypePointer) if (ThisArg->Typ->Base == TypePointer)
ScanfArg[ArgCount] = ThisArg->Val->Pointer; ScanfArg[ArgCount] = ThisArg->Val->Pointer;
else if (ThisArg->Typ->Base == TypeArray) else if (ThisArg->Typ->Base == TypeArray)
ScanfArg[ArgCount] = &ThisArg->Val->ArrayMem[0]; ScanfArg[ArgCount] = &ThisArg->Val->ArrayMem[0];
else else
ProgramFail(Parser, "non-pointer argument to scanf() - argument %d after format", ArgCount+1); ProgramFail(Parser,
"non-pointer argument to scanf() - argument %d after format",
ArgCount+1);
} }
if (Stream != NULL) if (Stream != NULL)
return fscanf(Stream, Format, ScanfArg[0], ScanfArg[1], ScanfArg[2], ScanfArg[3], ScanfArg[4], ScanfArg[5], ScanfArg[6], ScanfArg[7], ScanfArg[8], ScanfArg[9]); return fscanf(Stream, Format, ScanfArg[0], ScanfArg[1], ScanfArg[2],
ScanfArg[3], ScanfArg[4], ScanfArg[5], ScanfArg[6], ScanfArg[7],
ScanfArg[8], ScanfArg[9]);
else else
return sscanf(StrIn, Format, ScanfArg[0], ScanfArg[1], ScanfArg[2], ScanfArg[3], ScanfArg[4], ScanfArg[5], ScanfArg[6], ScanfArg[7], ScanfArg[8], ScanfArg[9]); return sscanf(StrIn, Format, ScanfArg[0], ScanfArg[1], ScanfArg[2],
ScanfArg[3], ScanfArg[4], ScanfArg[5], ScanfArg[6], ScanfArg[7],
ScanfArg[8], ScanfArg[9]);
} }
/* stdio calls */ /* stdio calls */
void StdioFopen(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioFopen(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = fopen(Param[0]->Val->Pointer, Param[1]->Val->Pointer); ReturnValue->Val->Pointer = fopen(Param[0]->Val->Pointer,
Param[1]->Val->Pointer);
} }
void StdioFreopen(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioFreopen(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = freopen(Param[0]->Val->Pointer, Param[1]->Val->Pointer, Param[2]->Val->Pointer); ReturnValue->Val->Pointer = freopen(Param[0]->Val->Pointer,
Param[1]->Val->Pointer, Param[2]->Val->Pointer);
} }
void StdioFclose(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioFclose(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = fclose(Param[0]->Val->Pointer); ReturnValue->Val->Integer = fclose(Param[0]->Val->Pointer);
} }
void StdioFread(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioFread(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = fread(Param[0]->Val->Pointer, Param[1]->Val->Integer, Param[2]->Val->Integer, Param[3]->Val->Pointer); ReturnValue->Val->Integer = fread(Param[0]->Val->Pointer,
Param[1]->Val->Integer, Param[2]->Val->Integer, Param[3]->Val->Pointer);
} }
void StdioFwrite(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioFwrite(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = fwrite(Param[0]->Val->Pointer, Param[1]->Val->Integer, Param[2]->Val->Integer, Param[3]->Val->Pointer); ReturnValue->Val->Integer = fwrite(Param[0]->Val->Pointer,
Param[1]->Val->Integer, Param[2]->Val->Integer, Param[3]->Val->Pointer);
} }
void StdioFgetc(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioFgetc(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = fgetc(Param[0]->Val->Pointer); ReturnValue->Val->Integer = fgetc(Param[0]->Val->Pointer);
} }
void StdioFgets(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioFgets(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = fgets(Param[0]->Val->Pointer, Param[1]->Val->Integer, Param[2]->Val->Pointer); ReturnValue->Val->Pointer = fgets(Param[0]->Val->Pointer,
Param[1]->Val->Integer, Param[2]->Val->Pointer);
} }
void StdioRemove(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioRemove(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = remove(Param[0]->Val->Pointer); ReturnValue->Val->Integer = remove(Param[0]->Val->Pointer);
} }
void StdioRename(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioRename(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = rename(Param[0]->Val->Pointer, Param[1]->Val->Pointer); ReturnValue->Val->Integer = rename(Param[0]->Val->Pointer,
Param[1]->Val->Pointer);
} }
void StdioRewind(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioRewind(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
rewind(Param[0]->Val->Pointer); rewind(Param[0]->Val->Pointer);
} }
void StdioTmpfile(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioTmpfile(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = tmpfile(); ReturnValue->Val->Pointer = tmpfile();
} }
void StdioClearerr(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioClearerr(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
clearerr((FILE *)Param[0]->Val->Pointer); clearerr((FILE *)Param[0]->Val->Pointer);
} }
void StdioFeof(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioFeof(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = feof((FILE *)Param[0]->Val->Pointer); ReturnValue->Val->Integer = feof((FILE *)Param[0]->Val->Pointer);
} }
void StdioFerror(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioFerror(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = ferror((FILE *)Param[0]->Val->Pointer); ReturnValue->Val->Integer = ferror((FILE *)Param[0]->Val->Pointer);
} }
void StdioFileno(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioFileno(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
#ifndef WIN32 #ifndef WIN32
ReturnValue->Val->Integer = fileno(Param[0]->Val->Pointer); ReturnValue->Val->Integer = fileno(Param[0]->Val->Pointer);
@ -385,79 +469,99 @@ void StdioFileno(struct ParseState *Parser, struct Value *ReturnValue, struct Va
#endif #endif
} }
void StdioFflush(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioFflush(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = fflush(Param[0]->Val->Pointer); ReturnValue->Val->Integer = fflush(Param[0]->Val->Pointer);
} }
void StdioFgetpos(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioFgetpos(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = fgetpos(Param[0]->Val->Pointer, Param[1]->Val->Pointer); ReturnValue->Val->Integer = fgetpos(Param[0]->Val->Pointer, Param[1]->Val->Pointer);
} }
void StdioFsetpos(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioFsetpos(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = fsetpos(Param[0]->Val->Pointer, Param[1]->Val->Pointer); ReturnValue->Val->Integer = fsetpos(Param[0]->Val->Pointer, Param[1]->Val->Pointer);
} }
void StdioFputc(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioFputc(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = fputc(Param[0]->Val->Integer, Param[1]->Val->Pointer); ReturnValue->Val->Integer = fputc(Param[0]->Val->Integer, Param[1]->Val->Pointer);
} }
void StdioFputs(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioFputs(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = fputs(Param[0]->Val->Pointer, Param[1]->Val->Pointer); ReturnValue->Val->Integer = fputs(Param[0]->Val->Pointer, Param[1]->Val->Pointer);
} }
void StdioFtell(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioFtell(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = ftell(Param[0]->Val->Pointer); ReturnValue->Val->Integer = ftell(Param[0]->Val->Pointer);
} }
void StdioFseek(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioFseek(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = fseek(Param[0]->Val->Pointer, Param[1]->Val->Integer, Param[2]->Val->Integer); ReturnValue->Val->Integer = fseek(Param[0]->Val->Pointer,
Param[1]->Val->Integer, Param[2]->Val->Integer);
} }
void StdioPerror(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioPerror(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
perror(Param[0]->Val->Pointer); perror(Param[0]->Val->Pointer);
} }
void StdioPutc(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioPutc(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = putc(Param[0]->Val->Integer, Param[1]->Val->Pointer); ReturnValue->Val->Integer = putc(Param[0]->Val->Integer,
Param[1]->Val->Pointer);
} }
void StdioPutchar(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioPutchar(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = putchar(Param[0]->Val->Integer); ReturnValue->Val->Integer = putchar(Param[0]->Val->Integer);
} }
void StdioSetbuf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioSetbuf(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
setbuf(Param[0]->Val->Pointer, Param[1]->Val->Pointer); setbuf(Param[0]->Val->Pointer, Param[1]->Val->Pointer);
} }
void StdioSetvbuf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioSetvbuf(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
setvbuf(Param[0]->Val->Pointer, Param[1]->Val->Pointer, Param[2]->Val->Integer, Param[3]->Val->Integer); setvbuf(Param[0]->Val->Pointer, Param[1]->Val->Pointer,
Param[2]->Val->Integer, Param[3]->Val->Integer);
} }
void StdioUngetc(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioUngetc(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = ungetc(Param[0]->Val->Integer, Param[1]->Val->Pointer); ReturnValue->Val->Integer = ungetc(Param[0]->Val->Integer,
Param[1]->Val->Pointer);
} }
void StdioPuts(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioPuts(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = puts(Param[0]->Val->Pointer); ReturnValue->Val->Integer = puts(Param[0]->Val->Pointer);
} }
void StdioGets(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioGets(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = fgets(Param[0]->Val->Pointer, GETS_MAXValue, stdin); ReturnValue->Val->Pointer = fgets(Param[0]->Val->Pointer,
GETS_MAXValue, stdin);
if (ReturnValue->Val->Pointer != NULL) { if (ReturnValue->Val->Pointer != NULL) {
char *EOLPos = strchr(Param[0]->Val->Pointer, '\n'); char *EOLPos = strchr(Param[0]->Val->Pointer, '\n');
if (EOLPos != NULL) if (EOLPos != NULL)
@ -465,107 +569,136 @@ void StdioGets(struct ParseState *Parser, struct Value *ReturnValue, struct Valu
} }
} }
void StdioGetchar(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioGetchar(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = getchar(); ReturnValue->Val->Integer = getchar();
} }
void StdioPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioPrintf(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
struct StdVararg PrintfArgs; struct StdVararg PrintfArgs;
PrintfArgs.Param = Param; PrintfArgs.Param = Param;
PrintfArgs.NumArgs = NumArgs-1; PrintfArgs.NumArgs = NumArgs-1;
ReturnValue->Val->Integer = StdioBasePrintf(Parser, stdout, NULL, 0, Param[0]->Val->Pointer, &PrintfArgs); ReturnValue->Val->Integer = StdioBasePrintf(Parser, stdout, NULL, 0,
Param[0]->Val->Pointer, &PrintfArgs);
} }
void StdioVprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioVprintf(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = StdioBasePrintf(Parser, stdout, NULL, 0, Param[0]->Val->Pointer, Param[1]->Val->Pointer); ReturnValue->Val->Integer = StdioBasePrintf(Parser, stdout, NULL, 0,
Param[0]->Val->Pointer, Param[1]->Val->Pointer);
} }
void StdioFprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioFprintf(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
struct StdVararg PrintfArgs; struct StdVararg PrintfArgs;
PrintfArgs.Param = Param + 1; PrintfArgs.Param = Param + 1;
PrintfArgs.NumArgs = NumArgs-2; PrintfArgs.NumArgs = NumArgs-2;
ReturnValue->Val->Integer = StdioBasePrintf(Parser, Param[0]->Val->Pointer, NULL, 0, Param[1]->Val->Pointer, &PrintfArgs); ReturnValue->Val->Integer = StdioBasePrintf(Parser, Param[0]->Val->Pointer,
NULL, 0, Param[1]->Val->Pointer, &PrintfArgs);
} }
void StdioVfprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioVfprintf(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = StdioBasePrintf(Parser, Param[0]->Val->Pointer, NULL, 0, Param[1]->Val->Pointer, Param[2]->Val->Pointer); ReturnValue->Val->Integer = StdioBasePrintf(Parser, Param[0]->Val->Pointer,
NULL, 0, Param[1]->Val->Pointer, Param[2]->Val->Pointer);
} }
void StdioSprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioSprintf(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
struct StdVararg PrintfArgs; struct StdVararg PrintfArgs;
PrintfArgs.Param = Param + 1; PrintfArgs.Param = Param + 1;
PrintfArgs.NumArgs = NumArgs-2; PrintfArgs.NumArgs = NumArgs-2;
ReturnValue->Val->Integer = StdioBasePrintf(Parser, NULL, Param[0]->Val->Pointer, -1, Param[1]->Val->Pointer, &PrintfArgs); ReturnValue->Val->Integer = StdioBasePrintf(Parser, NULL,
Param[0]->Val->Pointer, -1, Param[1]->Val->Pointer, &PrintfArgs);
} }
void StdioSnprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioSnprintf(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
struct StdVararg PrintfArgs; struct StdVararg PrintfArgs;
PrintfArgs.Param = Param+2; PrintfArgs.Param = Param+2;
PrintfArgs.NumArgs = NumArgs-3; PrintfArgs.NumArgs = NumArgs-3;
ReturnValue->Val->Integer = StdioBasePrintf(Parser, NULL, Param[0]->Val->Pointer, Param[1]->Val->Integer, Param[2]->Val->Pointer, &PrintfArgs); ReturnValue->Val->Integer = StdioBasePrintf(Parser, NULL,
Param[0]->Val->Pointer, Param[1]->Val->Integer, Param[2]->Val->Pointer, &PrintfArgs);
} }
void StdioScanf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioScanf(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
struct StdVararg ScanfArgs; struct StdVararg ScanfArgs;
ScanfArgs.Param = Param; ScanfArgs.Param = Param;
ScanfArgs.NumArgs = NumArgs-1; ScanfArgs.NumArgs = NumArgs-1;
ReturnValue->Val->Integer = StdioBaseScanf(Parser, stdin, NULL, Param[0]->Val->Pointer, &ScanfArgs); ReturnValue->Val->Integer = StdioBaseScanf(Parser, stdin, NULL,
Param[0]->Val->Pointer, &ScanfArgs);
} }
void StdioFscanf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioFscanf(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
struct StdVararg ScanfArgs; struct StdVararg ScanfArgs;
ScanfArgs.Param = Param+1; ScanfArgs.Param = Param+1;
ScanfArgs.NumArgs = NumArgs-2; ScanfArgs.NumArgs = NumArgs-2;
ReturnValue->Val->Integer = StdioBaseScanf(Parser, Param[0]->Val->Pointer, NULL, Param[1]->Val->Pointer, &ScanfArgs); ReturnValue->Val->Integer = StdioBaseScanf(Parser, Param[0]->Val->Pointer,
NULL, Param[1]->Val->Pointer, &ScanfArgs);
} }
void StdioSscanf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioSscanf(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
struct StdVararg ScanfArgs; struct StdVararg ScanfArgs;
ScanfArgs.Param = Param+1; ScanfArgs.Param = Param+1;
ScanfArgs.NumArgs = NumArgs-2; ScanfArgs.NumArgs = NumArgs-2;
ReturnValue->Val->Integer = StdioBaseScanf(Parser, NULL, Param[0]->Val->Pointer, Param[1]->Val->Pointer, &ScanfArgs); ReturnValue->Val->Integer = StdioBaseScanf(Parser, NULL,
Param[0]->Val->Pointer, Param[1]->Val->Pointer, &ScanfArgs);
} }
void StdioVsprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioVsprintf(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = StdioBasePrintf(Parser, NULL, Param[0]->Val->Pointer, -1, Param[1]->Val->Pointer, Param[2]->Val->Pointer); ReturnValue->Val->Integer = StdioBasePrintf(Parser, NULL,
Param[0]->Val->Pointer, -1, Param[1]->Val->Pointer, Param[2]->Val->Pointer);
} }
void StdioVsnprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioVsnprintf(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = StdioBasePrintf(Parser, NULL, Param[0]->Val->Pointer, Param[1]->Val->Integer, Param[2]->Val->Pointer, Param[3]->Val->Pointer); ReturnValue->Val->Integer = StdioBasePrintf(Parser, NULL,
Param[0]->Val->Pointer, Param[1]->Val->Integer, Param[2]->Val->Pointer, Param[3]->Val->Pointer);
} }
void StdioVscanf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioVscanf(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = StdioBaseScanf(Parser, stdin, NULL, Param[0]->Val->Pointer, Param[1]->Val->Pointer); ReturnValue->Val->Integer = StdioBaseScanf(Parser, stdin, NULL,
Param[0]->Val->Pointer, Param[1]->Val->Pointer);
} }
void StdioVfscanf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioVfscanf(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = StdioBaseScanf(Parser, Param[0]->Val->Pointer, NULL, Param[1]->Val->Pointer, Param[2]->Val->Pointer); ReturnValue->Val->Integer = StdioBaseScanf(Parser, Param[0]->Val->Pointer,
NULL, Param[1]->Val->Pointer, Param[2]->Val->Pointer);
} }
void StdioVsscanf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdioVsscanf(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = StdioBaseScanf(Parser, NULL, Param[0]->Val->Pointer, Param[1]->Val->Pointer, Param[2]->Val->Pointer); ReturnValue->Val->Integer = StdioBaseScanf(Parser, NULL,
Param[0]->Val->Pointer, Param[1]->Val->Pointer, Param[2]->Val->Pointer);
} }
/* handy structure definitions */ /* handy structure definitions */
@ -634,35 +767,53 @@ void StdioSetupFunc(Picoc *pc)
struct ValueType *FilePtrType; struct ValueType *FilePtrType;
/* make a "struct __FILEStruct" which is the same size as a native FILE structure */ /* make a "struct __FILEStruct" which is the same size as a native FILE structure */
StructFileType = TypeCreateOpaqueStruct(pc, NULL, TableStrRegister(pc, "__FILEStruct"), sizeof(FILE)); StructFileType = TypeCreateOpaqueStruct(pc, NULL,
TableStrRegister(pc, "__FILEStruct"), sizeof(FILE));
/* get a FILE * type */ /* get a FILE * type */
FilePtrType = TypeGetMatching(pc, NULL, StructFileType, TypePointer, 0, pc->StrEmpty, true); FilePtrType = TypeGetMatching(pc, NULL, StructFileType, TypePointer, 0,
pc->StrEmpty, true);
/* make a "struct __va_listStruct" which is the same size as our struct StdVararg */ /* make a "struct __va_listStruct" which is the same size as our struct StdVararg */
TypeCreateOpaqueStruct(pc, NULL, TableStrRegister(pc, "__va_listStruct"), sizeof(FILE)); TypeCreateOpaqueStruct(pc, NULL, TableStrRegister(pc, "__va_listStruct"),
sizeof(FILE));
/* define EOF equal to the system EOF */ /* define EOF equal to the system EOF */
VariableDefinePlatformVar(pc, NULL, "EOF", &pc->IntType, (union AnyValue *)&EOFValue, false); VariableDefinePlatformVar(pc, NULL, "EOF", &pc->IntType,
VariableDefinePlatformVar(pc, NULL, "SEEK_SET", &pc->IntType, (union AnyValue *)&SEEK_SETValue, false); (union AnyValue*)&EOFValue, false);
VariableDefinePlatformVar(pc, NULL, "SEEK_CUR", &pc->IntType, (union AnyValue *)&SEEK_CURValue, false); VariableDefinePlatformVar(pc, NULL, "SEEK_SET", &pc->IntType,
VariableDefinePlatformVar(pc, NULL, "SEEK_END", &pc->IntType, (union AnyValue *)&SEEK_ENDValue, false); (union AnyValue*)&SEEK_SETValue, false);
VariableDefinePlatformVar(pc, NULL, "BUFSIZ", &pc->IntType, (union AnyValue *)&BUFSIZValue, false); VariableDefinePlatformVar(pc, NULL, "SEEK_CUR", &pc->IntType,
VariableDefinePlatformVar(pc, NULL, "FILENAME_MAX", &pc->IntType, (union AnyValue *)&FILENAME_MAXValue, false); (union AnyValue*)&SEEK_CURValue, false);
VariableDefinePlatformVar(pc, NULL, "_IOFBF", &pc->IntType, (union AnyValue *)&_IOFBFValue, false); VariableDefinePlatformVar(pc, NULL, "SEEK_END", &pc->IntType,
VariableDefinePlatformVar(pc, NULL, "_IOLBF", &pc->IntType, (union AnyValue *)&_IOLBFValue, false); (union AnyValue*)&SEEK_ENDValue, false);
VariableDefinePlatformVar(pc, NULL, "_IONBF", &pc->IntType, (union AnyValue *)&_IONBFValue, false); VariableDefinePlatformVar(pc, NULL, "BUFSIZ", &pc->IntType,
VariableDefinePlatformVar(pc, NULL, "L_tmpnam", &pc->IntType, (union AnyValue *)&L_tmpnamValue, false); (union AnyValue*)&BUFSIZValue, false);
VariableDefinePlatformVar(pc, NULL, "GETS_MAX", &pc->IntType, (union AnyValue *)&GETS_MAXValue, false); VariableDefinePlatformVar(pc, NULL, "FILENAME_MAX", &pc->IntType,
(union AnyValue*)&FILENAME_MAXValue, false);
VariableDefinePlatformVar(pc, NULL, "_IOFBF", &pc->IntType,
(union AnyValue*)&_IOFBFValue, false);
VariableDefinePlatformVar(pc, NULL, "_IOLBF", &pc->IntType,
(union AnyValue*)&_IOLBFValue, false);
VariableDefinePlatformVar(pc, NULL, "_IONBF", &pc->IntType,
(union AnyValue*)&_IONBFValue, false);
VariableDefinePlatformVar(pc, NULL, "L_tmpnam", &pc->IntType,
(union AnyValue*)&L_tmpnamValue, false);
VariableDefinePlatformVar(pc, NULL, "GETS_MAX", &pc->IntType,
(union AnyValue*)&GETS_MAXValue, false);
/* define stdin, stdout and stderr */ /* define stdin, stdout and stderr */
VariableDefinePlatformVar(pc, NULL, "stdin", FilePtrType, (union AnyValue *)&stdinValue, false); VariableDefinePlatformVar(pc, NULL, "stdin", FilePtrType,
VariableDefinePlatformVar(pc, NULL, "stdout", FilePtrType, (union AnyValue *)&stdoutValue, false); (union AnyValue*)&stdinValue, false);
VariableDefinePlatformVar(pc, NULL, "stderr", FilePtrType, (union AnyValue *)&stderrValue, false); VariableDefinePlatformVar(pc, NULL, "stdout", FilePtrType,
(union AnyValue*)&stdoutValue, false);
VariableDefinePlatformVar(pc, NULL, "stderr", FilePtrType,
(union AnyValue*)&stderrValue, false);
/* define NULL, true and false */ /* define NULL, true and false */
if (!VariableDefined(pc, TableStrRegister(pc, "NULL"))) if (!VariableDefined(pc, TableStrRegister(pc, "NULL")))
VariableDefinePlatformVar(pc, NULL, "NULL", &pc->IntType, (union AnyValue *)&Stdio_ZeroValue, false); VariableDefinePlatformVar(pc, NULL, "NULL", &pc->IntType,
(union AnyValue*)&Stdio_ZeroValue, false);
} }
/* portability-related I/O calls */ /* portability-related I/O calls */

View file

@ -5,112 +5,140 @@
static int Stdlib_ZeroValue = 0; static int Stdlib_ZeroValue = 0;
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);
} }
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);
} }
void StdlibAtol(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdlibAtol(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = atol(Param[0]->Val->Pointer); ReturnValue->Val->Integer = atol(Param[0]->Val->Pointer);
} }
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);
} }
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);
} }
void StdlibStrtoul(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdlibStrtoul(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = strtoul(Param[0]->Val->Pointer, Param[1]->Val->Pointer, Param[2]->Val->Integer); ReturnValue->Val->Integer = strtoul(Param[0]->Val->Pointer,
Param[1]->Val->Pointer, Param[2]->Val->Integer);
} }
void StdlibMalloc(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdlibMalloc(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = malloc(Param[0]->Val->Integer); ReturnValue->Val->Pointer = malloc(Param[0]->Val->Integer);
} }
void StdlibCalloc(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdlibCalloc(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = calloc(Param[0]->Val->Integer, Param[1]->Val->Integer); ReturnValue->Val->Pointer = calloc(Param[0]->Val->Integer,
Param[1]->Val->Integer);
} }
void StdlibRealloc(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdlibRealloc(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = realloc(Param[0]->Val->Pointer, Param[1]->Val->Integer); ReturnValue->Val->Pointer = realloc(Param[0]->Val->Pointer,
Param[1]->Val->Integer);
} }
void StdlibFree(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdlibFree(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
free(Param[0]->Val->Pointer); free(Param[0]->Val->Pointer);
} }
void StdlibRand(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdlibRand(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = rand(); ReturnValue->Val->Integer = rand();
} }
void StdlibSrand(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdlibSrand(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
srand(Param[0]->Val->Integer); srand(Param[0]->Val->Integer);
} }
void StdlibAbort(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdlibAbort(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ProgramFail(Parser, "abort"); ProgramFail(Parser, "abort");
} }
void StdlibExit(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdlibExit(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
PlatformExit(Parser->pc, Param[0]->Val->Integer); PlatformExit(Parser->pc, Param[0]->Val->Integer);
} }
void StdlibGetenv(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdlibGetenv(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = getenv(Param[0]->Val->Pointer); ReturnValue->Val->Pointer = getenv(Param[0]->Val->Pointer);
} }
void StdlibSystem(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdlibSystem(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = system(Param[0]->Val->Pointer); ReturnValue->Val->Integer = system(Param[0]->Val->Pointer);
} }
#if 0 #if 0
void StdlibBsearch(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdlibBsearch(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = bsearch(Param[0]->Val->Pointer, Param[1]->Val->Pointer, Param[2]->Val->Integer, Param[3]->Val->Integer, (int (*)())Param[4]->Val->Pointer); ReturnValue->Val->Pointer = bsearch(Param[0]->Val->Pointer,
Param[1]->Val->Pointer, Param[2]->Val->Integer, Param[3]->Val->Integer, (int (*)())Param[4]->Val->Pointer);
} }
#endif #endif
void StdlibAbs(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdlibAbs(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = abs(Param[0]->Val->Integer); ReturnValue->Val->Integer = abs(Param[0]->Val->Integer);
} }
void StdlibLabs(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdlibLabs(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = labs(Param[0]->Val->Integer); ReturnValue->Val->Integer = labs(Param[0]->Val->Integer);
} }
#if 0 #if 0
void StdlibDiv(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdlibDiv(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = div(Param[0]->Val->Integer, Param[1]->Val->Integer); ReturnValue->Val->Integer = div(Param[0]->Val->Integer,
Param[1]->Val->Integer);
} }
void StdlibLdiv(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdlibLdiv(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = ldiv(Param[0]->Val->Integer, Param[1]->Val->Integer); ReturnValue->Val->Integer = ldiv(Param[0]->Val->Integer,
Param[1]->Val->Integer);
} }
#endif #endif
@ -162,6 +190,7 @@ void StdlibSetupFunc(Picoc *pc)
{ {
/* define NULL, TRUE and FALSE */ /* define NULL, TRUE and FALSE */
if (!VariableDefined(pc, TableStrRegister(pc, "NULL"))) if (!VariableDefined(pc, TableStrRegister(pc, "NULL")))
VariableDefinePlatformVar(pc, NULL, "NULL", &pc->IntType, (union AnyValue *)&Stdlib_ZeroValue, false); VariableDefinePlatformVar(pc, NULL, "NULL", &pc->IntType,
(union AnyValue*)&Stdlib_ZeroValue, false);
} }

View file

@ -4,137 +4,186 @@
static int String_ZeroValue = 0; static int String_ZeroValue = 0;
void StringStrcpy(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringStrcpy(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = strcpy(Param[0]->Val->Pointer, Param[1]->Val->Pointer); ReturnValue->Val->Pointer = strcpy(Param[0]->Val->Pointer,
Param[1]->Val->Pointer);
} }
void StringStrncpy(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringStrncpy(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = strncpy(Param[0]->Val->Pointer, Param[1]->Val->Pointer, Param[2]->Val->Integer); ReturnValue->Val->Pointer = strncpy(Param[0]->Val->Pointer,
Param[1]->Val->Pointer, Param[2]->Val->Integer);
} }
void StringStrcmp(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringStrcmp(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = strcmp(Param[0]->Val->Pointer, Param[1]->Val->Pointer); ReturnValue->Val->Integer = strcmp(Param[0]->Val->Pointer,
Param[1]->Val->Pointer);
} }
void StringStrncmp(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringStrncmp(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = strncmp(Param[0]->Val->Pointer, Param[1]->Val->Pointer, Param[2]->Val->Integer); ReturnValue->Val->Integer = strncmp(Param[0]->Val->Pointer,
Param[1]->Val->Pointer, Param[2]->Val->Integer);
} }
void StringStrcat(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringStrcat(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = strcat(Param[0]->Val->Pointer, Param[1]->Val->Pointer); ReturnValue->Val->Pointer = strcat(Param[0]->Val->Pointer,
Param[1]->Val->Pointer);
} }
void StringStrncat(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringStrncat(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = strncat(Param[0]->Val->Pointer, Param[1]->Val->Pointer, Param[2]->Val->Integer); ReturnValue->Val->Pointer = strncat(Param[0]->Val->Pointer,
Param[1]->Val->Pointer, Param[2]->Val->Integer);
} }
#ifndef WIN32 #ifndef WIN32
void StringIndex(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringIndex(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = index(Param[0]->Val->Pointer, Param[1]->Val->Integer); ReturnValue->Val->Pointer = index(Param[0]->Val->Pointer,
Param[1]->Val->Integer);
} }
void StringRindex(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringRindex(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = rindex(Param[0]->Val->Pointer, Param[1]->Val->Integer); ReturnValue->Val->Pointer = rindex(Param[0]->Val->Pointer,
Param[1]->Val->Integer);
} }
#endif #endif
void StringStrlen(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringStrlen(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = strlen(Param[0]->Val->Pointer); ReturnValue->Val->Integer = strlen(Param[0]->Val->Pointer);
} }
void StringMemset(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringMemset(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = memset(Param[0]->Val->Pointer, Param[1]->Val->Integer, Param[2]->Val->Integer); ReturnValue->Val->Pointer = memset(Param[0]->Val->Pointer,
Param[1]->Val->Integer, Param[2]->Val->Integer);
} }
void StringMemcpy(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringMemcpy(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = memcpy(Param[0]->Val->Pointer, Param[1]->Val->Pointer, Param[2]->Val->Integer); ReturnValue->Val->Pointer = memcpy(Param[0]->Val->Pointer,
Param[1]->Val->Pointer, Param[2]->Val->Integer);
} }
void StringMemcmp(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringMemcmp(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = memcmp(Param[0]->Val->Pointer, Param[1]->Val->Pointer, Param[2]->Val->Integer); ReturnValue->Val->Integer = memcmp(Param[0]->Val->Pointer,
Param[1]->Val->Pointer, Param[2]->Val->Integer);
} }
void StringMemmove(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringMemmove(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = memmove(Param[0]->Val->Pointer, Param[1]->Val->Pointer, Param[2]->Val->Integer); ReturnValue->Val->Pointer = memmove(Param[0]->Val->Pointer,
Param[1]->Val->Pointer, Param[2]->Val->Integer);
} }
void StringMemchr(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringMemchr(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = memchr(Param[0]->Val->Pointer, Param[1]->Val->Integer, Param[2]->Val->Integer); ReturnValue->Val->Pointer = memchr(Param[0]->Val->Pointer,
Param[1]->Val->Integer, Param[2]->Val->Integer);
} }
void StringStrchr(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringStrchr(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = strchr(Param[0]->Val->Pointer, Param[1]->Val->Integer); ReturnValue->Val->Pointer = strchr(Param[0]->Val->Pointer,
Param[1]->Val->Integer);
} }
void StringStrrchr(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringStrrchr(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = strrchr(Param[0]->Val->Pointer, Param[1]->Val->Integer); ReturnValue->Val->Pointer = strrchr(Param[0]->Val->Pointer,
Param[1]->Val->Integer);
} }
void StringStrcoll(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringStrcoll(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = strcoll(Param[0]->Val->Pointer, Param[1]->Val->Pointer); ReturnValue->Val->Integer = strcoll(Param[0]->Val->Pointer,
Param[1]->Val->Pointer);
} }
void StringStrerror(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringStrerror(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = strerror(Param[0]->Val->Integer); ReturnValue->Val->Pointer = strerror(Param[0]->Val->Integer);
} }
void StringStrspn(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringStrspn(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = strspn(Param[0]->Val->Pointer, Param[1]->Val->Pointer); ReturnValue->Val->Integer = strspn(Param[0]->Val->Pointer,
Param[1]->Val->Pointer);
} }
void StringStrcspn(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringStrcspn(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = strcspn(Param[0]->Val->Pointer, Param[1]->Val->Pointer); ReturnValue->Val->Integer = strcspn(Param[0]->Val->Pointer,
Param[1]->Val->Pointer);
} }
void StringStrpbrk(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringStrpbrk(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = strpbrk(Param[0]->Val->Pointer, Param[1]->Val->Pointer); ReturnValue->Val->Pointer = strpbrk(Param[0]->Val->Pointer,
Param[1]->Val->Pointer);
} }
void StringStrstr(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringStrstr(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = strstr(Param[0]->Val->Pointer, Param[1]->Val->Pointer); ReturnValue->Val->Pointer = strstr(Param[0]->Val->Pointer,
Param[1]->Val->Pointer);
} }
void StringStrtok(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringStrtok(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = strtok(Param[0]->Val->Pointer, Param[1]->Val->Pointer); ReturnValue->Val->Pointer = strtok(Param[0]->Val->Pointer,
Param[1]->Val->Pointer);
} }
void StringStrxfrm(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringStrxfrm(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = strxfrm(Param[0]->Val->Pointer, Param[1]->Val->Pointer, Param[2]->Val->Integer); ReturnValue->Val->Integer = strxfrm(Param[0]->Val->Pointer,
Param[1]->Val->Pointer, Param[2]->Val->Integer);
} }
#ifndef WIN32 #ifndef WIN32
void StringStrdup(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringStrdup(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = strdup(Param[0]->Val->Pointer); ReturnValue->Val->Pointer = strdup(Param[0]->Val->Pointer);
} }
void StringStrtok_r(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StringStrtok_r(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = strtok_r(Param[0]->Val->Pointer, Param[1]->Val->Pointer, Param[2]->Val->Pointer); ReturnValue->Val->Pointer = strtok_r(Param[0]->Val->Pointer,
Param[1]->Val->Pointer, Param[2]->Val->Pointer);
} }
#endif #endif
@ -179,6 +228,7 @@ void StringSetupFunc(Picoc *pc)
{ {
/* define NULL */ /* define NULL */
if (!VariableDefined(pc, TableStrRegister(pc, "NULL"))) if (!VariableDefined(pc, TableStrRegister(pc, "NULL")))
VariableDefinePlatformVar(pc, NULL, "NULL", &pc->IntType, (union AnyValue *)&String_ZeroValue, false); VariableDefinePlatformVar(pc, NULL, "NULL", &pc->IntType,
(union AnyValue*)&String_ZeroValue, false);
} }

View file

@ -13,65 +13,81 @@ static int CLK_PER_SECValue = CLK_PER_SEC;
static int CLK_TCKValue = CLK_TCK; static int CLK_TCKValue = CLK_TCK;
#endif #endif
void StdAsctime(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdAsctime(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = asctime(Param[0]->Val->Pointer); ReturnValue->Val->Pointer = asctime(Param[0]->Val->Pointer);
} }
void StdClock(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdClock(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = clock(); ReturnValue->Val->Integer = clock();
} }
void StdCtime(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdCtime(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = ctime(Param[0]->Val->Pointer); ReturnValue->Val->Pointer = ctime(Param[0]->Val->Pointer);
} }
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);
} }
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);
} }
void StdLocaltime(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdLocaltime(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = localtime(Param[0]->Val->Pointer); ReturnValue->Val->Pointer = localtime(Param[0]->Val->Pointer);
} }
void StdMktime(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdMktime(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = (int)mktime(Param[0]->Val->Pointer); ReturnValue->Val->Integer = (int)mktime(Param[0]->Val->Pointer);
} }
void StdTime(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdTime(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = (int)time(Param[0]->Val->Pointer); ReturnValue->Val->Integer = (int)time(Param[0]->Val->Pointer);
} }
void StdStrftime(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdStrftime(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = strftime(Param[0]->Val->Pointer, Param[1]->Val->Integer, Param[2]->Val->Pointer, Param[3]->Val->Pointer); ReturnValue->Val->Integer = strftime(Param[0]->Val->Pointer,
Param[1]->Val->Integer, Param[2]->Val->Pointer, Param[3]->Val->Pointer);
} }
#ifndef WIN32 #ifndef WIN32
void StdStrptime(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdStrptime(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
extern char *strptime(const char *s, const char *format, struct tm *tm); extern char *strptime(const char *s, const char *format, struct tm *tm);
ReturnValue->Val->Pointer = strptime(Param[0]->Val->Pointer, Param[1]->Val->Pointer, Param[2]->Val->Pointer); ReturnValue->Val->Pointer = strptime(Param[0]->Val->Pointer,
Param[1]->Val->Pointer, Param[2]->Val->Pointer);
} }
void StdGmtime_r(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdGmtime_r(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = gmtime_r(Param[0]->Val->Pointer, Param[1]->Val->Pointer); ReturnValue->Val->Pointer = gmtime_r(Param[0]->Val->Pointer,
Param[1]->Val->Pointer);
} }
void StdTimegm(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void StdTimegm(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = timegm(Param[0]->Val->Pointer); ReturnValue->Val->Integer = timegm(Param[0]->Val->Pointer);
} }
@ -108,15 +124,19 @@ struct LibraryFunction StdTimeFunctions[] =
void StdTimeSetupFunc(Picoc *pc) void StdTimeSetupFunc(Picoc *pc)
{ {
/* make a "struct tm" which is the same size as a native tm structure */ /* make a "struct tm" which is the same size as a native tm structure */
TypeCreateOpaqueStruct(pc, NULL, TableStrRegister(pc, "tm"), sizeof(struct tm)); TypeCreateOpaqueStruct(pc, NULL, TableStrRegister(pc, "tm"),
sizeof(struct tm));
/* define CLK_PER_SEC etc. */ /* define CLK_PER_SEC etc. */
VariableDefinePlatformVar(pc, NULL, "CLOCKS_PER_SEC", &pc->IntType, (union AnyValue *)&CLOCKS_PER_SECValue, false); VariableDefinePlatformVar(pc, NULL, "CLOCKS_PER_SEC", &pc->IntType,
(union AnyValue*)&CLOCKS_PER_SECValue, false);
#ifdef CLK_PER_SEC #ifdef CLK_PER_SEC
VariableDefinePlatformVar(pc, NULL, "CLK_PER_SEC", &pc->IntType, (union AnyValue *)&CLK_PER_SECValue, false); VariableDefinePlatformVar(pc, NULL, "CLK_PER_SEC", &pc->IntType,
(union AnyValue*)&CLK_PER_SECValue, false);
#endif #endif
#ifdef CLK_TCK #ifdef CLK_TCK
VariableDefinePlatformVar(pc, NULL, "CLK_TCK", &pc->IntType, (union AnyValue *)&CLK_TCKValue, false); VariableDefinePlatformVar(pc, NULL, "CLK_TCK", &pc->IntType,
(union AnyValue*)&CLK_TCKValue, false);
#endif #endif
} }

View file

@ -6,79 +6,96 @@
static int ZeroValue = 0; static int ZeroValue = 0;
void UnistdAccess(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdAccess(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = access(Param[0]->Val->Pointer, Param[1]->Val->Integer); ReturnValue->Val->Integer = access(Param[0]->Val->Pointer, Param[1]->Val->Integer);
} }
void UnistdAlarm(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdAlarm(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = alarm(Param[0]->Val->Integer); ReturnValue->Val->Integer = alarm(Param[0]->Val->Integer);
} }
void UnistdChdir(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdChdir(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = chdir(Param[0]->Val->Pointer); ReturnValue->Val->Integer = chdir(Param[0]->Val->Pointer);
} }
void UnistdChroot(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdChroot(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = chroot(Param[0]->Val->Pointer); ReturnValue->Val->Integer = chroot(Param[0]->Val->Pointer);
} }
void UnistdChown(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdChown(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = chown(Param[0]->Val->Pointer, Param[1]->Val->Integer, Param[2]->Val->Integer); ReturnValue->Val->Integer = chown(Param[0]->Val->Pointer, Param[1]->Val->Integer, Param[2]->Val->Integer);
} }
void UnistdClose(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdClose(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = close(Param[0]->Val->Integer); ReturnValue->Val->Integer = close(Param[0]->Val->Integer);
} }
void UnistdConfstr(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdConfstr(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = confstr(Param[0]->Val->Integer, Param[1]->Val->Pointer, Param[2]->Val->Integer); ReturnValue->Val->Integer = confstr(Param[0]->Val->Integer,
Param[1]->Val->Pointer, Param[2]->Val->Integer);
} }
void UnistdCtermid(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdCtermid(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = ctermid(Param[0]->Val->Pointer); ReturnValue->Val->Pointer = ctermid(Param[0]->Val->Pointer);
} }
#if 0 #if 0
void UnistdCuserid(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdCuserid(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = cuserid(Param[0]->Val->Pointer); ReturnValue->Val->Pointer = cuserid(Param[0]->Val->Pointer);
} }
#endif #endif
void UnistdDup(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdDup(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = dup(Param[0]->Val->Integer); ReturnValue->Val->Integer = dup(Param[0]->Val->Integer);
} }
void UnistdDup2(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdDup2(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = dup2(Param[0]->Val->Integer, Param[1]->Val->Integer); ReturnValue->Val->Integer = dup2(Param[0]->Val->Integer, Param[1]->Val->Integer);
} }
void Unistd_Exit(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void Unistd_Exit(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
_exit(Param[0]->Val->Integer); _exit(Param[0]->Val->Integer);
} }
void UnistdFchown(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdFchown(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = fchown(Param[0]->Val->Integer, Param[1]->Val->Integer, Param[2]->Val->Integer); ReturnValue->Val->Integer = fchown(Param[0]->Val->Integer,
Param[1]->Val->Integer, Param[2]->Val->Integer);
} }
void UnistdFchdir(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdFchdir(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = fchdir(Param[0]->Val->Integer); ReturnValue->Val->Integer = fchdir(Param[0]->Val->Integer);
} }
void UnistdFdatasync(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdFdatasync(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
#ifdef F_FULLSYNC #ifdef F_FULLSYNC
/* Mac OS X equivalent */ /* Mac OS X equivalent */
@ -88,297 +105,375 @@ void UnistdFdatasync(struct ParseState *Parser, struct Value *ReturnValue, struc
#endif #endif
} }
void UnistdFork(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdFork(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = fork(); ReturnValue->Val->Integer = fork();
} }
void UnistdFpathconf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdFpathconf(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = fpathconf(Param[0]->Val->Integer, Param[1]->Val->Integer); ReturnValue->Val->Integer = fpathconf(Param[0]->Val->Integer,
Param[1]->Val->Integer);
} }
void UnistdFsync(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdFsync(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = fsync(Param[0]->Val->Integer); ReturnValue->Val->Integer = fsync(Param[0]->Val->Integer);
} }
void UnistdFtruncate(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdFtruncate(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = ftruncate(Param[0]->Val->Integer, Param[1]->Val->Integer); ReturnValue->Val->Integer = ftruncate(Param[0]->Val->Integer,
Param[1]->Val->Integer);
} }
void UnistdGetcwd(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdGetcwd(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = getcwd(Param[0]->Val->Pointer, Param[1]->Val->Integer); ReturnValue->Val->Pointer = getcwd(Param[0]->Val->Pointer, Param[1]->Val->Integer);
} }
void UnistdGetdtablesize(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdGetdtablesize(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = getdtablesize(); ReturnValue->Val->Integer = getdtablesize();
} }
void UnistdGetegid(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdGetegid(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = getegid(); ReturnValue->Val->Integer = getegid();
} }
void UnistdGeteuid(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdGeteuid(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = geteuid(); ReturnValue->Val->Integer = geteuid();
} }
void UnistdGetgid(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdGetgid(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = getgid(); ReturnValue->Val->Integer = getgid();
} }
void UnistdGethostid(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdGethostid(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = gethostid(); ReturnValue->Val->Integer = gethostid();
} }
void UnistdGetlogin(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdGetlogin(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = getlogin(); ReturnValue->Val->Pointer = getlogin();
} }
void UnistdGetlogin_r(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdGetlogin_r(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = getlogin_r(Param[0]->Val->Pointer, Param[1]->Val->Integer); ReturnValue->Val->Integer = getlogin_r(Param[0]->Val->Pointer,
Param[1]->Val->Integer);
} }
void UnistdGetpagesize(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdGetpagesize(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = getpagesize(); ReturnValue->Val->Integer = getpagesize();
} }
void UnistdGetpass(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdGetpass(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = getpass(Param[0]->Val->Pointer); ReturnValue->Val->Pointer = getpass(Param[0]->Val->Pointer);
} }
#if 0 #if 0
void UnistdGetpgid(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdGetpgid(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = getpgid(Param[0]->Val->Integer); ReturnValue->Val->Integer = getpgid(Param[0]->Val->Integer);
} }
#endif #endif
void UnistdGetpgrp(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdGetpgrp(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = getpgrp(); ReturnValue->Val->Integer = getpgrp();
} }
void UnistdGetpid(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdGetpid(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = getpid(); ReturnValue->Val->Integer = getpid();
} }
void UnistdGetppid(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdGetppid(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = getppid(); ReturnValue->Val->Integer = getppid();
} }
#if 0 #if 0
void UnistdGetsid(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdGetsid(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = getsid(Param[0]->Val->Integer); ReturnValue->Val->Integer = getsid(Param[0]->Val->Integer);
} }
#endif #endif
void UnistdGetuid(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdGetuid(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = getuid(); ReturnValue->Val->Integer = getuid();
} }
void UnistdGetwd(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdGetwd(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = getcwd(Param[0]->Val->Pointer, PATH_MAX); ReturnValue->Val->Pointer = getcwd(Param[0]->Val->Pointer, PATH_MAX);
} }
void UnistdIsatty(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdIsatty(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = isatty(Param[0]->Val->Integer); ReturnValue->Val->Integer = isatty(Param[0]->Val->Integer);
} }
void UnistdLchown(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdLchown(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = lchown(Param[0]->Val->Pointer, Param[1]->Val->Integer, Param[2]->Val->Integer); ReturnValue->Val->Integer = lchown(Param[0]->Val->Pointer,
Param[1]->Val->Integer, Param[2]->Val->Integer);
} }
void UnistdLink(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdLink(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = link(Param[0]->Val->Pointer, Param[1]->Val->Pointer); ReturnValue->Val->Integer = link(Param[0]->Val->Pointer, Param[1]->Val->Pointer);
} }
void UnistdLockf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdLockf(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = lockf(Param[0]->Val->Integer, Param[1]->Val->Integer, Param[2]->Val->Integer); ReturnValue->Val->Integer = lockf(Param[0]->Val->Integer,
Param[1]->Val->Integer, Param[2]->Val->Integer);
} }
void UnistdLseek(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdLseek(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = lseek(Param[0]->Val->Integer, Param[1]->Val->Integer, Param[2]->Val->Integer); ReturnValue->Val->Integer = lseek(Param[0]->Val->Integer,
Param[1]->Val->Integer, Param[2]->Val->Integer);
} }
void UnistdNice(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdNice(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = nice(Param[0]->Val->Integer); ReturnValue->Val->Integer = nice(Param[0]->Val->Integer);
} }
void UnistdPathconf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdPathconf(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = pathconf(Param[0]->Val->Pointer, Param[1]->Val->Integer); ReturnValue->Val->Integer = pathconf(Param[0]->Val->Pointer,
Param[1]->Val->Integer);
} }
void UnistdPause(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdPause(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = pause(); ReturnValue->Val->Integer = pause();
} }
#if 0 #if 0
void UnistdPread(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdPread(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = pread(Param[0]->Val->Integer, Param[1]->Val->Pointer, Param[2]->Val->Integer, Param[3]->Val->Integer); ReturnValue->Val->Integer = pread(Param[0]->Val->Integer,
Param[1]->Val->Pointer, Param[2]->Val->Integer, Param[3]->Val->Integer);
} }
void UnistdPwrite(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdPwrite(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = pwrite(Param[0]->Val->Integer, Param[1]->Val->Pointer, Param[2]->Val->Integer, Param[3]->Val->Integer); ReturnValue->Val->Integer = pwrite(Param[0]->Val->Integer,
Param[1]->Val->Pointer, Param[2]->Val->Integer, Param[3]->Val->Integer);
} }
#endif #endif
void UnistdRead(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdRead(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = read(Param[0]->Val->Integer, Param[1]->Val->Pointer, Param[2]->Val->Integer); ReturnValue->Val->Integer = read(Param[0]->Val->Integer,
Param[1]->Val->Pointer, Param[2]->Val->Integer);
} }
void UnistdReadlink(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdReadlink(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = readlink(Param[0]->Val->Pointer, Param[1]->Val->Pointer, Param[2]->Val->Integer); ReturnValue->Val->Integer = readlink(Param[0]->Val->Pointer,
Param[1]->Val->Pointer, Param[2]->Val->Integer);
} }
void UnistdRmdir(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdRmdir(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = rmdir(Param[0]->Val->Pointer); ReturnValue->Val->Integer = rmdir(Param[0]->Val->Pointer);
} }
void UnistdSbrk(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdSbrk(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = sbrk(Param[0]->Val->Integer); ReturnValue->Val->Pointer = sbrk(Param[0]->Val->Integer);
} }
void UnistdSetgid(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdSetgid(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = setgid(Param[0]->Val->Integer); ReturnValue->Val->Integer = setgid(Param[0]->Val->Integer);
} }
void UnistdSetpgid(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdSetpgid(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = setpgid(Param[0]->Val->Integer, Param[1]->Val->Integer); ReturnValue->Val->Integer = setpgid(Param[0]->Val->Integer,
Param[1]->Val->Integer);
} }
void UnistdSetpgrp(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdSetpgrp(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = setpgrp(); ReturnValue->Val->Integer = setpgrp();
} }
void UnistdSetregid(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdSetregid(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = setregid(Param[0]->Val->Integer, Param[1]->Val->Integer); ReturnValue->Val->Integer = setregid(Param[0]->Val->Integer,
Param[1]->Val->Integer);
} }
void UnistdSetreuid(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdSetreuid(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = setreuid(Param[0]->Val->Integer, Param[1]->Val->Integer); ReturnValue->Val->Integer = setreuid(Param[0]->Val->Integer,
Param[1]->Val->Integer);
} }
void UnistdSetsid(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdSetsid(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = setsid(); ReturnValue->Val->Integer = setsid();
} }
void UnistdSetuid(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdSetuid(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = setuid(Param[0]->Val->Integer); ReturnValue->Val->Integer = setuid(Param[0]->Val->Integer);
} }
void UnistdSleep(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdSleep(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = sleep(Param[0]->Val->Integer); ReturnValue->Val->Integer = sleep(Param[0]->Val->Integer);
} }
#if 0 #if 0
void UnistdSwab(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdSwab(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = swab(Param[0]->Val->Pointer, Param[1]->Val->Pointer, Param[2]->Val->Integer); ReturnValue->Val->Integer = swab(Param[0]->Val->Pointer,
Param[1]->Val->Pointer, Param[2]->Val->Integer);
} }
#endif #endif
void UnistdSymlink(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdSymlink(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = symlink(Param[0]->Val->Pointer, Param[1]->Val->Pointer); ReturnValue->Val->Integer = symlink(Param[0]->Val->Pointer,
Param[1]->Val->Pointer);
} }
void UnistdSync(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdSync(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
sync(); sync();
} }
void UnistdSysconf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdSysconf(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = sysconf(Param[0]->Val->Integer); ReturnValue->Val->Integer = sysconf(Param[0]->Val->Integer);
} }
void UnistdTcgetpgrp(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdTcgetpgrp(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = tcgetpgrp(Param[0]->Val->Integer); ReturnValue->Val->Integer = tcgetpgrp(Param[0]->Val->Integer);
} }
void UnistdTcsetpgrp(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdTcsetpgrp(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = tcsetpgrp(Param[0]->Val->Integer, Param[1]->Val->Integer); ReturnValue->Val->Integer = tcsetpgrp(Param[0]->Val->Integer,
Param[1]->Val->Integer);
} }
void UnistdTruncate(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdTruncate(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = truncate(Param[0]->Val->Pointer, Param[1]->Val->Integer); ReturnValue->Val->Integer = truncate(Param[0]->Val->Pointer,
Param[1]->Val->Integer);
} }
void UnistdTtyname(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdTtyname(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Pointer = ttyname(Param[0]->Val->Integer); ReturnValue->Val->Pointer = ttyname(Param[0]->Val->Integer);
} }
void UnistdTtyname_r(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdTtyname_r(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = ttyname_r(Param[0]->Val->Integer, Param[1]->Val->Pointer, Param[2]->Val->Integer); ReturnValue->Val->Integer = ttyname_r(Param[0]->Val->Integer,
Param[1]->Val->Pointer, Param[2]->Val->Integer);
} }
void UnistdUalarm(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdUalarm(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = ualarm(Param[0]->Val->Integer, Param[1]->Val->Integer); ReturnValue->Val->Integer = ualarm(Param[0]->Val->Integer,
Param[1]->Val->Integer);
} }
void UnistdUnlink(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdUnlink(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = unlink(Param[0]->Val->Pointer); ReturnValue->Val->Integer = unlink(Param[0]->Val->Pointer);
} }
void UnistdUsleep(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdUsleep(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = usleep(Param[0]->Val->Integer); ReturnValue->Val->Integer = usleep(Param[0]->Val->Integer);
} }
void UnistdVfork(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdVfork(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = vfork(); ReturnValue->Val->Integer = vfork();
} }
void UnistdWrite(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void UnistdWrite(struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = write(Param[0]->Val->Integer, Param[1]->Val->Pointer, Param[2]->Val->Integer); ReturnValue->Val->Integer = write(Param[0]->Val->Integer,
Param[1]->Val->Pointer, Param[2]->Val->Integer);
} }
@ -491,12 +586,17 @@ void UnistdSetupFunc(Picoc *pc)
{ {
/* define NULL */ /* define NULL */
if (!VariableDefined(pc, TableStrRegister(pc, "NULL"))) if (!VariableDefined(pc, TableStrRegister(pc, "NULL")))
VariableDefinePlatformVar(pc, NULL, "NULL", &pc->IntType, (union AnyValue *)&ZeroValue, false); VariableDefinePlatformVar(pc, NULL, "NULL", &pc->IntType,
(union AnyValue *)&ZeroValue, false);
/* define optarg and friends */ /* define optarg and friends */
VariableDefinePlatformVar(pc, NULL, "optarg", pc->CharPtrType, (union AnyValue *)&optarg, true); VariableDefinePlatformVar(pc, NULL, "optarg", pc->CharPtrType,
VariableDefinePlatformVar(pc, NULL, "optind", &pc->IntType, (union AnyValue *)&optind, true); (union AnyValue *)&optarg, true);
VariableDefinePlatformVar(pc, NULL, "opterr", &pc->IntType, (union AnyValue *)&opterr, true); VariableDefinePlatformVar(pc, NULL, "optind", &pc->IntType,
VariableDefinePlatformVar(pc, NULL, "optopt", &pc->IntType, (union AnyValue *)&optopt, true); (union AnyValue *)&optind, true);
VariableDefinePlatformVar(pc, NULL, "opterr", &pc->IntType,
(union AnyValue *)&opterr, true);
VariableDefinePlatformVar(pc, NULL, "optopt", &pc->IntType,
(union AnyValue *)&optopt, true);
} }

View file

@ -7,7 +7,8 @@
/* initialise the debugger by clearing the breakpoint table */ /* initialise the debugger by clearing the breakpoint table */
void DebugInit(Picoc *pc) void DebugInit(Picoc *pc)
{ {
TableInitTable(&pc->BreakpointTable, &pc->BreakpointHashTable[0], BREAKPOINT_TABLE_SIZE, true); TableInitTable(&pc->BreakpointTable, &pc->BreakpointHashTable[0],
BREAKPOINT_TABLE_SIZE, true);
pc->BreakpointCount = 0; pc->BreakpointCount = 0;
} }
@ -19,7 +20,8 @@ void DebugCleanup(Picoc *pc)
int Count; int Count;
for (Count = 0; Count < pc->BreakpointTable.Size; Count++) { for (Count = 0; Count < pc->BreakpointTable.Size; Count++) {
for (Entry = pc->BreakpointHashTable[Count]; Entry != NULL; Entry = NextEntry) { for (Entry = pc->BreakpointHashTable[Count]; Entry != NULL;
Entry = NextEntry) {
NextEntry = Entry->Next; NextEntry = Entry->Next;
HeapFreeMem(pc, Entry); HeapFreeMem(pc, Entry);
} }

View file

@ -92,7 +92,8 @@ static struct OpPrecedence OperatorPrecedence[] =
/* TokenCloseBracket, */ {0, 15, 0, ")"} /* TokenCloseBracket, */ {0, 15, 0, ")"}
}; };
void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionStack **StackTop, const char *FuncName, int RunIt); void ExpressionParseFunctionCall(struct ParseState *Parser,
struct ExpressionStack **StackTop, const char *FuncName, int RunIt);
#ifdef DEBUG_EXPRESSIONS #ifdef DEBUG_EXPRESSIONS
/* show the contents of the expression stack */ /* show the contents of the expression stack */
@ -153,7 +154,8 @@ void ExpressionStackShow(Picoc *pc, struct ExpressionStack *StackTop)
} }
#endif #endif
int IsTypeToken(struct ParseState * Parser, enum LexToken t, struct Value * LexValue) int IsTypeToken(struct ParseState * Parser, enum LexToken t,
struct Value * LexValue)
{ {
if (t >= TokenIntType && t <= TokenUnsignedType) if (t >= TokenIntType && t <= TokenUnsignedType)
return 1; /* base type */ return 1; /* base type */
@ -225,7 +227,8 @@ double ExpressionCoerceFP(struct Value *Val)
} }
/* 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)
{ {
long Result; long Result;
@ -252,7 +255,8 @@ long ExpressionAssignInt(struct ParseState *Parser, struct Value *DestValue, lon
} }
/* 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)
ProgramFail(Parser, "can't assign to this"); ProgramFail(Parser, "can't assign to this");
@ -262,9 +266,11 @@ double ExpressionAssignFP(struct ParseState *Parser, struct Value *DestValue, do
} }
/* 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)
{ {
struct ExpressionStack *StackNode = VariableAlloc(Parser->pc, Parser, sizeof(struct ExpressionStack), false); struct ExpressionStack *StackNode = VariableAlloc(Parser->pc, Parser,
sizeof(struct ExpressionStack), false);
StackNode->Next = *StackTop; StackNode->Next = *StackTop;
StackNode->Val = ValueLoc; StackNode->Val = ValueLoc;
*StackTop = StackNode; *StackTop = StackNode;
@ -278,59 +284,72 @@ void ExpressionStackPushValueNode(struct ParseState *Parser, struct ExpressionSt
} }
/* push a blank value on to the expression stack by type */ /* push a blank value on to the expression stack by type */
struct Value *ExpressionStackPushValueByType(struct ParseState *Parser, struct ExpressionStack **StackTop, struct ValueType *PushType) struct Value *ExpressionStackPushValueByType(struct ParseState *Parser,
struct ExpressionStack **StackTop, struct ValueType *PushType)
{ {
struct Value *ValueLoc = VariableAllocValueFromType(Parser->pc, Parser, PushType, false, NULL, false); struct Value *ValueLoc = VariableAllocValueFromType(Parser->pc, Parser,
PushType, false, NULL, false);
ExpressionStackPushValueNode(Parser, StackTop, ValueLoc); ExpressionStackPushValueNode(Parser, StackTop, ValueLoc);
return ValueLoc; return ValueLoc;
} }
/* push a value on to the expression stack */ /* push a value on to the expression stack */
void ExpressionStackPushValue(struct ParseState *Parser, struct ExpressionStack **StackTop, struct Value *PushValue) void ExpressionStackPushValue(struct ParseState *Parser,
struct ExpressionStack **StackTop, struct Value *PushValue)
{ {
struct Value *ValueLoc = VariableAllocValueAndCopy(Parser->pc, Parser, PushValue, false); struct Value *ValueLoc = VariableAllocValueAndCopy(Parser->pc, Parser,
PushValue, false);
ExpressionStackPushValueNode(Parser, StackTop, ValueLoc); ExpressionStackPushValueNode(Parser, StackTop, ValueLoc);
} }
void ExpressionStackPushLValue(struct ParseState *Parser, struct ExpressionStack **StackTop, struct Value *PushValue, int Offset) void ExpressionStackPushLValue(struct ParseState *Parser,
struct ExpressionStack **StackTop, struct Value *PushValue, int Offset)
{ {
struct Value *ValueLoc = VariableAllocValueShared(Parser, PushValue); struct Value *ValueLoc = VariableAllocValueShared(Parser, PushValue);
ValueLoc->Val = (void *)((char *)ValueLoc->Val + Offset); ValueLoc->Val = (void *)((char *)ValueLoc->Val + Offset);
ExpressionStackPushValueNode(Parser, StackTop, ValueLoc); ExpressionStackPushValueNode(Parser, StackTop, ValueLoc);
} }
void ExpressionStackPushDereference(struct ParseState *Parser, struct ExpressionStack **StackTop, struct Value *DereferenceValue) void ExpressionStackPushDereference(struct ParseState *Parser,
struct ExpressionStack **StackTop, struct Value *DereferenceValue)
{ {
int Offset; int Offset;
int DerefIsLValue; int DerefIsLValue;
struct Value *DerefVal; struct Value *DerefVal;
struct Value *ValueLoc; struct Value *ValueLoc;
struct ValueType *DerefType; struct ValueType *DerefType;
void *DerefDataLoc = VariableDereferencePointer(Parser, DereferenceValue, &DerefVal, &Offset, &DerefType, &DerefIsLValue); void *DerefDataLoc = VariableDereferencePointer(Parser, DereferenceValue,
&DerefVal, &Offset, &DerefType, &DerefIsLValue);
if (DerefDataLoc == NULL) if (DerefDataLoc == NULL)
ProgramFail(Parser, "NULL pointer dereference"); ProgramFail(Parser, "NULL pointer dereference");
ValueLoc = VariableAllocValueFromExistingData(Parser, DerefType, (union AnyValue *)DerefDataLoc, DerefIsLValue, DerefVal); ValueLoc = VariableAllocValueFromExistingData(Parser, DerefType,
(union AnyValue*)DerefDataLoc, DerefIsLValue, DerefVal);
ExpressionStackPushValueNode(Parser, StackTop, ValueLoc); ExpressionStackPushValueNode(Parser, StackTop, ValueLoc);
} }
void ExpressionPushInt(struct ParseState *Parser, struct ExpressionStack **StackTop, long IntValue) void ExpressionPushInt(struct ParseState *Parser,
struct ExpressionStack **StackTop, long IntValue)
{ {
struct Value *ValueLoc = VariableAllocValueFromType(Parser->pc, Parser, &Parser->pc->IntType, false, NULL, false); struct Value *ValueLoc = VariableAllocValueFromType(Parser->pc, Parser,
&Parser->pc->IntType, false, NULL, false);
ValueLoc->Val->Integer = IntValue; ValueLoc->Val->Integer = IntValue;
ExpressionStackPushValueNode(Parser, StackTop, ValueLoc); ExpressionStackPushValueNode(Parser, StackTop, ValueLoc);
} }
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->pc, Parser, &Parser->pc->FPType, false, NULL, false); struct Value *ValueLoc = VariableAllocValueFromType(Parser->pc, Parser,
&Parser->pc->FPType, false, NULL, false);
ValueLoc->Val->FP = FPValue; ValueLoc->Val->FP = FPValue;
ExpressionStackPushValueNode(Parser, StackTop, ValueLoc); ExpressionStackPushValueNode(Parser, StackTop, ValueLoc);
} }
/* 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)
{ {
struct ValueType *PointedToType = ToValue->Typ->FromType; struct ValueType *PointedToType = ToValue->Typ->FromType;
@ -357,7 +376,9 @@ void ExpressionAssignToPointer(struct ParseState *Parser, struct Value *ToValue,
} }
/* assign any kind of value */ /* assign any kind of value */
void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, struct Value *SourceValue, int Force, const char *FuncName, int ParamNo, int AllowPointerCoercion) void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue,
struct Value *SourceValue, int Force, const char *FuncName, int ParamNo,
int AllowPointerCoercion)
{ {
if (!DestValue->IsLValue && !Force) if (!DestValue->IsLValue && !Force)
AssignFail(Parser, "not an lvalue", NULL, NULL, 0, 0, FuncName, ParamNo); AssignFail(Parser, "not an lvalue", NULL, NULL, 0, 0, FuncName, ParamNo);
@ -405,14 +426,17 @@ void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, struct
PRINT_SOURCE_POS(); PRINT_SOURCE_POS();
fprintf(stderr, "str size: %d\n", Size); fprintf(stderr, "str size: %d\n", Size);
#endif #endif
DestValue->Typ = TypeGetMatching(Parser->pc, Parser, DestValue->Typ->FromType, DestValue->Typ->Base, Size, DestValue->Typ->Identifier, true); DestValue->Typ = TypeGetMatching(Parser->pc, Parser,
DestValue->Typ->FromType, DestValue->Typ->Base,
Size, DestValue->Typ->Identifier, true);
VariableRealloc(Parser, DestValue, TypeSizeValue(DestValue, false)); VariableRealloc(Parser, DestValue, TypeSizeValue(DestValue, false));
} }
/* else, it's char x[10] = "abcd" */ /* else, it's char x[10] = "abcd" */
#ifdef DEBUG_ARRAY_INITIALIZER #ifdef DEBUG_ARRAY_INITIALIZER
PRINT_SOURCE_POS(); PRINT_SOURCE_POS();
fprintf(stderr, "char[%d] from char* (len=%d)\n", DestValue->Typ->ArraySize, strlen(SourceValue->Val->Pointer)); fprintf(stderr, "char[%d] from char* (len=%d)\n",
DestValue->Typ->ArraySize, strlen(SourceValue->Val->Pointer));
#endif #endif
memcpy((void *)DestValue->Val, SourceValue->Val->Pointer, TypeSizeValue(DestValue, false)); memcpy((void *)DestValue->Val, SourceValue->Val->Pointer, TypeSizeValue(DestValue, false));
break; break;
@ -422,17 +446,22 @@ void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, struct
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);
if (DestValue->Typ->ArraySize != SourceValue->Typ->ArraySize) if (DestValue->Typ->ArraySize != SourceValue->Typ->ArraySize)
AssignFail(Parser, "from an array of size %d to one of size %d", NULL, NULL, DestValue->Typ->ArraySize, SourceValue->Typ->ArraySize, FuncName, ParamNo); AssignFail(Parser, "from an array of size %d to one of size %d",
NULL, NULL, DestValue->Typ->ArraySize,
SourceValue->Typ->ArraySize, FuncName, ParamNo);
memcpy((void *)DestValue->Val, (void *)SourceValue->Val, TypeSizeValue(DestValue, false)); memcpy((void *)DestValue->Val, (void *)SourceValue->Val,
TypeSizeValue(DestValue, false));
break; break;
case TypeStruct: case TypeStruct:
case TypeUnion: case TypeUnion:
if (DestValue->Typ != SourceValue->Typ) if (DestValue->Typ != SourceValue->Typ)
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);
memcpy((void *)DestValue->Val, (void *)SourceValue->Val, TypeSizeValue(SourceValue, false)); memcpy((void *)DestValue->Val, (void *)SourceValue->Val,
TypeSizeValue(SourceValue, false));
break; break;
default: default:
@ -442,7 +471,9 @@ void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, struct
} }
/* evaluate the first half of a ternary operator x ? y : z */ /* evaluate the first half of a ternary operator x ? y : z */
void ExpressionQuestionMarkOperator(struct ParseState *Parser, struct ExpressionStack **StackTop, struct Value *BottomValue, struct Value *TopValue) void ExpressionQuestionMarkOperator(struct ParseState *Parser,
struct ExpressionStack **StackTop, struct Value *BottomValue,
struct Value *TopValue)
{ {
if (!IS_NUMERIC_COERCIBLE(TopValue)) if (!IS_NUMERIC_COERCIBLE(TopValue))
ProgramFail(Parser, "first argument to '?' should be a number"); ProgramFail(Parser, "first argument to '?' should be a number");
@ -457,7 +488,9 @@ void ExpressionQuestionMarkOperator(struct ParseState *Parser, struct Expression
} }
/* evaluate the second half of a ternary operator x ? y : z */ /* evaluate the second half of a ternary operator x ? y : z */
void ExpressionColonOperator(struct ParseState *Parser, struct ExpressionStack **StackTop, struct Value *BottomValue, struct Value *TopValue) void ExpressionColonOperator(struct ParseState *Parser,
struct ExpressionStack **StackTop, struct Value *BottomValue,
struct Value *TopValue)
{ {
if (TopValue->Typ->Base == TypeVoid) { if (TopValue->Typ->Base == TypeVoid) {
/* invoke the "else" part - return the BottomValue */ /* invoke the "else" part - return the BottomValue */
@ -469,7 +502,8 @@ void ExpressionColonOperator(struct ParseState *Parser, struct ExpressionStack *
} }
/* evaluate a prefix operator */ /* evaluate a prefix operator */
void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack **StackTop, enum LexToken Op, struct Value *TopValue) void ExpressionPrefixOperator(struct ParseState *Parser,
struct ExpressionStack **StackTop, enum LexToken Op, struct Value *TopValue)
{ {
struct Value *Result; struct Value *Result;
union AnyValue *ValPtr; union AnyValue *ValPtr;
@ -484,7 +518,10 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack
ProgramFail(Parser, "can't get the address of this"); ProgramFail(Parser, "can't get the address of this");
ValPtr = TopValue->Val; ValPtr = TopValue->Val;
Result = VariableAllocValueFromType(Parser->pc, Parser, TypeGetMatching(Parser->pc, Parser, TopValue->Typ, TypePointer, 0, Parser->pc->StrEmpty, true), false, NULL, false); Result = VariableAllocValueFromType(Parser->pc, Parser,
TypeGetMatching(Parser->pc, Parser, TopValue->Typ,
TypePointer, 0, Parser->pc->StrEmpty, true),
false, NULL, false);
Result->Val->Pointer = (void *)ValPtr; Result->Val->Pointer = (void *)ValPtr;
ExpressionStackPushValueNode(Parser, StackTop, Result); ExpressionStackPushValueNode(Parser, StackTop, Result);
break; break;
@ -496,9 +533,11 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack
case TokenSizeof: case TokenSizeof:
/* return the size of the argument */ /* return the size of the argument */
if (TopValue->Typ == &Parser->pc->TypeType) if (TopValue->Typ == &Parser->pc->TypeType)
ExpressionPushInt(Parser, StackTop, TypeSize(TopValue->Val->Typ, TopValue->Val->Typ->ArraySize, true)); ExpressionPushInt(Parser, StackTop, TypeSize(TopValue->Val->Typ,
TopValue->Val->Typ->ArraySize, true));
else else
ExpressionPushInt(Parser, StackTop, TypeSize(TopValue->Typ, TopValue->Typ->ArraySize, true)); ExpressionPushInt(Parser, StackTop, TypeSize(TopValue->Typ,
TopValue->Typ->ArraySize, true));
break; break;
default: default:
@ -560,7 +599,8 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack
} }
/* evaluate a postfix operator */ /* evaluate a postfix operator */
void ExpressionPostfixOperator(struct ParseState *Parser, struct ExpressionStack **StackTop, enum LexToken Op, struct Value *TopValue) void ExpressionPostfixOperator(struct ParseState *Parser,
struct ExpressionStack **StackTop, enum LexToken Op, struct Value *TopValue)
{ {
#ifdef DEBUG_EXPRESSIONS #ifdef DEBUG_EXPRESSIONS
printf("ExpressionPostfixOperator()\n"); printf("ExpressionPostfixOperator()\n");
@ -616,7 +656,9 @@ void ExpressionPostfixOperator(struct ParseState *Parser, struct ExpressionStack
} }
/* evaluate an infix operator */ /* evaluate an infix operator */
void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack **StackTop, enum LexToken Op, struct Value *BottomValue, struct Value *TopValue) void ExpressionInfixOperator(struct ParseState *Parser,
struct ExpressionStack **StackTop, enum LexToken Op,
struct Value *BottomValue, struct Value *TopValue)
{ {
long ResultInt = 0; long ResultInt = 0;
struct Value *StackValue; struct Value *StackValue;
@ -641,8 +683,19 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
/* make the array element result */ /* make the array element result */
switch (BottomValue->Typ->Base) { switch (BottomValue->Typ->Base) {
case TypeArray: Result = VariableAllocValueFromExistingData(Parser, BottomValue->Typ->FromType, (union AnyValue *)(&BottomValue->Val->ArrayMem[0] + TypeSize(BottomValue->Typ, ArrayIndex, true)), BottomValue->IsLValue, BottomValue->LValueFrom); break; case TypeArray:
case TypePointer: Result = VariableAllocValueFromExistingData(Parser, BottomValue->Typ->FromType, (union AnyValue *)((char *)BottomValue->Val->Pointer + TypeSize(BottomValue->Typ->FromType, 0, true) * ArrayIndex), BottomValue->IsLValue, BottomValue->LValueFrom); break; Result = VariableAllocValueFromExistingData(Parser,
BottomValue->Typ->FromType,
(union AnyValue*)(&BottomValue->Val->ArrayMem[0]+TypeSize(BottomValue->Typ,
ArrayIndex, true)),
BottomValue->IsLValue, BottomValue->LValueFrom);
break;
case TypePointer: Result = VariableAllocValueFromExistingData(Parser,
BottomValue->Typ->FromType,
(union AnyValue*)((char*)BottomValue->Val->Pointer+TypeSize(BottomValue->Typ->FromType,
0, true) * ArrayIndex),
BottomValue->IsLValue, BottomValue->LValueFrom);
break;
default: ProgramFail(Parser, "this %t is not an array", BottomValue->Typ); default: ProgramFail(Parser, "this %t is not an array", BottomValue->Typ);
} }
@ -790,14 +843,16 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
ExpressionStackPushValueNode(Parser, StackTop, BottomValue); ExpressionStackPushValueNode(Parser, StackTop, BottomValue);
} else if (Op == TokenCast) { } else if (Op == TokenCast) {
/* cast a value to a different type */ /* XXX - possible bug if the destination type takes more than sizeof(struct Value) + sizeof(struct ValueType *) */ /* cast a value to a different type */ /* XXX - possible bug if the destination type takes more than sizeof(struct Value) + sizeof(struct ValueType *) */
struct Value *ValueLoc = ExpressionStackPushValueByType(Parser, StackTop, BottomValue->Val->Typ); struct Value *ValueLoc = ExpressionStackPushValueByType(Parser, StackTop,
BottomValue->Val->Typ);
ExpressionAssign(Parser, ValueLoc, TopValue, true, NULL, 0, true); ExpressionAssign(Parser, ValueLoc, TopValue, true, NULL, 0, true);
} else } else
ProgramFail(Parser, "invalid operation"); ProgramFail(Parser, "invalid operation");
} }
/* take the contents of the expression stack and compute the top until there's nothing greater than the given precedence */ /* take the contents of the expression stack and compute the top until there's nothing greater than the given precedence */
void ExpressionStackCollapse(struct ParseState *Parser, struct ExpressionStack **StackTop, int Precedence, int *IgnorePrecedence) void ExpressionStackCollapse(struct ParseState *Parser,
struct ExpressionStack **StackTop, int Precedence, int *IgnorePrecedence)
{ {
int FoundPrecedence = Precedence; int FoundPrecedence = Precedence;
struct Value *TopValue; struct Value *TopValue;
@ -830,7 +885,7 @@ void ExpressionStackCollapse(struct ParseState *Parser, struct ExpressionStack *
TopValue = TopStackNode->Val; TopValue = TopStackNode->Val;
/* pop the value and then the prefix operator - assume they'll still be there until we're done */ /* pop the value and then the prefix operator - assume they'll still be there until we're done */
HeapPopStack(Parser->pc, NULL, sizeof(struct ExpressionStack) + sizeof(struct Value) + TypeStackSizeValue(TopValue)); HeapPopStack(Parser->pc, NULL, sizeof(struct ExpressionStack)+sizeof(struct Value)+TypeStackSizeValue(TopValue));
HeapPopStack(Parser->pc, TopOperatorNode, sizeof(struct ExpressionStack)); HeapPopStack(Parser->pc, TopOperatorNode, sizeof(struct ExpressionStack));
*StackTop = TopOperatorNode->Next; *StackTop = TopOperatorNode->Next;
@ -853,7 +908,7 @@ void ExpressionStackCollapse(struct ParseState *Parser, struct ExpressionStack *
/* pop the postfix operator and then the value - assume they'll still be there until we're done */ /* pop the postfix operator and then the value - assume they'll still be there until we're done */
HeapPopStack(Parser->pc, NULL, sizeof(struct ExpressionStack)); HeapPopStack(Parser->pc, NULL, sizeof(struct ExpressionStack));
HeapPopStack(Parser->pc, TopValue, sizeof(struct ExpressionStack) + sizeof(struct Value) + TypeStackSizeValue(TopValue)); HeapPopStack(Parser->pc, TopValue, sizeof(struct ExpressionStack)+sizeof(struct Value)+TypeStackSizeValue(TopValue));
*StackTop = TopStackNode->Next->Next; *StackTop = TopStackNode->Next->Next;
/* do the postfix operation */ /* do the postfix operation */
@ -876,9 +931,9 @@ void ExpressionStackCollapse(struct ParseState *Parser, struct ExpressionStack *
BottomValue = TopOperatorNode->Next->Val; BottomValue = TopOperatorNode->Next->Val;
/* pop a value, the operator and another value - assume they'll still be there until we're done */ /* pop a value, the operator and another value - assume they'll still be there until we're done */
HeapPopStack(Parser->pc, NULL, sizeof(struct ExpressionStack) + sizeof(struct Value) + TypeStackSizeValue(TopValue)); HeapPopStack(Parser->pc, NULL, sizeof(struct ExpressionStack) + sizeof(struct Value)+TypeStackSizeValue(TopValue));
HeapPopStack(Parser->pc, NULL, sizeof(struct ExpressionStack)); HeapPopStack(Parser->pc, NULL, sizeof(struct ExpressionStack));
HeapPopStack(Parser->pc, BottomValue, sizeof(struct ExpressionStack) + sizeof(struct Value) + TypeStackSizeValue(BottomValue)); HeapPopStack(Parser->pc, BottomValue, sizeof(struct ExpressionStack) + sizeof(struct Value)+TypeStackSizeValue(BottomValue));
*StackTop = TopOperatorNode->Next->Next; *StackTop = TopOperatorNode->Next->Next;
/* do the infix operation */ /* do the infix operation */
@ -916,9 +971,12 @@ void ExpressionStackCollapse(struct ParseState *Parser, struct ExpressionStack *
} }
/* push an operator on to the expression stack */ /* push an operator on to the expression stack */
void ExpressionStackPushOperator(struct ParseState *Parser, struct ExpressionStack **StackTop, enum OperatorOrder Order, enum LexToken Token, int Precedence) void ExpressionStackPushOperator(struct ParseState *Parser,
struct ExpressionStack **StackTop, enum OperatorOrder Order,
enum LexToken Token, int Precedence)
{ {
struct ExpressionStack *StackNode = VariableAlloc(Parser->pc, Parser, sizeof(struct ExpressionStack), false); struct ExpressionStack *StackNode = VariableAlloc(Parser->pc, Parser,
sizeof(struct ExpressionStack), false);
StackNode->Next = *StackTop; StackNode->Next = *StackTop;
StackNode->Order = Order; StackNode->Order = Order;
StackNode->Op = Token; StackNode->Op = Token;
@ -937,13 +995,15 @@ void ExpressionStackPushOperator(struct ParseState *Parser, struct ExpressionSta
} }
/* do the '.' and '->' operators */ /* do the '.' and '->' operators */
void ExpressionGetStructElement(struct ParseState *Parser, struct ExpressionStack **StackTop, enum LexToken Token) void ExpressionGetStructElement(struct ParseState *Parser,
struct ExpressionStack **StackTop, enum LexToken Token)
{ {
struct Value *Ident; struct Value *Ident;
/* get the identifier following the '.' or '->' */ /* get the identifier following the '.' or '->' */
if (LexGetToken(Parser, &Ident, true) != TokenIdentifier) if (LexGetToken(Parser, &Ident, true) != TokenIdentifier)
ProgramFail(Parser, "need an structure or union member after '%s'", (Token == TokenDot) ? "." : "->"); ProgramFail(Parser, "need an structure or union member after '%s'",
(Token == TokenDot) ? "." : "->");
if (Parser->Mode == RunModeRun) { if (Parser->Mode == RunModeRun) {
/* look up the struct element */ /* look up the struct element */
@ -956,20 +1016,26 @@ void ExpressionGetStructElement(struct ParseState *Parser, struct ExpressionStac
/* if we're doing '->' dereference the struct pointer first */ /* if we're doing '->' dereference the struct pointer first */
if (Token == TokenArrow) if (Token == TokenArrow)
DerefDataLoc = VariableDereferencePointer(Parser, ParamVal, &StructVal, NULL, &StructType, NULL); DerefDataLoc = VariableDereferencePointer(Parser, ParamVal, &StructVal,
NULL, &StructType, NULL);
if (StructType->Base != TypeStruct && StructType->Base != TypeUnion) if (StructType->Base != TypeStruct && StructType->Base != TypeUnion)
ProgramFail(Parser, "can't use '%s' on something that's not a struct or union %s : it's a %t", (Token == TokenDot) ? "." : "->", (Token == TokenArrow) ? "pointer" : "", ParamVal->Typ); ProgramFail(Parser, "can't use '%s' on something that's not a struct or union %s : it's a %t",
(Token == TokenDot) ? "." : "->",
(Token == TokenArrow) ? "pointer" : "", ParamVal->Typ);
if (!TableGet(StructType->Members, Ident->Val->Identifier, &MemberValue, NULL, NULL, NULL)) if (!TableGet(StructType->Members, Ident->Val->Identifier, &MemberValue, NULL, NULL, NULL))
ProgramFail(Parser, "doesn't have a member called '%s'", Ident->Val->Identifier); ProgramFail(Parser, "doesn't have a member called '%s'", Ident->Val->Identifier);
/* pop the value - assume it'll still be there until we're done */ /* pop the value - assume it'll still be there until we're done */
HeapPopStack(Parser->pc, ParamVal, sizeof(struct ExpressionStack) + sizeof(struct Value) + TypeStackSizeValue(StructVal)); HeapPopStack(Parser->pc, ParamVal,
sizeof(struct ExpressionStack)+sizeof(struct Value)+TypeStackSizeValue(StructVal));
*StackTop = (*StackTop)->Next; *StackTop = (*StackTop)->Next;
/* make the result value for this member only */ /* make the result value for this member only */
Result = VariableAllocValueFromExistingData(Parser, MemberValue->Typ, (void *)(DerefDataLoc + MemberValue->Val->Integer), true, (StructVal != NULL) ? StructVal->LValueFrom : NULL); Result = VariableAllocValueFromExistingData(Parser, MemberValue->Typ,
(void*)(DerefDataLoc + MemberValue->Val->Integer), true,
(StructVal != NULL) ? StructVal->LValueFrom : NULL);
ExpressionStackPushValueNode(Parser, StackTop, Result); ExpressionStackPushValueNode(Parser, StackTop, Result);
} }
} }
@ -997,9 +1063,9 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
ParserCopy(&PreState, Parser); ParserCopy(&PreState, Parser);
Token = LexGetToken(Parser, &LexValue, true); Token = LexGetToken(Parser, &LexValue, true);
if ( ( ( (int)Token > TokenComma && (int)Token <= (int)TokenOpenBracket) || if ((((int)Token > TokenComma && (int)Token <= (int)TokenOpenBracket) ||
(Token == TokenCloseBracket && BracketPrecedence != 0)) && (Token == TokenCloseBracket && BracketPrecedence != 0)) &&
(Token != TokenColon || TernaryDepth > 0) ) { (Token != TokenColon || TernaryDepth > 0)) {
/* it's an operator with precedence */ /* it's an operator with precedence */
if (PrefixState) { if (PrefixState) {
/* expect a prefix operator */ /* expect a prefix operator */
@ -1026,10 +1092,12 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
Precedence = BracketPrecedence + OperatorPrecedence[(int)TokenCast].PrefixPrecedence; Precedence = BracketPrecedence + OperatorPrecedence[(int)TokenCast].PrefixPrecedence;
ExpressionStackCollapse(Parser, &StackTop, Precedence+1, &IgnorePrecedence); ExpressionStackCollapse(Parser, &StackTop, Precedence+1, &IgnorePrecedence);
CastTypeValue = VariableAllocValueFromType(Parser->pc, Parser, &Parser->pc->TypeType, false, NULL, false); CastTypeValue = VariableAllocValueFromType(Parser->pc,
Parser, &Parser->pc->TypeType, false, NULL, false);
CastTypeValue->Val->Typ = CastType; CastTypeValue->Val->Typ = CastType;
ExpressionStackPushValueNode(Parser, &StackTop, CastTypeValue); ExpressionStackPushValueNode(Parser, &StackTop, CastTypeValue);
ExpressionStackPushOperator(Parser, &StackTop, OrderInfix, TokenCast, Precedence); ExpressionStackPushOperator(Parser, &StackTop, OrderInfix,
TokenCast, Precedence);
} else { } else {
/* boost the bracket operator precedence */ /* boost the bracket operator precedence */
BracketPrecedence += BRACKET_PRECEDENCE; BracketPrecedence += BRACKET_PRECEDENCE;
@ -1049,8 +1117,10 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
TempPrecedenceBoost = -1; TempPrecedenceBoost = -1;
} }
ExpressionStackCollapse(Parser, &StackTop, Precedence, &IgnorePrecedence); ExpressionStackCollapse(Parser, &StackTop, Precedence,
ExpressionStackPushOperator(Parser, &StackTop, OrderPrefix, Token, Precedence + TempPrecedenceBoost); &IgnorePrecedence);
ExpressionStackPushOperator(Parser, &StackTop, OrderPrefix,
Token, Precedence + TempPrecedenceBoost);
} }
} else { } else {
/* expect an infix or postfix operator */ /* expect an infix or postfix operator */
@ -1064,15 +1134,18 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
Done = true; Done = true;
} else { } else {
/* collapse to the bracket precedence */ /* collapse to the bracket precedence */
ExpressionStackCollapse(Parser, &StackTop, BracketPrecedence, &IgnorePrecedence); ExpressionStackCollapse(Parser, &StackTop,
BracketPrecedence, &IgnorePrecedence);
BracketPrecedence -= BRACKET_PRECEDENCE; BracketPrecedence -= BRACKET_PRECEDENCE;
} }
break; break;
default: default:
/* scan and collapse the stack to the precedence of this operator, then push */ /* scan and collapse the stack to the precedence of this operator, then push */
Precedence = BracketPrecedence + OperatorPrecedence[(int)Token].PostfixPrecedence; Precedence = BracketPrecedence + OperatorPrecedence[(int)Token].PostfixPrecedence;
ExpressionStackCollapse(Parser, &StackTop, Precedence, &IgnorePrecedence); ExpressionStackCollapse(Parser, &StackTop, Precedence,
ExpressionStackPushOperator(Parser, &StackTop, OrderPostfix, Token, Precedence); &IgnorePrecedence);
ExpressionStackPushOperator(Parser, &StackTop,
OrderPostfix, Token, Precedence);
break; break;
} }
} else if (OperatorPrecedence[(int)Token].InfixPrecedence != 0) { } else if (OperatorPrecedence[(int)Token].InfixPrecedence != 0) {
@ -1082,12 +1155,15 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
/* for right to left order, only go down to the next higher precedence so we evaluate it in reverse order */ /* for right to left order, only go down to the next higher precedence so we evaluate it in reverse order */
/* for left to right order, collapse down to this precedence so we evaluate it in forward order */ /* for left to right order, collapse down to this precedence so we evaluate it in forward order */
if (IS_LEFT_TO_RIGHT(OperatorPrecedence[(int)Token].InfixPrecedence)) if (IS_LEFT_TO_RIGHT(OperatorPrecedence[(int)Token].InfixPrecedence))
ExpressionStackCollapse(Parser, &StackTop, Precedence, &IgnorePrecedence); ExpressionStackCollapse(Parser, &StackTop, Precedence,
&IgnorePrecedence);
else else
ExpressionStackCollapse(Parser, &StackTop, Precedence+1, &IgnorePrecedence); ExpressionStackCollapse(Parser, &StackTop, Precedence+1,
&IgnorePrecedence);
if (Token == TokenDot || Token == TokenArrow) { if (Token == TokenDot || Token == TokenArrow) {
ExpressionGetStructElement(Parser, &StackTop, Token); /* this operator is followed by a struct element so handle it as a special case */ /* this operator is followed by a struct element so handle it as a special case */
ExpressionGetStructElement(Parser, &StackTop, Token);
} else { } else {
/* if it's a && or || operator we may not need to evaluate the right hand side of the expression */ /* if it's a && or || operator we may not need to evaluate the right hand side of the expression */
if ( (Token == TokenLogicalOr || Token == TokenLogicalAnd) && IS_NUMERIC_COERCIBLE(StackTop->Val)) { if ( (Token == TokenLogicalOr || Token == TokenLogicalAnd) && IS_NUMERIC_COERCIBLE(StackTop->Val)) {
@ -1098,7 +1174,8 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
} }
/* push the operator on the stack */ /* push the operator on the stack */
ExpressionStackPushOperator(Parser, &StackTop, OrderInfix, Token, Precedence); ExpressionStackPushOperator(Parser, &StackTop,
OrderInfix, Token, Precedence);
PrefixState = true; PrefixState = true;
switch (Token) { switch (Token) {
@ -1122,12 +1199,15 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
ProgramFail(Parser, "identifier not expected here"); ProgramFail(Parser, "identifier not expected here");
if (LexGetToken(Parser, NULL, false) == TokenOpenBracket) { if (LexGetToken(Parser, NULL, false) == TokenOpenBracket) {
ExpressionParseFunctionCall(Parser, &StackTop, LexValue->Val->Identifier, Parser->Mode == RunModeRun && Precedence < IgnorePrecedence); ExpressionParseFunctionCall(Parser, &StackTop,
LexValue->Val->Identifier,
Parser->Mode == RunModeRun && Precedence < IgnorePrecedence);
} else { } else {
if (Parser->Mode == RunModeRun /* && Precedence < IgnorePrecedence */) { if (Parser->Mode == RunModeRun /* && Precedence < IgnorePrecedence */) {
struct Value *VariableValue = NULL; struct Value *VariableValue = NULL;
VariableGet(Parser->pc, Parser, LexValue->Val->Identifier, &VariableValue); VariableGet(Parser->pc, Parser, LexValue->Val->Identifier,
&VariableValue);
if (VariableValue->Typ->Base == TypeMacro) { if (VariableValue->Typ->Base == TypeMacro) {
/* evaluate a macro as a kind of simple subroutine */ /* evaluate a macro as a kind of simple subroutine */
struct ParseState MacroParser; struct ParseState MacroParser;
@ -1145,7 +1225,8 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
} else if (VariableValue->Typ == &Parser->pc->VoidType) } else if (VariableValue->Typ == &Parser->pc->VoidType)
ProgramFail(Parser, "a void value isn't much use here"); ProgramFail(Parser, "a void value isn't much use here");
else else
ExpressionStackPushLValue(Parser, &StackTop, VariableValue, 0); /* it's a value variable */ ExpressionStackPushLValue(Parser, &StackTop,
VariableValue, 0); /* it's a value variable */
} else /* push a dummy value */ } else /* push a dummy value */
ExpressionPushInt(Parser, &StackTop, 0); ExpressionPushInt(Parser, &StackTop, 0);
@ -1175,7 +1256,8 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
PrefixState = false; PrefixState = false;
ParserCopy(Parser, &PreState); ParserCopy(Parser, &PreState);
TypeParse(Parser, &Typ, &Identifier, NULL); TypeParse(Parser, &Typ, &Identifier, NULL);
TypeValue = VariableAllocValueFromType(Parser->pc, Parser, &Parser->pc->TypeType, false, NULL, false); TypeValue = VariableAllocValueFromType(Parser->pc, Parser,
&Parser->pc->TypeType, false, NULL, false);
TypeValue->Val->Typ = Typ; TypeValue->Val->Typ = Typ;
ExpressionStackPushValueNode(Parser, &StackTop, TypeValue); ExpressionStackPushValueNode(Parser, &StackTop, TypeValue);
} else { } else {
@ -1183,7 +1265,6 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
ParserCopy(Parser, &PreState); ParserCopy(Parser, &PreState);
Done = true; Done = true;
} }
} while (!Done); } while (!Done);
/* check that brackets have been closed */ /* check that brackets have been closed */
@ -1203,7 +1284,8 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
*Result = StackTop->Val; *Result = StackTop->Val;
HeapPopStack(Parser->pc, StackTop, sizeof(struct ExpressionStack)); HeapPopStack(Parser->pc, StackTop, sizeof(struct ExpressionStack));
} else } else
HeapPopStack(Parser->pc, StackTop->Val, sizeof(struct ExpressionStack) + sizeof(struct Value) + TypeStackSizeValue(StackTop->Val)); HeapPopStack(Parser->pc, StackTop->Val,
sizeof(struct ExpressionStack)+sizeof(struct Value)+TypeStackSizeValue(StackTop->Val));
} }
#ifdef DEBUG_EXPRESSIONS #ifdef DEBUG_EXPRESSIONS
@ -1213,9 +1295,10 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
return StackTop != NULL; return StackTop != NULL;
} }
/* do a parameterised macro call */ /* do a parameterised macro call */
void ExpressionParseMacroCall(struct ParseState *Parser, struct ExpressionStack **StackTop, const char *MacroName, struct MacroDef *MDef) void ExpressionParseMacroCall(struct ParseState *Parser,
struct ExpressionStack **StackTop, const char *MacroName,
struct MacroDef *MDef)
{ {
int ArgCount; int ArgCount;
enum LexToken Token; enum LexToken Token;
@ -1228,7 +1311,8 @@ void ExpressionParseMacroCall(struct ParseState *Parser, struct ExpressionStack
ExpressionStackPushValueByType(Parser, StackTop, &Parser->pc->FPType); /* largest return type there is */ ExpressionStackPushValueByType(Parser, StackTop, &Parser->pc->FPType); /* largest return type there is */
ReturnValue = (*StackTop)->Val; ReturnValue = (*StackTop)->Val;
HeapPushStackFrame(Parser->pc); HeapPushStackFrame(Parser->pc);
ParamArray = HeapAllocStack(Parser->pc, sizeof(struct Value *) * MDef->NumParams); ParamArray = HeapAllocStack(Parser->pc,
sizeof(struct Value*)*MDef->NumParams);
if (ParamArray == NULL) if (ParamArray == NULL)
ProgramFail(Parser, "(ExpressionParseMacroCall) out of memory"); ProgramFail(Parser, "(ExpressionParseMacroCall) out of memory");
} else } else
@ -1276,7 +1360,8 @@ void ExpressionParseMacroCall(struct ParseState *Parser, struct ExpressionStack
Parser->pc->TopStackFrame->NumParams = ArgCount; Parser->pc->TopStackFrame->NumParams = ArgCount;
Parser->pc->TopStackFrame->ReturnValue = ReturnValue; Parser->pc->TopStackFrame->ReturnValue = ReturnValue;
for (Count = 0; Count < MDef->NumParams; Count++) for (Count = 0; Count < MDef->NumParams; Count++)
VariableDefine(Parser->pc, Parser, MDef->ParamName[Count], ParamArray[Count], NULL, true); VariableDefine(Parser->pc, Parser, MDef->ParamName[Count],
ParamArray[Count], NULL, true);
ExpressionParse(&MacroParser, &EvalValue); ExpressionParse(&MacroParser, &EvalValue);
ExpressionAssign(Parser, ReturnValue, EvalValue, true, MacroName, 0, false); ExpressionAssign(Parser, ReturnValue, EvalValue, true, MacroName, 0, false);
@ -1286,7 +1371,8 @@ void ExpressionParseMacroCall(struct ParseState *Parser, struct ExpressionStack
} }
/* do a function call */ /* do a function call */
void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionStack **StackTop, const char *FuncName, int RunIt) void ExpressionParseFunctionCall(struct ParseState *Parser,
struct ExpressionStack **StackTop, const char *FuncName, int RunIt)
{ {
int ArgCount; int ArgCount;
enum LexToken Token = LexGetToken(Parser, NULL, true); /* open bracket */ enum LexToken Token = LexGetToken(Parser, NULL, true); /* open bracket */
@ -1302,7 +1388,8 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
if (FuncValue->Typ->Base == TypeMacro) { if (FuncValue->Typ->Base == TypeMacro) {
/* this is actually a macro, not a function */ /* this is actually a macro, not a function */
ExpressionParseMacroCall(Parser, StackTop, FuncName, &FuncValue->Val->MacroDef); ExpressionParseMacroCall(Parser, StackTop, FuncName,
&FuncValue->Val->MacroDef);
return; return;
} }
@ -1312,7 +1399,7 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
ExpressionStackPushValueByType(Parser, StackTop, FuncValue->Val->FuncDef.ReturnType); ExpressionStackPushValueByType(Parser, StackTop, FuncValue->Val->FuncDef.ReturnType);
ReturnValue = (*StackTop)->Val; ReturnValue = (*StackTop)->Val;
HeapPushStackFrame(Parser->pc); HeapPushStackFrame(Parser->pc);
ParamArray = HeapAllocStack(Parser->pc, sizeof(struct Value *) * FuncValue->Val->FuncDef.NumParams); ParamArray = HeapAllocStack(Parser->pc, sizeof(struct Value*)*FuncValue->Val->FuncDef.NumParams);
if (ParamArray == NULL) if (ParamArray == NULL)
ProgramFail(Parser, "(ExpressionParseFunctionCall) out of memory"); ProgramFail(Parser, "(ExpressionParseFunctionCall) out of memory");
} else { } else {
@ -1324,12 +1411,14 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
ArgCount = 0; ArgCount = 0;
do { do {
if (RunIt && ArgCount < FuncValue->Val->FuncDef.NumParams) if (RunIt && ArgCount < FuncValue->Val->FuncDef.NumParams)
ParamArray[ArgCount] = VariableAllocValueFromType(Parser->pc, Parser, FuncValue->Val->FuncDef.ParamType[ArgCount], false, NULL, false); ParamArray[ArgCount] = VariableAllocValueFromType(Parser->pc, Parser,
FuncValue->Val->FuncDef.ParamType[ArgCount], false, NULL, false);
if (ExpressionParse(Parser, &Param)) { if (ExpressionParse(Parser, &Param)) {
if (RunIt) { if (RunIt) {
if (ArgCount < FuncValue->Val->FuncDef.NumParams) { if (ArgCount < FuncValue->Val->FuncDef.NumParams) {
ExpressionAssign(Parser, ParamArray[ArgCount], Param, true, FuncName, ArgCount+1, false); ExpressionAssign(Parser, ParamArray[ArgCount], Param, true,
FuncName, ArgCount+1, false);
VariableStackPop(Parser, Param); VariableStackPop(Parser, Param);
} else { } else {
if (!FuncValue->Val->FuncDef.VarArgs) if (!FuncValue->Val->FuncDef.VarArgs)
@ -1365,7 +1454,8 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
ProgramFail(Parser, "ExpressionParseFunctionCall FuncName: '%s' is undefined", FuncName); ProgramFail(Parser, "ExpressionParseFunctionCall FuncName: '%s' is undefined", FuncName);
ParserCopy(&FuncParser, &FuncValue->Val->FuncDef.Body); ParserCopy(&FuncParser, &FuncValue->Val->FuncDef.Body);
VariableStackFrameAdd(Parser, FuncName, FuncValue->Val->FuncDef.Intrinsic ? FuncValue->Val->FuncDef.NumParams : 0); VariableStackFrameAdd(Parser, FuncName,
FuncValue->Val->FuncDef.Intrinsic ? FuncValue->Val->FuncDef.NumParams : 0);
Parser->pc->TopStackFrame->NumParams = ArgCount; Parser->pc->TopStackFrame->NumParams = ArgCount;
Parser->pc->TopStackFrame->ReturnValue = ReturnValue; Parser->pc->TopStackFrame->ReturnValue = ReturnValue;
@ -1373,7 +1463,9 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
Parser->ScopeID = -1; Parser->ScopeID = -1;
for (Count = 0; Count < FuncValue->Val->FuncDef.NumParams; Count++) for (Count = 0; Count < FuncValue->Val->FuncDef.NumParams; Count++)
VariableDefine(Parser->pc, Parser, FuncValue->Val->FuncDef.ParamName[Count], ParamArray[Count], NULL, true); VariableDefine(Parser->pc, Parser,
FuncValue->Val->FuncDef.ParamName[Count], ParamArray[Count],
NULL, true);
Parser->ScopeID = OldScopeID; Parser->ScopeID = OldScopeID;
@ -1382,15 +1474,19 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
if (RunIt) { if (RunIt) {
if (FuncParser.Mode == RunModeRun && FuncValue->Val->FuncDef.ReturnType != &Parser->pc->VoidType) if (FuncParser.Mode == RunModeRun && FuncValue->Val->FuncDef.ReturnType != &Parser->pc->VoidType)
ProgramFail(&FuncParser, "no value returned from a function returning %t", FuncValue->Val->FuncDef.ReturnType); ProgramFail(&FuncParser,
"no value returned from a function returning %t",
FuncValue->Val->FuncDef.ReturnType);
else if (FuncParser.Mode == RunModeGoto) else if (FuncParser.Mode == RunModeGoto)
ProgramFail(&FuncParser, "couldn't find goto label '%s'", FuncParser.SearchGotoLabel); ProgramFail(&FuncParser, "couldn't find goto label '%s'",
FuncParser.SearchGotoLabel);
} }
VariableStackFramePop(Parser); VariableStackFramePop(Parser);
} else } else
FuncValue->Val->FuncDef.Intrinsic(Parser, ReturnValue, ParamArray, ArgCount); FuncValue->Val->FuncDef.Intrinsic(Parser, ReturnValue, ParamArray,
ArgCount);
HeapPopStackFrame(Parser->pc); HeapPopStackFrame(Parser->pc);
} }

6
heap.c
View file

@ -52,7 +52,8 @@ void *HeapAllocStack(Picoc *pc, int Size)
char *NewMem = pc->HeapStackTop; char *NewMem = pc->HeapStackTop;
char *NewTop = (char*)pc->HeapStackTop + MEM_ALIGN(Size); char *NewTop = (char*)pc->HeapStackTop + MEM_ALIGN(Size);
#ifdef DEBUG_HEAP #ifdef DEBUG_HEAP
printf("HeapAllocStack(%ld) at 0x%lx\n", (unsigned long)MEM_ALIGN(Size), (unsigned long)pc->HeapStackTop); printf("HeapAllocStack(%ld) at 0x%lx\n", (unsigned long)MEM_ALIGN(Size),
(unsigned long)pc->HeapStackTop);
#endif #endif
if (NewTop > (char*)pc->HeapBottom) if (NewTop > (char*)pc->HeapBottom)
return NULL; return NULL;
@ -66,7 +67,8 @@ void *HeapAllocStack(Picoc *pc, int Size)
void HeapUnpopStack(Picoc *pc, int Size) void HeapUnpopStack(Picoc *pc, int Size)
{ {
#ifdef DEBUG_HEAP #ifdef DEBUG_HEAP
printf("HeapUnpopStack(%ld) at 0x%lx\n", (unsigned long)MEM_ALIGN(Size), (unsigned long)pc->HeapStackTop); printf("HeapUnpopStack(%ld) at 0x%lx\n", (unsigned long)MEM_ALIGN(Size),
(unsigned long)pc->HeapStackTop);
#endif #endif
pc->HeapStackTop = (void*)((char*)pc->HeapStackTop + MEM_ALIGN(Size)); pc->HeapStackTop = (void*)((char*)pc->HeapStackTop + MEM_ALIGN(Size));
} }

View file

@ -39,7 +39,9 @@ void IncludeCleanup(Picoc *pc)
} }
/* register a new build-in include file */ /* register a new build-in include file */
void IncludeRegister(Picoc *pc, const char *IncludeName, void (*SetupFunction)(Picoc *pc), struct LibraryFunction *FuncList, const char *SetupCSource) void IncludeRegister(Picoc *pc, const char *IncludeName,
void (*SetupFunction)(Picoc *pc), struct LibraryFunction *FuncList,
const char *SetupCSource)
{ {
struct IncludeLibrary *NewLib = HeapAllocMem(pc, sizeof(struct IncludeLibrary)); struct IncludeLibrary *NewLib = HeapAllocMem(pc, sizeof(struct IncludeLibrary));
NewLib->IncludeName = TableStrRegister(pc, IncludeName); NewLib->IncludeName = TableStrRegister(pc, IncludeName);
@ -77,7 +79,8 @@ void IncludeFile(Picoc *pc, char *FileName)
/* parse the setup C source code - may define types etc. */ /* parse the setup C source code - may define types etc. */
if (LInclude->SetupCSource != NULL) if (LInclude->SetupCSource != NULL)
PicocParse(pc, FileName, LInclude->SetupCSource, strlen(LInclude->SetupCSource), true, true, false, false); PicocParse(pc, FileName, LInclude->SetupCSource,
strlen(LInclude->SetupCSource), true, true, false, false);
/* set up the library functions */ /* set up the library functions */
if (LInclude->FuncList != NULL) if (LInclude->FuncList != NULL)

221
lex.c
View file

@ -80,10 +80,13 @@ void LexInit(Picoc *pc)
{ {
int Count; int Count;
TableInitTable(&pc->ReservedWordTable, &pc->ReservedWordHashTable[0], sizeof(ReservedWords) / sizeof(struct ReservedWord) * 2, true); TableInitTable(&pc->ReservedWordTable, &pc->ReservedWordHashTable[0],
sizeof(ReservedWords) / sizeof(struct ReservedWord) * 2, true);
for (Count = 0; Count < sizeof(ReservedWords) / sizeof(struct ReservedWord); Count++) { for (Count = 0; Count < sizeof(ReservedWords) / sizeof(struct ReservedWord); Count++) {
TableSet(pc, &pc->ReservedWordTable, TableStrRegister(pc, ReservedWords[Count].Word), (struct Value *)&ReservedWords[Count], NULL, 0, 0); TableSet(pc, &pc->ReservedWordTable,
TableStrRegister(pc, ReservedWords[Count].Word),
(struct Value *)&ReservedWords[Count], NULL, 0, 0);
} }
pc->LexValue.Typ = NULL; pc->LexValue.Typ = NULL;
@ -103,7 +106,8 @@ void LexCleanup(Picoc *pc)
LexInteractiveClear(pc, NULL); LexInteractiveClear(pc, NULL);
for (Count = 0; Count < sizeof(ReservedWords) / sizeof(struct ReservedWord); Count++) for (Count = 0; Count < sizeof(ReservedWords) / sizeof(struct ReservedWord); Count++)
TableDelete(pc, &pc->ReservedWordTable, TableStrRegister(pc, ReservedWords[Count].Word)); TableDelete(pc, &pc->ReservedWordTable,
TableStrRegister(pc, ReservedWords[Count].Word));
} }
/* check if a word is a reserved word - used while scanning */ /* check if a word is a reserved word - used while scanning */
@ -178,7 +182,8 @@ enum LexToken LexGetNumber(Picoc *pc, struct LexState *Lexer, struct Value *Valu
if (*Lexer->Pos == '.') { if (*Lexer->Pos == '.') {
LEXER_INC(Lexer); LEXER_INC(Lexer);
for (FPDiv = 1.0/Base; Lexer->Pos != Lexer->End && IS_BASE_DIGIT(*Lexer->Pos, Base); LEXER_INC(Lexer), FPDiv /= (double)Base) { for (FPDiv = 1.0/Base; Lexer->Pos != Lexer->End && IS_BASE_DIGIT(*Lexer->Pos, Base);
LEXER_INC(Lexer), FPDiv /= (double)Base) {
FPResult += GET_BASE_DIGIT(*Lexer->Pos) * FPDiv; FPResult += GET_BASE_DIGIT(*Lexer->Pos) * FPDiv;
} }
} }
@ -239,7 +244,8 @@ enum LexToken LexGetWord(Picoc *pc, struct LexState *Lexer, struct Value *Value)
} }
/* unescape a character from an octal character constant */ /* unescape a character from an octal character constant */
unsigned char LexUnEscapeCharacterConstant(const char **From, const char *End, unsigned char FirstChar, int Base) unsigned char LexUnEscapeCharacterConstant(const char **From, const char *End,
unsigned char FirstChar, int Base)
{ {
int CCount; int CCount;
unsigned char Total = GET_BASE_DIGIT(FirstChar); unsigned char Total = GET_BASE_DIGIT(FirstChar);
@ -293,7 +299,8 @@ unsigned char LexUnEscapeCharacter(const char **From, const char *End)
} }
/* get a string constant - used while scanning */ /* get a string constant - used while scanning */
enum LexToken LexGetStringConstant(Picoc *pc, struct LexState *Lexer, struct Value *Value, char EndChar) enum LexToken LexGetStringConstant(Picoc *pc, struct LexState *Lexer,
struct Value *Value, char EndChar)
{ {
int Escape = false; int Escape = false;
const char *StartPos = Lexer->Pos; const char *StartPos = Lexer->Pos;
@ -353,7 +360,8 @@ enum LexToken LexGetStringConstant(Picoc *pc, struct LexState *Lexer, struct Val
} }
/* get a character constant - used while scanning */ /* get a character constant - used while scanning */
enum LexToken LexGetCharacterConstant(Picoc *pc, struct LexState *Lexer, struct Value *Value) enum LexToken LexGetCharacterConstant(Picoc *pc, struct LexState *Lexer,
struct Value *Value)
{ {
Value->Typ = &pc->CharType; Value->Typ = &pc->CharType;
Value->Val->Character = LexUnEscapeCharacter(&Lexer->Pos, Lexer->End); Value->Val->Character = LexUnEscapeCharacter(&Lexer->Pos, Lexer->End);
@ -365,7 +373,8 @@ enum LexToken LexGetCharacterConstant(Picoc *pc, struct LexState *Lexer, struct
} }
/* skip a comment - used while scanning */ /* skip a comment - used while scanning */
void LexSkipComment(struct LexState *Lexer, char NextChar, enum LexToken *ReturnToken) void LexSkipComment(struct LexState *Lexer, char NextChar,
enum LexToken *ReturnToken)
{ {
if (NextChar == '*') { if (NextChar == '*') {
/* conventional C comment */ /* conventional C comment */
@ -388,7 +397,8 @@ void LexSkipComment(struct LexState *Lexer, char NextChar, enum LexToken *Return
} }
/* get a single token from the source - used while scanning */ /* get a single token from the source - used while scanning */
enum LexToken LexScanGetToken(Picoc *pc, struct LexState *Lexer, struct Value **Value) enum LexToken LexScanGetToken(Picoc *pc, struct LexState *Lexer,
struct Value **Value)
{ {
char ThisChar; char ThisChar;
char NextChar; char NextChar;
@ -431,33 +441,99 @@ enum LexToken LexScanGetToken(Picoc *pc, struct LexState *Lexer, struct Value **
NextChar = (Lexer->Pos+1 != Lexer->End) ? *(Lexer->Pos+1) : 0; NextChar = (Lexer->Pos+1 != Lexer->End) ? *(Lexer->Pos+1) : 0;
LEXER_INC(Lexer); LEXER_INC(Lexer);
switch (ThisChar) { switch (ThisChar) {
case '"': GotToken = LexGetStringConstant(pc, Lexer, *Value, '"'); break; case '"':
case '\'': GotToken = LexGetCharacterConstant(pc, Lexer, *Value); break; GotToken = LexGetStringConstant(pc, Lexer, *Value, '"');
case '(': if (Lexer->Mode == LexModeHashDefineSpaceIdent) GotToken = TokenOpenMacroBracket; else GotToken = TokenOpenBracket; Lexer->Mode = LexModeNormal; break; break;
case ')': GotToken = TokenCloseBracket; break; case '\'':
case '=': NEXTIS('=', TokenEqual, TokenAssign); break; GotToken = LexGetCharacterConstant(pc, Lexer, *Value);
case '+': NEXTIS3('=', TokenAddAssign, '+', TokenIncrement, TokenPlus); break; break;
case '-': NEXTIS4('=', TokenSubtractAssign, '>', TokenArrow, '-', TokenDecrement, TokenMinus); break; case '(':
case '*': NEXTIS('=', TokenMultiplyAssign, TokenAsterisk); break; if (Lexer->Mode == LexModeHashDefineSpaceIdent)
case '/': if (NextChar == '/' || NextChar == '*') { LEXER_INC(Lexer); LexSkipComment(Lexer, NextChar, &GotToken); } else NEXTIS('=', TokenDivideAssign, TokenSlash); break; GotToken = TokenOpenMacroBracket;
case '%': NEXTIS('=', TokenModulusAssign, TokenModulus); break; else
case '<': if (Lexer->Mode == LexModeHashInclude) GotToken = LexGetStringConstant(pc, Lexer, *Value, '>'); else { NEXTIS3PLUS('=', TokenLessEqual, '<', TokenShiftLeft, '=', TokenShiftLeftAssign, TokenLessThan); } break; GotToken = TokenOpenBracket;
case '>': NEXTIS3PLUS('=', TokenGreaterEqual, '>', TokenShiftRight, '=', TokenShiftRightAssign, TokenGreaterThan); break; Lexer->Mode = LexModeNormal;
case ';': GotToken = TokenSemicolon; break; break;
case '&': NEXTIS3('=', TokenArithmeticAndAssign, '&', TokenLogicalAnd, TokenAmpersand); break; case ')':
case '|': NEXTIS3('=', TokenArithmeticOrAssign, '|', TokenLogicalOr, TokenArithmeticOr); break; GotToken = TokenCloseBracket;
case '{': GotToken = TokenLeftBrace; break; break;
case '}': GotToken = TokenRightBrace; break; case '=':
case '[': GotToken = TokenLeftSquareBracket; break; NEXTIS('=', TokenEqual, TokenAssign);
case ']': GotToken = TokenRightSquareBracket; break; break;
case '!': NEXTIS('=', TokenNotEqual, TokenUnaryNot); break; case '+':
case '^': NEXTIS('=', TokenArithmeticExorAssign, TokenArithmeticExor); break; NEXTIS3('=', TokenAddAssign, '+', TokenIncrement, TokenPlus);
case '~': GotToken = TokenUnaryExor; break; break;
case ',': GotToken = TokenComma; break; case '-':
case '.': NEXTISEXACTLY3('.', '.', TokenEllipsis, TokenDot); break; NEXTIS4('=', TokenSubtractAssign, '>', TokenArrow, '-',
case '?': GotToken = TokenQuestionMark; break; TokenDecrement, TokenMinus);
case ':': GotToken = TokenColon; break; break;
default: LexFail(pc, Lexer, "illegal character '%c'", ThisChar); break; case '*':
NEXTIS('=', TokenMultiplyAssign, TokenAsterisk); break;
case '/':
if (NextChar == '/' || NextChar == '*') {
LEXER_INC(Lexer);
LexSkipComment(Lexer, NextChar, &GotToken);
} else
NEXTIS('=', TokenDivideAssign, TokenSlash);
break;
case '%':
NEXTIS('=', TokenModulusAssign, TokenModulus); break;
case '<':
if (Lexer->Mode == LexModeHashInclude)
GotToken = LexGetStringConstant(pc, Lexer, *Value, '>');
else {
NEXTIS3PLUS('=', TokenLessEqual, '<', TokenShiftLeft, '=',
TokenShiftLeftAssign, TokenLessThan);
}
break;
case '>':
NEXTIS3PLUS('=', TokenGreaterEqual, '>', TokenShiftRight, '=', TokenShiftRightAssign, TokenGreaterThan);
break;
case ';':
GotToken = TokenSemicolon;
break;
case '&':
NEXTIS3('=', TokenArithmeticAndAssign, '&', TokenLogicalAnd, TokenAmpersand);
break;
case '|':
NEXTIS3('=', TokenArithmeticOrAssign, '|', TokenLogicalOr, TokenArithmeticOr);
break;
case '{':
GotToken = TokenLeftBrace;
break;
case '}':
GotToken = TokenRightBrace;
break;
case '[':
GotToken = TokenLeftSquareBracket;
break;
case ']':
GotToken = TokenRightSquareBracket;
break;
case '!':
NEXTIS('=', TokenNotEqual, TokenUnaryNot);
break;
case '^':
NEXTIS('=', TokenArithmeticExorAssign, TokenArithmeticExor);
break;
case '~':
GotToken = TokenUnaryExor;
break;
case ',':
GotToken = TokenComma;
break;
case '.':
NEXTISEXACTLY3('.', '.', TokenEllipsis, TokenDot);
break;
case '?':
GotToken = TokenQuestionMark;
break;
case ':':
GotToken = TokenColon;
break;
default:
LexFail(pc, Lexer, "illegal character '%c'", ThisChar);
break;
} }
} while (GotToken == TokenNone); } while (GotToken == TokenNone);
@ -542,7 +618,8 @@ void *LexTokenise(Picoc *pc, struct LexState *Lexer, int *TokenLen)
} }
/* lexically analyse some source text */ /* lexically analyse some source text */
void *LexAnalyse(Picoc *pc, const char *FileName, const char *Source, int SourceLen, int *TokenLen) void *LexAnalyse(Picoc *pc, const char *FileName, const char *Source,
int SourceLen, int *TokenLen)
{ {
struct LexState Lexer; struct LexState Lexer;
@ -559,7 +636,8 @@ void *LexAnalyse(Picoc *pc, const char *FileName, const char *Source, int Source
} }
/* prepare to parse a pre-tokenised buffer */ /* prepare to parse a pre-tokenised buffer */
void LexInitParser(struct ParseState *Parser, Picoc *pc, const char *SourceText, void *TokenSource, char *FileName, int RunIt, int EnableDebugger) void LexInitParser(struct ParseState *Parser, Picoc *pc, const char *SourceText,
void *TokenSource, char *FileName, int RunIt, int EnableDebugger)
{ {
Parser->pc = pc; Parser->pc = pc;
Parser->Pos = TokenSource; Parser->Pos = TokenSource;
@ -575,7 +653,8 @@ void LexInitParser(struct ParseState *Parser, Picoc *pc, const char *SourceText,
} }
/* get the next token, without pre-processing */ /* get the next token, without pre-processing */
enum LexToken LexGetRawToken(struct ParseState *Parser, struct Value **Value, int IncPos) enum LexToken LexGetRawToken(struct ParseState *Parser, struct Value **Value,
int IncPos)
{ {
int ValueSize; int ValueSize;
char *Prompt = NULL; char *Prompt = NULL;
@ -602,7 +681,7 @@ enum LexToken LexGetRawToken(struct ParseState *Parser, struct Value **Value, in
int LineBytes; int LineBytes;
struct TokenLine *LineNode; struct TokenLine *LineNode;
if (pc->InteractiveHead == NULL || (unsigned char *)Parser->Pos == &pc->InteractiveTail->Tokens[pc->InteractiveTail->NumBytes-TOKEN_DATA_OFFSET]) { if (pc->InteractiveHead == NULL || (unsigned char*)Parser->Pos == &pc->InteractiveTail->Tokens[pc->InteractiveTail->NumBytes-TOKEN_DATA_OFFSET]) {
/* get interactive input */ /* get interactive input */
if (pc->LexUseStatementPrompt) { if (pc->LexUseStatementPrompt) {
Prompt = INTERACTIVE_PROMPT_STATEMENT; Prompt = INTERACTIVE_PROMPT_STATEMENT;
@ -614,8 +693,10 @@ enum LexToken LexGetRawToken(struct ParseState *Parser, struct Value **Value, in
return TokenEOF; return TokenEOF;
/* put the new line at the end of the linked list of interactive lines */ /* put the new line at the end of the linked list of interactive lines */
LineTokens = LexAnalyse(pc, pc->StrEmpty, &LineBuffer[0], strlen(LineBuffer), &LineBytes); LineTokens = LexAnalyse(pc, pc->StrEmpty, &LineBuffer[0],
LineNode = VariableAlloc(pc, Parser, sizeof(struct TokenLine), true); strlen(LineBuffer), &LineBytes);
LineNode = VariableAlloc(pc, Parser,
sizeof(struct TokenLine), true);
LineNode->Tokens = LineTokens; LineNode->Tokens = LineTokens;
LineNode->NumBytes = LineBytes; LineNode->NumBytes = LineBytes;
if (pc->InteractiveHead == NULL) { if (pc->InteractiveHead == NULL) {
@ -654,15 +735,27 @@ enum LexToken LexGetRawToken(struct ParseState *Parser, struct Value **Value, in
/* this token requires a value - unpack it */ /* this token requires a value - unpack it */
if (Value != NULL) { if (Value != NULL) {
switch (Token) { switch (Token) {
case TokenStringConstant: pc->LexValue.Typ = pc->CharPtrType; break; case TokenStringConstant:
case TokenIdentifier: pc->LexValue.Typ = NULL; break; pc->LexValue.Typ = pc->CharPtrType;
case TokenIntegerConstant: pc->LexValue.Typ = &pc->LongType; break; break;
case TokenCharacterConstant: pc->LexValue.Typ = &pc->CharType; break; case TokenIdentifier:
case TokenFPConstant: pc->LexValue.Typ = &pc->FPType; break; pc->LexValue.Typ = NULL;
default: break; break;
case TokenIntegerConstant:
pc->LexValue.Typ = &pc->LongType;
break;
case TokenCharacterConstant:
pc->LexValue.Typ = &pc->CharType;
break;
case TokenFPConstant:
pc->LexValue.Typ = &pc->FPType;
break;
default:
break;
} }
memcpy((void *)pc->LexValue.Val, (void *)((char *)Parser->Pos + TOKEN_DATA_OFFSET), ValueSize); memcpy((void *)pc->LexValue.Val,
(void *)((char *)Parser->Pos+TOKEN_DATA_OFFSET), ValueSize);
pc->LexValue.ValOnHeap = false; pc->LexValue.ValOnHeap = false;
pc->LexValue.ValOnStack = false; pc->LexValue.ValOnStack = false;
pc->LexValue.IsLValue = false; pc->LexValue.IsLValue = false;
@ -704,7 +797,8 @@ void LexHashIfdef(struct ParseState *Parser, int IfNot)
ProgramFail(Parser, "identifier expected"); ProgramFail(Parser, "identifier expected");
/* is the identifier defined? */ /* is the identifier defined? */
IsDefined = TableGet(&Parser->pc->GlobalTable, IdentValue->Val->Identifier, &SavedValue, NULL, NULL, NULL); IsDefined = TableGet(&Parser->pc->GlobalTable, IdentValue->Val->Identifier,
&SavedValue, NULL, NULL, NULL);
if (Parser->HashIfEvaluateToLevel == Parser->HashIfLevel && ((IsDefined && !IfNot) || (!IsDefined && IfNot))) { if (Parser->HashIfEvaluateToLevel == Parser->HashIfLevel && ((IsDefined && !IfNot) || (!IsDefined && IfNot))) {
/* #if is active, evaluate to this new level */ /* #if is active, evaluate to this new level */
Parser->HashIfEvaluateToLevel++; Parser->HashIfEvaluateToLevel++;
@ -724,7 +818,8 @@ void LexHashIf(struct ParseState *Parser)
if (Token == TokenIdentifier) { if (Token == TokenIdentifier) {
/* look up a value from a macro definition */ /* look up a value from a macro definition */
if (!TableGet(&Parser->pc->GlobalTable, IdentValue->Val->Identifier, &SavedValue, NULL, NULL, NULL)) if (!TableGet(&Parser->pc->GlobalTable, IdentValue->Val->Identifier,
&SavedValue, NULL, NULL, NULL))
ProgramFail(Parser, "'%s' is undefined", IdentValue->Val->Identifier); ProgramFail(Parser, "'%s' is undefined", IdentValue->Val->Identifier);
if (SavedValue->Typ->Base != TypeMacro) if (SavedValue->Typ->Base != TypeMacro)
@ -820,12 +915,24 @@ enum LexToken LexGetToken(struct ParseState *Parser, struct Value **Value, int I
Token = LexGetRawToken(Parser, Value, IncPos); Token = LexGetRawToken(Parser, Value, IncPos);
switch (Token) { switch (Token) {
case TokenHashIfdef: LexHashIncPos(Parser, IncPos); LexHashIfdef(Parser, false); break; case TokenHashIfdef:
case TokenHashIfndef: LexHashIncPos(Parser, IncPos); LexHashIfdef(Parser, true); break; LexHashIncPos(Parser, IncPos); LexHashIfdef(Parser, false);
case TokenHashIf: LexHashIncPos(Parser, IncPos); LexHashIf(Parser); break; break;
case TokenHashElse: LexHashIncPos(Parser, IncPos); LexHashElse(Parser); break; case TokenHashIfndef:
case TokenHashEndif: LexHashIncPos(Parser, IncPos); LexHashEndif(Parser); break; LexHashIncPos(Parser, IncPos); LexHashIfdef(Parser, true);
default: WasPreProcToken = false; break; break;
case TokenHashIf:
LexHashIncPos(Parser, IncPos); LexHashIf(Parser);
break;
case TokenHashElse:
LexHashIncPos(Parser, IncPos); LexHashElse(Parser);
break;
case TokenHashEndif:
LexHashIncPos(Parser, IncPos); LexHashEndif(Parser);
break;
default:
WasPreProcToken = false;
break;
} }
/* if we're going to reject this token, increment the token pointer to the next one */ /* if we're going to reject this token, increment the token pointer to the next one */

92
parse.c
View file

@ -26,7 +26,8 @@ void ParseCleanup(Picoc *pc)
} }
/* parse a statement, but only run it if Condition is true */ /* parse a statement, but only run it if Condition is true */
enum ParseResult ParseStatementMaybeRun(struct ParseState *Parser, int Condition, int CheckTrailingSemicolon) enum ParseResult ParseStatementMaybeRun(struct ParseState *Parser,
int Condition, int CheckTrailingSemicolon)
{ {
if (Parser->Mode != RunModeSkip && !Condition) { if (Parser->Mode != RunModeSkip && !Condition) {
enum RunMode OldMode = Parser->Mode; enum RunMode OldMode = Parser->Mode;
@ -58,7 +59,8 @@ int ParseCountParams(struct ParseState *Parser)
} }
/* parse a function definition and store it for later */ /* parse a function definition and store it for later */
struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, char *Identifier) struct Value *ParseFunctionDefinition(struct ParseState *Parser,
struct ValueType *ReturnType, char *Identifier)
{ {
int ParamCount = 0; int ParamCount = 0;
char *ParamIdentifier; char *ParamIdentifier;
@ -79,13 +81,17 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp
if (ParamCount > PARAMETER_MAX) if (ParamCount > PARAMETER_MAX)
ProgramFail(Parser, "too many parameters (%d allowed)", PARAMETER_MAX); ProgramFail(Parser, "too many parameters (%d allowed)", PARAMETER_MAX);
FuncValue = VariableAllocValueAndData(pc, Parser, sizeof(struct FuncDef) + sizeof(struct ValueType *) * ParamCount + sizeof(const char *) * ParamCount, false, NULL, true); FuncValue = VariableAllocValueAndData(pc, Parser,
sizeof(struct FuncDef)+sizeof(struct ValueType*)*ParamCount+sizeof(const char*)*ParamCount,
false, NULL, true);
FuncValue->Typ = &pc->FunctionType; FuncValue->Typ = &pc->FunctionType;
FuncValue->Val->FuncDef.ReturnType = ReturnType; FuncValue->Val->FuncDef.ReturnType = ReturnType;
FuncValue->Val->FuncDef.NumParams = ParamCount; FuncValue->Val->FuncDef.NumParams = ParamCount;
FuncValue->Val->FuncDef.VarArgs = false; FuncValue->Val->FuncDef.VarArgs = false;
FuncValue->Val->FuncDef.ParamType = (struct ValueType **)((char *)FuncValue->Val + sizeof(struct FuncDef)); FuncValue->Val->FuncDef.ParamType =
FuncValue->Val->FuncDef.ParamName = (char **)((char *)FuncValue->Val->FuncDef.ParamType + sizeof(struct ValueType *) * ParamCount); (struct ValueType**)((char*)FuncValue->Val+sizeof(struct FuncDef));
FuncValue->Val->FuncDef.ParamName =
(char**)((char*)FuncValue->Val->FuncDef.ParamType+sizeof(struct ValueType*)*ParamCount);
for (ParamCount = 0; ParamCount < FuncValue->Val->FuncDef.NumParams; ParamCount++) { for (ParamCount = 0; ParamCount < FuncValue->Val->FuncDef.NumParams; ParamCount++) {
/* harvest the parameters into the function definition */ /* harvest the parameters into the function definition */
@ -129,7 +135,7 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp
/* look for a function body */ /* look for a function body */
Token = LexGetToken(Parser, NULL, false); Token = LexGetToken(Parser, NULL, false);
if (Token == TokenSemicolon) if (Token == TokenSemicolon)
LexGetToken(Parser, NULL, true); /* it's a prototype, absorb the trailing semicolon */ LexGetToken(Parser, NULL, true); /* it's a prototype, absorb the trailing semicolon */
else { else {
/* it's a full function definition with a body */ /* it's a full function definition with a body */
if (Token != TokenLeftBrace) if (Token != TokenLeftBrace)
@ -152,14 +158,16 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp
} }
} }
if (!TableSet(pc, &pc->GlobalTable, Identifier, FuncValue, (char *)Parser->FileName, Parser->Line, Parser->CharacterPos)) if (!TableSet(pc, &pc->GlobalTable, Identifier, FuncValue,
(char*)Parser->FileName, Parser->Line, Parser->CharacterPos))
ProgramFail(Parser, "'%s' is already defined", Identifier); ProgramFail(Parser, "'%s' is already defined", Identifier);
return FuncValue; return FuncValue;
} }
/* parse an array initialiser and assign to a variable */ /* parse an array initialiser and assign to a variable */
int ParseArrayInitialiser(struct ParseState *Parser, struct Value *NewVariable, int DoAssignment) int ParseArrayInitialiser(struct ParseState *Parser, struct Value *NewVariable,
int DoAssignment)
{ {
int ArrayIndex = 0; int ArrayIndex = 0;
enum LexToken Token; enum LexToken Token;
@ -174,10 +182,13 @@ int ParseArrayInitialiser(struct ParseState *Parser, struct Value *NewVariable,
NumElements = ParseArrayInitialiser(&CountParser, NewVariable, false); NumElements = ParseArrayInitialiser(&CountParser, NewVariable, false);
if (NewVariable->Typ->Base != TypeArray) if (NewVariable->Typ->Base != TypeArray)
AssignFail(Parser, "%t from array initializer", NewVariable->Typ, NULL, 0, 0, NULL, 0); AssignFail(Parser, "%t from array initializer", NewVariable->Typ,
NULL, 0, 0, NULL, 0);
if (NewVariable->Typ->ArraySize == 0) { if (NewVariable->Typ->ArraySize == 0) {
NewVariable->Typ = TypeGetMatching(Parser->pc, Parser, NewVariable->Typ->FromType, NewVariable->Typ->Base, NumElements, NewVariable->Typ->Identifier, true); NewVariable->Typ = TypeGetMatching(Parser->pc, Parser,
NewVariable->Typ->FromType, NewVariable->Typ->Base, NumElements,
NewVariable->Typ->Identifier, true);
VariableRealloc(Parser, NewVariable, TypeSizeValue(NewVariable, false)); VariableRealloc(Parser, NewVariable, TypeSizeValue(NewVariable, false));
} }
#ifdef DEBUG_ARRAY_INITIALIZER #ifdef DEBUG_ARRAY_INITIALIZER
@ -194,13 +205,19 @@ int ParseArrayInitialiser(struct ParseState *Parser, struct Value *NewVariable,
int SubArraySize = 0; int SubArraySize = 0;
struct Value *SubArray = NewVariable; struct Value *SubArray = NewVariable;
if (Parser->Mode == RunModeRun && DoAssignment) { if (Parser->Mode == RunModeRun && DoAssignment) {
SubArraySize = TypeSize(NewVariable->Typ->FromType, NewVariable->Typ->FromType->ArraySize, true); SubArraySize = TypeSize(NewVariable->Typ->FromType,
SubArray = VariableAllocValueFromExistingData(Parser, NewVariable->Typ->FromType, (union AnyValue *)(&NewVariable->Val->ArrayMem[0] + SubArraySize * ArrayIndex), true, NewVariable); NewVariable->Typ->FromType->ArraySize, true);
SubArray = VariableAllocValueFromExistingData(Parser,
NewVariable->Typ->FromType,
(union AnyValue*)(&NewVariable->Val->ArrayMem[0]+SubArraySize*ArrayIndex),
true, NewVariable);
#ifdef DEBUG_ARRAY_INITIALIZER #ifdef DEBUG_ARRAY_INITIALIZER
int FullArraySize = TypeSize(NewVariable->Typ, NewVariable->Typ->ArraySize, true); int FullArraySize = TypeSize(NewVariable->Typ,
NewVariable->Typ->ArraySize, true);
PRINT_SOURCE_POS(); PRINT_SOURCE_POS();
PRINT_TYPE(NewVariable->Typ) PRINT_TYPE(NewVariable->Typ)
printf("[%d] subarray size: %d (full: %d,%d) \n", ArrayIndex, SubArraySize, FullArraySize, NewVariable->Typ->ArraySize); printf("[%d] subarray size: %d (full: %d,%d) \n", ArrayIndex,
SubArraySize, FullArraySize, NewVariable->Typ->ArraySize);
#endif #endif
if (ArrayIndex >= NewVariable->Typ->ArraySize) if (ArrayIndex >= NewVariable->Typ->ArraySize)
ProgramFail(Parser, "too many array elements"); ProgramFail(Parser, "too many array elements");
@ -227,11 +244,15 @@ int ParseArrayInitialiser(struct ParseState *Parser, struct Value *NewVariable,
ElementSize = TypeSize(ElementType, ElementType->ArraySize, true); ElementSize = TypeSize(ElementType, ElementType->ArraySize, true);
#ifdef DEBUG_ARRAY_INITIALIZER #ifdef DEBUG_ARRAY_INITIALIZER
PRINT_SOURCE_POS(); PRINT_SOURCE_POS();
printf("[%d/%d] element size: %d (x%d) \n", ArrayIndex, TotalSize, ElementSize, ElementType->ArraySize); printf("[%d/%d] element size: %d (x%d) \n", ArrayIndex, TotalSize,
ElementSize, ElementType->ArraySize);
#endif #endif
if (ArrayIndex >= TotalSize) if (ArrayIndex >= TotalSize)
ProgramFail(Parser, "too many array elements"); ProgramFail(Parser, "too many array elements");
ArrayElement = VariableAllocValueFromExistingData(Parser, ElementType, (union AnyValue *)(&NewVariable->Val->ArrayMem[0] + ElementSize * ArrayIndex), true, NewVariable); ArrayElement = VariableAllocValueFromExistingData(Parser,
ElementType,
(union AnyValue*)(&NewVariable->Val->ArrayMem[0]+ElementSize*ArrayIndex),
true, NewVariable);
} }
/* this is a normal expression initialiser */ /* this is a normal expression initialiser */
@ -264,7 +285,8 @@ int ParseArrayInitialiser(struct ParseState *Parser, struct Value *NewVariable,
} }
/* assign an initial value to a variable */ /* assign an initial value to a variable */
void ParseDeclarationAssignment(struct ParseState *Parser, struct Value *NewVariable, int DoAssignment) void ParseDeclarationAssignment(struct ParseState *Parser,
struct Value *NewVariable, int DoAssignment)
{ {
struct Value *CValue; struct Value *CValue;
@ -312,12 +334,14 @@ int ParseDeclaration(struct ParseState *Parser, enum LexToken Token)
ProgramFail(Parser, "can't define a void variable"); ProgramFail(Parser, "can't define a void variable");
if (Parser->Mode == RunModeRun || Parser->Mode == RunModeGoto) if (Parser->Mode == RunModeRun || Parser->Mode == RunModeGoto)
NewVariable = VariableDefineButIgnoreIdentical(Parser, Identifier, Typ, IsStatic, &FirstVisit); NewVariable = VariableDefineButIgnoreIdentical(Parser,
Identifier, Typ, IsStatic, &FirstVisit);
if (LexGetToken(Parser, NULL, false) == TokenAssign) { if (LexGetToken(Parser, NULL, false) == TokenAssign) {
/* we're assigning an initial value */ /* we're assigning an initial value */
LexGetToken(Parser, NULL, true); LexGetToken(Parser, NULL, true);
ParseDeclarationAssignment(Parser, NewVariable, !IsStatic || FirstVisit); ParseDeclarationAssignment(Parser, NewVariable,
!IsStatic || FirstVisit);
} }
} }
} }
@ -353,7 +377,9 @@ void ParseMacroDefinition(struct ParseState *Parser)
ParserCopy(&ParamParser, Parser); ParserCopy(&ParamParser, Parser);
NumParams = ParseCountParams(&ParamParser); NumParams = ParseCountParams(&ParamParser);
MacroValue = VariableAllocValueAndData(Parser->pc, Parser, sizeof(struct MacroDef) + sizeof(const char *) * NumParams, false, NULL, true); MacroValue = VariableAllocValueAndData(Parser->pc, Parser,
sizeof(struct MacroDef) + sizeof(const char *) * NumParams,
false, NULL, true);
MacroValue->Val->MacroDef.NumParams = NumParams; MacroValue->Val->MacroDef.NumParams = NumParams;
MacroValue->Val->MacroDef.ParamName = (char **)((char *)MacroValue->Val + sizeof(struct MacroDef)); MacroValue->Val->MacroDef.ParamName = (char **)((char *)MacroValue->Val + sizeof(struct MacroDef));
@ -376,7 +402,8 @@ void ParseMacroDefinition(struct ParseState *Parser)
ProgramFail(Parser, "close bracket expected"); ProgramFail(Parser, "close bracket expected");
} else { } else {
/* allocate a simple unparameterised macro */ /* allocate a simple unparameterised macro */
MacroValue = VariableAllocValueAndData(Parser->pc, Parser, sizeof(struct MacroDef), false, NULL, true); MacroValue = VariableAllocValueAndData(Parser->pc, Parser,
sizeof(struct MacroDef), false, NULL, true);
MacroValue->Val->MacroDef.NumParams = 0; MacroValue->Val->MacroDef.NumParams = 0;
} }
@ -386,7 +413,8 @@ void ParseMacroDefinition(struct ParseState *Parser)
LexToEndOfLine(Parser); LexToEndOfLine(Parser);
MacroValue->Val->MacroDef.Body.Pos = LexCopyTokens(&MacroValue->Val->MacroDef.Body, Parser); MacroValue->Val->MacroDef.Body.Pos = LexCopyTokens(&MacroValue->Val->MacroDef.Body, Parser);
if (!TableSet(Parser->pc, &Parser->pc->GlobalTable, MacroNameStr, MacroValue, (char *)Parser->FileName, Parser->Line, Parser->CharacterPos)) if (!TableSet(Parser->pc, &Parser->pc->GlobalTable, MacroNameStr, MacroValue,
(char *)Parser->FileName, Parser->Line, Parser->CharacterPos))
ProgramFail(Parser, "'%s' is already defined", MacroNameStr); ProgramFail(Parser, "'%s' is already defined", MacroNameStr);
} }
@ -478,7 +506,8 @@ void ParseFor(struct ParseState *Parser)
} }
/* parse a block of code and return what mode it returned in */ /* parse a block of code and return what mode it returned in */
enum RunMode ParseBlock(struct ParseState *Parser, int AbsorbOpenBrace, int Condition) enum RunMode ParseBlock(struct ParseState *Parser, int AbsorbOpenBrace,
int Condition)
{ {
int PrevScopeID = 0; int PrevScopeID = 0;
int ScopeID = VariableScopeBegin(Parser, &PrevScopeID); int ScopeID = VariableScopeBegin(Parser, &PrevScopeID);
@ -526,7 +555,8 @@ void ParseTypedef(struct ParseState *Parser)
} }
/* parse a statement */ /* parse a statement */
enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemicolon) enum ParseResult ParseStatement(struct ParseState *Parser,
int CheckTrailingSemicolon)
{ {
int Condition; int Condition;
enum LexToken Token; enum LexToken Token;
@ -740,7 +770,9 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi
if (!Parser->pc->TopStackFrame) /* return from top-level program? */ if (!Parser->pc->TopStackFrame) /* return from top-level program? */
PlatformExit(Parser->pc, ExpressionCoerceInteger(CValue)); PlatformExit(Parser->pc, ExpressionCoerceInteger(CValue));
else else
ExpressionAssign(Parser, Parser->pc->TopStackFrame->ReturnValue, CValue, true, NULL, 0, false); ExpressionAssign(Parser,
Parser->pc->TopStackFrame->ReturnValue, CValue, true,
NULL, 0, false);
VariableStackPop(Parser, CValue); VariableStackPop(Parser, CValue);
} else { } else {
if (ExpressionParse(Parser, &CValue)) if (ExpressionParse(Parser, &CValue))
@ -770,9 +802,11 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi
ProgramFail(Parser, "identifier expected"); ProgramFail(Parser, "identifier expected");
if (Parser->Mode == RunModeRun) { if (Parser->Mode == RunModeRun) {
/* delete this variable or function */ /* delete this variable or function */
CValue = TableDelete(Parser->pc, &Parser->pc->GlobalTable, LexerValue->Val->Identifier); CValue = TableDelete(Parser->pc, &Parser->pc->GlobalTable,
LexerValue->Val->Identifier);
if (CValue == NULL) if (CValue == NULL)
ProgramFail(Parser, "'%s' is not defined", LexerValue->Val->Identifier); ProgramFail(Parser, "'%s' is not defined",
LexerValue->Val->Identifier);
VariableFree(Parser->pc, CValue); VariableFree(Parser->pc, CValue);
} }
@ -792,7 +826,9 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi
} }
/* quick scan a source file for definitions */ /* quick scan a source file for definitions */
void PicocParse(Picoc *pc, const char *FileName, const char *Source, int SourceLen, int RunIt, int CleanupNow, int CleanupSource, int EnableDebugger) void PicocParse(Picoc *pc, const char *FileName, const char *Source,
int SourceLen, int RunIt, int CleanupNow, int CleanupSource,
int EnableDebugger)
{ {
char *RegFileName = TableStrRegister(pc, FileName); char *RegFileName = TableStrRegister(pc, FileName);
enum ParseResult Ok; enum ParseResult Ok;

View file

@ -68,27 +68,35 @@ void PicocCallMain(Picoc *pc, int argc, char **argv)
if (FuncValue->Val->FuncDef.NumParams != 0) { if (FuncValue->Val->FuncDef.NumParams != 0) {
/* define the arguments */ /* define the arguments */
VariableDefinePlatformVar(pc, NULL, "__argc", &pc->IntType, (union AnyValue *)&argc, false); VariableDefinePlatformVar(pc, NULL, "__argc", &pc->IntType,
VariableDefinePlatformVar(pc, NULL, "__argv", pc->CharPtrPtrType, (union AnyValue *)&argv, false); (union AnyValue *)&argc, false);
VariableDefinePlatformVar(pc, NULL, "__argv", pc->CharPtrPtrType,
(union AnyValue *)&argv, false);
} }
if (FuncValue->Val->FuncDef.ReturnType == &pc->VoidType) { if (FuncValue->Val->FuncDef.ReturnType == &pc->VoidType) {
if (FuncValue->Val->FuncDef.NumParams == 0) if (FuncValue->Val->FuncDef.NumParams == 0)
PicocParse(pc, "startup", CALL_MAIN_NO_ARGS_RETURN_VOID, strlen(CALL_MAIN_NO_ARGS_RETURN_VOID), true, true, false, gEnableDebugger); PicocParse(pc, "startup", CALL_MAIN_NO_ARGS_RETURN_VOID,
strlen(CALL_MAIN_NO_ARGS_RETURN_VOID), true, true, false, gEnableDebugger);
else else
PicocParse(pc, "startup", CALL_MAIN_WITH_ARGS_RETURN_VOID, strlen(CALL_MAIN_WITH_ARGS_RETURN_VOID), true, true, false, gEnableDebugger); PicocParse(pc, "startup", CALL_MAIN_WITH_ARGS_RETURN_VOID,
strlen(CALL_MAIN_WITH_ARGS_RETURN_VOID), true, true, false, gEnableDebugger);
} else { } else {
VariableDefinePlatformVar(pc, NULL, "__exit_value", &pc->IntType, (union AnyValue *)&pc->PicocExitValue, true); VariableDefinePlatformVar(pc, NULL, "__exit_value", &pc->IntType,
(union AnyValue *)&pc->PicocExitValue, true);
if (FuncValue->Val->FuncDef.NumParams == 0) if (FuncValue->Val->FuncDef.NumParams == 0)
PicocParse(pc, "startup", CALL_MAIN_NO_ARGS_RETURN_INT, strlen(CALL_MAIN_NO_ARGS_RETURN_INT), true, true, false, gEnableDebugger); PicocParse(pc, "startup", CALL_MAIN_NO_ARGS_RETURN_INT,
strlen(CALL_MAIN_NO_ARGS_RETURN_INT), true, true, false, gEnableDebugger);
else else
PicocParse(pc, "startup", CALL_MAIN_WITH_ARGS_RETURN_INT, strlen(CALL_MAIN_WITH_ARGS_RETURN_INT), true, true, false, gEnableDebugger); PicocParse(pc, "startup", CALL_MAIN_WITH_ARGS_RETURN_INT,
strlen(CALL_MAIN_WITH_ARGS_RETURN_INT), true, true, false, gEnableDebugger);
} }
} }
#endif #endif
void PrintSourceTextErrorLine(IOFILE *Stream, const char *FileName, const char *SourceText, int Line, int CharacterPos) void PrintSourceTextErrorLine(IOFILE *Stream, const char *FileName,
const char *SourceText, int Line, int CharacterPos)
{ {
int LineCount; int LineCount;
int CCount; int CCount;
@ -116,7 +124,7 @@ void PrintSourceTextErrorLine(IOFILE *Stream, const char *FileName, const char *
} }
} else { } else {
/* assume we're in interactive mode - try to make the arrow match up with the input text */ /* assume we're in interactive mode - try to make the arrow match up with the input text */
for (CCount = 0; CCount < CharacterPos + (int)strlen(INTERACTIVE_PROMPT_STATEMENT); CCount++) for (CCount = 0; CCount < CharacterPos+(int)strlen(INTERACTIVE_PROMPT_STATEMENT); CCount++)
PrintCh(' ', Stream); PrintCh(' ', Stream);
} }
PlatformPrintf(Stream, "^\n%s:%d:%d ", FileName, Line, CharacterPos); PlatformPrintf(Stream, "^\n%s:%d:%d ", FileName, Line, CharacterPos);
@ -127,7 +135,8 @@ void ProgramFail(struct ParseState *Parser, const char *Message, ...)
{ {
va_list Args; va_list Args;
PrintSourceTextErrorLine(Parser->pc->CStdOut, Parser->FileName, Parser->SourceText, Parser->Line, Parser->CharacterPos); PrintSourceTextErrorLine(Parser->pc->CStdOut, Parser->FileName,
Parser->SourceText, Parser->Line, Parser->CharacterPos);
va_start(Args, Message); va_start(Args, Message);
PlatformVPrintf(Parser->pc->CStdOut, Message, Args); PlatformVPrintf(Parser->pc->CStdOut, Message, Args);
va_end(Args); va_end(Args);
@ -148,11 +157,14 @@ void ProgramFailNoParser(Picoc *pc, const char *Message, ...)
} }
/* like ProgramFail() but gives descriptive error messages for assignment */ /* like ProgramFail() but gives descriptive error messages for assignment */
void AssignFail(struct ParseState *Parser, const char *Format, struct ValueType *Type1, struct ValueType *Type2, int Num1, int Num2, const char *FuncName, int ParamNo) void AssignFail(struct ParseState *Parser, const char *Format,
struct ValueType *Type1, struct ValueType *Type2, int Num1, int Num2,
const char *FuncName, int ParamNo)
{ {
IOFILE *Stream = Parser->pc->CStdOut; IOFILE *Stream = Parser->pc->CStdOut;
PrintSourceTextErrorLine(Parser->pc->CStdOut, Parser->FileName, Parser->SourceText, Parser->Line, Parser->CharacterPos); PrintSourceTextErrorLine(Parser->pc->CStdOut, Parser->FileName,
Parser->SourceText, Parser->Line, Parser->CharacterPos);
PlatformPrintf(Stream, "can't %s ", (FuncName == NULL) ? "assign" : "set"); PlatformPrintf(Stream, "can't %s ", (FuncName == NULL) ? "assign" : "set");
if (Type1 != NULL) if (Type1 != NULL)
@ -172,7 +184,8 @@ void LexFail(Picoc *pc, struct LexState *Lexer, const char *Message, ...)
{ {
va_list Args; va_list Args;
PrintSourceTextErrorLine(pc->CStdOut, Lexer->FileName, Lexer->SourceText, Lexer->Line, Lexer->CharacterPos); PrintSourceTextErrorLine(pc->CStdOut, Lexer->FileName, Lexer->SourceText,
Lexer->Line, Lexer->CharacterPos);
va_start(Args, Message); va_start(Args, Message);
PlatformVPrintf(pc->CStdOut, Message, Args); PlatformVPrintf(pc->CStdOut, Message, Args);
va_end(Args); va_end(Args);
@ -212,7 +225,8 @@ void PlatformVPrintf(IOFILE *Stream, const char *Format, va_list Args)
} }
} }
/* make a new temporary name. takes a static buffer of char [7] as a parameter. should be initialised to "XX0000" /* make a new temporary name. takes a static buffer of char [7] as a parameter.
* should be initialised to "XX0000"
* where XX can be any characters */ * where XX can be any characters */
char *PlatformMakeTempName(Picoc *pc, char *TempNameBuffer) char *PlatformMakeTempName(Picoc *pc, char *TempNameBuffer)
{ {

View file

@ -4,13 +4,15 @@ void MsvcSetupFunc(Picoc *pc)
{ {
} }
void CTest (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void CTest (struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
printf("test(%d)\n", Param[0]->Val->Integer); printf("test(%d)\n", Param[0]->Val->Integer);
Param[0]->Val->Integer = 1234; Param[0]->Val->Integer = 1234;
} }
void CLineNo (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void CLineNo (struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = Parser->Line; ReturnValue->Val->Integer = Parser->Line;
} }

View file

@ -4,13 +4,15 @@ void UnixSetupFunc()
{ {
} }
void Ctest (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void Ctest (struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
printf("test(%d)\n", Param[0]->Val->Integer); printf("test(%d)\n", Param[0]->Val->Integer);
Param[0]->Val->Integer = 1234; Param[0]->Val->Integer = 1234;
} }
void Clineno (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void Clineno (struct ParseState *Parser, struct Value *ReturnValue,
struct Value **Param, int NumArgs)
{ {
ReturnValue->Val->Integer = Parser->Line; ReturnValue->Val->Integer = Parser->Line;
} }

View file

@ -81,7 +81,8 @@ char *PlatformReadFile(Picoc *pc, const char *FileName)
void PicocPlatformScanFile(Picoc *pc, const char *FileName) void PicocPlatformScanFile(Picoc *pc, const char *FileName)
{ {
char *SourceStr = PlatformReadFile(pc, FileName); char *SourceStr = PlatformReadFile(pc, FileName);
PicocParse(pc, FileName, SourceStr, strlen(SourceStr), true, false, true, gEnableDebugger); PicocParse(pc, FileName, SourceStr, strlen(SourceStr), true, false, true,
gEnableDebugger);
} }
/* exit the program */ /* exit the program */

View file

@ -126,7 +126,8 @@ void PicocPlatformScanFile(Picoc *pc, const char *FileName)
SourceStr[1] = '/'; SourceStr[1] = '/';
} }
PicocParse(pc, FileName, SourceStr, strlen(SourceStr), true, false, true, gEnableDebugger); PicocParse(pc, FileName, SourceStr, strlen(SourceStr), true, false, true,
gEnableDebugger);
} }
/* exit the program */ /* exit the program */

15
table.c
View file

@ -6,7 +6,8 @@
/* initialise the shared string system */ /* initialise the shared string system */
void TableInit(Picoc *pc) void TableInit(Picoc *pc)
{ {
TableInitTable(&pc->StringTable, &pc->StringHashTable[0], STRING_TABLE_SIZE, true); TableInitTable(&pc->StringTable, &pc->StringHashTable[0],
STRING_TABLE_SIZE, true);
pc->StrEmpty = TableStrRegister(pc, ""); pc->StrEmpty = TableStrRegister(pc, "");
} }
@ -28,7 +29,8 @@ static unsigned int TableHash(const char *Key, int Len)
} }
/* initialise a table */ /* initialise a table */
void TableInitTable(struct Table *Tbl, struct TableEntry **HashTable, int Size, int OnHeap) void TableInitTable(struct Table *Tbl, struct TableEntry **HashTable, int Size,
int OnHeap)
{ {
Tbl->Size = Size; Tbl->Size = Size;
Tbl->OnHeap = OnHeap; Tbl->OnHeap = OnHeap;
@ -53,7 +55,8 @@ static struct TableEntry *TableSearch(struct Table *Tbl, const char *Key, int *A
/* set an identifier to a value. returns FALSE if it already exists. /* set an identifier to a value. returns FALSE if it already exists.
* Key must be a shared string from TableStrRegister() */ * Key must be a shared string from TableStrRegister() */
int TableSet(Picoc *pc, struct Table *Tbl, char *Key, struct Value *Val, const char *DeclFileName, int DeclLine, int DeclColumn) int TableSet(Picoc *pc, struct Table *Tbl, char *Key, struct Value *Val,
const char *DeclFileName, int DeclLine, int DeclColumn)
{ {
int AddAt; int AddAt;
struct TableEntry *FoundEntry = TableSearch(Tbl, Key, &AddAt); struct TableEntry *FoundEntry = TableSearch(Tbl, Key, &AddAt);
@ -75,7 +78,8 @@ int TableSet(Picoc *pc, struct Table *Tbl, char *Key, struct Value *Val, const c
/* find a value in a table. returns FALSE if not found. /* find a value in a table. returns FALSE if not found.
* Key must be a shared string from TableStrRegister() */ * Key must be a shared string from TableStrRegister() */
int TableGet(struct Table *Tbl, const 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)
{ {
int AddAt; int AddAt;
struct TableEntry *FoundEntry = TableSearch(Tbl, Key, &AddAt); struct TableEntry *FoundEntry = TableSearch(Tbl, Key, &AddAt);
@ -114,7 +118,8 @@ struct Value *TableDelete(Picoc *pc, struct Table *Tbl, const char *Key)
} }
/* check a hash table entry for an identifier */ /* check a hash table entry for an identifier */
static struct TableEntry *TableSearchIdentifier(struct Table *Tbl, const char *Key, int Len, int *AddAt) static struct TableEntry *TableSearchIdentifier(struct Table *Tbl,
const char *Key, int Len, int *AddAt)
{ {
int HashValue = TableHash(Key, Len) % Tbl->Size; int HashValue = TableHash(Key, Len) % Tbl->Size;
struct TableEntry *Entry; struct TableEntry *Entry;

138
type.c
View file

@ -9,7 +9,9 @@ static int IntAlignBytes;
/* add a new type to the set of types we know about */ /* add a new type to the set of types we know about */
struct ValueType *TypeAdd(Picoc *pc, struct ParseState *Parser, struct ValueType *ParentType, enum BaseType Base, int ArraySize, const char *Identifier, int Sizeof, int AlignBytes) struct ValueType *TypeAdd(Picoc *pc, struct ParseState *Parser,
struct ValueType *ParentType, enum BaseType Base, int ArraySize,
const char *Identifier, int Sizeof, int AlignBytes)
{ {
struct ValueType *NewType = VariableAlloc(pc, Parser, sizeof(struct ValueType), true); struct ValueType *NewType = VariableAlloc(pc, Parser, sizeof(struct ValueType), true);
NewType->Base = Base; NewType->Base = Base;
@ -29,7 +31,9 @@ struct ValueType *TypeAdd(Picoc *pc, struct ParseState *Parser, struct ValueType
/* given a parent type, get a matching derived type and make one if necessary. /* given a parent type, get a matching derived type and make one if necessary.
* Identifier should be registered with the shared string table. */ * Identifier should be registered with the shared string table. */
struct ValueType *TypeGetMatching(Picoc *pc, struct ParseState *Parser, struct ValueType *ParentType, enum BaseType Base, int ArraySize, const char *Identifier, int AllowDuplicates) struct ValueType *TypeGetMatching(Picoc *pc, struct ParseState *Parser,
struct ValueType *ParentType, enum BaseType Base, int ArraySize,
const char *Identifier, int AllowDuplicates)
{ {
int Sizeof; int Sizeof;
int AlignBytes; int AlignBytes;
@ -45,10 +49,14 @@ struct ValueType *TypeGetMatching(Picoc *pc, struct ParseState *Parser, struct V
} }
switch (Base) { switch (Base) {
case TypePointer: Sizeof = sizeof(void *); AlignBytes = PointerAlignBytes; break; case TypePointer:
case TypeArray: Sizeof = ArraySize * ParentType->Sizeof; AlignBytes = ParentType->AlignBytes; break; Sizeof = sizeof(void*); AlignBytes = PointerAlignBytes; break;
case TypeEnum: Sizeof = sizeof(int); AlignBytes = IntAlignBytes; break; case TypeArray:
default: Sizeof = 0; AlignBytes = 0; break; /* structs and unions will get bigger when we add members to them */ Sizeof = ArraySize * ParentType->Sizeof; AlignBytes = ParentType->AlignBytes; break;
case TypeEnum:
Sizeof = sizeof(int); AlignBytes = IntAlignBytes; break;
default:
Sizeof = 0; AlignBytes = 0; break; /* structs and unions will get bigger when we add members to them */
} }
return TypeAdd(pc, Parser, ParentType, Base, ArraySize, Identifier, Sizeof, AlignBytes); return TypeAdd(pc, Parser, ParentType, Base, ArraySize, Identifier, Sizeof, AlignBytes);
@ -86,7 +94,8 @@ int TypeSize(struct ValueType *Typ, int ArraySize, int Compact)
} }
/* add a base type */ /* add a base type */
void TypeAddBaseType(Picoc *pc, struct ValueType *TypeNode, enum BaseType Base, int Sizeof, int AlignBytes) void TypeAddBaseType(Picoc *pc, struct ValueType *TypeNode, enum BaseType Base,
int Sizeof, int AlignBytes)
{ {
TypeNode->Base = Base; TypeNode->Base = Base;
TypeNode->ArraySize = 0; TypeNode->ArraySize = 0;
@ -116,23 +125,35 @@ void TypeInit(Picoc *pc)
pc->UberType.DerivedTypeList = NULL; pc->UberType.DerivedTypeList = NULL;
TypeAddBaseType(pc, &pc->IntType, TypeInt, sizeof(int), IntAlignBytes); TypeAddBaseType(pc, &pc->IntType, TypeInt, sizeof(int), IntAlignBytes);
TypeAddBaseType(pc, &pc->ShortType, TypeShort, sizeof(short), (char*)&sa.y - &sa.x); TypeAddBaseType(pc, &pc->ShortType, TypeShort, sizeof(short),
TypeAddBaseType(pc, &pc->CharType, TypeChar, sizeof(char), (char*)&ca.y - &ca.x); (char*)&sa.y - &sa.x);
TypeAddBaseType(pc, &pc->LongType, TypeLong, sizeof(long), (char*)&la.y - &la.x); TypeAddBaseType(pc, &pc->CharType, TypeChar, sizeof(char),
TypeAddBaseType(pc, &pc->UnsignedIntType, TypeUnsignedInt, sizeof(unsigned int), IntAlignBytes); (char*)&ca.y - &ca.x);
TypeAddBaseType(pc, &pc->UnsignedShortType, TypeUnsignedShort, sizeof(unsigned short), (char*)&sa.y - &sa.x); TypeAddBaseType(pc, &pc->LongType, TypeLong, sizeof(long),
TypeAddBaseType(pc, &pc->UnsignedLongType, TypeUnsignedLong, sizeof(unsigned long), (char*)&la.y - &la.x); (char*)&la.y - &la.x);
TypeAddBaseType(pc, &pc->UnsignedCharType, TypeUnsignedChar, sizeof(unsigned char), (char*)&ca.y - &ca.x); TypeAddBaseType(pc, &pc->UnsignedIntType, TypeUnsignedInt,
sizeof(unsigned int), IntAlignBytes);
TypeAddBaseType(pc, &pc->UnsignedShortType, TypeUnsignedShort,
sizeof(unsigned short), (char*)&sa.y - &sa.x);
TypeAddBaseType(pc, &pc->UnsignedLongType, TypeUnsignedLong,
sizeof(unsigned long), (char*)&la.y - &la.x);
TypeAddBaseType(pc, &pc->UnsignedCharType, TypeUnsignedChar,
sizeof(unsigned char), (char*)&ca.y - &ca.x);
TypeAddBaseType(pc, &pc->VoidType, TypeVoid, 0, 1); TypeAddBaseType(pc, &pc->VoidType, TypeVoid, 0, 1);
TypeAddBaseType(pc, &pc->FunctionType, TypeFunction, sizeof(int), IntAlignBytes); TypeAddBaseType(pc, &pc->FunctionType, TypeFunction, sizeof(int), IntAlignBytes);
TypeAddBaseType(pc, &pc->MacroType, TypeMacro, sizeof(int), IntAlignBytes); TypeAddBaseType(pc, &pc->MacroType, TypeMacro, sizeof(int), IntAlignBytes);
TypeAddBaseType(pc, &pc->GotoLabelType, TypeGotoLabel, 0, 1); TypeAddBaseType(pc, &pc->GotoLabelType, TypeGotoLabel, 0, 1);
TypeAddBaseType(pc, &pc->FPType, TypeFP, sizeof(double), (char*)&da.y - &da.x); TypeAddBaseType(pc, &pc->FPType, TypeFP, sizeof(double), (char*)&da.y - &da.x);
TypeAddBaseType(pc, &pc->TypeType, Type_Type, sizeof(double), (char*)&da.y - &da.x); /* must be large enough to cast to a double */ TypeAddBaseType(pc, &pc->TypeType, Type_Type, sizeof(double),
pc->CharArrayType = TypeAdd(pc, NULL, &pc->CharType, TypeArray, 0, pc->StrEmpty, sizeof(char), (char*)&ca.y - &ca.x); (char*)&da.y - &da.x); /* must be large enough to cast to a double */
pc->CharPtrType = TypeAdd(pc, NULL, &pc->CharType, TypePointer, 0, pc->StrEmpty, sizeof(void*), PointerAlignBytes); pc->CharArrayType = TypeAdd(pc, NULL, &pc->CharType, TypeArray, 0,
pc->CharPtrPtrType = TypeAdd(pc, NULL, pc->CharPtrType, TypePointer, 0, pc->StrEmpty, sizeof(void*), PointerAlignBytes); pc->StrEmpty, sizeof(char), (char*)&ca.y - &ca.x);
pc->VoidPtrType = TypeAdd(pc, NULL, &pc->VoidType, TypePointer, 0, pc->StrEmpty, sizeof(void*), PointerAlignBytes); pc->CharPtrType = TypeAdd(pc, NULL, &pc->CharType, TypePointer, 0,
pc->StrEmpty, sizeof(void*), PointerAlignBytes);
pc->CharPtrPtrType = TypeAdd(pc, NULL, pc->CharPtrType, TypePointer, 0,
pc->StrEmpty, sizeof(void*), PointerAlignBytes);
pc->VoidPtrType = TypeAdd(pc, NULL, &pc->VoidType, TypePointer, 0,
pc->StrEmpty, sizeof(void*), PointerAlignBytes);
} }
/* deallocate heap-allocated types */ /* deallocate heap-allocated types */
@ -185,7 +206,8 @@ void TypeParseStruct(struct ParseState *Parser, struct ValueType **Typ, int IsSt
StructIdentifier = PlatformMakeTempName(pc, TempNameBuf); StructIdentifier = PlatformMakeTempName(pc, TempNameBuf);
} }
*Typ = TypeGetMatching(pc, Parser, &Parser->pc->UberType, IsStruct ? TypeStruct : TypeUnion, 0, StructIdentifier, true); *Typ = TypeGetMatching(pc, Parser, &Parser->pc->UberType,
IsStruct ? TypeStruct : TypeUnion, 0, StructIdentifier, true);
if (Token == TokenLeftBrace && (*Typ)->Members != NULL) if (Token == TokenLeftBrace && (*Typ)->Members != NULL)
ProgramFail(Parser, "data type '%t' is already defined", *Typ); ProgramFail(Parser, "data type '%t' is already defined", *Typ);
@ -203,9 +225,13 @@ void TypeParseStruct(struct ParseState *Parser, struct ValueType **Typ, int IsSt
ProgramFail(Parser, "struct/union definitions can only be globals"); ProgramFail(Parser, "struct/union definitions can only be globals");
LexGetToken(Parser, NULL, true); LexGetToken(Parser, NULL, true);
(*Typ)->Members = VariableAlloc(pc, Parser, sizeof(struct Table) + STRUCT_TABLE_SIZE * sizeof(struct TableEntry), true); (*Typ)->Members = VariableAlloc(pc, Parser,
(*Typ)->Members->HashTable = (struct TableEntry**)((char*)(*Typ)->Members + sizeof(struct Table)); sizeof(struct Table)+STRUCT_TABLE_SIZE*sizeof(struct TableEntry), true);
TableInitTable((*Typ)->Members, (struct TableEntry**)((char*)(*Typ)->Members + sizeof(struct Table)), STRUCT_TABLE_SIZE, true); (*Typ)->Members->HashTable =
(struct TableEntry**)((char*)(*Typ)->Members + sizeof(struct Table));
TableInitTable((*Typ)->Members,
(struct TableEntry**)((char*)(*Typ)->Members + sizeof(struct Table)),
STRUCT_TABLE_SIZE, true);
do { do {
TypeParse(Parser, &MemberType, &MemberIdentifier, NULL); TypeParse(Parser, &MemberType, &MemberIdentifier, NULL);
@ -234,7 +260,8 @@ void TypeParseStruct(struct ParseState *Parser, struct ValueType **Typ, int IsSt
(*Typ)->AlignBytes = MemberValue->Typ->AlignBytes; (*Typ)->AlignBytes = MemberValue->Typ->AlignBytes;
/* define it */ /* define it */
if (!TableSet(pc, (*Typ)->Members, MemberIdentifier, MemberValue, Parser->FileName, Parser->Line, Parser->CharacterPos)) if (!TableSet(pc, (*Typ)->Members, MemberIdentifier, MemberValue,
Parser->FileName, Parser->Line, Parser->CharacterPos))
ProgramFail(Parser, "member '%s' already defined", &MemberIdentifier); ProgramFail(Parser, "member '%s' already defined", &MemberIdentifier);
if (LexGetToken(Parser, NULL, true) != TokenSemicolon) if (LexGetToken(Parser, NULL, true) != TokenSemicolon)
@ -251,14 +278,20 @@ void TypeParseStruct(struct ParseState *Parser, struct ValueType **Typ, int IsSt
} }
/* create a system struct which has no user-visible members */ /* create a system struct which has no user-visible members */
struct ValueType *TypeCreateOpaqueStruct(Picoc *pc, struct ParseState *Parser, const char *StructName, int Size) struct ValueType *TypeCreateOpaqueStruct(Picoc *pc, struct ParseState *Parser,
const char *StructName, int Size)
{ {
struct ValueType *Typ = TypeGetMatching(pc, Parser, &pc->UberType, TypeStruct, 0, StructName, false); struct ValueType *Typ = TypeGetMatching(pc, Parser, &pc->UberType,
TypeStruct, 0, StructName, false);
/* create the (empty) table */ /* create the (empty) table */
Typ->Members = VariableAlloc(pc, Parser, sizeof(struct Table) + STRUCT_TABLE_SIZE * sizeof(struct TableEntry), true); Typ->Members = VariableAlloc(pc,
Parser,
sizeof(struct Table)+STRUCT_TABLE_SIZE*sizeof(struct TableEntry), true);
Typ->Members->HashTable = (struct TableEntry**)((char*)Typ->Members + sizeof(struct Table)); Typ->Members->HashTable = (struct TableEntry**)((char*)Typ->Members + sizeof(struct Table));
TableInitTable(Typ->Members, (struct TableEntry**)((char*)Typ->Members + sizeof(struct Table)), STRUCT_TABLE_SIZE, true); TableInitTable(Typ->Members,
(struct TableEntry**)((char*)Typ->Members+sizeof(struct Table)),
STRUCT_TABLE_SIZE, true);
Typ->Sizeof = Size; Typ->Sizeof = Size;
return Typ; return Typ;
@ -365,33 +398,45 @@ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ, int *IsSta
} }
switch (Token) { switch (Token) {
case TokenIntType: *Typ = Unsigned ? &pc->UnsignedIntType : &pc->IntType; break; case TokenIntType:
case TokenShortType: *Typ = Unsigned ? &pc->UnsignedShortType : &pc->ShortType; break; *Typ = Unsigned ? &pc->UnsignedIntType : &pc->IntType;
case TokenCharType: *Typ = Unsigned ? &pc->UnsignedCharType : &pc->CharType; break; break;
case TokenLongType: *Typ = Unsigned ? &pc->UnsignedLongType : &pc->LongType; break; case TokenShortType:
case TokenFloatType: case TokenDoubleType: *Typ = &pc->FPType; break; *Typ = Unsigned ? &pc->UnsignedShortType : &pc->ShortType;
case TokenVoidType: *Typ = &pc->VoidType; break; break;
case TokenCharType:
*Typ = Unsigned ? &pc->UnsignedCharType : &pc->CharType;
break;
case TokenLongType:
*Typ = Unsigned ? &pc->UnsignedLongType : &pc->LongType;
break;
case TokenFloatType:
case TokenDoubleType:
*Typ = &pc->FPType;
break;
case TokenVoidType:
*Typ = &pc->VoidType;
break;
case TokenStructType: case TokenUnionType: case TokenStructType: case TokenUnionType:
if (*Typ != NULL) if (*Typ != NULL)
ProgramFail(Parser, "bad type declaration"); ProgramFail(Parser, "bad type declaration");
TypeParseStruct(Parser, Typ, Token == TokenStructType); TypeParseStruct(Parser, Typ, Token == TokenStructType);
break; break;
case TokenEnumType: case TokenEnumType:
if (*Typ != NULL) if (*Typ != NULL)
ProgramFail(Parser, "bad type declaration"); ProgramFail(Parser, "bad type declaration");
TypeParseEnum(Parser, Typ); TypeParseEnum(Parser, Typ);
break; break;
case TokenIdentifier: case TokenIdentifier:
/* we already know it's a typedef-defined type because we got here */ /* we already know it's a typedef-defined type because we got here */
VariableGet(pc, Parser, LexerValue->Val->Identifier, &VarValue); VariableGet(pc, Parser, LexerValue->Val->Identifier, &VarValue);
*Typ = VarValue->Val->Typ; *Typ = VarValue->Val->Typ;
break; break;
default: ParserCopy(Parser, &Before); return false; default:
ParserCopy(Parser, &Before);
return false;
} }
return true; return true;
@ -410,7 +455,9 @@ struct ValueType *TypeParseBack(struct ParseState *Parser, struct ValueType *Fro
if (LexGetToken(Parser, NULL, false) == TokenRightSquareBracket) { if (LexGetToken(Parser, NULL, false) == TokenRightSquareBracket) {
/* an unsized array */ /* an unsized array */
LexGetToken(Parser, NULL, true); LexGetToken(Parser, NULL, true);
return TypeGetMatching(Parser->pc, Parser, TypeParseBack(Parser, FromType), TypeArray, 0, Parser->pc->StrEmpty, true); return TypeGetMatching(Parser->pc, Parser,
TypeParseBack(Parser, FromType), TypeArray, 0,
Parser->pc->StrEmpty, true);
} else { } else {
/* get a numeric array size */ /* get a numeric array size */
enum RunMode OldMode = Parser->Mode; enum RunMode OldMode = Parser->Mode;
@ -422,7 +469,9 @@ struct ValueType *TypeParseBack(struct ParseState *Parser, struct ValueType *Fro
if (LexGetToken(Parser, NULL, true) != TokenRightSquareBracket) if (LexGetToken(Parser, NULL, true) != TokenRightSquareBracket)
ProgramFail(Parser, "']' expected"); ProgramFail(Parser, "']' expected");
return TypeGetMatching(Parser->pc, Parser, TypeParseBack(Parser, FromType), TypeArray, ArraySize, Parser->pc->StrEmpty, true); return TypeGetMatching(Parser->pc, Parser,
TypeParseBack(Parser, FromType), TypeArray, ArraySize,
Parser->pc->StrEmpty, true);
} }
} else { } else {
/* the type specification has finished */ /* the type specification has finished */
@ -432,7 +481,8 @@ struct ValueType *TypeParseBack(struct ParseState *Parser, struct ValueType *Fro
} }
/* parse a type - the part which is repeated with each identifier in a declaration list */ /* parse a type - the part which is repeated with each identifier in a declaration list */
void TypeParseIdentPart(struct ParseState *Parser, struct ValueType *BasicTyp, struct ValueType **Typ, char **Identifier) void TypeParseIdentPart(struct ParseState *Parser, struct ValueType *BasicTyp,
struct ValueType **Typ, char **Identifier)
{ {
int Done = false; int Done = false;
enum LexToken Token; enum LexToken Token;
@ -458,7 +508,8 @@ void TypeParseIdentPart(struct ParseState *Parser, struct ValueType *BasicTyp, s
if (*Typ == NULL) if (*Typ == NULL)
ProgramFail(Parser, "bad type declaration"); ProgramFail(Parser, "bad type declaration");
*Typ = TypeGetMatching(Parser->pc, Parser, *Typ, TypePointer, 0, Parser->pc->StrEmpty, true); *Typ = TypeGetMatching(Parser->pc, Parser, *Typ, TypePointer, 0,
Parser->pc->StrEmpty, true);
break; break;
case TokenIdentifier: case TokenIdentifier:
@ -483,7 +534,8 @@ void TypeParseIdentPart(struct ParseState *Parser, struct ValueType *BasicTyp, s
} }
/* parse a type - a complete declaration including identifier */ /* parse a type - a complete declaration including identifier */
void TypeParse(struct ParseState *Parser, struct ValueType **Typ, char **Identifier, int *IsStatic) void TypeParse(struct ParseState *Parser, struct ValueType **Typ,
char **Identifier, int *IsStatic)
{ {
struct ValueType *BasicType; struct ValueType *BasicType;

View file

@ -10,8 +10,10 @@
/* initialise the variable system */ /* initialise the variable system */
void VariableInit(Picoc *pc) void VariableInit(Picoc *pc)
{ {
TableInitTable(&(pc->GlobalTable), &(pc->GlobalHashTable)[0], GLOBAL_TABLE_SIZE, true); TableInitTable(&(pc->GlobalTable), &(pc->GlobalHashTable)[0],
TableInitTable(&pc->StringLiteralTable, &pc->StringLiteralHashTable[0], STRING_LITERAL_TABLE_SIZE, true); GLOBAL_TABLE_SIZE, true);
TableInitTable(&pc->StringLiteralTable, &pc->StringLiteralHashTable[0],
STRING_LITERAL_TABLE_SIZE, true);
pc->TopStackFrame = NULL; pc->TopStackFrame = NULL;
} }
@ -83,10 +85,13 @@ void *VariableAlloc(Picoc *pc, struct ParseState *Parser, int Size, int OnHeap)
} }
/* allocate a value either on the heap or the stack using space dependent on what type we want */ /* allocate a value either on the heap or the stack using space dependent on what type we want */
struct Value *VariableAllocValueAndData(Picoc *pc, struct ParseState *Parser, int DataSize, int IsLValue, struct Value *LValueFrom, int OnHeap) struct Value *VariableAllocValueAndData(Picoc *pc, struct ParseState *Parser,
int DataSize, int IsLValue, struct Value *LValueFrom, int OnHeap)
{ {
struct Value *NewValue = VariableAlloc(pc, Parser, MEM_ALIGN(sizeof(struct Value)) + DataSize, OnHeap); struct Value *NewValue = VariableAlloc(pc, Parser,
NewValue->Val = (union AnyValue*)((char*)NewValue + MEM_ALIGN(sizeof(struct Value))); MEM_ALIGN(sizeof(struct Value)) + DataSize, OnHeap);
NewValue->Val = (union AnyValue*)((char*)NewValue +
MEM_ALIGN(sizeof(struct Value)));
NewValue->ValOnHeap = OnHeap; NewValue->ValOnHeap = OnHeap;
NewValue->AnyValOnHeap = false; NewValue->AnyValOnHeap = false;
NewValue->ValOnStack = !OnHeap; NewValue->ValOnStack = !OnHeap;
@ -101,7 +106,8 @@ struct Value *VariableAllocValueAndData(Picoc *pc, struct ParseState *Parser, in
} }
/* allocate a value given its type */ /* allocate a value given its type */
struct Value *VariableAllocValueFromType(Picoc *pc, struct ParseState *Parser, struct ValueType *Typ, int IsLValue, struct Value *LValueFrom, int OnHeap) struct Value *VariableAllocValueFromType(Picoc *pc, struct ParseState *Parser,
struct ValueType *Typ, int IsLValue, struct Value *LValueFrom, int OnHeap)
{ {
int Size = TypeSize(Typ, Typ->ArraySize, false); int Size = TypeSize(Typ, Typ->ArraySize, false);
struct Value *NewValue = VariableAllocValueAndData(pc, Parser, Size, IsLValue, LValueFrom, OnHeap); struct Value *NewValue = VariableAllocValueAndData(pc, Parser, Size, IsLValue, LValueFrom, OnHeap);
@ -112,7 +118,8 @@ struct Value *VariableAllocValueFromType(Picoc *pc, struct ParseState *Parser, s
} }
/* allocate a value either on the heap or the stack and copy its value. handles overlapping data */ /* allocate a value either on the heap or the stack and copy its value. handles overlapping data */
struct Value *VariableAllocValueAndCopy(Picoc *pc, struct ParseState *Parser, struct Value *FromValue, int OnHeap) struct Value *VariableAllocValueAndCopy(Picoc *pc, struct ParseState *Parser,
struct Value *FromValue, int OnHeap)
{ {
int CopySize = TypeSizeValue(FromValue, true); int CopySize = TypeSizeValue(FromValue, true);
char TmpBuf[MAX_TMP_COPY_BUF]; char TmpBuf[MAX_TMP_COPY_BUF];
@ -121,7 +128,8 @@ struct Value *VariableAllocValueAndCopy(Picoc *pc, struct ParseState *Parser, st
assert(CopySize <= MAX_TMP_COPY_BUF); assert(CopySize <= MAX_TMP_COPY_BUF);
memcpy((void*)&TmpBuf[0], (void*)FromValue->Val, CopySize); memcpy((void*)&TmpBuf[0], (void*)FromValue->Val, CopySize);
NewValue = VariableAllocValueAndData(pc, Parser, CopySize, FromValue->IsLValue, FromValue->LValueFrom, OnHeap); NewValue = VariableAllocValueAndData(pc, Parser, CopySize,
FromValue->IsLValue, FromValue->LValueFrom, OnHeap);
NewValue->Typ = DType; NewValue->Typ = DType;
memcpy((void*)NewValue->Val, (void*)&TmpBuf[0], CopySize); memcpy((void*)NewValue->Val, (void*)&TmpBuf[0], CopySize);
@ -129,7 +137,9 @@ struct Value *VariableAllocValueAndCopy(Picoc *pc, struct ParseState *Parser, st
} }
/* allocate a value either on the heap or the stack from an existing AnyValue and type */ /* allocate a value either on the heap or the stack from an existing AnyValue and type */
struct Value *VariableAllocValueFromExistingData(struct ParseState *Parser, struct ValueType *Typ, union AnyValue *FromValue, int IsLValue, struct Value *LValueFrom) struct Value *VariableAllocValueFromExistingData(struct ParseState *Parser,
struct ValueType *Typ, union AnyValue *FromValue, int IsLValue,
struct Value *LValueFrom)
{ {
struct Value *NewValue = VariableAlloc(Parser->pc, Parser, sizeof(struct Value), false); struct Value *NewValue = VariableAlloc(Parser->pc, Parser, sizeof(struct Value), false);
NewValue->Typ = Typ; NewValue->Typ = Typ;
@ -144,9 +154,11 @@ struct Value *VariableAllocValueFromExistingData(struct ParseState *Parser, stru
} }
/* allocate a value either on the heap or the stack from an existing Value, sharing the value */ /* allocate a value either on the heap or the stack from an existing Value, sharing the value */
struct Value *VariableAllocValueShared(struct ParseState *Parser, struct Value *FromValue) struct Value *VariableAllocValueShared(struct ParseState *Parser,
struct Value *FromValue)
{ {
return VariableAllocValueFromExistingData(Parser, FromValue->Typ, FromValue->Val, FromValue->IsLValue, FromValue->IsLValue ? FromValue : NULL); return VariableAllocValueFromExistingData(Parser, FromValue->Typ,
FromValue->Val, FromValue->IsLValue, FromValue->IsLValue ? FromValue : NULL);
} }
/* reallocate a variable so its data has a new size */ /* reallocate a variable so its data has a new size */
@ -188,7 +200,8 @@ int VariableScopeBegin(struct ParseState *Parser, int* OldScopeID)
#ifdef DEBUG_VAR_SCOPE #ifdef DEBUG_VAR_SCOPE
if (!FirstPrint) PRINT_SOURCE_POS(); if (!FirstPrint) PRINT_SOURCE_POS();
FirstPrint = 1; FirstPrint = 1;
printf(">>> back into scope: %s %x %d\n", Entry->p.v.Key, Entry->p.v.Val->ScopeID, Entry->p.v.Val->Val->Integer); printf(">>> back into scope: %s %x %d\n", Entry->p.v.Key,
Entry->p.v.Val->ScopeID, Entry->p.v.Val->Val->Integer);
#endif #endif
} }
} }
@ -218,7 +231,8 @@ void VariableScopeEnd(struct ParseState *Parser, int ScopeID, int PrevScopeID)
#ifdef DEBUG_VAR_SCOPE #ifdef DEBUG_VAR_SCOPE
if (!FirstPrint) PRINT_SOURCE_POS(); if (!FirstPrint) PRINT_SOURCE_POS();
FirstPrint = 1; FirstPrint = 1;
printf(">>> out of scope: %s %x %d\n", Entry->p.v.Key, Entry->p.v.Val->ScopeID, Entry->p.v.Val->Val->Integer); printf(">>> out of scope: %s %x %d\n", Entry->p.v.Key,
Entry->p.v.Val->ScopeID, Entry->p.v.Val->Val->Integer);
#endif #endif
Entry->p.v.Val->OutOfScope = true; Entry->p.v.Val->OutOfScope = true;
Entry->p.v.Key = (char*)((intptr_t)Entry->p.v.Key | 1); /* alter the key so it won't be found by normal searches */ Entry->p.v.Key = (char*)((intptr_t)Entry->p.v.Key | 1); /* alter the key so it won't be found by normal searches */
@ -245,20 +259,23 @@ int VariableDefinedAndOutOfScope(Picoc * pc, const char* Ident)
} }
/* define a variable. Ident must be registered */ /* define a variable. Ident must be registered */
struct Value *VariableDefine(Picoc *pc, struct ParseState *Parser, char *Ident, struct Value *InitValue, struct ValueType *Typ, int MakeWritable) struct Value *VariableDefine(Picoc *pc, struct ParseState *Parser, char *Ident,
struct Value *InitValue, struct ValueType *Typ, int MakeWritable)
{ {
int ScopeID = Parser ? Parser->ScopeID : -1; int ScopeID = Parser ? Parser->ScopeID : -1;
struct Value * AssignValue; struct Value * AssignValue;
struct Table * currentTable = (pc->TopStackFrame == NULL) ? &(pc->GlobalTable) : &(pc->TopStackFrame)->LocalTable; struct Table * currentTable = (pc->TopStackFrame == NULL) ? &(pc->GlobalTable) : &(pc->TopStackFrame)->LocalTable;
#ifdef DEBUG_VAR_SCOPE #ifdef DEBUG_VAR_SCOPE
if (Parser) fprintf(stderr, "def %s %x (%s:%d:%d)\n", Ident, ScopeID, Parser->FileName, Parser->Line, Parser->CharacterPos); if (Parser) fprintf(stderr, "def %s %x (%s:%d:%d)\n", Ident, ScopeID,
Parser->FileName, Parser->Line, Parser->CharacterPos);
#endif #endif
if (InitValue != NULL) if (InitValue != NULL)
AssignValue = VariableAllocValueAndCopy(pc, Parser, InitValue, pc->TopStackFrame == NULL); AssignValue = VariableAllocValueAndCopy(pc, Parser, InitValue, pc->TopStackFrame == NULL);
else else
AssignValue = VariableAllocValueFromType(pc, Parser, Typ, MakeWritable, NULL, pc->TopStackFrame == NULL); AssignValue = VariableAllocValueFromType(pc, Parser, Typ, MakeWritable,
NULL, pc->TopStackFrame == NULL);
AssignValue->IsLValue = MakeWritable; AssignValue->IsLValue = MakeWritable;
AssignValue->ScopeID = ScopeID; AssignValue->ScopeID = ScopeID;
@ -271,7 +288,8 @@ struct Value *VariableDefine(Picoc *pc, struct ParseState *Parser, char *Ident,
} }
/* define a variable. Ident must be registered. If it's a redefinition from the same declaration don't throw an error */ /* define a variable. Ident must be registered. If it's a redefinition from the same declaration don't throw an error */
struct Value *VariableDefineButIgnoreIdentical(struct ParseState *Parser, char *Ident, struct ValueType *Typ, int IsStatic, int *FirstVisit) struct Value *VariableDefineButIgnoreIdentical(struct ParseState *Parser,
char *Ident, struct ValueType *Typ, int IsStatic, int *FirstVisit)
{ {
int DeclLine; int DeclLine;
int DeclColumn; int DeclColumn;
@ -331,7 +349,8 @@ int VariableDefined(Picoc *pc, const char *Ident)
{ {
struct Value *FoundValue; struct Value *FoundValue;
if (pc->TopStackFrame == NULL || !TableGet(&pc->TopStackFrame->LocalTable, Ident, &FoundValue, NULL, NULL, NULL)) { if (pc->TopStackFrame == NULL || !TableGet(&pc->TopStackFrame->LocalTable,
Ident, &FoundValue, NULL, NULL, NULL)) {
if (!TableGet(&pc->GlobalTable, Ident, &FoundValue, NULL, NULL, NULL)) if (!TableGet(&pc->GlobalTable, Ident, &FoundValue, NULL, NULL, NULL))
return false; return false;
} }
@ -340,9 +359,11 @@ int VariableDefined(Picoc *pc, const char *Ident)
} }
/* get the value of a variable. must be defined. Ident must be registered */ /* get the value of a variable. must be defined. Ident must be registered */
void VariableGet(Picoc *pc, struct ParseState *Parser, const char *Ident, struct Value **LVal) void VariableGet(Picoc *pc, struct ParseState *Parser, const char *Ident,
struct Value **LVal)
{ {
if (pc->TopStackFrame == NULL || !TableGet(&pc->TopStackFrame->LocalTable, Ident, LVal, NULL, NULL, NULL)) { if (pc->TopStackFrame == NULL || !TableGet(&pc->TopStackFrame->LocalTable,
Ident, LVal, NULL, NULL, NULL)) {
if (!TableGet(&pc->GlobalTable, Ident, LVal, NULL, NULL, NULL)) { if (!TableGet(&pc->GlobalTable, Ident, LVal, NULL, NULL, NULL)) {
if (VariableDefinedAndOutOfScope(pc, Ident)) if (VariableDefinedAndOutOfScope(pc, Ident))
ProgramFail(Parser, "'%s' is out of scope", Ident); ProgramFail(Parser, "'%s' is out of scope", Ident);
@ -353,7 +374,8 @@ void VariableGet(Picoc *pc, struct ParseState *Parser, const char *Ident, struct
} }
/* define a global variable shared with a platform global. Ident will be registered */ /* define a global variable shared with a platform global. Ident will be registered */
void VariableDefinePlatformVar(Picoc *pc, struct ParseState *Parser, char *Ident, struct ValueType *Typ, union AnyValue *FromValue, int IsWritable) void VariableDefinePlatformVar(Picoc *pc, struct ParseState *Parser, char *Ident,
struct ValueType *Typ, union AnyValue *FromValue, int IsWritable)
{ {
struct Value *SomeValue = VariableAllocValueAndData(pc, NULL, 0, IsWritable, NULL, true); struct Value *SomeValue = VariableAllocValueAndData(pc, NULL, 0, IsWritable, NULL, true);
SomeValue->Typ = Typ; SomeValue->Typ = Typ;
@ -370,37 +392,43 @@ void VariableStackPop(struct ParseState *Parser, struct Value *Var)
#ifdef DEBUG_HEAP #ifdef DEBUG_HEAP
if (Var->ValOnStack) if (Var->ValOnStack)
printf("popping %ld at 0x%lx\n", (unsigned long)(sizeof(struct Value) + TypeSizeValue(Var, false)), (unsigned long)Var); printf("popping %ld at 0x%lx\n",
(unsigned long)(sizeof(struct Value) + TypeSizeValue(Var, false)),
(unsigned long)Var);
#endif #endif
if (Var->ValOnHeap) { if (Var->ValOnHeap) {
if (Var->Val != NULL) if (Var->Val != NULL)
HeapFreeMem(Parser->pc, Var->Val); HeapFreeMem(Parser->pc, Var->Val);
Success = HeapPopStack(Parser->pc, Var, sizeof(struct Value)); /* free from heap */ Success = HeapPopStack(Parser->pc, Var, sizeof(struct Value)); /* free from heap */
} else if (Var->ValOnStack) } else if (Var->ValOnStack)
Success = HeapPopStack(Parser->pc, Var, sizeof(struct Value) + TypeSizeValue(Var, false)); /* free from stack */ Success = HeapPopStack(Parser->pc, Var,
sizeof(struct Value)+TypeSizeValue(Var, false)); /* free from stack */
else else
Success = HeapPopStack(Parser->pc, Var, sizeof(struct Value)); /* value isn't our problem */ Success = HeapPopStack(Parser->pc, Var, sizeof(struct Value)); /* value isn't our problem */
if (!Success) if (!Success)
ProgramFail(Parser, "stack underrun"); ProgramFail(Parser, "stack underrun");
} }
/* add a stack frame when doing a function call */ /* add a stack frame when doing a function call */
void VariableStackFrameAdd(struct ParseState *Parser, const char *FuncName, int NumParams) void VariableStackFrameAdd(struct ParseState *Parser, const char *FuncName,
int NumParams)
{ {
struct StackFrame *NewFrame; struct StackFrame *NewFrame;
HeapPushStackFrame(Parser->pc); HeapPushStackFrame(Parser->pc);
NewFrame = HeapAllocStack(Parser->pc, sizeof(struct StackFrame) + sizeof(struct Value *) * NumParams); NewFrame = HeapAllocStack(Parser->pc,
sizeof(struct StackFrame)+sizeof(struct Value*)*NumParams);
if (NewFrame == NULL) if (NewFrame == NULL)
ProgramFail(Parser, "(VariableStackFrameAdd) out of memory"); ProgramFail(Parser, "(VariableStackFrameAdd) out of memory");
ParserCopy(&NewFrame->ReturnParser, Parser); ParserCopy(&NewFrame->ReturnParser, Parser);
NewFrame->FuncName = FuncName; NewFrame->FuncName = FuncName;
NewFrame->Parameter = (NumParams > 0) ? ((void*)((char *)NewFrame + sizeof(struct StackFrame))) : NULL; NewFrame->Parameter = (NumParams > 0) ? ((void*)((char *)NewFrame+sizeof(struct StackFrame))) : NULL;
TableInitTable(&NewFrame->LocalTable, &NewFrame->LocalHashTable[0], LOCAL_TABLE_SIZE, false); TableInitTable(&NewFrame->LocalTable, &NewFrame->LocalHashTable[0],
LOCAL_TABLE_SIZE, false);
NewFrame->PreviousStackFrame = Parser->pc->TopStackFrame; NewFrame->PreviousStackFrame = Parser->pc->TopStackFrame;
Parser->pc->TopStackFrame = NewFrame; Parser->pc->TopStackFrame = NewFrame;
} }
@ -434,7 +462,9 @@ void VariableStringLiteralDefine(Picoc *pc, char *Ident, struct Value *Val)
} }
/* check a pointer for validity and dereference it for use */ /* check a pointer for validity and dereference it for use */
void *VariableDereferencePointer(struct ParseState *Parser, struct Value *PointerValue, struct Value **DerefVal, int *DerefOffset, struct ValueType **DerefType, int *DerefIsLValue) void *VariableDereferencePointer(struct ParseState *Parser,
struct Value *PointerValue, struct Value **DerefVal, int *DerefOffset,
struct ValueType **DerefType, int *DerefIsLValue)
{ {
if (DerefVal != NULL) if (DerefVal != NULL)
*DerefVal = NULL; *DerefVal = NULL;