diff --git a/clibrary.c b/clibrary.c index d6ca7ca..758378c 100644 --- a/clibrary.c +++ b/clibrary.c @@ -1,6 +1,6 @@ -/* picoc mini standard C library - provides an optional tiny C standard library - * if BUILTIN_MINI_STDLIB is defined */ - +/* picoc mini standard C library - provides an optional tiny C standard library + * if BUILTIN_MINI_STDLIB is defined */ + #include "picoc.h" #include "interpreter.h" @@ -14,7 +14,7 @@ static int LittleEndian; /* global initialisation for libraries */ void LibraryInit(Picoc *pc) { - + /* define the version number macro */ pc->VersionString = TableStrRegister(pc, PICOC_VERSION); VariableDefinePlatformVar(pc, NULL, "PICOC_VERSION", pc->CharPtrType, (union AnyValue *)&pc->VersionString, FALSE); @@ -37,7 +37,7 @@ void LibraryAdd(Picoc *pc, struct Table *GlobalTable, const char *LibraryName, s struct Value *NewValue; void *Tokens; char *IntrinsicName = TableStrRegister(pc, "c library"); - + /* read all the library definitions */ for (Count = 0; FuncList[Count].Prototype != NULL; Count++) { @@ -82,13 +82,13 @@ void PrintType(struct ValueType *Typ, IOFILE *Stream) #ifdef BUILTIN_MINI_STDLIB -/* +/* * This is a simplified standard library for small embedded systems. It doesn't require * a system stdio library to operate. * * A more complete standard library for larger computers is in the library_XXX.c files. */ - + static int TRUEValue = 1; static int ZeroValue = 0; @@ -143,7 +143,7 @@ void PrintUnsigned(unsigned long Num, unsigned int Base, int FieldWidth, int Zer Result[--ResPos] = '\0'; if (Num == 0) Result[--ResPos] = '0'; - + while (Num > 0) { unsigned long NextNum = Num / Base; @@ -152,13 +152,13 @@ void PrintUnsigned(unsigned long Num, unsigned int Base, int FieldWidth, int Zer Result[--ResPos] = '0' + Digit; else Result[--ResPos] = 'a' + Digit - 10; - + Num = NextNum; } - + if (FieldWidth > 0 && !LeftJustify) PrintRepeatedChar(ZeroPad ? '0' : ' ', FieldWidth - (sizeof(Result) - 1 - ResPos), Stream); - + PrintStr(&Result[ResPos], Stream); if (FieldWidth > 0 && LeftJustify) @@ -181,7 +181,7 @@ void PrintInt(long Num, int FieldWidth, int ZeroPad, int LeftJustify, struct Out if (FieldWidth != 0) FieldWidth--; } - + PrintUnsigned((unsigned long)Num, 10, FieldWidth, ZeroPad, LeftJustify, Stream); } @@ -191,19 +191,19 @@ void PrintFP(double Num, struct OutputStream *Stream) { int Exponent = 0; int MaxDecimal; - + if (Num < 0) { PrintCh('-', Stream); - Num = -Num; + Num = -Num; } - + if (Num >= 1e7) Exponent = log10(Num); else if (Num <= 1e-7 && Num != 0.0) Exponent = log10(Num) - 0.999999999; - - Num /= pow(10.0, Exponent); + + Num /= pow(10.0, Exponent); PrintInt((long)Num, 0, FALSE, FALSE, Stream); PrintCh('.', Stream); Num = (Num - (long)Num) * 10; @@ -214,7 +214,7 @@ void PrintFP(double Num, struct OutputStream *Stream) } else PrintCh('0', Stream); - + if (Exponent != 0) { PrintCh('e', Stream); @@ -234,7 +234,7 @@ void GenericPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct int ZeroPad = FALSE; int FieldWidth = 0; char *Format = Param[0]->Val->Pointer; - + for (FPos = Format; *FPos != '\0'; FPos++) { if (*FPos == '%') @@ -247,18 +247,18 @@ void GenericPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct LeftJustify = TRUE; FPos++; } - + if (*FPos == '0') { /* a leading zero means zero pad a decimal number */ ZeroPad = TRUE; FPos++; } - + /* get any field width in the format */ while (isdigit((int)*FPos)) FieldWidth = FieldWidth * 10 + (*FPos++ - '0'); - + /* now check the format type */ switch (*FPos) { @@ -271,18 +271,18 @@ void GenericPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct case '\0': FPos--; FormatType = NULL; break; default: PrintCh(*FPos, Stream); FormatType = NULL; break; } - + if (FormatType != NULL) - { + { /* we have to format something */ if (ArgCount >= NumArgs) PrintStr("XXX", Stream); /* not enough parameters for format */ else { NextArg = (struct Value *)((char *)NextArg + MEM_ALIGN(sizeof(struct Value) + TypeStackSizeValue(NextArg))); - if (NextArg->Typ != FormatType && + if (NextArg->Typ != FormatType && !((FormatType == &IntType || *FPos == 'f') && IS_NUMERIC_COERCIBLE(NextArg)) && - !(FormatType == CharPtrType && (NextArg->Typ->Base == TypePointer || + !(FormatType == CharPtrType && (NextArg->Typ->Base == TypePointer || (NextArg->Typ->Base == TypeArray && NextArg->Typ->FromType->Base == TypeChar) ) ) ) PrintStr("XXX", Stream); /* bad type for format */ else @@ -292,16 +292,16 @@ void GenericPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct case 's': { char *Str; - + if (NextArg->Typ->Base == TypePointer) Str = NextArg->Val->Pointer; else Str = &NextArg->Val->ArrayMem[0]; - + if (Str == NULL) - PrintStr("NULL", Stream); + PrintStr("NULL", Stream); else - PrintStr(Str, Stream); + PrintStr(Str, Stream); break; } case 'd': PrintInt(ExpressionCoerceInteger(NextArg), FieldWidth, ZeroPad, LeftJustify, Stream); break; @@ -315,7 +315,7 @@ void GenericPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct } } } - + ArgCount++; } } @@ -328,7 +328,7 @@ void GenericPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct void LibPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { struct OutputStream ConsoleStream; - + ConsoleStream.Putch = &PlatformPutc; GenericPrintf(Parser, ReturnValue, Param, NumArgs, &ConsoleStream); } @@ -337,7 +337,7 @@ void LibPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Valu void LibSPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { struct OutputStream StrStream; - + StrStream.Putch = &SPutc; StrStream.i.Str.Parser = Parser; StrStream.i.Str.WritePos = Param[0]->Val->Pointer; @@ -490,10 +490,10 @@ void LibStrcpy(struct ParseState *Parser, struct Value *ReturnValue, struct Valu { char *To = (char *)Param[0]->Val->Pointer; char *From = (char *)Param[1]->Val->Pointer; - + while (*From != '\0') *To++ = *From++; - + *To = '\0'; } @@ -502,10 +502,10 @@ void LibStrncpy(struct ParseState *Parser, struct Value *ReturnValue, struct Val char *To = (char *)Param[0]->Val->Pointer; char *From = (char *)Param[1]->Val->Pointer; int Len = Param[2]->Val->Integer; - + for (; *From != '\0' && Len > 0; Len--) *To++ = *From++; - + if (Len > 0) *To = '\0'; } @@ -515,13 +515,13 @@ void LibStrcmp(struct ParseState *Parser, struct Value *ReturnValue, struct Valu char *Str1 = (char *)Param[0]->Val->Pointer; char *Str2 = (char *)Param[1]->Val->Pointer; int StrEnded; - + for (StrEnded = FALSE; !StrEnded; StrEnded = (*Str1 == '\0' || *Str2 == '\0'), Str1++, Str2++) { - if (*Str1 < *Str2) { ReturnValue->Val->Integer = -1; return; } + if (*Str1 < *Str2) { ReturnValue->Val->Integer = -1; return; } else if (*Str1 > *Str2) { ReturnValue->Val->Integer = 1; return; } } - + ReturnValue->Val->Integer = 0; } @@ -531,13 +531,13 @@ void LibStrncmp(struct ParseState *Parser, struct Value *ReturnValue, struct Val char *Str2 = (char *)Param[1]->Val->Pointer; int Len = Param[2]->Val->Integer; int StrEnded; - + for (StrEnded = FALSE; !StrEnded && Len > 0; StrEnded = (*Str1 == '\0' || *Str2 == '\0'), Str1++, Str2++, Len--) { - if (*Str1 < *Str2) { ReturnValue->Val->Integer = -1; return; } + if (*Str1 < *Str2) { ReturnValue->Val->Integer = -1; return; } else if (*Str1 > *Str2) { ReturnValue->Val->Integer = 1; return; } } - + ReturnValue->Val->Integer = 0; } @@ -545,13 +545,13 @@ void LibStrcat(struct ParseState *Parser, struct Value *ReturnValue, struct Valu { char *To = (char *)Param[0]->Val->Pointer; char *From = (char *)Param[1]->Val->Pointer; - + while (*To != '\0') To++; - + while (*From != '\0') *To++ = *From++; - + *To = '\0'; } @@ -562,7 +562,7 @@ void LibIndex(struct ParseState *Parser, struct Value *ReturnValue, struct Value while (*Pos != '\0' && *Pos != SearchChar) Pos++; - + if (*Pos != SearchChar) ReturnValue->Val->Pointer = NULL; else @@ -586,10 +586,10 @@ void LibStrlen(struct ParseState *Parser, struct Value *ReturnValue, struct Valu { char *Pos = (char *)Param[0]->Val->Pointer; int Len; - + for (Len = 0; *Pos != '\0'; Pos++) Len++; - + ReturnValue->Val->Integer = Len; } @@ -610,13 +610,13 @@ void LibMemcmp(struct ParseState *Parser, struct Value *ReturnValue, struct Valu unsigned char *Mem1 = (unsigned char *)Param[0]->Val->Pointer; unsigned char *Mem2 = (unsigned char *)Param[1]->Val->Pointer; int Len = Param[2]->Val->Integer; - + for (; Len > 0; Mem1++, Mem2++, Len--) { - if (*Mem1 < *Mem2) { ReturnValue->Val->Integer = -1; return; } + if (*Mem1 < *Mem2) { ReturnValue->Val->Integer = -1; return; } else if (*Mem1 > *Mem2) { ReturnValue->Val->Integer = 1; return; } } - + ReturnValue->Val->Integer = 0; } #endif diff --git a/cstdlib/stdio.c b/cstdlib/stdio.c index 486fb78..4274193 100644 --- a/cstdlib/stdio.c +++ b/cstdlib/stdio.c @@ -32,7 +32,7 @@ typedef struct StdOutStreamStruct char *StrOutPtr; int StrOutLen; int CharCount; - + } StdOutStream; /* our representation of varargs within picoc */ @@ -65,7 +65,7 @@ void StdioOutPutc(int OutCh, StdOutStream *Stream) /* output to a string */ *Stream->StrOutPtr = OutCh; Stream->StrOutPtr++; - + if (Stream->StrOutLen > 1) Stream->StrOutLen--; @@ -92,12 +92,12 @@ void StdioOutPuts(const char *Str, StdOutStream *Stream) *Stream->StrOutPtr = *Str; Str++; Stream->StrOutPtr++; - + if (Stream->StrOutLen > 1) Stream->StrOutLen--; - + Stream->CharCount++; - } + } } } } @@ -107,7 +107,7 @@ void StdioFprintfWord(StdOutStream *Stream, const char *Format, unsigned long Va { if (Stream->FilePtr != NULL) Stream->CharCount += fprintf(Stream->FilePtr, Format, Value); - + else if (Stream->StrOutLen >= 0) { #ifndef WIN32 @@ -132,7 +132,7 @@ void StdioFprintfFP(StdOutStream *Stream, const char *Format, double Value) { if (Stream->FilePtr != NULL) Stream->CharCount += fprintf(Stream->FilePtr, Format, Value); - + else if (Stream->StrOutLen >= 0) { #ifndef WIN32 @@ -157,7 +157,7 @@ void StdioFprintfPointer(StdOutStream *Stream, const char *Format, void *Value) { if (Stream->FilePtr != NULL) Stream->CharCount += fprintf(Stream->FilePtr, Format, Value); - + else if (Stream->StrOutLen >= 0) { #ifndef WIN32 @@ -188,16 +188,16 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, int S struct ValueType *ShowType; StdOutStream SOStream; Picoc *pc = Parser->pc; - + if (Format == NULL) Format = "[null format]\n"; - - FPos = Format; + + FPos = Format; SOStream.FilePtr = Stream; SOStream.StrOutPtr = StrOut; SOStream.StrOutLen = StrOutLen; SOStream.CharCount = 0; - + while (*FPos != '\0') { if (*FPos == '%') @@ -207,7 +207,7 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, int S ShowType = NULL; OneFormatBuf[0] = '%'; OneFormatCount = 1; - + do { switch (*FPos) @@ -228,7 +228,7 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, int S 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 */ OneFormatBuf[OneFormatCount] = *FPos; OneFormatCount++; @@ -241,18 +241,18 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, int S case 'm': StdioOutPuts(strerror(errno), &SOStream); 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))); if (ThisArg->Typ->Base == TypeArray && ThisArg->Typ->FromType->Base == TypeInt) *(int *)ThisArg->Val->Pointer = SOStream.CharCount; break; } } - + FPos++; - + } while (ShowType == NULL && OneFormatCount < MAX_FORMAT); - + if (ShowType != &pc->VoidType) { if (ArgCount >= Args->NumArgs) @@ -261,7 +261,7 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, int S { /* null-terminate the buffer */ OneFormatBuf[OneFormatCount] = '\0'; - + /* print this argument */ ThisArg = (struct Value *)((char *)ThisArg + MEM_ALIGN(sizeof(struct Value) + TypeStackSizeValue(ThisArg))); if (ShowType == &pc->IntType) @@ -280,16 +280,16 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, int S StdioFprintfFP(&SOStream, OneFormatBuf, ExpressionCoerceFP(ThisArg)); else StdioOutPuts("XXX", &SOStream); - } + } #endif else if (ShowType == pc->CharPtrType) { if (ThisArg->Typ->Base == TypePointer) StdioFprintfPointer(&SOStream, OneFormatBuf, ThisArg->Val->Pointer); - + else if (ThisArg->Typ->Base == TypeArray && ThisArg->Typ->FromType->Base == TypeChar) StdioFprintfPointer(&SOStream, OneFormatBuf, &ThisArg->Val->ArrayMem[0]); - + else StdioOutPuts("XXX", &SOStream); } @@ -297,14 +297,14 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, int S { if (ThisArg->Typ->Base == TypePointer) StdioFprintfPointer(&SOStream, OneFormatBuf, ThisArg->Val->Pointer); - + else if (ThisArg->Typ->Base == TypeArray) StdioFprintfPointer(&SOStream, OneFormatBuf, &ThisArg->Val->ArrayMem[0]); - + else StdioOutPuts("XXX", &SOStream); } - + ArgCount++; } } @@ -316,11 +316,11 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, int S FPos++; } } - + /* null-terminate */ if (SOStream.StrOutPtr != NULL && SOStream.StrOutLen > 0) - *SOStream.StrOutPtr = '\0'; - + *SOStream.StrOutPtr = '\0'; + return SOStream.CharCount; } @@ -330,24 +330,24 @@ int StdioBaseScanf(struct ParseState *Parser, FILE *Stream, char *StrIn, char *F struct Value *ThisArg = Args->Param[0]; int ArgCount = 0; void *ScanfArg[MAX_SCANF_ARGS]; - + if (Args->NumArgs > MAX_SCANF_ARGS) ProgramFail(Parser, "too many arguments to scanf() - %d max", MAX_SCANF_ARGS); - + for (ArgCount = 0; ArgCount < Args->NumArgs; ArgCount++) { 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; - + else if (ThisArg->Typ->Base == TypeArray) ScanfArg[ArgCount] = &ThisArg->Val->ArrayMem[0]; - + else ProgramFail(Parser, "non-pointer argument to scanf() - argument %d after format", ArgCount+1); } - + 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]); else @@ -355,77 +355,77 @@ int StdioBaseScanf(struct ParseState *Parser, FILE *Stream, char *StrIn, char *F } /* 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); } -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); } -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); } -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); } -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); } -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); } -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); } -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); } -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); } -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); } -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(); } -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); } -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); } -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); } -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 ReturnValue->Val->Integer = fileno(Param[0]->Val->Pointer); @@ -434,77 +434,77 @@ void StdioFileno(struct ParseState *Parser, struct Value *ReturnValue, struct Va #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); } -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); } -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); } -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); } -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); } -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); } -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); } -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); } -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); } -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); } -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); } -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); } -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); } -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); } -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); if (ReturnValue->Val->Pointer != NULL) @@ -515,7 +515,7 @@ 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(); } @@ -523,7 +523,7 @@ void StdioGetchar(struct ParseState *Parser, struct Value *ReturnValue, struct V void StdioPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { struct StdVararg PrintfArgs; - + PrintfArgs.Param = Param; PrintfArgs.NumArgs = NumArgs-1; ReturnValue->Val->Integer = StdioBasePrintf(Parser, stdout, NULL, 0, Param[0]->Val->Pointer, &PrintfArgs); @@ -537,7 +537,7 @@ void StdioVprintf(struct ParseState *Parser, struct Value *ReturnValue, struct V void StdioFprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { struct StdVararg PrintfArgs; - + PrintfArgs.Param = Param + 1; PrintfArgs.NumArgs = NumArgs-2; ReturnValue->Val->Integer = StdioBasePrintf(Parser, Param[0]->Val->Pointer, NULL, 0, Param[1]->Val->Pointer, &PrintfArgs); @@ -548,19 +548,19 @@ void StdioVfprintf(struct ParseState *Parser, struct Value *ReturnValue, struct 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; - + PrintfArgs.Param = Param + 1; PrintfArgs.NumArgs = NumArgs-2; 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; - + PrintfArgs.Param = Param+2; PrintfArgs.NumArgs = NumArgs-3; ReturnValue->Val->Integer = StdioBasePrintf(Parser, NULL, Param[0]->Val->Pointer, Param[1]->Val->Integer, Param[2]->Val->Pointer, &PrintfArgs); @@ -569,7 +569,7 @@ void StdioSnprintf(struct ParseState *Parser, struct Value *ReturnValue, struct void StdioScanf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { struct StdVararg ScanfArgs; - + ScanfArgs.Param = Param; ScanfArgs.NumArgs = NumArgs-1; ReturnValue->Val->Integer = StdioBaseScanf(Parser, stdin, NULL, Param[0]->Val->Pointer, &ScanfArgs); @@ -578,7 +578,7 @@ void StdioScanf(struct ParseState *Parser, struct Value *ReturnValue, struct Val void StdioFscanf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { struct StdVararg ScanfArgs; - + ScanfArgs.Param = Param+1; ScanfArgs.NumArgs = NumArgs-2; ReturnValue->Val->Integer = StdioBaseScanf(Parser, Param[0]->Val->Pointer, NULL, Param[1]->Val->Pointer, &ScanfArgs); @@ -587,7 +587,7 @@ void StdioFscanf(struct ParseState *Parser, struct Value *ReturnValue, struct Va void StdioSscanf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { struct StdVararg ScanfArgs; - + ScanfArgs.Param = Param+1; ScanfArgs.NumArgs = NumArgs-2; ReturnValue->Val->Integer = StdioBaseScanf(Parser, NULL, Param[0]->Val->Pointer, Param[1]->Val->Pointer, &ScanfArgs); @@ -685,13 +685,13 @@ void StdioSetupFunc(Picoc *pc) /* make a "struct __FILEStruct" which is the same size as a native FILE structure */ StructFileType = TypeCreateOpaqueStruct(pc, NULL, TableStrRegister(pc, "__FILEStruct"), sizeof(FILE)); - + /* get a FILE * type */ FilePtrType = TypeGetMatching(pc, NULL, StructFileType, TypePointer, 0, pc->StrEmpty, TRUE); /* make a "struct __va_listStruct" which is the same size as our struct StdVararg */ TypeCreateOpaqueStruct(pc, NULL, TableStrRegister(pc, "__va_listStruct"), sizeof(FILE)); - + /* define EOF equal to the system EOF */ VariableDefinePlatformVar(pc, NULL, "EOF", &pc->IntType, (union AnyValue *)&EOFValue, FALSE); VariableDefinePlatformVar(pc, NULL, "SEEK_SET", &pc->IntType, (union AnyValue *)&SEEK_SETValue, FALSE); @@ -704,7 +704,7 @@ void StdioSetupFunc(Picoc *pc) 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 */ VariableDefinePlatformVar(pc, NULL, "stdin", FilePtrType, (union AnyValue *)&stdinValue, FALSE); VariableDefinePlatformVar(pc, NULL, "stdout", FilePtrType, (union AnyValue *)&stdoutValue, FALSE); diff --git a/cstdlib/time.c b/cstdlib/time.c index db1d00d..54f9d07 100644 --- a/cstdlib/time.c +++ b/cstdlib/time.c @@ -65,7 +65,7 @@ void StdStrftime(struct ParseState *Parser, struct Value *ReturnValue, struct Va 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); - + ReturnValue->Val->Pointer = strptime(Param[0]->Val->Pointer, Param[1]->Val->Pointer, Param[2]->Val->Pointer); } @@ -114,7 +114,7 @@ void StdTimeSetupFunc(Picoc *pc) { /* make a "struct tm" which is the same size as a native tm structure */ TypeCreateOpaqueStruct(pc, NULL, TableStrRegister(pc, "tm"), sizeof(struct tm)); - + /* define CLK_PER_SEC etc. */ VariableDefinePlatformVar(pc, NULL, "CLOCKS_PER_SEC", &pc->IntType, (union AnyValue *)&CLOCKS_PER_SECValue, FALSE); #ifdef CLK_PER_SEC diff --git a/expression.c b/expression.c index 60de722..261936c 100644 --- a/expression.c +++ b/expression.c @@ -1,6 +1,6 @@ /* picoc expression evaluator - a stack-based expression evaluation system * which handles operator precedence */ - + #include "interpreter.h" /* whether evaluation is left to right for a given precedence level */ @@ -55,9 +55,9 @@ static struct OpPrecedence OperatorPrecedence[] = { /* TokenNone, */ { 0, 0, 0, "none" }, /* TokenComma, */ { 0, 0, 0, "," }, - /* TokenAssign, */ { 0, 0, 2, "=" }, /* TokenAddAssign, */ { 0, 0, 2, "+=" }, /* TokenSubtractAssign, */ { 0, 0, 2, "-=" }, + /* TokenAssign, */ { 0, 0, 2, "=" }, /* TokenAddAssign, */ { 0, 0, 2, "+=" }, /* TokenSubtractAssign, */ { 0, 0, 2, "-=" }, /* TokenMultiplyAssign, */ { 0, 0, 2, "*=" }, /* TokenDivideAssign, */ { 0, 0, 2, "/=" }, /* TokenModulusAssign, */ { 0, 0, 2, "%=" }, - /* TokenShiftLeftAssign, */ { 0, 0, 2, "<<=" }, /* TokenShiftRightAssign, */ { 0, 0, 2, ">>=" }, /* TokenArithmeticAndAssign, */ { 0, 0, 2, "&=" }, + /* TokenShiftLeftAssign, */ { 0, 0, 2, "<<=" }, /* TokenShiftRightAssign, */ { 0, 0, 2, ">>=" }, /* TokenArithmeticAndAssign, */ { 0, 0, 2, "&=" }, /* TokenArithmeticOrAssign, */ { 0, 0, 2, "|=" }, /* TokenArithmeticExorAssign, */ { 0, 0, 2, "^=" }, /* TokenQuestionMark, */ { 0, 0, 3, "?" }, /* TokenColon, */ { 0, 0, 3, ":" }, /* TokenLogicalOr, */ { 0, 0, 4, "||" }, @@ -82,17 +82,17 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta void ExpressionStackShow(Picoc *pc, struct ExpressionStack *StackTop) { printf("Expression stack [0x%lx,0x%lx]: ", (long)pc->HeapStackTop, (long)StackTop); - + while (StackTop != NULL) { if (StackTop->Order == OrderNone) - { + { /* it's a value */ if (StackTop->Val->IsLValue) printf("lvalue="); else printf("value="); - + switch (StackTop->Val->Typ->Base) { case TypeVoid: printf("void"); break; @@ -112,7 +112,7 @@ void ExpressionStackShow(Picoc *pc, struct ExpressionStack *StackTop) else if (StackTop->Val->Typ->FromType->Base == TypeChar) printf("\"%s\":string", (char *)StackTop->Val->Val->Pointer); else - printf("ptr(0x%lx)", (long)StackTop->Val->Val->Pointer); + printf("ptr(0x%lx)", (long)StackTop->Val->Val->Pointer); break; case TypeArray: printf("array"); break; case TypeStruct: printf("%s:struct", StackTop->Val->Val->Identifier); break; @@ -124,19 +124,19 @@ void ExpressionStackShow(Picoc *pc, struct ExpressionStack *StackTop) printf("[0x%lx,0x%lx]", (long)StackTop, (long)StackTop->Val); } else - { + { /* it's an operator */ - printf("op='%s' %s %d", OperatorPrecedence[(int)StackTop->Op].Name, - (StackTop->Order == OrderPrefix) ? "prefix" : ((StackTop->Order == OrderPostfix) ? "postfix" : "infix"), + printf("op='%s' %s %d", OperatorPrecedence[(int)StackTop->Op].Name, + (StackTop->Order == OrderPrefix) ? "prefix" : ((StackTop->Order == OrderPostfix) ? "postfix" : "infix"), StackTop->Precedence); printf("[0x%lx]", (long)StackTop); } - + StackTop = StackTop->Next; if (StackTop != NULL) printf(", "); } - + printf("\n"); } #endif @@ -145,7 +145,7 @@ int IsTypeToken(struct ParseState * Parser, enum LexToken t, struct Value * LexV { if (t >= TokenIntType && t <= TokenUnsignedType) return 1; /* base type */ - + /* typedef'ed type? */ if (t == TokenIdentifier) /* see TypeParseFront, case TokenIdentifier and ParseTypedef */ { @@ -157,7 +157,7 @@ int IsTypeToken(struct ParseState * Parser, enum LexToken t, struct Value * LexV return 1; } } - + return 0; } @@ -207,7 +207,7 @@ double ExpressionCoerceFP(struct Value *Val) #ifndef BROKEN_FLOAT_CASTS int IntVal; unsigned UnsignedVal; - + switch (Val->Typ->Base) { case TypeInt: IntVal = Val->Val->Integer; return (double)IntVal; @@ -243,10 +243,10 @@ double ExpressionCoerceFP(struct Value *Val) long ExpressionAssignInt(struct ParseState *Parser, struct Value *DestValue, long FromInt, int After) { long Result; - - if (!DestValue->IsLValue) - ProgramFail(Parser, "can't assign to this"); - + + if (!DestValue->IsLValue) + ProgramFail(Parser, "can't assign to this"); + if (After) Result = ExpressionCoerceInteger(DestValue); else @@ -271,9 +271,9 @@ long ExpressionAssignInt(struct ParseState *Parser, struct Value *DestValue, lon /* assign a floating point value */ double ExpressionAssignFP(struct ParseState *Parser, struct Value *DestValue, double FromFP) { - if (!DestValue->IsLValue) - ProgramFail(Parser, "can't assign to this"); - + if (!DestValue->IsLValue) + ProgramFail(Parser, "can't assign to this"); + DestValue->Val->FP = FromFP; return FromFP; } @@ -300,7 +300,7 @@ struct Value *ExpressionStackPushValueByType(struct ParseState *Parser, struct E { struct Value *ValueLoc = VariableAllocValueFromType(Parser->pc, Parser, PushType, FALSE, NULL, FALSE); ExpressionStackPushValueNode(Parser, StackTop, ValueLoc); - + return ValueLoc; } @@ -353,16 +353,16 @@ void ExpressionPushFP(struct ParseState *Parser, struct ExpressionStack **StackT void ExpressionAssignToPointer(struct ParseState *Parser, struct Value *ToValue, struct Value *FromValue, const char *FuncName, int ParamNo, int AllowPointerCoercion) { struct ValueType *PointedToType = ToValue->Typ->FromType; - + if (FromValue->Typ == ToValue->Typ || FromValue->Typ == Parser->pc->VoidPtrType || (ToValue->Typ == Parser->pc->VoidPtrType && FromValue->Typ->Base == TypePointer)) ToValue->Val->Pointer = FromValue->Val->Pointer; /* plain old pointer assignment */ - + else if (FromValue->Typ->Base == TypeArray && (PointedToType == FromValue->Typ->FromType || ToValue->Typ == Parser->pc->VoidPtrType)) { /* the form is: blah *x = array of blah */ ToValue->Val->Pointer = (void *)&FromValue->Val->ArrayMem[0]; } - else if (FromValue->Typ->Base == TypePointer && FromValue->Typ->FromType->Base == TypeArray && + else if (FromValue->Typ->Base == TypePointer && FromValue->Typ->FromType->Base == TypeArray && (PointedToType == FromValue->Typ->FromType->FromType || ToValue->Typ == Parser->pc->VoidPtrType) ) { /* the form is: blah *x = pointer to array of blah */ @@ -384,17 +384,17 @@ void ExpressionAssignToPointer(struct ParseState *Parser, struct Value *ToValue, ToValue->Val->Pointer = FromValue->Val->Pointer; } else - AssignFail(Parser, "%t from %t", ToValue->Typ, FromValue->Typ, 0, 0, FuncName, ParamNo); + AssignFail(Parser, "%t from %t", ToValue->Typ, FromValue->Typ, 0, 0, FuncName, ParamNo); } /* 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) { - if (!DestValue->IsLValue && !Force) - AssignFail(Parser, "not an lvalue", NULL, NULL, 0, 0, FuncName, ParamNo); + if (!DestValue->IsLValue && !Force) + AssignFail(Parser, "not an lvalue", NULL, NULL, 0, 0, FuncName, ParamNo); if (IS_NUMERIC_COERCIBLE(DestValue) && !IS_NUMERIC_COERCIBLE_PLUS_POINTERS(SourceValue, AllowPointerCoercion)) - AssignFail(Parser, "%t from %t", DestValue->Typ, SourceValue->Typ, 0, 0, FuncName, ParamNo); + AssignFail(Parser, "%t from %t", DestValue->Typ, SourceValue->Typ, 0, 0, FuncName, ParamNo); switch (DestValue->Typ->Base) { @@ -409,23 +409,23 @@ void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, struct #ifndef NO_FP case TypeFP: - if (!IS_NUMERIC_COERCIBLE_PLUS_POINTERS(SourceValue, AllowPointerCoercion)) - AssignFail(Parser, "%t from %t", DestValue->Typ, SourceValue->Typ, 0, 0, FuncName, ParamNo); - + if (!IS_NUMERIC_COERCIBLE_PLUS_POINTERS(SourceValue, AllowPointerCoercion)) + AssignFail(Parser, "%t from %t", DestValue->Typ, SourceValue->Typ, 0, 0, FuncName, ParamNo); + DestValue->Val->FP = ExpressionCoerceFP(SourceValue); break; #endif case TypePointer: ExpressionAssignToPointer(Parser, DestValue, SourceValue, FuncName, ParamNo, AllowPointerCoercion); break; - + case TypeArray: if (SourceValue->Typ->Base == TypeArray && DestValue->Typ->FromType == DestValue->Typ->FromType && DestValue->Typ->ArraySize == 0) { /* destination array is unsized - need to resize the destination array to the same size as the source array */ DestValue->Typ = SourceValue->Typ; VariableRealloc(Parser, DestValue, TypeSizeValue(DestValue, FALSE)); - + if (DestValue->LValueFrom != NULL) { /* copy the resized value back to the LValue */ @@ -458,24 +458,24 @@ void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, struct } 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); + 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); - + memcpy((void *)DestValue->Val, (void *)SourceValue->Val, TypeSizeValue(DestValue, FALSE)); break; - + case TypeStruct: case TypeUnion: 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)); break; - + default: - AssignFail(Parser, "%t", DestValue->Typ, NULL, 0, 0, FuncName, ParamNo); + AssignFail(Parser, "%t", DestValue->Typ, NULL, 0, 0, FuncName, ParamNo); break; } } @@ -535,7 +535,7 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack case TokenAsterisk: ExpressionStackPushDereference(Parser, StackTop, TopValue); break; - + case TokenSizeof: /* return the size of the argument */ if (TopValue->Typ == &Parser->pc->TypeType) @@ -543,7 +543,7 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack else ExpressionPushInt(Parser, StackTop, TypeSize(TopValue->Typ, TopValue->Typ->ArraySize, TRUE)); break; - + default: /* an arithmetic operator */ #ifndef NO_FP @@ -551,7 +551,7 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack { /* floating point prefix arithmetic */ double ResultFP = 0.0; - + switch (Op) { case TokenPlus: ResultFP = TopValue->Val->FP; break; @@ -561,10 +561,10 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack case TokenUnaryNot: ResultFP = !TopValue->Val->FP; break; default: ProgramFail(Parser, "invalid operation"); break; } - + ExpressionPushFP(Parser, StackTop, ResultFP); } - else + else #endif if (IS_NUMERIC_COERCIBLE(TopValue)) { @@ -593,10 +593,10 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack if (TopValue->Val->Pointer == NULL) ProgramFail(Parser, "invalid use of a NULL pointer"); - - if (!TopValue->IsLValue) - ProgramFail(Parser, "can't assign to this"); - + + if (!TopValue->IsLValue) + ProgramFail(Parser, "can't assign to this"); + switch (Op) { case TokenIncrement: TopValue->Val->Pointer = (void *)((char *)TopValue->Val->Pointer + Size); break; @@ -623,17 +623,17 @@ void ExpressionPostfixOperator(struct ParseState *Parser, struct ExpressionStack { /* floating point prefix arithmetic */ double ResultFP = 0.0; - + switch (Op) { case TokenIncrement: ResultFP = ExpressionAssignFP(Parser, TopValue, TopValue->Val->FP+1); break; case TokenDecrement: ResultFP = ExpressionAssignFP(Parser, TopValue, TopValue->Val->FP-1); break; default: ProgramFail(Parser, "invalid operation"); break; } - + ExpressionPushFP(Parser, StackTop, ResultFP); } - else + else #endif if (IS_NUMERIC_COERCIBLE(TopValue)) { @@ -647,7 +647,7 @@ void ExpressionPostfixOperator(struct ParseState *Parser, struct ExpressionStack case TokenCloseBracket: ProgramFail(Parser, "not supported"); break; /* XXX */ default: ProgramFail(Parser, "invalid operation"); break; } - + ExpressionPushInt(Parser, StackTop, ResultInt); } else if (TopValue->Typ->Base == TypePointer) @@ -656,20 +656,20 @@ void ExpressionPostfixOperator(struct ParseState *Parser, struct ExpressionStack int Size = TypeSize(TopValue->Typ->FromType, 0, TRUE); struct Value *StackValue; void *OrigPointer = TopValue->Val->Pointer; - + if (TopValue->Val->Pointer == NULL) ProgramFail(Parser, "invalid use of a NULL pointer"); - - if (!TopValue->IsLValue) - ProgramFail(Parser, "can't assign to this"); - + + if (!TopValue->IsLValue) + ProgramFail(Parser, "can't assign to this"); + switch (Op) { case TokenIncrement: TopValue->Val->Pointer = (void *)((char *)TopValue->Val->Pointer + Size); break; case TokenDecrement: TopValue->Val->Pointer = (void *)((char *)TopValue->Val->Pointer - Size); break; default: ProgramFail(Parser, "invalid operation"); break; } - + StackValue = ExpressionStackPushValueByType(Parser, StackTop, TopValue->Typ); StackValue->Val->Pointer = OrigPointer; } @@ -683,20 +683,20 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack * long ResultInt = 0; struct Value *StackValue; void *Pointer; - + debugf("ExpressionInfixOperator()\n"); if (BottomValue == NULL || TopValue == NULL) ProgramFail(Parser, "invalid expression"); - + if (Op == TokenLeftSquareBracket) - { + { /* array index */ int ArrayIndex; struct Value *Result = NULL; - + if (!IS_NUMERIC_COERCIBLE(TopValue)) ProgramFail(Parser, "array index must be an integer"); - + ArrayIndex = ExpressionCoerceInteger(TopValue); /* make the array element result */ @@ -706,15 +706,15 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack * 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); } - + ExpressionStackPushValueNode(Parser, StackTop, Result); } else if (Op == TokenQuestionMark) ExpressionQuestionMarkOperator(Parser, StackTop, TopValue, BottomValue); - + else if (Op == TokenColon) ExpressionColonOperator(Parser, StackTop, TopValue, BottomValue); - + #ifndef NO_FP else if ( (TopValue->Typ == &Parser->pc->FPType && BottomValue->Typ == &Parser->pc->FPType) || (TopValue->Typ == &Parser->pc->FPType && IS_NUMERIC_COERCIBLE(BottomValue)) || @@ -753,7 +753,7 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack * } #endif else if (IS_NUMERIC_COERCIBLE(TopValue) && IS_NUMERIC_COERCIBLE(BottomValue)) - { + { /* integer operation */ long TopInt = ExpressionCoerceInteger(TopValue); long BottomInt = ExpressionCoerceInteger(BottomValue); @@ -794,7 +794,7 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack * #endif default: ProgramFail(Parser, "invalid operation"); break; } - + ExpressionPushInt(Parser, StackTop, ResultInt); } else if (BottomValue->Typ->Base == TypePointer && IS_NUMERIC_COERCIBLE(TopValue)) @@ -805,9 +805,9 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack * if (Op == TokenEqual || Op == TokenNotEqual) { /* comparison to a NULL pointer */ - if (TopInt != 0) + if (TopInt != 0) ProgramFail(Parser, "invalid operation"); - + if (Op == TokenEqual) ExpressionPushInt(Parser, StackTop, BottomValue->Val->Pointer == NULL); else @@ -817,16 +817,16 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack * { /* pointer arithmetic */ int Size = TypeSize(BottomValue->Typ->FromType, 0, TRUE); - + Pointer = BottomValue->Val->Pointer; if (Pointer == NULL) ProgramFail(Parser, "invalid use of a NULL pointer"); - + if (Op == TokenPlus) Pointer = (void *)((char *)Pointer + TopInt * Size); else Pointer = (void *)((char *)Pointer - TopInt * Size); - + StackValue = ExpressionStackPushValueByType(Parser, StackTop, BottomValue->Typ); StackValue->Val->Pointer = Pointer; } @@ -863,7 +863,7 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack * /* pointer/pointer operations */ char *TopLoc = (char *)TopValue->Val->Pointer; char *BottomLoc = (char *)BottomValue->Val->Pointer; - + switch (Op) { case TokenEqual: ExpressionPushInt(Parser, StackTop, BottomLoc == TopLoc); break; @@ -897,7 +897,7 @@ void ExpressionStackCollapse(struct ParseState *Parser, struct ExpressionStack * struct Value *BottomValue; struct ExpressionStack *TopStackNode = *StackTop; struct ExpressionStack *TopOperatorNode; - + debugf("ExpressionStackCollapse(%d):\n", Precedence); #ifdef DEBUG_EXPRESSIONS ExpressionStackShow(Parser->pc, *StackTop); @@ -909,9 +909,9 @@ void ExpressionStackCollapse(struct ParseState *Parser, struct ExpressionStack * TopOperatorNode = TopStackNode->Next; else TopOperatorNode = TopStackNode; - + FoundPrecedence = TopOperatorNode->Precedence; - + /* does it have a high enough precedence? */ if (FoundPrecedence >= Precedence && TopOperatorNode != NULL) { @@ -922,12 +922,12 @@ void ExpressionStackCollapse(struct ParseState *Parser, struct ExpressionStack * /* prefix evaluation */ debugf("prefix evaluation\n"); TopValue = TopStackNode->Val; - + /* 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, TopOperatorNode, sizeof(struct ExpressionStack)); *StackTop = TopOperatorNode->Next; - + /* do the prefix operation */ if (Parser->Mode == RunModeRun /* && FoundPrecedence < *IgnorePrecedence */) { @@ -940,12 +940,12 @@ void ExpressionStackCollapse(struct ParseState *Parser, struct ExpressionStack * ExpressionPushInt(Parser, StackTop, 0); } break; - + case OrderPostfix: /* postfix evaluation */ debugf("postfix evaluation\n"); TopValue = TopStackNode->Next->Val; - + /* 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, TopValue, sizeof(struct ExpressionStack) + sizeof(struct Value) + TypeStackSizeValue(TopValue)); @@ -963,7 +963,7 @@ void ExpressionStackCollapse(struct ParseState *Parser, struct ExpressionStack * ExpressionPushInt(Parser, StackTop, 0); } break; - + case OrderInfix: /* infix evaluation */ debugf("infix evaluation\n"); @@ -971,13 +971,13 @@ void ExpressionStackCollapse(struct ParseState *Parser, struct ExpressionStack * if (TopValue != NULL) { BottomValue = TopOperatorNode->Next->Val; - + /* 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)); HeapPopStack(Parser->pc, BottomValue, sizeof(struct ExpressionStack) + sizeof(struct Value) + TypeStackSizeValue(BottomValue)); *StackTop = TopOperatorNode->Next->Next; - + /* do the infix operation */ if (Parser->Mode == RunModeRun /* && FoundPrecedence <= *IgnorePrecedence */) { @@ -999,7 +999,7 @@ void ExpressionStackCollapse(struct ParseState *Parser, struct ExpressionStack * assert(TopOperatorNode->Order != OrderNone); break; } - + /* if we've returned above the ignored precedence level turn ignoring off */ if (FoundPrecedence <= *IgnorePrecedence) *IgnorePrecedence = DEEP_PRECEDENCE; @@ -1038,13 +1038,13 @@ void ExpressionStackPushOperator(struct ParseState *Parser, struct ExpressionSta void ExpressionGetStructElement(struct ParseState *Parser, struct ExpressionStack **StackTop, enum LexToken Token) { struct Value *Ident; - + /* get the identifier following the '.' or '->' */ if (LexGetToken(Parser, &Ident, TRUE) != TokenIdentifier) ProgramFail(Parser, "need an structure or union member after '%s'", (Token == TokenDot) ? "." : "->"); if (Parser->Mode == RunModeRun) - { + { /* look up the struct element */ struct Value *ParamVal = (*StackTop)->Val; struct Value *StructVal = ParamVal; @@ -1056,17 +1056,17 @@ void ExpressionGetStructElement(struct ParseState *Parser, struct ExpressionStac /* if we're doing '->' dereference the struct pointer first */ if (Token == TokenArrow) DerefDataLoc = VariableDereferencePointer(Parser, ParamVal, &StructVal, NULL, &StructType, NULL); - + 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); - + if (!TableGet(StructType->Members, Ident->Val->Identifier, &MemberValue, NULL, NULL, NULL)) 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 */ HeapPopStack(Parser->pc, ParamVal, sizeof(struct ExpressionStack) + sizeof(struct Value) + TypeStackSizeValue(StructVal)); *StackTop = (*StackTop)->Next; - + /* make the result value for this member only */ Result = VariableAllocValueFromExistingData(Parser, MemberValue->Typ, (void *)(DerefDataLoc + MemberValue->Val->Integer), TRUE, (StructVal != NULL) ? StructVal->LValueFrom : NULL); ExpressionStackPushValueNode(Parser, StackTop, Result); @@ -1085,7 +1085,7 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) int IgnorePrecedence = DEEP_PRECEDENCE; struct ExpressionStack *StackTop = NULL; int TernaryDepth = 0; - + debugf("ExpressionParse():\n"); do { @@ -1094,22 +1094,22 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) ParserCopy(&PreState, Parser); Token = LexGetToken(Parser, &LexValue, TRUE); - if ( ( ( (int)Token > TokenComma && (int)Token <= (int)TokenOpenBracket) || - (Token == TokenCloseBracket && BracketPrecedence != 0)) && + if ( ( ( (int)Token > TokenComma && (int)Token <= (int)TokenOpenBracket) || + (Token == TokenCloseBracket && BracketPrecedence != 0)) && (Token != TokenColon || TernaryDepth > 0) ) - { + { /* it's an operator with precedence */ if (PrefixState) - { + { /* expect a prefix operator */ if (OperatorPrecedence[(int)Token].PrefixPrecedence == 0) ProgramFail(Parser, "operator not expected here"); - + LocalPrecedence = OperatorPrecedence[(int)Token].PrefixPrecedence; Precedence = BracketPrecedence + LocalPrecedence; if (Token == TokenOpenBracket) - { + { /* it's either a new bracket level or a cast */ enum LexToken BracketToken = LexGetToken(Parser, &LexValue, FALSE); if (IsTypeToken(Parser, BracketToken, LexValue) && (StackTop == NULL || StackTop->Op != TokenSizeof) ) @@ -1118,11 +1118,11 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) struct ValueType *CastType; char *CastIdentifier; struct Value *CastTypeValue; - + TypeParse(Parser, &CastType, &CastIdentifier, NULL); if (LexGetToken(Parser, &LexValue, TRUE) != TokenCloseBracket) ProgramFail(Parser, "brackets not closed"); - + /* scan and collapse the stack to the precedence of this infix cast operator, then push */ Precedence = BracketPrecedence + OperatorPrecedence[(int)TokenCast].PrefixPrecedence; @@ -1139,16 +1139,16 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) } } else - { + { /* scan and collapse the stack to the precedence of this operator, then push */ - + /* take some extra care for double prefix operators, e.g. x = - -5, or x = **y */ int NextToken = LexGetToken(Parser, NULL, FALSE); int TempPrecedenceBoost = 0; if (NextToken > TokenComma && NextToken < TokenOpenBracket) { int NextPrecedence = OperatorPrecedence[(int)NextToken].PrefixPrecedence; - + /* two prefix operators with equal precedence? make sure the innermost one runs first */ /* XXX - probably not correct, but can't find a test that fails at this */ if (LocalPrecedence == NextPrecedence) @@ -1160,7 +1160,7 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) } } else - { + { /* expect an infix or postfix operator */ if (OperatorPrecedence[(int)Token].PostfixPrecedence != 0) { @@ -1169,7 +1169,7 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) case TokenCloseBracket: case TokenRightSquareBracket: if (BracketPrecedence == 0) - { + { /* assume this bracket is after the end of the expression */ ParserCopy(Parser, &PreState); Done = TRUE; @@ -1179,9 +1179,9 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) /* collapse to the bracket precedence */ ExpressionStackCollapse(Parser, &StackTop, BracketPrecedence, &IgnorePrecedence); BracketPrecedence -= BRACKET_PRECEDENCE; - } + } break; - + default: /* scan and collapse the stack to the precedence of this operator, then push */ Precedence = BracketPrecedence + OperatorPrecedence[(int)Token].PostfixPrecedence; @@ -1191,23 +1191,23 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) } } else if (OperatorPrecedence[(int)Token].InfixPrecedence != 0) - { + { /* scan and collapse the stack, then push */ Precedence = BracketPrecedence + OperatorPrecedence[(int)Token].InfixPrecedence; - + /* 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 */ if (IS_LEFT_TO_RIGHT(OperatorPrecedence[(int)Token].InfixPrecedence)) ExpressionStackCollapse(Parser, &StackTop, Precedence, &IgnorePrecedence); else ExpressionStackCollapse(Parser, &StackTop, Precedence+1, &IgnorePrecedence); - + if (Token == TokenDot || Token == TokenArrow) { ExpressionGetStructElement(Parser, &StackTop, Token); /* this operator is followed by a struct element so handle it as a special case */ } else - { + { /* 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)) { @@ -1216,11 +1216,11 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) (IgnorePrecedence > Precedence) ) IgnorePrecedence = Precedence; } - + /* push the operator on the stack */ ExpressionStackPushOperator(Parser, &StackTop, OrderInfix, Token, Precedence); PrefixState = TRUE; - + switch (Token) { case TokenQuestionMark: TernaryDepth++; break; @@ -1231,7 +1231,7 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) /* treat an open square bracket as an infix array index operator followed by an open bracket */ if (Token == TokenLeftSquareBracket) - { + { /* boost the bracket operator precedence, then push */ BracketPrecedence += BRACKET_PRECEDENCE; } @@ -1241,11 +1241,11 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) } } else if (Token == TokenIdentifier) - { + { /* it's a variable, function or a macro */ if (!PrefixState) ProgramFail(Parser, "identifier not expected here"); - + if (LexGetToken(Parser, NULL, FALSE) == TokenOpenBracket) { ExpressionParseFunctionCall(Parser, &StackTop, LexValue->Val->Identifier, Parser->Mode == RunModeRun && Precedence < IgnorePrecedence); @@ -1255,22 +1255,22 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) if (Parser->Mode == RunModeRun /* && Precedence < IgnorePrecedence */) { struct Value *VariableValue = NULL; - + VariableGet(Parser->pc, Parser, LexValue->Val->Identifier, &VariableValue); if (VariableValue->Typ->Base == TypeMacro) { /* evaluate a macro as a kind of simple subroutine */ struct ParseState MacroParser; struct Value *MacroResult; - + ParserCopy(&MacroParser, &VariableValue->Val->MacroDef.Body); MacroParser.Mode = Parser->Mode; if (VariableValue->Val->MacroDef.NumParams != 0) ProgramFail(&MacroParser, "macro arguments missing"); - + if (!ExpressionParse(&MacroParser, &MacroResult) || LexGetToken(&MacroParser, NULL, FALSE) != TokenEndOfFunction) ProgramFail(&MacroParser, "expression expected"); - + ExpressionStackPushValueNode(Parser, &StackTop, MacroResult); } else if (VariableValue->Typ == &Parser->pc->VoidType) @@ -1280,7 +1280,7 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) } else /* push a dummy value */ ExpressionPushInt(Parser, &StackTop, 0); - + } /* if we've successfully ignored the RHS turn ignoring off */ @@ -1290,11 +1290,11 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) PrefixState = FALSE; } else if ((int)Token > TokenCloseBracket && (int)Token <= TokenCharacterConstant) - { + { /* it's a value of some sort, push it */ if (!PrefixState) ProgramFail(Parser, "value not expected here"); - + PrefixState = FALSE; ExpressionStackPushValue(Parser, &StackTop, LexValue); } @@ -1304,10 +1304,10 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) struct ValueType *Typ; char *Identifier; struct Value *TypeValue; - + if (!PrefixState) ProgramFail(Parser, "type not expected here"); - + PrefixState = FALSE; ParserCopy(Parser, &PreState); TypeParse(Parser, &Typ, &Identifier, NULL); @@ -1316,21 +1316,21 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) ExpressionStackPushValueNode(Parser, &StackTop, TypeValue); } else - { + { /* it isn't a token from an expression */ ParserCopy(Parser, &PreState); Done = TRUE; } - + } while (!Done); - + /* check that brackets have been closed */ if (BracketPrecedence > 0) ProgramFail(Parser, "brackets not closed"); - + /* scan and collapse the stack to precedence 0 */ ExpressionStackCollapse(Parser, &StackTop, 0, &IgnorePrecedence); - + /* fix up the stack and return the result if we're in run mode */ if (StackTop != NULL) { @@ -1339,14 +1339,14 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) { if (StackTop->Order != OrderNone || StackTop->Next != NULL) ProgramFail(Parser, "invalid expression"); - + *Result = StackTop->Val; HeapPopStack(Parser->pc, StackTop, sizeof(struct ExpressionStack)); } else HeapPopStack(Parser->pc, StackTop->Val, sizeof(struct ExpressionStack) + sizeof(struct Value) + TypeStackSizeValue(StackTop->Val)); } - + debugf("ExpressionParse() done\n\n"); #ifdef DEBUG_EXPRESSIONS ExpressionStackShow(Parser->pc, StackTop); @@ -1363,9 +1363,9 @@ void ExpressionParseMacroCall(struct ParseState *Parser, struct ExpressionStack struct Value **ParamArray = NULL; int ArgCount; enum LexToken Token; - - if (Parser->Mode == RunModeRun) - { + + if (Parser->Mode == RunModeRun) + { /* create a stack frame for this macro */ #ifndef NO_FP ExpressionStackPushValueByType(Parser, StackTop, &Parser->pc->FPType); /* largest return type there is */ @@ -1374,54 +1374,54 @@ void ExpressionParseMacroCall(struct ParseState *Parser, struct ExpressionStack #endif ReturnValue = (*StackTop)->Val; HeapPushStackFrame(Parser->pc); - ParamArray = HeapAllocStack(Parser->pc, sizeof(struct Value *) * MDef->NumParams); + ParamArray = HeapAllocStack(Parser->pc, sizeof(struct Value *) * MDef->NumParams); if (ParamArray == NULL) ProgramFail(Parser, "out of memory"); } else ExpressionPushInt(Parser, StackTop, 0); - + /* parse arguments */ ArgCount = 0; do { if (ExpressionParse(Parser, &Param)) { if (Parser->Mode == RunModeRun) - { + { if (ArgCount < MDef->NumParams) ParamArray[ArgCount] = Param; else ProgramFail(Parser, "too many arguments to %s()", MacroName); } - + ArgCount++; Token = LexGetToken(Parser, NULL, TRUE); if (Token != TokenComma && Token != TokenCloseBracket) ProgramFail(Parser, "comma expected"); } else - { + { /* end of argument list? */ Token = LexGetToken(Parser, NULL, TRUE); if (!TokenCloseBracket) ProgramFail(Parser, "bad argument"); } - + } while (Token != TokenCloseBracket); - - if (Parser->Mode == RunModeRun) - { + + if (Parser->Mode == RunModeRun) + { /* evaluate the macro */ struct ParseState MacroParser; int Count; struct Value *EvalValue; - + if (ArgCount < MDef->NumParams) ProgramFail(Parser, "not enough arguments to '%s'", MacroName); - + if (MDef->Body.Pos == NULL) ProgramFail(Parser, "'%s' is undefined", MacroName); - + ParserCopy(&MacroParser, &MDef->Body); MacroParser.Mode = Parser->Mode; VariableStackFrameAdd(Parser, MacroName, 0); @@ -1429,7 +1429,7 @@ void ExpressionParseMacroCall(struct ParseState *Parser, struct ExpressionStack Parser->pc->TopStackFrame->ReturnValue = ReturnValue; for (Count = 0; Count < MDef->NumParams; Count++) VariableDefine(Parser->pc, Parser, MDef->ParamName[Count], ParamArray[Count], NULL, TRUE); - + ExpressionParse(&MacroParser, &EvalValue); ExpressionAssign(Parser, ReturnValue, EvalValue, TRUE, MacroName, 0, FALSE); VariableStackFramePop(Parser); @@ -1447,26 +1447,26 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta int ArgCount; enum LexToken Token = LexGetToken(Parser, NULL, TRUE); /* open bracket */ enum RunMode OldMode = Parser->Mode; - + if (RunIt) - { + { /* get the function definition */ VariableGet(Parser->pc, Parser, FuncName, &FuncValue); - + if (FuncValue->Typ->Base == TypeMacro) { /* this is actually a macro, not a function */ ExpressionParseMacroCall(Parser, StackTop, FuncName, &FuncValue->Val->MacroDef); return; } - + if (FuncValue->Typ->Base != TypeFunction) ProgramFail(Parser, "%t is not a function - can't call", FuncValue->Typ); - + ExpressionStackPushValueByType(Parser, StackTop, FuncValue->Val->FuncDef.ReturnType); ReturnValue = (*StackTop)->Val; 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) ProgramFail(Parser, "out of memory"); } @@ -1475,17 +1475,17 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta ExpressionPushInt(Parser, StackTop, 0); Parser->Mode = RunModeSkip; } - + /* parse arguments */ ArgCount = 0; do { if (RunIt && ArgCount < FuncValue->Val->FuncDef.NumParams) ParamArray[ArgCount] = VariableAllocValueFromType(Parser->pc, Parser, FuncValue->Val->FuncDef.ParamType[ArgCount], FALSE, NULL, FALSE); - + if (ExpressionParse(Parser, &Param)) { if (RunIt) - { + { if (ArgCount < FuncValue->Val->FuncDef.NumParams) { ExpressionAssign(Parser, ParamArray[ArgCount], Param, TRUE, FuncName, ArgCount+1, FALSE); @@ -1497,38 +1497,38 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta ProgramFail(Parser, "too many arguments to %s()", FuncName); } } - + ArgCount++; Token = LexGetToken(Parser, NULL, TRUE); if (Token != TokenComma && Token != TokenCloseBracket) ProgramFail(Parser, "comma expected"); } else - { + { /* end of argument list? */ Token = LexGetToken(Parser, NULL, TRUE); if (!TokenCloseBracket) ProgramFail(Parser, "bad argument"); } - + } while (Token != TokenCloseBracket); - - if (RunIt) - { + + if (RunIt) + { /* run the function */ if (ArgCount < FuncValue->Val->FuncDef.NumParams) ProgramFail(Parser, "not enough arguments to '%s'", FuncName); - + if (FuncValue->Val->FuncDef.Intrinsic == NULL) - { + { /* run a user-defined function */ struct ParseState FuncParser; int Count; int OldScopeID = Parser->ScopeID; - + if (FuncValue->Val->FuncDef.Body.Pos == NULL) ProgramFail(Parser, "'%s' is undefined", FuncName); - + ParserCopy(&FuncParser, &FuncValue->Val->FuncDef.Body); VariableStackFrameAdd(Parser, FuncName, FuncValue->Val->FuncDef.Intrinsic ? FuncValue->Val->FuncDef.NumParams : 0); Parser->pc->TopStackFrame->NumParams = ArgCount; @@ -1541,10 +1541,10 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta VariableDefine(Parser->pc, Parser, FuncValue->Val->FuncDef.ParamName[Count], ParamArray[Count], NULL, TRUE); Parser->ScopeID = OldScopeID; - + if (ParseStatement(&FuncParser, TRUE) != ParseResultOk) ProgramFail(&FuncParser, "function body expected"); - + if (RunIt) { if (FuncParser.Mode == RunModeRun && FuncValue->Val->FuncDef.ReturnType != &Parser->pc->VoidType) @@ -1553,7 +1553,7 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta else if (FuncParser.Mode == RunModeGoto) ProgramFail(&FuncParser, "couldn't find goto label '%s'", FuncParser.SearchGotoLabel); } - + VariableStackFramePop(Parser); } else @@ -1570,19 +1570,19 @@ long ExpressionParseInt(struct ParseState *Parser) { struct Value *Val; long Result = 0; - + if (!ExpressionParse(Parser, &Val)) ProgramFail(Parser, "expression expected"); - + if (Parser->Mode == RunModeRun) - { + { if (!IS_NUMERIC_COERCIBLE(Val)) ProgramFail(Parser, "integer value expected instead of %t", Val->Typ); - + Result = ExpressionCoerceInteger(Val); VariableStackPop(Parser, Val); } - + return Result; } diff --git a/heap.c b/heap.c index 938d2ee..bdc3058 100644 --- a/heap.c +++ b/heap.c @@ -1,7 +1,7 @@ /* picoc heap memory allocation. This is a complete (but small) memory * allocator for embedded systems which have no memory allocator. Alternatively * you can define USE_MALLOC_HEAP to use your system's own malloc() allocator */ - + /* stack grows up from the bottom and heap grows down from the top of heap space */ #include "interpreter.h" @@ -9,11 +9,11 @@ void ShowBigList(Picoc *pc) { struct AllocNode *LPos; - + printf("Heap: bottom=0x%lx 0x%lx-0x%lx, big freelist=", (long)pc->HeapBottom, (long)&(pc->HeapMemory)[0], (long)&(pc->HeapMemory)[HEAP_SIZE]); for (LPos = pc->FreeListBig; LPos != NULL; LPos = LPos->NextFree) printf("0x%lx:%d ", (long)LPos, LPos->Size); - + printf("\n"); } #endif @@ -23,7 +23,7 @@ void HeapInit(Picoc *pc, int StackOrHeapSize) { int Count; int AlignOffset = 0; - + #ifdef USE_MALLOC_STACK pc->HeapMemory = malloc(StackOrHeapSize); pc->HeapBottom = NULL; /* the bottom of the (downward-growing) heap */ @@ -45,7 +45,7 @@ void HeapInit(Picoc *pc, int StackOrHeapSize) while (((unsigned long)&pc->HeapMemory[AlignOffset] & (sizeof(ALIGN_TYPE)-1)) != 0) AlignOffset++; - + pc->StackFrame = &(pc->HeapMemory)[AlignOffset]; pc->HeapStackTop = &(pc->HeapMemory)[AlignOffset]; *(void **)(pc->StackFrame) = NULL; @@ -73,7 +73,7 @@ void *HeapAllocStack(Picoc *pc, int Size) #endif if (NewTop > (char *)pc->HeapBottom) return NULL; - + pc->HeapStackTop = (void *)NewTop; memset((void *)NewMem, '\0', Size); return NewMem; @@ -94,13 +94,13 @@ int HeapPopStack(Picoc *pc, void *Addr, int Size) int ToLose = MEM_ALIGN(Size); if (ToLose > ((char *)pc->HeapStackTop - (char *)&(pc->HeapMemory)[0])) return FALSE; - + #ifdef DEBUG_HEAP printf("HeapPopStack(0x%lx, %ld) back to 0x%lx\n", (unsigned long)Addr, (unsigned long)MEM_ALIGN(Size), (unsigned long)pc->HeapStackTop - ToLose); #endif pc->HeapStackTop = (void *)((char *)pc->HeapStackTop - ToLose); assert(Addr == NULL || pc->HeapStackTop == Addr); - + return TRUE; } @@ -142,19 +142,19 @@ void *HeapAllocMem(Picoc *pc, int Size) int AllocSize = MEM_ALIGN(Size) + MEM_ALIGN(sizeof(NewMem->Size)); int Bucket; void *ReturnMem; - + if (Size == 0) return NULL; - + assert(Size > 0); - + /* make sure we have enough space for an AllocNode */ if (AllocSize < sizeof(struct AllocNode)) AllocSize = sizeof(struct AllocNode); - + Bucket = AllocSize >> 2; if (Bucket < FREELIST_BUCKETS && pc->FreeListBucket[Bucket] != NULL) - { + { /* try to allocate from a freelist bucket first */ #ifdef DEBUG_HEAP printf("allocating %d(%d) from bucket", Size, AllocSize); @@ -166,17 +166,17 @@ void *HeapAllocMem(Picoc *pc, int Size) NewMem->Size = AllocSize; } else if (pc->FreeListBig != NULL) - { + { /* grab the first item from the "big" freelist we can fit in */ for (FreeNode = &pc->FreeListBig; *FreeNode != NULL && (*FreeNode)->Size < AllocSize; FreeNode = &(*FreeNode)->NextFree) {} - + if (*FreeNode != NULL) { assert((unsigned long)*FreeNode >= (unsigned long)&(pc->HeapMemory)[0] && (unsigned char *)*FreeNode - &(pc->HeapMemory)[0] < HEAP_SIZE); assert((*FreeNode)->Size < HEAP_SIZE && (*FreeNode)->Size > 0); if ((*FreeNode)->Size < AllocSize + SPLIT_MEM_THRESHOLD) - { + { /* close in size - reduce fragmentation by not splitting */ #ifdef DEBUG_HEAP printf("allocating %d(%d) from freelist, no split (%d)", Size, AllocSize, (*FreeNode)->Size); @@ -186,7 +186,7 @@ void *HeapAllocMem(Picoc *pc, int Size) *FreeNode = NewMem->NextFree; } else - { + { /* split this big memory chunk */ #ifdef DEBUG_HEAP printf("allocating %d(%d) from freelist, split chunk (%d)", Size, AllocSize, (*FreeNode)->Size); @@ -198,21 +198,21 @@ void *HeapAllocMem(Picoc *pc, int Size) } } } - + if (NewMem == NULL) - { + { /* couldn't allocate from a freelist - try to increase the size of the heap area */ #ifdef DEBUG_HEAP printf("allocating %d(%d) at bottom of heap (0x%lx-0x%lx)", Size, AllocSize, (long)((char *)pc->HeapBottom - AllocSize), (long)HeapBottom); #endif if ((char *)pc->HeapBottom - AllocSize < (char *)pc->HeapStackTop) return NULL; - + pc->HeapBottom = (void *)((char *)pc->HeapBottom - AllocSize); NewMem = pc->HeapBottom; NewMem->Size = AllocSize; } - + ReturnMem = (void *)((char *)NewMem + MEM_ALIGN(sizeof(NewMem->Size))); memset(ReturnMem, '\0', AllocSize - MEM_ALIGN(sizeof(NewMem->Size))); #ifdef DEBUG_HEAP @@ -230,7 +230,7 @@ void HeapFreeMem(Picoc *pc, void *Mem) #else struct AllocNode *MemNode = (struct AllocNode *)((char *)Mem - MEM_ALIGN(sizeof(MemNode->Size))); int Bucket = MemNode->Size >> 2; - + #ifdef DEBUG_HEAP printf("HeapFreeMem(0x%lx)\n", (unsigned long)Mem); #endif @@ -238,9 +238,9 @@ void HeapFreeMem(Picoc *pc, void *Mem) assert(MemNode->Size < HEAP_SIZE && MemNode->Size > 0); if (Mem == NULL) return; - + if ((void *)MemNode == pc->HeapBottom) - { + { /* pop it off the bottom of the heap, reducing the heap size */ #ifdef DEBUG_HEAP printf("freeing %d from bottom of heap\n", MemNode->Size); @@ -251,7 +251,7 @@ void HeapFreeMem(Picoc *pc, void *Mem) #endif } else if (Bucket < FREELIST_BUCKETS) - { + { /* we can fit it in a bucket */ #ifdef DEBUG_HEAP printf("freeing %d to bucket\n", MemNode->Size); @@ -261,7 +261,7 @@ void HeapFreeMem(Picoc *pc, void *Mem) pc->FreeListBucket[Bucket] = (struct AllocNode *)MemNode; } else - { + { /* put it in the big memory freelist */ #ifdef DEBUG_HEAP printf("freeing %lx:%d to freelist\n", (unsigned long)Mem, MemNode->Size); diff --git a/include.c b/include.c index 2a964b5..b2e0583 100644 --- a/include.c +++ b/include.c @@ -1,6 +1,6 @@ /* picoc include system - can emulate system includes from built-in libraries * or it can include and parse files if the system has files */ - + #include "picoc.h" #include "interpreter.h" @@ -32,7 +32,7 @@ void IncludeCleanup(Picoc *pc) { struct IncludeLibrary *ThisInclude = pc->IncludeLibList; struct IncludeLibrary *NextInclude; - + while (ThisInclude != NULL) { NextInclude = ThisInclude->NextLib; @@ -59,7 +59,7 @@ void IncludeRegister(Picoc *pc, const char *IncludeName, void (*SetupFunction)(P void PicocIncludeAllSystemHeaders(Picoc *pc) { struct IncludeLibrary *ThisInclude = pc->IncludeLibList; - + for (; ThisInclude != NULL; ThisInclude = ThisInclude->NextLib) IncludeFile(pc, ThisInclude->IncludeName); } @@ -68,7 +68,7 @@ void PicocIncludeAllSystemHeaders(Picoc *pc) void IncludeFile(Picoc *pc, char *FileName) { struct IncludeLibrary *LInclude; - + /* scan for the include file name to see if it's in our list of predefined includes */ for (LInclude = pc->IncludeLibList; LInclude != NULL; LInclude = LInclude->NextLib) { @@ -78,24 +78,24 @@ void IncludeFile(Picoc *pc, char *FileName) if (!VariableDefined(pc, FileName)) { VariableDefine(pc, NULL, FileName, NULL, &pc->VoidType, FALSE); - + /* run an extra startup function if there is one */ if (LInclude->SetupFunction != NULL) (*LInclude->SetupFunction)(pc); - + /* parse the setup C source code - may define types etc. */ if (LInclude->SetupCSource != NULL) PicocParse(pc, FileName, LInclude->SetupCSource, strlen(LInclude->SetupCSource), TRUE, TRUE, FALSE, FALSE); - + /* set up the library functions */ if (LInclude->FuncList != NULL) LibraryAdd(pc, &pc->GlobalTable, FileName, LInclude->FuncList); } - + return; } } - + /* not a predefined file, read a real file */ PicocPlatformScanFile(pc, FileName); } diff --git a/interpreter.h b/interpreter.h index 616fffa..6beff14 100644 --- a/interpreter.h +++ b/interpreter.h @@ -1,7 +1,7 @@ -/* picoc main header file - this has all the main data structures and +/* picoc main header file - this has all the main data structures and * function prototypes. If you're just calling picoc you should look at the * external interface instead, in picoc.h */ - + #ifndef INTERPRETER_H #define INTERPRETER_H @@ -63,23 +63,23 @@ typedef struct Picoc_Struct Picoc; /* lexical tokens */ enum LexToken { - /* 0x00 */ TokenNone, + /* 0x00 */ TokenNone, /* 0x01 */ TokenComma, /* 0x02 */ TokenAssign, TokenAddAssign, TokenSubtractAssign, TokenMultiplyAssign, TokenDivideAssign, TokenModulusAssign, /* 0x08 */ TokenShiftLeftAssign, TokenShiftRightAssign, TokenArithmeticAndAssign, TokenArithmeticOrAssign, TokenArithmeticExorAssign, - /* 0x0d */ TokenQuestionMark, TokenColon, - /* 0x0f */ TokenLogicalOr, - /* 0x10 */ TokenLogicalAnd, - /* 0x11 */ TokenArithmeticOr, - /* 0x12 */ TokenArithmeticExor, - /* 0x13 */ TokenAmpersand, - /* 0x14 */ TokenEqual, TokenNotEqual, + /* 0x0d */ TokenQuestionMark, TokenColon, + /* 0x0f */ TokenLogicalOr, + /* 0x10 */ TokenLogicalAnd, + /* 0x11 */ TokenArithmeticOr, + /* 0x12 */ TokenArithmeticExor, + /* 0x13 */ TokenAmpersand, + /* 0x14 */ TokenEqual, TokenNotEqual, /* 0x16 */ TokenLessThan, TokenGreaterThan, TokenLessEqual, TokenGreaterEqual, - /* 0x1a */ TokenShiftLeft, TokenShiftRight, - /* 0x1c */ TokenPlus, TokenMinus, + /* 0x1a */ TokenShiftLeft, TokenShiftRight, + /* 0x1c */ TokenPlus, TokenMinus, /* 0x1e */ TokenAsterisk, TokenSlash, TokenModulus, /* 0x21 */ TokenIncrement, TokenDecrement, TokenUnaryNot, TokenUnaryExor, TokenSizeof, TokenCast, - /* 0x27 */ TokenLeftSquareBracket, TokenRightSquareBracket, TokenDot, TokenArrow, + /* 0x27 */ TokenLeftSquareBracket, TokenRightSquareBracket, TokenDot, TokenArrow, /* 0x2b */ TokenOpenBracket, TokenCloseBracket, /* 0x2d */ TokenIdentifier, TokenIntegerConstant, TokenFPConstant, TokenStringConstant, TokenCharacterConstant, /* 0x32 */ TokenSemicolon, TokenEllipsis, @@ -242,19 +242,19 @@ struct TableEntry char *Key; /* points to the shared string table */ struct Value *Val; /* the value we're storing */ } v; /* used for tables of values */ - + char Key[1]; /* dummy size - used for the shared string table */ - + struct BreakpointEntry /* defines a breakpoint */ { const char *FileName; short int Line; short int CharacterPos; } b; - + } p; }; - + struct Table { short Size; @@ -366,7 +366,7 @@ struct Picoc_Struct struct Table GlobalTable; struct CleanupTokenNode *CleanupTokenList; struct TableEntry *GlobalHashTable[GLOBAL_TABLE_SIZE]; - + /* lexer global data */ struct TokenLine *InteractiveHead; struct TokenLine *InteractiveTail; @@ -380,7 +380,7 @@ struct Picoc_Struct /* the table of string literal values */ struct Table StringLiteralTable; struct TableEntry *StringLiteralHashTable[STRING_LITERAL_TABLE_SIZE]; - + /* the stack */ struct StackFrame *TopStackFrame; @@ -414,7 +414,7 @@ struct Picoc_Struct struct AllocNode *FreeListBucket[FREELIST_BUCKETS]; /* we keep a pool of freelist buckets to reduce fragmentation */ struct AllocNode *FreeListBig; /* free memory which doesn't fit in a bucket */ - /* types */ + /* types */ struct ValueType UberType; struct ValueType IntType; struct ValueType ShortType; @@ -443,7 +443,7 @@ struct Picoc_Struct struct TableEntry *BreakpointHashTable[BREAKPOINT_TABLE_SIZE]; int BreakpointCount; int DebugManualBreak; - + /* C library */ int BigEndian; int LittleEndian; @@ -453,7 +453,7 @@ struct Picoc_Struct /* the picoc version string */ const char *VersionString; - + /* exit longjump buffer */ #if defined(UNIX_HOST) || defined(WIN32) jmp_buf PicocExitBuf; @@ -461,7 +461,7 @@ struct Picoc_Struct #ifdef SURVEYOR_HOST int PicocExitBuf[41]; #endif - + /* string table */ struct Table StringTable; struct TableEntry *StringHashTable[STRING_TABLE_SIZE]; @@ -608,7 +608,7 @@ void IncludeRegister(Picoc *pc, const char *IncludeName, void (*SetupFunction)(P void IncludeFile(Picoc *pc, char *Filename); /* the following is defined in picoc.h: * void PicocIncludeAllSystemHeaders(); */ - + /* debug.c */ void DebugInit(); void DebugCleanup(); diff --git a/lex.c b/lex.c index 9524b5b..798003c 100644 --- a/lex.c +++ b/lex.c @@ -1,4 +1,4 @@ -/* picoc lexer - converts source text into a tokenised form */ +/* picoc lexer - converts source text into a tokenised form */ #include "interpreter.h" @@ -87,14 +87,14 @@ static struct ReservedWord ReservedWords[] = void LexInit(Picoc *pc) { int Count; - + TableInitTable(&pc->ReservedWordTable, &pc->ReservedWordHashTable[0], sizeof(ReservedWords) / sizeof(struct ReservedWord) * 2, TRUE); 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); } - + pc->LexValue.Typ = NULL; pc->LexValue.Val = &pc->LexAnyValue; pc->LexValue.LValueFrom = FALSE; @@ -119,7 +119,7 @@ void LexCleanup(Picoc *pc) enum LexToken LexCheckReservedWord(Picoc *pc, const char *Word) { struct Value *val; - + if (TableGet(&pc->ReservedWordTable, Word, &val, NULL, NULL, NULL)) return ((struct ReservedWord *)val)->Token; else @@ -141,9 +141,9 @@ enum LexToken LexGetNumber(Picoc *pc, struct LexState *Lexer, struct Value *Valu char IsLong = 0; char IsUnsigned = 0; #endif - + if (*Lexer->Pos == '0') - { + { /* a binary, octal or hex literal */ LEXER_INC(Lexer); if (Lexer->Pos != Lexer->End) @@ -171,29 +171,29 @@ enum LexToken LexGetNumber(Picoc *pc, struct LexState *Lexer, struct Value *Valu LEXER_INC(Lexer); /* IsLong = 1; */ } - + Value->Typ = &pc->LongType; /* ignored? */ Value->Val->LongInteger = Result; ResultToken = TokenIntegerConstant; - + if (Lexer->Pos == Lexer->End) return ResultToken; - + #ifndef NO_FP if (Lexer->Pos == Lexer->End) { return ResultToken; } - + if (*Lexer->Pos != '.' && *Lexer->Pos != 'e' && *Lexer->Pos != 'E') { return ResultToken; } - + Value->Typ = &pc->FPType; FPResult = (double)Result; - + if (*Lexer->Pos == '.') { LEXER_INC(Lexer); @@ -206,14 +206,14 @@ enum LexToken LexGetNumber(Picoc *pc, struct LexState *Lexer, struct Value *Valu if (Lexer->Pos != Lexer->End && (*Lexer->Pos == 'e' || *Lexer->Pos == 'E')) { int ExponentSign = 1; - + LEXER_INC(Lexer); if (Lexer->Pos != Lexer->End && *Lexer->Pos == '-') { ExponentSign = -1; LEXER_INC(Lexer); } - + Result = 0; while (Lexer->Pos != Lexer->End && IS_BASE_DIGIT(*Lexer->Pos, Base)) { @@ -223,7 +223,7 @@ enum LexToken LexGetNumber(Picoc *pc, struct LexState *Lexer, struct Value *Valu FPResult *= pow((double)Base, (double)Result * ExponentSign); } - + Value->Val->FP = FPResult; if (*Lexer->Pos == 'f' || *Lexer->Pos == 'F') @@ -240,14 +240,14 @@ enum LexToken LexGetWord(Picoc *pc, struct LexState *Lexer, struct Value *Value) { const char *StartPos = Lexer->Pos; enum LexToken Token; - + do { LEXER_INC(Lexer); } while (Lexer->Pos != Lexer->End && isCident((int)*Lexer->Pos)); - + Value->Typ = NULL; Value->Val->Identifier = TableStrRegister2(pc, StartPos, Lexer->Pos - StartPos); - + Token = LexCheckReservedWord(pc, Value->Val->Identifier); switch (Token) { @@ -255,13 +255,13 @@ enum LexToken LexGetWord(Picoc *pc, struct LexState *Lexer, struct Value *Value) case TokenHashDefine: Lexer->Mode = LexModeHashDefine; break; default: break; } - + if (Token != TokenNone) return Token; - + if (Lexer->Mode == LexModeHashDefineSpace) Lexer->Mode = LexModeHashDefineSpaceIdent; - + return TokenIdentifier; } @@ -272,7 +272,7 @@ unsigned char LexUnEscapeCharacterConstant(const char **From, const char *End, u int CCount; for (CCount = 0; IS_BASE_DIGIT(**From, Base) && CCount < 2; CCount++, (*From)++) Total = Total * Base + GET_BASE_DIGIT(**From); - + return Total; } @@ -280,29 +280,29 @@ unsigned char LexUnEscapeCharacterConstant(const char **From, const char *End, u unsigned char LexUnEscapeCharacter(const char **From, const char *End) { unsigned char ThisChar; - - while ( *From != End && **From == '\\' && + + while ( *From != End && **From == '\\' && &(*From)[1] != End && (*From)[1] == '\n' ) (*From) += 2; /* skip escaped end of lines with LF line termination */ - - while ( *From != End && **From == '\\' && + + while ( *From != End && **From == '\\' && &(*From)[1] != End && &(*From)[2] != End && (*From)[1] == '\r' && (*From)[2] == '\n') (*From) += 3; /* skip escaped end of lines with CR/LF line termination */ - + if (*From == End) return '\\'; - + if (**From == '\\') - { + { /* it's escaped */ (*From)++; if (*From == End) return '\\'; - + ThisChar = *(*From)++; switch (ThisChar) { - case '\\': return '\\'; + case '\\': return '\\'; case '\'': return '\''; case '"': return '"'; case 'a': return '\a'; @@ -331,15 +331,15 @@ enum LexToken LexGetStringConstant(Picoc *pc, struct LexState *Lexer, struct Val char *EscBufPos; char *RegString; struct Value *ArrayValue; - + while (Lexer->Pos != Lexer->End && (*Lexer->Pos != EndChar || Escape)) - { + { /* find the end */ if (Escape) { if (*Lexer->Pos == '\r' && Lexer->Pos+1 != Lexer->End) Lexer->Pos++; - + if (*Lexer->Pos == '\n' && Lexer->Pos+1 != Lexer->End) { Lexer->Line++; @@ -347,23 +347,23 @@ enum LexToken LexGetStringConstant(Picoc *pc, struct LexState *Lexer, struct Val Lexer->CharacterPos = 0; Lexer->EmitExtraNewlines++; } - + Escape = FALSE; } else if (*Lexer->Pos == '\\') Escape = TRUE; - + LEXER_INC(Lexer); } EndPos = Lexer->Pos; - + EscBuf = HeapAllocStack(pc, EndPos - StartPos); if (EscBuf == NULL) LexFail(pc, Lexer, "out of memory"); - + for (EscBufPos = EscBuf, Lexer->Pos = StartPos; Lexer->Pos != EndPos;) *EscBufPos++ = LexUnEscapeCharacter(&Lexer->Pos, EndPos); - + /* try to find an existing copy of this string literal */ RegString = TableStrRegister2(pc, EscBuf, EscBufPos - EscBuf); HeapPopStack(pc, EscBuf, EndPos - StartPos); @@ -382,7 +382,7 @@ enum LexToken LexGetStringConstant(Picoc *pc, struct LexState *Lexer, struct Val Value->Val->Pointer = RegString; if (*Lexer->Pos == EndChar) LEXER_INC(Lexer); - + return TokenStringConstant; } @@ -393,7 +393,7 @@ enum LexToken LexGetCharacterConstant(Picoc *pc, struct LexState *Lexer, struct Value->Val->Character = LexUnEscapeCharacter(&Lexer->Pos, Lexer->End); if (Lexer->Pos != Lexer->End && *Lexer->Pos != '\'') LexFail(pc, Lexer, "expected \"'\""); - + LEXER_INC(Lexer); return TokenCharacterConstant; } @@ -402,7 +402,7 @@ enum LexToken LexGetCharacterConstant(Picoc *pc, struct LexState *Lexer, struct void LexSkipComment(struct LexState *Lexer, char NextChar, enum LexToken *ReturnToken) { if (NextChar == '*') - { + { /* conventional C comment */ while (Lexer->Pos != Lexer->End && (*(Lexer->Pos-1) != '*' || *Lexer->Pos != '/')) { @@ -411,14 +411,14 @@ void LexSkipComment(struct LexState *Lexer, char NextChar, enum LexToken *Return LEXER_INC(Lexer); } - + if (Lexer->Pos != Lexer->End) LEXER_INC(Lexer); - + Lexer->Mode = LexModeNormal; } else - { + { /* C++ style comment */ while (Lexer->Pos != Lexer->End && *Lexer->Pos != '\n') LEXER_INC(Lexer); @@ -431,14 +431,14 @@ enum LexToken LexScanGetToken(Picoc *pc, struct LexState *Lexer, struct Value ** char ThisChar; char NextChar; enum LexToken GotToken = TokenNone; - + /* handle cases line multi-line comments or string constants which mess up the line count */ if (Lexer->EmitExtraNewlines > 0) { Lexer->EmitExtraNewlines--; return TokenEndOfLine; } - + /* scan for a token */ do { @@ -455,23 +455,23 @@ enum LexToken LexScanGetToken(Picoc *pc, struct LexState *Lexer, struct Value ** } else if (Lexer->Mode == LexModeHashDefine || Lexer->Mode == LexModeHashDefineSpace) Lexer->Mode = LexModeHashDefineSpace; - + else if (Lexer->Mode == LexModeHashDefineSpaceIdent) Lexer->Mode = LexModeNormal; - + LEXER_INC(Lexer); } - + if (Lexer->Pos == Lexer->End || *Lexer->Pos == '\0') return TokenEOF; - + ThisChar = *Lexer->Pos; if (isCidstart((int)ThisChar)) return LexGetWord(pc, Lexer, *Value); - + if (isdigit((int)ThisChar)) return LexGetNumber(pc, Lexer, *Value); - + NextChar = (Lexer->Pos+1 != Lexer->End) ? *(Lexer->Pos+1) : 0; LEXER_INC(Lexer); switch (ThisChar) @@ -486,7 +486,7 @@ enum LexToken LexScanGetToken(Picoc *pc, struct LexState *Lexer, struct Value ** 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 '<': 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; @@ -505,7 +505,7 @@ enum LexToken LexScanGetToken(Picoc *pc, struct LexState *Lexer, struct Value ** default: LexFail(pc, Lexer, "illegal character '%c'", ThisChar); break; } } while (GotToken == TokenNone); - + return GotToken; } @@ -530,16 +530,16 @@ void *LexTokenise(Picoc *pc, struct LexState *Lexer, int *TokenLen) struct Value *GotValue; int MemUsed = 0; int ValueSize; - int ReserveSpace = (Lexer->End - Lexer->Pos) * 4 + 16; + int ReserveSpace = (Lexer->End - Lexer->Pos) * 4 + 16; void *TokenSpace = HeapAllocStack(pc, ReserveSpace); char *TokenPos = (char *)TokenSpace; int LastCharacterPos = 0; if (TokenSpace == NULL) LexFail(pc, Lexer, "out of memory"); - + do - { + { /* store the token at the end of the stack area */ Token = LexScanGetToken(pc, Lexer, &GotValue); @@ -556,21 +556,21 @@ void *LexTokenise(Picoc *pc, struct LexState *Lexer, int *TokenLen) ValueSize = LexTokenSize(Token); if (ValueSize > 0) - { + { /* store a value as well */ memcpy((void *)TokenPos, (void *)GotValue->Val, ValueSize); TokenPos += ValueSize; MemUsed += ValueSize; } - + LastCharacterPos = Lexer->CharacterPos; - + } while (Token != TokenEOF); - + HeapMem = HeapAllocMem(pc, MemUsed); if (HeapMem == NULL) LexFail(pc, Lexer, "out of memory"); - + assert(ReserveSpace >= MemUsed); memcpy(HeapMem, TokenSpace, MemUsed); HeapPopStack(pc, TokenSpace, ReserveSpace); @@ -585,7 +585,7 @@ void *LexTokenise(Picoc *pc, struct LexState *Lexer, int *TokenLen) #endif if (TokenLen) *TokenLen = MemUsed; - + return HeapMem; } @@ -593,7 +593,7 @@ void *LexTokenise(Picoc *pc, struct LexState *Lexer, int *TokenLen) void *LexAnalyse(Picoc *pc, const char *FileName, const char *Source, int SourceLen, int *TokenLen) { struct LexState Lexer; - + Lexer.Pos = Source; Lexer.End = Source + SourceLen; Lexer.Line = 1; @@ -602,7 +602,7 @@ void *LexAnalyse(Picoc *pc, const char *FileName, const char *Source, int Source Lexer.EmitExtraNewlines = 0; Lexer.CharacterPos = 1; Lexer.SourceText = Source; - + return LexTokenise(pc, &Lexer, TokenLen); } @@ -629,15 +629,15 @@ enum LexToken LexGetRawToken(struct ParseState *Parser, struct Value **Value, in int ValueSize; char *Prompt = NULL; Picoc *pc = Parser->pc; - + do - { + { /* get the next token */ if (Parser->Pos == NULL && pc->InteractiveHead != NULL) Parser->Pos = pc->InteractiveHead->Tokens; - + if (Parser->FileName != pc->StrEmpty || pc->InteractiveHead != NULL) - { + { /* skip leading newlines */ while ((Token = (enum LexToken)*(unsigned char *)Parser->Pos) == TokenEndOfLine) { @@ -645,17 +645,17 @@ enum LexToken LexGetRawToken(struct ParseState *Parser, struct Value **Value, in Parser->Pos += TOKEN_DATA_OFFSET; } } - + if (Parser->FileName == pc->StrEmpty && (pc->InteractiveHead == NULL || Token == TokenEOF)) - { + { /* we're at the end of an interactive input token list */ char LineBuffer[LINEBUFFER_MAX]; void *LineTokens; int LineBytes; struct TokenLine *LineNode; - + if (pc->InteractiveHead == NULL || (unsigned char *)Parser->Pos == &pc->InteractiveTail->Tokens[pc->InteractiveTail->NumBytes-TOKEN_DATA_OFFSET]) - { + { /* get interactive input */ if (pc->LexUseStatementPrompt) { @@ -664,17 +664,17 @@ enum LexToken LexGetRawToken(struct ParseState *Parser, struct Value **Value, in } else Prompt = INTERACTIVE_PROMPT_LINE; - + if (PlatformGetLine(&LineBuffer[0], LINEBUFFER_MAX, Prompt) == NULL) 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); LineNode = VariableAlloc(pc, Parser, sizeof(struct TokenLine), TRUE); LineNode->Tokens = LineTokens; LineNode->NumBytes = LineBytes; if (pc->InteractiveHead == NULL) - { + { /* start a new list */ pc->InteractiveHead = LineNode; Parser->Line = 1; @@ -688,10 +688,10 @@ enum LexToken LexGetRawToken(struct ParseState *Parser, struct Value **Value, in Parser->Pos = LineTokens; } else - { + { /* go to the next token line */ if (Parser->Pos != &pc->InteractiveCurrentLine->Tokens[pc->InteractiveCurrentLine->NumBytes-TOKEN_DATA_OFFSET]) - { + { /* scan for the line */ for (pc->InteractiveCurrentLine = pc->InteractiveHead; Parser->Pos != &pc->InteractiveCurrentLine->Tokens[pc->InteractiveCurrentLine->NumBytes-TOKEN_DATA_OFFSET]; pc->InteractiveCurrentLine = pc->InteractiveCurrentLine->Next) { assert(pc->InteractiveCurrentLine->Next != NULL); } @@ -710,10 +710,10 @@ enum LexToken LexGetRawToken(struct ParseState *Parser, struct Value **Value, in Parser->CharacterPos = *((unsigned char *)Parser->Pos + 1); ValueSize = LexTokenSize(Token); if (ValueSize > 0) - { + { /* this token requires a value - unpack it */ if (Value != NULL) - { + { switch (Token) { case TokenStringConstant: pc->LexValue.Typ = pc->CharPtrType; break; @@ -725,7 +725,7 @@ enum LexToken LexGetRawToken(struct ParseState *Parser, struct Value **Value, in #endif default: break; } - + memcpy((void *)pc->LexValue.Val, (void *)((char *)Parser->Pos + TOKEN_DATA_OFFSET), ValueSize); pc->LexValue.ValOnHeap = FALSE; pc->LexValue.ValOnStack = FALSE; @@ -733,7 +733,7 @@ enum LexToken LexGetRawToken(struct ParseState *Parser, struct Value **Value, in pc->LexValue.LValueFrom = NULL; *Value = &pc->LexValue; } - + if (IncPos) Parser->Pos += ValueSize + TOKEN_DATA_OFFSET; } @@ -742,7 +742,7 @@ enum LexToken LexGetRawToken(struct ParseState *Parser, struct Value **Value, in if (IncPos && Token != TokenEOF) Parser->Pos += TOKEN_DATA_OFFSET; } - + #ifdef DEBUG_LEXER printf("Got token=%02x inc=%d pos=%d\n", Token, IncPos, Parser->CharacterPos); #endif @@ -765,10 +765,10 @@ void LexHashIfdef(struct ParseState *Parser, int IfNot) struct Value *SavedValue; int IsDefined; enum LexToken Token = LexGetRawToken(Parser, &IdentValue, TRUE); - + if (Token != TokenIdentifier) ProgramFail(Parser, "identifier expected"); - + /* is the identifier defined? */ IsDefined = TableGet(&Parser->pc->GlobalTable, IdentValue->Val->Identifier, &SavedValue, NULL, NULL, NULL); if (Parser->HashIfEvaluateToLevel == Parser->HashIfLevel && ( (IsDefined && !IfNot) || (!IsDefined && IfNot)) ) @@ -776,7 +776,7 @@ void LexHashIfdef(struct ParseState *Parser, int IfNot) /* #if is active, evaluate to this new level */ Parser->HashIfEvaluateToLevel++; } - + Parser->HashIfLevel++; } @@ -794,24 +794,24 @@ void LexHashIf(struct ParseState *Parser) /* look up a value from a macro definition */ if (!TableGet(&Parser->pc->GlobalTable, IdentValue->Val->Identifier, &SavedValue, NULL, NULL, NULL)) ProgramFail(Parser, "'%s' is undefined", IdentValue->Val->Identifier); - + if (SavedValue->Typ->Base != TypeMacro) ProgramFail(Parser, "value expected"); - + ParserCopy(&MacroParser, &SavedValue->Val->MacroDef.Body); Token = LexGetRawToken(&MacroParser, &IdentValue, TRUE); } - + if (Token != TokenCharacterConstant && Token != TokenIntegerConstant) ProgramFail(Parser, "value expected"); - + /* is the identifier defined? */ if (Parser->HashIfEvaluateToLevel == Parser->HashIfLevel && IdentValue->Val->Character) { /* #if is active, evaluate to this new level */ Parser->HashIfEvaluateToLevel++; } - + Parser->HashIfLevel++; } @@ -820,13 +820,13 @@ void LexHashElse(struct ParseState *Parser) { if (Parser->HashIfEvaluateToLevel == Parser->HashIfLevel - 1) Parser->HashIfEvaluateToLevel++; /* #if was not active, make this next section active */ - + else if (Parser->HashIfEvaluateToLevel == Parser->HashIfLevel) { /* #if was active, now go inactive */ if (Parser->HashIfLevel == 0) ProgramFail(Parser, "#else without #if"); - + Parser->HashIfEvaluateToLevel--; } } @@ -846,23 +846,23 @@ void LexHashEndif(struct ParseState *Parser) void LexPrintToken(enum LexToken Token) { char* TokenNames[] = { - /* 0x00 */ "None", + /* 0x00 */ "None", /* 0x01 */ "Comma", /* 0x02 */ "Assign", "AddAssign", "SubtractAssign", "MultiplyAssign", "DivideAssign", "ModulusAssign", /* 0x08 */ "ShiftLeftAssign", "ShiftRightAssign", "ArithmeticAndAssign", "ArithmeticOrAssign", "ArithmeticExorAssign", - /* 0x0d */ "QuestionMark", "Colon", - /* 0x0f */ "LogicalOr", - /* 0x10 */ "LogicalAnd", - /* 0x11 */ "ArithmeticOr", - /* 0x12 */ "ArithmeticExor", - /* 0x13 */ "Ampersand", - /* 0x14 */ "Equal", "NotEqual", + /* 0x0d */ "QuestionMark", "Colon", + /* 0x0f */ "LogicalOr", + /* 0x10 */ "LogicalAnd", + /* 0x11 */ "ArithmeticOr", + /* 0x12 */ "ArithmeticExor", + /* 0x13 */ "Ampersand", + /* 0x14 */ "Equal", "NotEqual", /* 0x16 */ "LessThan", "GreaterThan", "LessEqual", "GreaterEqual", - /* 0x1a */ "ShiftLeft", "ShiftRight", - /* 0x1c */ "Plus", "Minus", + /* 0x1a */ "ShiftLeft", "ShiftRight", + /* 0x1c */ "Plus", "Minus", /* 0x1e */ "Asterisk", "Slash", "Modulus", /* 0x21 */ "Increment", "Decrement", "UnaryNot", "UnaryExor", "Sizeof", "Cast", - /* 0x27 */ "LeftSquareBracket", "RightSquareBracket", "Dot", "Arrow", + /* 0x27 */ "LeftSquareBracket", "RightSquareBracket", "Dot", "Arrow", /* 0x2b */ "OpenBracket", "CloseBracket", /* 0x2d */ "Identifier", "IntegerConstant", "FPConstant", "StringConstant", "CharacterConstant", /* 0x32 */ "Semicolon", "Ellipsis", @@ -884,7 +884,7 @@ enum LexToken LexGetToken(struct ParseState *Parser, struct Value **Value, int I { enum LexToken Token; int TryNextToken; - + /* implements the pre-processor #if commands */ do { @@ -905,9 +905,9 @@ enum LexToken LexGetToken(struct ParseState *Parser, struct Value **Value, int I TryNextToken = (Parser->HashIfEvaluateToLevel < Parser->HashIfLevel && Token != TokenEOF) || WasPreProcToken; if (!IncPos && TryNextToken) LexGetRawToken(Parser, NULL, TRUE); - + } while (TryNextToken); - + return Token; } @@ -940,39 +940,39 @@ void *LexCopyTokens(struct ParseState *StartParser, struct ParseState *EndParser unsigned char *NewTokenPos; struct TokenLine *ILine; Picoc *pc = StartParser->pc; - + if (pc->InteractiveHead == NULL) - { + { /* non-interactive mode - copy the tokens */ MemSize = EndParser->Pos - StartParser->Pos; NewTokens = VariableAlloc(pc, StartParser, MemSize + TOKEN_DATA_OFFSET, TRUE); memcpy(NewTokens, (void *)StartParser->Pos, MemSize); } else - { + { /* we're in interactive mode - add up line by line */ for (pc->InteractiveCurrentLine = pc->InteractiveHead; pc->InteractiveCurrentLine != NULL && (Pos < &pc->InteractiveCurrentLine->Tokens[0] || Pos >= &pc->InteractiveCurrentLine->Tokens[pc->InteractiveCurrentLine->NumBytes]); pc->InteractiveCurrentLine = pc->InteractiveCurrentLine->Next) {} /* find the line we just counted */ - + if (EndParser->Pos >= StartParser->Pos && EndParser->Pos < &pc->InteractiveCurrentLine->Tokens[pc->InteractiveCurrentLine->NumBytes]) - { + { /* all on a single line */ MemSize = EndParser->Pos - StartParser->Pos; NewTokens = VariableAlloc(pc, StartParser, MemSize + TOKEN_DATA_OFFSET, TRUE); memcpy(NewTokens, (void *)StartParser->Pos, MemSize); } else - { + { /* it's spread across multiple lines */ MemSize = &pc->InteractiveCurrentLine->Tokens[pc->InteractiveCurrentLine->NumBytes-TOKEN_DATA_OFFSET] - Pos; for (ILine = pc->InteractiveCurrentLine->Next; ILine != NULL && (EndParser->Pos < &ILine->Tokens[0] || EndParser->Pos >= &ILine->Tokens[ILine->NumBytes]); ILine = ILine->Next) MemSize += ILine->NumBytes - TOKEN_DATA_OFFSET; - + assert(ILine != NULL); MemSize += EndParser->Pos - &ILine->Tokens[0]; NewTokens = VariableAlloc(pc, StartParser, MemSize + TOKEN_DATA_OFFSET, TRUE); - + CopySize = &pc->InteractiveCurrentLine->Tokens[pc->InteractiveCurrentLine->NumBytes-TOKEN_DATA_OFFSET] - Pos; memcpy(NewTokens, Pos, CopySize); NewTokenPos = NewTokens + CopySize; @@ -985,9 +985,9 @@ void *LexCopyTokens(struct ParseState *StartParser, struct ParseState *EndParser memcpy(NewTokenPos, &ILine->Tokens[0], EndParser->Pos - &ILine->Tokens[0]); } } - + NewTokens[MemSize] = (unsigned char)TokenEndOfFunction; - + return NewTokens; } @@ -997,7 +997,7 @@ void LexInteractiveClear(Picoc *pc, struct ParseState *Parser) while (pc->InteractiveHead != NULL) { struct TokenLine *NextLine = pc->InteractiveHead->Next; - + HeapFreeMem(pc, pc->InteractiveHead->Tokens); HeapFreeMem(pc, pc->InteractiveHead); pc->InteractiveHead = NextLine; @@ -1005,7 +1005,7 @@ void LexInteractiveClear(Picoc *pc, struct ParseState *Parser) if (Parser != NULL) Parser->Pos = NULL; - + pc->InteractiveTail = NULL; } @@ -1013,16 +1013,16 @@ void LexInteractiveClear(Picoc *pc, struct ParseState *Parser) void LexInteractiveCompleted(Picoc *pc, struct ParseState *Parser) { while (pc->InteractiveHead != NULL && !(Parser->Pos >= &pc->InteractiveHead->Tokens[0] && Parser->Pos < &pc->InteractiveHead->Tokens[pc->InteractiveHead->NumBytes])) - { + { /* this token line is no longer needed - free it */ struct TokenLine *NextLine = pc->InteractiveHead->Next; - + HeapFreeMem(pc, pc->InteractiveHead->Tokens); HeapFreeMem(pc, pc->InteractiveHead); pc->InteractiveHead = NextLine; - + if (pc->InteractiveHead == NULL) - { + { /* we've emptied the list */ Parser->Pos = NULL; pc->InteractiveTail = NULL; diff --git a/parse.c b/parse.c index c9c7513..daf5f1f 100644 --- a/parse.c +++ b/parse.c @@ -9,11 +9,11 @@ void ParseCleanup(Picoc *pc) while (pc->CleanupTokenList != NULL) { struct CleanupTokenNode *Next = pc->CleanupTokenList->Next; - + HeapFreeMem(pc, pc->CleanupTokenList->Tokens); if (pc->CleanupTokenList->SourceText != NULL) HeapFreeMem(pc, (void *)pc->CleanupTokenList->SourceText); - + HeapFreeMem(pc, pc->CleanupTokenList); pc->CleanupTokenList = Next; } @@ -39,19 +39,19 @@ enum ParseResult ParseStatementMaybeRun(struct ParseState *Parser, int Condition int ParseCountParams(struct ParseState *Parser) { int ParamCount = 0; - + enum LexToken Token = LexGetToken(Parser, NULL, TRUE); if (Token != TokenCloseBracket && Token != TokenEOF) - { + { /* count the number of parameters */ ParamCount++; while ((Token = LexGetToken(Parser, NULL, TRUE)) != TokenCloseBracket && Token != TokenEOF) - { + { if (Token == TokenComma) ParamCount++; - } + } } - + return ParamCount; } @@ -70,13 +70,13 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp if (pc->TopStackFrame != NULL) ProgramFail(Parser, "nested function definitions are not allowed"); - + LexGetToken(Parser, NULL, TRUE); /* open bracket */ ParserCopy(&ParamParser, Parser); ParamCount = ParseCountParams(Parser); if (ParamCount > 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->Typ = &pc->FunctionType; FuncValue->Val->FuncDef.ReturnType = ReturnType; @@ -84,19 +84,19 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp FuncValue->Val->FuncDef.VarArgs = FALSE; FuncValue->Val->FuncDef.ParamType = (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++) - { + { /* harvest the parameters into the function definition */ if (ParamCount == FuncValue->Val->FuncDef.NumParams-1 && LexGetToken(&ParamParser, NULL, FALSE) == TokenEllipsis) - { + { /* ellipsis at end */ FuncValue->Val->FuncDef.NumParams--; FuncValue->Val->FuncDef.VarArgs = TRUE; break; } else - { + { /* add a parameter */ TypeParse(&ParamParser, &ParamType, &ParamIdentifier, NULL); if (ParamType->Base == TypeVoid) @@ -111,15 +111,15 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp FuncValue->Val->FuncDef.ParamName[ParamCount] = ParamIdentifier; } } - + Token = LexGetToken(&ParamParser, NULL, TRUE); if (Token != TokenComma && ParamCount < FuncValue->Val->FuncDef.NumParams-1) ProgramFail(&ParamParser, "comma expected"); } - + if (FuncValue->Val->FuncDef.NumParams != 0 && Token != TokenCloseBracket && Token != TokenComma && Token != TokenEllipsis) ProgramFail(&ParamParser, "bad parameter"); - + if (strcmp(Identifier, "main") == 0) { /* make sure it's int main() */ @@ -131,7 +131,7 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp (FuncValue->Val->FuncDef.NumParams != 2 || FuncValue->Val->FuncDef.ParamType[0] != &pc->IntType) ) ProgramFail(Parser, "bad parameters to main()"); } - + /* look for a function body */ Token = LexGetToken(Parser, NULL, FALSE); if (Token == TokenSemicolon) @@ -141,7 +141,7 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp /* it's a full function definition with a body */ if (Token != TokenLeftBrace) ProgramFail(Parser, "bad function definition"); - + ParserCopy(&FuncBody, Parser); if (ParseStatementMaybeRun(Parser, FALSE, TRUE) != ParseResultOk) ProgramFail(Parser, "function definition expected"); @@ -164,7 +164,7 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp if (!TableSet(pc, &pc->GlobalTable, Identifier, FuncValue, (char *)Parser->FileName, Parser->Line, Parser->CharacterPos)) ProgramFail(Parser, "'%s' is already defined", Identifier); - + return FuncValue; } @@ -174,13 +174,13 @@ int ParseArrayInitialiser(struct ParseState *Parser, struct Value *NewVariable, int ArrayIndex = 0; enum LexToken Token; struct Value *CValue; - + /* count the number of elements in the array */ if (DoAssignment && Parser->Mode == RunModeRun) { struct ParseState CountParser; int NumElements; - + ParserCopy(&CountParser, Parser); NumElements = ParseArrayInitialiser(&CountParser, NewVariable, FALSE); @@ -197,7 +197,7 @@ int ParseArrayInitialiser(struct ParseState *Parser, struct Value *NewVariable, printf("array size: %d \n", NewVariable->Typ->ArraySize); #endif } - + /* parse the array initialiser */ Token = LexGetToken(Parser, NULL, FALSE); while (Token != TokenRightBrace) @@ -206,7 +206,7 @@ int ParseArrayInitialiser(struct ParseState *Parser, struct Value *NewVariable, { /* this is a sub-array initialiser */ int SubArraySize = 0; - struct Value *SubArray = NewVariable; + struct Value *SubArray = NewVariable; if (Parser->Mode == RunModeRun && DoAssignment) { SubArraySize = TypeSize(NewVariable->Typ->FromType, NewVariable->Typ->FromType->ArraySize, TRUE); @@ -226,19 +226,19 @@ int ParseArrayInitialiser(struct ParseState *Parser, struct Value *NewVariable, else { struct Value *ArrayElement = NULL; - + if (Parser->Mode == RunModeRun && DoAssignment) { struct ValueType * ElementType = NewVariable->Typ; int TotalSize = 1; int ElementSize = 0; - + /* int x[3][3] = {1,2,3,4} => handle it just like int x[9] = {1,2,3,4} */ while (ElementType->Base == TypeArray) { TotalSize *= ElementType->ArraySize; ElementType = ElementType->FromType; - + /* char x[10][10] = {"abc", "def"} => assign "abc" to x[0], "def" to x[1] etc */ if (LexGetToken(Parser, NULL, FALSE) == TokenStringConstant && ElementType->FromType->Base == TypeChar) break; @@ -264,7 +264,7 @@ int ParseArrayInitialiser(struct ParseState *Parser, struct Value *NewVariable, VariableStackPop(Parser, ArrayElement); } } - + ArrayIndex++; Token = LexGetToken(Parser, NULL, FALSE); @@ -272,16 +272,16 @@ int ParseArrayInitialiser(struct ParseState *Parser, struct Value *NewVariable, { LexGetToken(Parser, NULL, TRUE); Token = LexGetToken(Parser, NULL, FALSE); - } + } else if (Token != TokenRightBrace) ProgramFail(Parser, "comma expected"); } - + if (Token == TokenRightBrace) LexGetToken(Parser, NULL, TRUE); else ProgramFail(Parser, "'}' expected"); - + return ArrayIndex; } @@ -301,7 +301,7 @@ void ParseDeclarationAssignment(struct ParseState *Parser, struct Value *NewVari /* this is a normal expression initialiser */ if (!ExpressionParse(Parser, &CValue)) ProgramFail(Parser, "expression expected"); - + if (Parser->Mode == RunModeRun && DoAssignment) { ExpressionAssign(Parser, NewVariable, CValue, FALSE, NULL, 0, FALSE); @@ -327,7 +327,7 @@ int ParseDeclaration(struct ParseState *Parser, enum LexToken Token) TypeParseIdentPart(Parser, BasicType, &Typ, &Identifier); if ((Token != TokenVoidType && Token != TokenStructType && Token != TokenUnionType && Token != TokenEnumType) && Identifier == pc->StrEmpty) ProgramFail(Parser, "identifier expected"); - + if (Identifier != pc->StrEmpty) { /* handle function definitions */ @@ -340,10 +340,10 @@ int ParseDeclaration(struct ParseState *Parser, enum LexToken Token) { if (Typ == &pc->VoidType && Identifier != pc->StrEmpty) ProgramFail(Parser, "can't define a void variable"); - + if (Parser->Mode == RunModeRun || Parser->Mode == RunModeGoto) NewVariable = VariableDefineButIgnoreIdentical(Parser, Identifier, Typ, IsStatic, &FirstVisit); - + if (LexGetToken(Parser, NULL, FALSE) == TokenAssign) { /* we're assigning an initial value */ @@ -352,13 +352,13 @@ int ParseDeclaration(struct ParseState *Parser, enum LexToken Token) } } } - + Token = LexGetToken(Parser, NULL, FALSE); if (Token == TokenComma) LexGetToken(Parser, NULL, TRUE); - + } while (Token == TokenComma); - + return TRUE; } @@ -372,9 +372,9 @@ void ParseMacroDefinition(struct ParseState *Parser) if (LexGetToken(Parser, &MacroName, TRUE) != TokenIdentifier) ProgramFail(Parser, "identifier expected"); - + MacroNameStr = MacroName->Val->Identifier; - + if (LexRawPeekToken(Parser) == TokenOpenMacroBracket) { /* it's a parameterised macro, read the parameters */ @@ -382,7 +382,7 @@ void ParseMacroDefinition(struct ParseState *Parser) struct ParseState ParamParser; int NumParams; int ParamCount = 0; - + ParserCopy(&ParamParser, Parser); NumParams = ParseCountParams(&ParamParser); MacroValue = VariableAllocValueAndData(Parser->pc, Parser, sizeof(struct MacroDef) + sizeof(const char *) * NumParams, FALSE, NULL, TRUE); @@ -390,21 +390,21 @@ void ParseMacroDefinition(struct ParseState *Parser) MacroValue->Val->MacroDef.ParamName = (char **)((char *)MacroValue->Val + sizeof(struct MacroDef)); Token = LexGetToken(Parser, &ParamName, TRUE); - + while (Token == TokenIdentifier) { /* store a parameter name */ MacroValue->Val->MacroDef.ParamName[ParamCount++] = ParamName->Val->Identifier; - + /* get the trailing comma */ Token = LexGetToken(Parser, NULL, TRUE); if (Token == TokenComma) Token = LexGetToken(Parser, &ParamName, TRUE); - + else if (Token != TokenCloseBracket) ProgramFail(Parser, "comma expected"); } - + if (Token != TokenCloseBracket) ProgramFail(Parser, "close bracket expected"); } @@ -414,13 +414,13 @@ void ParseMacroDefinition(struct ParseState *Parser) MacroValue = VariableAllocValueAndData(Parser->pc, Parser, sizeof(struct MacroDef), FALSE, NULL, TRUE); MacroValue->Val->MacroDef.NumParams = 0; } - + /* copy the body of the macro to execute later */ ParserCopy(&MacroValue->Val->MacroDef.Body, Parser); MacroValue->Typ = &Parser->pc->MacroType; LexToEndOfLine(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)) ProgramFail(Parser, "'%s' is already defined", MacroNameStr); } @@ -449,62 +449,62 @@ void ParseFor(struct ParseState *Parser) struct ParseState PreIncrement; struct ParseState PreStatement; struct ParseState After; - + enum RunMode OldMode = Parser->Mode; - + int PrevScopeID = 0, ScopeID = VariableScopeBegin(Parser, &PrevScopeID); if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) ProgramFail(Parser, "'(' expected"); - + if (ParseStatement(Parser, TRUE) != ParseResultOk) ProgramFail(Parser, "statement expected"); - + ParserCopyPos(&PreConditional, Parser); if (LexGetToken(Parser, NULL, FALSE) == TokenSemicolon) Condition = TRUE; else Condition = ExpressionParseInt(Parser); - + if (LexGetToken(Parser, NULL, TRUE) != TokenSemicolon) ProgramFail(Parser, "';' expected"); - + ParserCopyPos(&PreIncrement, Parser); ParseStatementMaybeRun(Parser, FALSE, FALSE); - + if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) ProgramFail(Parser, "')' expected"); - + ParserCopyPos(&PreStatement, Parser); if (ParseStatementMaybeRun(Parser, Condition, TRUE) != ParseResultOk) ProgramFail(Parser, "statement expected"); - + if (Parser->Mode == RunModeContinue && OldMode == RunModeRun) Parser->Mode = RunModeRun; - + ParserCopyPos(&After, Parser); - + while (Condition && Parser->Mode == RunModeRun) { ParserCopyPos(Parser, &PreIncrement); ParseStatement(Parser, FALSE); - + ParserCopyPos(Parser, &PreConditional); if (LexGetToken(Parser, NULL, FALSE) == TokenSemicolon) Condition = TRUE; else Condition = ExpressionParseInt(Parser); - + if (Condition) { ParserCopyPos(Parser, &PreStatement); ParseStatement(Parser, TRUE); - + if (Parser->Mode == RunModeContinue) - Parser->Mode = RunModeRun; + Parser->Mode = RunModeRun; } } - + if (Parser->Mode == RunModeBreak && OldMode == RunModeRun) Parser->Mode = RunModeRun; @@ -522,7 +522,7 @@ enum RunMode ParseBlock(struct ParseState *Parser, int AbsorbOpenBrace, int Cond ProgramFail(Parser, "'{' expected"); if (Parser->Mode == RunModeSkip || !Condition) - { + { /* condition failed - skip this block instead */ enum RunMode OldMode = Parser->Mode; Parser->Mode = RunModeSkip; @@ -531,12 +531,12 @@ enum RunMode ParseBlock(struct ParseState *Parser, int AbsorbOpenBrace, int Cond Parser->Mode = OldMode; } else - { + { /* just run it in its current mode */ while (ParseStatement(Parser, TRUE) == ParseResultOk) {} } - + if (LexGetToken(Parser, NULL, TRUE) != TokenRightBrace) ProgramFail(Parser, "'}' expected"); @@ -552,9 +552,9 @@ void ParseTypedef(struct ParseState *Parser) struct ValueType **TypPtr; char *TypeName; struct Value InitValue; - + TypeParse(Parser, &Typ, &TypeName, NULL); - + if (Parser->Mode == RunModeRun) { TypPtr = &Typ; @@ -573,20 +573,20 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi int Condition; struct ParseState PreState; enum LexToken Token; - + /* if we're debugging, check for a breakpoint */ if (Parser->DebugMode && Parser->Mode == RunModeRun) DebugCheckStatement(Parser); - - /* take note of where we are and then grab a token to see what statement we have */ + + /* take note of where we are and then grab a token to see what statement we have */ ParserCopy(&PreState, Parser); Token = LexGetToken(Parser, &LexerValue, TRUE); - + switch (Token) { case TokenEOF: return ParseResultEOF; - + case TokenIdentifier: /* might be a typedef-typed variable declaration or it might be an expression */ if (VariableDefined(Parser->pc, LexerValue->Val->Identifier)) @@ -609,7 +609,7 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi LexGetToken(Parser, NULL, TRUE); if (Parser->Mode == RunModeGoto && LexerValue->Val->Identifier == Parser->SearchGotoLabel) Parser->Mode = RunModeRun; - + CheckTrailingSemicolon = FALSE; break; } @@ -628,7 +628,7 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi { ProgramFail(Parser, "expected: expression"); } - + #if 0 PRINT_SOURCE_POS; PlatformPrintf(Parser->pc->CStdOut, "%t %s = %d;\n", CValue->Typ, Identifier, CValue->Val->Integer); @@ -643,35 +643,35 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi } /* else fallthrough to expression */ /* no break */ - - case TokenAsterisk: - case TokenAmpersand: - case TokenIncrement: - case TokenDecrement: - case TokenOpenBracket: + + case TokenAsterisk: + case TokenAmpersand: + case TokenIncrement: + case TokenDecrement: + case TokenOpenBracket: *Parser = PreState; ExpressionParse(Parser, &CValue); - if (Parser->Mode == RunModeRun) + if (Parser->Mode == RunModeRun) VariableStackPop(Parser, CValue); break; - + case TokenLeftBrace: ParseBlock(Parser, FALSE, TRUE); CheckTrailingSemicolon = FALSE; break; - + case TokenIf: if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) ProgramFail(Parser, "'(' expected"); - + Condition = ExpressionParseInt(Parser); - + if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) ProgramFail(Parser, "')' expected"); if (ParseStatementMaybeRun(Parser, Condition, TRUE) != ParseResultOk) ProgramFail(Parser, "statement expected"); - + if (LexGetToken(Parser, NULL, FALSE) == TokenElse) { LexGetToken(Parser, NULL, TRUE); @@ -680,7 +680,7 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi } CheckTrailingSemicolon = FALSE; break; - + case TokenWhile: { struct ParseState PreConditional; @@ -688,7 +688,7 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) ProgramFail(Parser, "'(' expected"); - + ParserCopyPos(&PreConditional, Parser); do { @@ -696,22 +696,22 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi Condition = ExpressionParseInt(Parser); if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) ProgramFail(Parser, "')' expected"); - + if (ParseStatementMaybeRun(Parser, Condition, TRUE) != ParseResultOk) ProgramFail(Parser, "statement expected"); - + if (Parser->Mode == RunModeContinue) Parser->Mode = PreMode; - + } while (Parser->Mode == RunModeRun && Condition); - + if (Parser->Mode == RunModeBreak) Parser->Mode = PreMode; CheckTrailingSemicolon = FALSE; } break; - + case TokenDo: { struct ParseState PreStatement; @@ -722,34 +722,34 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi ParserCopyPos(Parser, &PreStatement); if (ParseStatement(Parser, TRUE) != ParseResultOk) ProgramFail(Parser, "statement expected"); - + if (Parser->Mode == RunModeContinue) Parser->Mode = PreMode; if (LexGetToken(Parser, NULL, TRUE) != TokenWhile) ProgramFail(Parser, "'while' expected"); - + if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) ProgramFail(Parser, "'(' expected"); - + Condition = ExpressionParseInt(Parser); if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) ProgramFail(Parser, "')' expected"); - - } while (Condition && Parser->Mode == RunModeRun); - + + } while (Condition && Parser->Mode == RunModeRun); + if (Parser->Mode == RunModeBreak) Parser->Mode = PreMode; } break; - + case TokenFor: ParseFor(Parser); CheckTrailingSemicolon = FALSE; break; - case TokenSemicolon: - CheckTrailingSemicolon = FALSE; + case TokenSemicolon: + CheckTrailingSemicolon = FALSE; break; case TokenIntType: @@ -771,17 +771,17 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi *Parser = PreState; CheckTrailingSemicolon = ParseDeclaration(Parser, Token); break; - + case TokenHashDefine: ParseMacroDefinition(Parser); CheckTrailingSemicolon = FALSE; break; - + #ifndef NO_HASH_INCLUDE case TokenHashInclude: if (LexGetToken(Parser, &LexerValue, TRUE) != TokenStringConstant) ProgramFail(Parser, "\"filename.h\" expected"); - + IncludeFile(Parser->pc, (char *)LexerValue->Val->Pointer); CheckTrailingSemicolon = FALSE; break; @@ -790,24 +790,24 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi case TokenSwitch: if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) ProgramFail(Parser, "'(' expected"); - + Condition = ExpressionParseInt(Parser); - + if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) ProgramFail(Parser, "')' expected"); - + if (LexGetToken(Parser, NULL, FALSE) != TokenLeftBrace) ProgramFail(Parser, "'{' expected"); - - { + + { /* new block so we can store parser state */ enum RunMode OldMode = Parser->Mode; int OldSearchLabel = Parser->SearchLabel; Parser->Mode = RunModeCaseSearch; Parser->SearchLabel = Condition; - + ParseBlock(Parser, TRUE, (OldMode != RunModeSkip) && (OldMode != RunModeReturn)); - + if (Parser->Mode != RunModeReturn) Parser->Mode = OldMode; @@ -826,23 +826,23 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi } else Condition = ExpressionParseInt(Parser); - + if (LexGetToken(Parser, NULL, TRUE) != TokenColon) ProgramFail(Parser, "':' expected"); - + if (Parser->Mode == RunModeCaseSearch && Condition == Parser->SearchLabel) Parser->Mode = RunModeRun; CheckTrailingSemicolon = FALSE; break; - + case TokenDefault: if (LexGetToken(Parser, NULL, TRUE) != TokenColon) ProgramFail(Parser, "':' expected"); - + if (Parser->Mode == RunModeCaseSearch) Parser->Mode = RunModeRun; - + CheckTrailingSemicolon = FALSE; break; @@ -850,12 +850,12 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi if (Parser->Mode == RunModeRun) Parser->Mode = RunModeBreak; break; - + case TokenContinue: if (Parser->Mode == RunModeRun) Parser->Mode = RunModeContinue; break; - + case TokenReturn: if (Parser->Mode == RunModeRun) { @@ -863,7 +863,7 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi { if (!ExpressionParse(Parser, &CValue)) ProgramFail(Parser, "value required in return"); - + if (!Parser->pc->TopStackFrame) /* return from top-level program? */ PlatformExit(Parser->pc, ExpressionCoerceInteger(CValue)); else @@ -874,9 +874,9 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi else { if (ExpressionParse(Parser, &CValue)) - ProgramFail(Parser, "value in return from a void function"); + ProgramFail(Parser, "value in return from a void function"); } - + Parser->Mode = RunModeReturn; } else @@ -886,49 +886,49 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi case TokenTypedef: ParseTypedef(Parser); break; - + case TokenGoto: if (LexGetToken(Parser, &LexerValue, TRUE) != TokenIdentifier) ProgramFail(Parser, "identifier expected"); - + if (Parser->Mode == RunModeRun) - { + { /* start scanning for the goto label */ Parser->SearchGotoLabel = LexerValue->Val->Identifier; Parser->Mode = RunModeGoto; } break; - + case TokenDelete: { /* try it as a function or variable name to delete */ if (LexGetToken(Parser, &LexerValue, TRUE) != TokenIdentifier) ProgramFail(Parser, "identifier expected"); - + if (Parser->Mode == RunModeRun) - { + { /* delete this variable or function */ CValue = TableDelete(Parser->pc, &Parser->pc->GlobalTable, LexerValue->Val->Identifier); if (CValue == NULL) ProgramFail(Parser, "'%s' is not defined", LexerValue->Val->Identifier); - + VariableFree(Parser->pc, CValue); } break; } - + default: *Parser = PreState; return ParseResultError; } - + if (CheckTrailingSemicolon) { if (LexGetToken(Parser, NULL, TRUE) != TokenSemicolon) ProgramFail(Parser, "';' expected"); } - + return ParseResultOk; } @@ -939,36 +939,36 @@ void PicocParse(Picoc *pc, const char *FileName, const char *Source, int SourceL enum ParseResult Ok; struct CleanupTokenNode *NewCleanupNode; char *RegFileName = TableStrRegister(pc, FileName); - + void *Tokens = LexAnalyse(pc, RegFileName, Source, SourceLen, NULL); - + /* allocate a cleanup node so we can clean up the tokens later */ if (!CleanupNow) { NewCleanupNode = HeapAllocMem(pc, sizeof(struct CleanupTokenNode)); if (NewCleanupNode == NULL) ProgramFailNoParser(pc, "out of memory"); - + NewCleanupNode->Tokens = Tokens; if (CleanupSource) NewCleanupNode->SourceText = Source; else NewCleanupNode->SourceText = NULL; - + NewCleanupNode->Next = pc->CleanupTokenList; pc->CleanupTokenList = NewCleanupNode; } - + /* do the parsing */ LexInitParser(&Parser, pc, Source, Tokens, RegFileName, RunIt, EnableDebugger); do { Ok = ParseStatement(&Parser, TRUE); } while (Ok == ParseResultOk); - + if (Ok == ParseResultError) ProgramFail(&Parser, "parse error"); - + /* clean up */ if (CleanupNow) HeapFreeMem(pc, Tokens); @@ -979,7 +979,7 @@ void PicocParseInteractiveNoStartPrompt(Picoc *pc, int EnableDebugger) { struct ParseState Parser; enum ParseResult Ok; - + LexInitParser(&Parser, pc, NULL, NULL, pc->StrEmpty, TRUE, EnableDebugger); PicocPlatformSetExitPoint(pc); LexInteractiveClear(pc, &Parser); @@ -989,12 +989,12 @@ void PicocParseInteractiveNoStartPrompt(Picoc *pc, int EnableDebugger) LexInteractiveStatementPrompt(pc); Ok = ParseStatement(&Parser, TRUE); LexInteractiveCompleted(pc, &Parser); - + } while (Ok == ParseResultOk); - + if (Ok == ParseResultError) ProgramFail(&Parser, "parse error"); - + PlatformPrintf(pc->CStdOut, "\n"); } diff --git a/picoc.c b/picoc.c index 19715ff..035b592 100644 --- a/picoc.c +++ b/picoc.c @@ -1,6 +1,6 @@ /* picoc main program - this varies depending on your operating system and * how you're using picoc */ - + /* include only picoc.h here - should be able to use it with only the external interfaces, no internals from interpreter.h */ #include "picoc.h" @@ -19,7 +19,7 @@ int main(int argc, char **argv) int DontRunMain = FALSE; int StackSize = getenv("STACKSIZE") ? atoi(getenv("STACKSIZE")) : PICOC_STACK_SIZE; Picoc pc; - + if (argc < 2) { printf("Format: picoc ... [- ...] : run a program (calls main() to start it)\n" @@ -27,16 +27,16 @@ int main(int argc, char **argv) " picoc -i : interactive mode\n"); exit(1); } - + PicocInitialise(&pc, StackSize); - + if (strcmp(argv[ParamCount], "-s") == 0 || strcmp(argv[ParamCount], "-m") == 0) { DontRunMain = TRUE; PicocIncludeAllSystemHeaders(&pc); ParamCount++; } - + if (argc > ParamCount && strcmp(argv[ParamCount], "-i") == 0) { PicocIncludeAllSystemHeaders(&pc); @@ -49,14 +49,14 @@ int main(int argc, char **argv) PicocCleanup(&pc); return pc.PicocExitValue; } - + for (; ParamCount < argc && strcmp(argv[ParamCount], "-") != 0; ParamCount++) PicocPlatformScanFile(&pc, argv[ParamCount]); - + if (!DontRunMain) PicocCallMain(&pc, argc - ParamCount, &argv[ParamCount]); } - + PicocCleanup(&pc); return pc.PicocExitValue; } @@ -69,7 +69,7 @@ int main(int argc, char **argv) # include "../string.h" int picoc(char *SourceStr) -{ +{ char *pos; PicocInitialise(HEAP_SIZE); @@ -93,12 +93,12 @@ int picoc(char *SourceStr) return PicocExitValue; } - if (SourceStr) + if (SourceStr) PicocParse("nofile", SourceStr, strlen(SourceStr), TRUE, TRUE, FALSE); PicocParseInteractive(); PicocCleanup(); - + return PicocExitValue; } # endif diff --git a/platform.c b/platform.c index 67ae13b..cdef4dd 100644 --- a/platform.c +++ b/platform.c @@ -1,6 +1,6 @@ /* picoc's interface to the underlying platform. most platform-specific code * is in platform/platform_XX.c and platform/library_XX.c */ - + #include "picoc.h" #include "interpreter.h" @@ -59,7 +59,7 @@ void PicocCallMain(Picoc *pc, int argc, char **argv) if (!VariableDefined(pc, TableStrRegister(pc, "main"))) ProgramFailNoParser(pc, "main() is not defined"); - + VariableGet(pc, NULL, TableStrRegister(pc, "main"), &FuncValue); if (FuncValue->Typ->Base != TypeFunction) ProgramFailNoParser(pc, "main is not a function - can't call it"); @@ -81,7 +81,7 @@ void PicocCallMain(Picoc *pc, int argc, char **argv) else { VariableDefinePlatformVar(pc, NULL, "__exit_value", &pc->IntType, (union AnyValue *)&pc->PicocExitValue, TRUE); - + 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, TRUE); else @@ -96,7 +96,7 @@ void PrintSourceTextErrorLine(IOFILE *Stream, const char *FileName, const char * const char *LinePos; const char *CPos; int CCount; - + if (SourceText != NULL) { /* find the source line */ @@ -105,12 +105,12 @@ void PrintSourceTextErrorLine(IOFILE *Stream, const char *FileName, const char * if (*LinePos == '\n') LineCount++; } - + /* display the line */ for (CPos = LinePos; *CPos != '\n' && *CPos != '\0'; CPos++) PrintCh(*CPos, Stream); PrintCh('\n', Stream); - + /* display the error position */ for (CPos = LinePos, CCount = 0; *CPos != '\n' && *CPos != '\0' && (CCount < CharacterPos || *CPos == ' '); CPos++, CCount++) { @@ -127,7 +127,7 @@ void PrintSourceTextErrorLine(IOFILE *Stream, const char *FileName, const char * PrintCh(' ', Stream); } PlatformPrintf(Stream, "^\n%s:%d:%d ", FileName, Line, CharacterPos); - + } /* exit with a message */ @@ -159,18 +159,18 @@ void ProgramFailNoParser(Picoc *pc, const char *Message, ...) 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; - + 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) PlatformPrintf(Stream, Format, Type1, Type2); else PlatformPrintf(Stream, Format, Num1, Num2); - + if (FuncName != NULL) PlatformPrintf(Stream, " in argument %d of call to %s()", ParamNo, FuncName); - + PlatformPrintf(Stream, "\n"); PlatformExit(Parser->pc, 1); } @@ -192,7 +192,7 @@ void LexFail(Picoc *pc, struct LexState *Lexer, const char *Message, ...) void PlatformPrintf(IOFILE *Stream, const char *Format, ...) { va_list Args; - + va_start(Args, Format); PlatformVPrintf(Stream, Format, Args); va_end(Args); @@ -201,7 +201,7 @@ void PlatformPrintf(IOFILE *Stream, const char *Format, ...) void PlatformVPrintf(IOFILE *Stream, const char *Format, va_list Args) { const char *FPos; - + for (FPos = Format; *FPos != '\0'; FPos++) { if (*FPos == '%') @@ -230,7 +230,7 @@ void PlatformVPrintf(IOFILE *Stream, const char *Format, va_list Args) char *PlatformMakeTempName(Picoc *pc, char *TempNameBuffer) { int CPos = 5; - + while (CPos > 1) { if (TempNameBuffer[CPos] < '9') diff --git a/platform/library_msvc.c b/platform/library_msvc.c index 621a067..f7a416a 100644 --- a/platform/library_msvc.c +++ b/platform/library_msvc.c @@ -1,16 +1,16 @@ #include "../interpreter.h" 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); 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; } diff --git a/platform/library_srv1.c b/platform/library_srv1.c index a8cd443..fa632e3 100644 --- a/platform/library_srv1.c +++ b/platform/library_srv1.c @@ -5,10 +5,10 @@ static int GPSlat, GPSlon, GPSalt, GPSfix, GPSsat, GPSutc, Elcount, Ercount; static int ScanVect[16], NNVect[NUM_OUTPUT]; struct ValueType *IntArrayType; - + void SRV1SetupFunc() -{ +{ IntArrayType = TypeGetMatching(NULL, &IntType, TypeArray, 16, StrEmpty, TRUE); VariableDefinePlatformVar(NULL, "scanvect", IntArrayType, (union AnyValue *)&ScanVect, FALSE); VariableDefinePlatformVar(NULL, "neuron", IntArrayType, (union AnyValue *)&NNVect, FALSE); @@ -49,7 +49,7 @@ void Cinput(struct ParseState *Parser, struct Value *ReturnValue, struct Value * void Cdelay(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { int del; - + del = Param[0]->Val->Integer; if ((del < 0) || (del > 1000000)) return; @@ -69,7 +69,7 @@ void Ctime(struct ParseState *Parser, struct Value *ReturnValue, struct Value ** void Ciodir(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { int dir; - + dir = Param[0]->Val->Integer; *pPORTHIO_DIR = ((dir << 10) & 0xFC00) + (*pPORTHIO_DIR & 0x03FF); // H15/14/13/12/11/10 - 1=output, 0=input *pPORTHIO_INEN = (((~dir) << 10) & 0xFC00) + (*pPORTHIO_INEN & 0x03FF); // invert dir bits to enable inputs @@ -91,7 +91,7 @@ void Cpeek(struct ParseState *Parser, struct Value *ReturnValue, struct Value ** unsigned char *cp; unsigned short *sp; unsigned int *ip; - + /* x = peek(addr, size); mask ptr to align with word size */ ptr = Param[0]->Val->Integer; @@ -121,7 +121,7 @@ void Cpoke(struct ParseState *Parser, struct Value *ReturnValue, struct Value ** unsigned char *cp; unsigned short *sp; unsigned int *ip; - + /* x = poke(addr, size, val); mask ptr to align with word size */ ptr = Param[0]->Val->Integer; @@ -148,10 +148,10 @@ void Cpoke(struct ParseState *Parser, struct Value *ReturnValue, struct Value ** void Cencoders(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { unsigned int ix; - - ix = encoders(); // read left and right encoders; save data to C globals lcount, rcount - Elcount = (ix >> 16) & 0x0000FFFF; - Ercount = ix & 0x0000FFFF; + + ix = encoders(); // read left and right encoders; save data to C globals lcount, rcount + Elcount = (ix >> 16) & 0x0000FFFF; + Ercount = ix & 0x0000FFFF; } void Cmotors(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) @@ -191,7 +191,7 @@ void Cmotors2(struct ParseState *Parser, struct Value *ReturnValue, struct Value void Cservos(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { int lspeed, rspeed; - + lspeed = Param[0]->Val->Integer; if ((lspeed < 0) || (lspeed > 100)) ProgramFail(NULL, "servos(): TMR2 value out of range"); @@ -209,7 +209,7 @@ void Cservos(struct ParseState *Parser, struct Value *ReturnValue, struct Value void Cservos2(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { int lspeed, rspeed; - + lspeed = Param[0]->Val->Integer; if ((lspeed < 0) || (lspeed > 100)) ProgramFail(NULL, "servos2(): TMR6 value out of range"); @@ -264,11 +264,11 @@ void Cbattery(struct ParseState *Parser, struct Value *ReturnValue, struct Value ReturnValue->Val->Integer = 1; // battery voltage okay } -void Cvcolor(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // set color bin - - // vcolor (color, ymin, ymax, umin, umax, vmin, vmax); +void Cvcolor(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // set color bin - + // vcolor (color, ymin, ymax, umin, umax, vmin, vmax); { int ix; - + ix = Param[0]->Val->Integer; ymin[ix] = Param[1]->Val->Integer; ymax[ix] = Param[2]->Val->Integer; @@ -278,7 +278,7 @@ void Cvcolor(struct ParseState *Parser, struct Value *ReturnValue, struct Value vmax[ix] = Param[6]->Val->Integer; } -void Cvcam(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // set camera functions - +void Cvcam(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // set camera functions - // enable/disable AGC(4) / AWB(2) / AEC(1) camera controls // vcam(7) = AGC+AWB+AEC on vcam(0) = AGC+AWB+AEC off { @@ -291,11 +291,11 @@ void Cvcam(struct ParseState *Parser, struct Value *ReturnValue, struct Value ** i2cwrite(0x21, (unsigned char *)i2c_data, 1, SCCB_ON); // OV7725 } -void Cvfind(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // set color bin - - // vfind (color, x1, x2, y1, y2); +void Cvfind(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // set color bin - + // vfind (color, x1, x2, y1, y2); { int ix, x1, x2, y1, y2; - + ix = Param[0]->Val->Integer; x1 = Param[1]->Val->Integer; x2 = Param[2]->Val->Integer; @@ -337,13 +337,13 @@ void Cvscan(struct ParseState *Parser, struct Value *ReturnValue, struct Value * if ((col < 1) || (col > 9)) ProgramFail(NULL, "vscan(): number of columns must be between 1 and 9"); thresh = Param[1]->Val->Integer; - if ((thresh < 0) || (thresh > 9999)) + if ((thresh < 0) || (thresh > 9999)) ProgramFail(NULL, "vscan(): threshold must be between 0 and 9999"); ix = vscan((unsigned char *)SPI_BUFFER1, (unsigned char *)FRAME_BUF, thresh, (unsigned int)col, (unsigned int *)&ScanVect[0]); ReturnValue->Val->Integer = ix; } -void Cvmean(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) +void Cvmean(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { vmean((unsigned char *)FRAME_BUF); Iy1 = mean[0]; @@ -361,7 +361,7 @@ void Cvblob(struct ParseState *Parser, struct Value *ReturnValue, struct Value * iblob = Param[1]->Val->Integer; if (iblob > MAX_BLOBS) ProgramFail(NULL, "blob(): invalid blob index"); - + numblob = vblob((unsigned char *)FRAME_BUF, (unsigned char *)FRAME_BUF3, ix); if ((blobcnt[iblob] == 0) || (numblob == -1)) { @@ -379,14 +379,14 @@ void Cvblob(struct ParseState *Parser, struct Value *ReturnValue, struct Value * void Cvjpeg (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { unsigned int image_size, qual; unsigned char *output_start, *output_end; - + qual = Param[0]->Val->Integer; if ((qual < 1) || (qual > 8)) ProgramFail(NULL, "vjpeg(): quality parameter out of range"); - + output_start = (unsigned char *)JPEG_BUF; - output_end = encode_image((unsigned char *)FRAME_BUF, output_start, qual, - FOUR_TWO_TWO, imgWidth, imgHeight); + output_end = encode_image((unsigned char *)FRAME_BUF, output_start, qual, + FOUR_TWO_TWO, imgWidth, imgHeight); image_size = (unsigned int)(output_end - output_start); ReturnValue->Val->Integer = image_size; @@ -395,15 +395,15 @@ void Cvjpeg (struct ParseState *Parser, struct Value *ReturnValue, struct Value void Cvsend (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { unsigned int ix, image_size; unsigned char *cp; - + image_size = Param[0]->Val->Integer; if ((image_size < 0) || (image_size > 200000)) ProgramFail(NULL, "vsend(): image size out of range"); - + led1_on(); cp = (unsigned char *)JPEG_BUF; - for (ix=0; ixVal->Integer; if ((ix<1) || (ix>3)) ProgramFail(NULL, "tilt(): invalid channel"); @@ -439,7 +439,7 @@ void Canalog(struct ParseState *Parser, struct Value *ReturnValue, struct Value unsigned int ix, channel; unsigned char mask1[] = { 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08 }; unsigned char mask2[] = { 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00 }; - + // decide which i2c device based on channel range ix = (unsigned char)Param[0]->Val->Integer; if ((ix<1) || (ix>28)) @@ -459,13 +459,13 @@ void Canalog(struct ParseState *Parser, struct Value *ReturnValue, struct Value channel = ix % 10; if ((channel<1) || (channel>8)) ProgramFail(NULL, "analog(): invalid channel"); - + // set timer register 3 i2c_data[0] = 0x03; i2c_data[1] = 0x01; i2cwrite(device_id, (unsigned char *)i2c_data, 1, SCCB_ON); - // set analog channel + // set analog channel i2c_data[0] = 0x02; i2c_data[1] = mask1[channel-1]; i2c_data[2] = mask2[channel-1]; @@ -495,21 +495,21 @@ void Cgps(struct ParseState *Parser, struct Value *ReturnValue, struct Value **P void Creadi2c(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // syntax val = readi2c(device, register); { unsigned char i2c_device, i2c_data[2]; - + i2c_device = (unsigned char)Param[0]->Val->Integer; i2c_data[0] = (unsigned char)Param[1]->Val->Integer; - + i2cread(i2c_device, (unsigned char *)i2c_data, 1, SCCB_OFF); ReturnValue->Val->Integer = ((int)i2c_data[0] & 0x000000FF); } -void Creadi2c2(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // syntax two_byte_val = readi2c(device, register); +void Creadi2c2(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // syntax two_byte_val = readi2c(device, register); { unsigned char i2c_device, i2c_data[2]; i2c_device = (unsigned char)Param[0]->Val->Integer; i2c_data[0] = (unsigned char)Param[1]->Val->Integer; - + i2cread(i2c_device, (unsigned char *)i2c_data, 2, SCCB_OFF); ReturnValue->Val->Integer = (((unsigned int)i2c_data[0] << 8) + i2c_data[1]); } @@ -521,14 +521,14 @@ void Cwritei2c(struct ParseState *Parser, struct Value *ReturnValue, struct Valu i2c_device = (unsigned char)Param[0]->Val->Integer; i2c_data[0] = (unsigned char)Param[1]->Val->Integer; i2c_data[1] = (unsigned char)Param[2]->Val->Integer; - + i2cwrite(i2c_device, (unsigned char *)i2c_data, 1, SCCB_OFF); } void Csin(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // sin(angle) { int ix; - + ix = Param[0]->Val->Integer; // input to function is angle in degrees ReturnValue->Val->Integer = sin(ix); } @@ -536,7 +536,7 @@ void Csin(struct ParseState *Parser, struct Value *ReturnValue, struct Value **P void Ccos(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // cos(angle) { int ix; - + ix = Param[0]->Val->Integer; // input to function is angle in degrees ReturnValue->Val->Integer = cos(ix); } @@ -544,7 +544,7 @@ void Ccos(struct ParseState *Parser, struct Value *ReturnValue, struct Value **P void Ctan(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // tan(angle) { int ix; - + ix = Param[0]->Val->Integer; // input to function is angle in degrees ReturnValue->Val->Integer = tan(ix); } @@ -575,7 +575,7 @@ void Catan(struct ParseState *Parser, struct Value *ReturnValue, struct Value ** y = Param[0]->Val->Integer; x = Param[1]->Val->Integer; ReturnValue->Val->Integer = atan(y, x); -} +} void Cgps_head(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // gps_head(lat1, lon1, lat2, lon2) { @@ -585,7 +585,7 @@ void Cgps_head(struct ParseState *Parser, struct Value *ReturnValue, struct Valu lat2 = Param[2]->Val->Integer; lon2 = Param[3]->Val->Integer; ReturnValue->Val->Integer = gps_head(lat1, lon1, lat2, lon2); -} +} void Cgps_dist(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // gps_dist(lat1, lon1, lat2, lon2) { @@ -595,18 +595,18 @@ void Cgps_dist(struct ParseState *Parser, struct Value *ReturnValue, struct Valu lat2 = Param[2]->Val->Integer; lon2 = Param[3]->Val->Integer; ReturnValue->Val->Integer = gps_dist(lat1, lon1, lat2, lon2); -} +} void Csqrt(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // sqrt(x) { int x; x = Param[0]->Val->Integer; ReturnValue->Val->Integer = isqrt(x); -} +} void Cnnset(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { int ix, i1; - + ix = Param[0]->Val->Integer; if (ix > NUM_NPATTERNS) ProgramFail(NULL, "nnset(): invalid index"); @@ -616,7 +616,7 @@ void Cnnset(struct ParseState *Parser, struct Value *ReturnValue, struct Value * void Cnnshow(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { int ix; - + ix = Param[0]->Val->Integer; if (ix > NUM_NPATTERNS) ProgramFail(NULL, "nnshow(): invalid index"); @@ -634,7 +634,7 @@ void Cnntrain(struct ParseState *Parser, struct Value *ReturnValue, struct Value for (ix=0; ixVal->Integer; @@ -667,9 +667,9 @@ void Cnntest(struct ParseState *Parser, struct Value *ReturnValue, struct Value ReturnValue->Val->Integer = ix; } -void Cnnmatchblob(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { +void Cnnmatchblob(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { int ix, i1, max; - + ix = Param[0]->Val->Integer; if (ix > MAX_BLOBS) ProgramFail(NULL, "nnmatchblob(): invalid blob index"); @@ -679,7 +679,7 @@ void Cnnmatchblob(struct ParseState *Parser, struct Value *ReturnValue, struct V square the aspect ratio of x1, x2, y1, y2 then subsample blob pixels to populate N_IN(0:63) with 0:1024 values then nncalculate_network() and display the N_OUT() results */ - nnscale8x8((unsigned char *)FRAME_BUF3, blobix[ix], blobx1[ix], blobx2[ix], + nnscale8x8((unsigned char *)FRAME_BUF3, blobix[ix], blobx1[ix], blobx2[ix], bloby1[ix], bloby2[ix], imgWidth, imgHeight); nncalculate_network(); ix = 0; @@ -696,13 +696,13 @@ void Cnnmatchblob(struct ParseState *Parser, struct Value *ReturnValue, struct V void Cnnlearnblob (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { int ix; - + ix = Param[0]->Val->Integer; if (ix > NUM_NPATTERNS) ProgramFail(NULL, "nnlearnblob(): invalid index"); if (!blobcnt[0]) ProgramFail(NULL, "nnlearnblob(): no blob to grab"); - nnscale8x8((unsigned char *)FRAME_BUF3, blobix[0], blobx1[0], blobx2[0], + nnscale8x8((unsigned char *)FRAME_BUF3, blobix[0], blobx1[0], blobx2[0], bloby1[0], bloby2[0], imgWidth, imgHeight); nnpack8x8(ix); nndisplay(ix); @@ -711,7 +711,7 @@ void Cnnlearnblob (struct ParseState *Parser, struct Value *ReturnValue, struct void Cautorun (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { int ix, t0; unsigned char ch; - + ix = Param[0]->Val->Integer; t0 = readRTC(); while (readRTC() < (t0 + ix*1000)) { // watch for ESC in 'ix' seconds diff --git a/platform/library_surveyor.c b/platform/library_surveyor.c index 283aff2..a10cc78 100644 --- a/platform/library_surveyor.c +++ b/platform/library_surveyor.c @@ -9,7 +9,7 @@ static int ScanVect[16], NNVect[NUM_OUTPUT]; void PlatformLibraryInit() { struct ValueType *IntArrayType; - + IntArrayType = TypeGetMatching(NULL, &IntType, TypeArray, 16, StrEmpty, TRUE); VariableDefinePlatformVar(NULL, "scanvect", IntArrayType, (union AnyValue *)&ScanVect, FALSE); VariableDefinePlatformVar(NULL, "neuron", IntArrayType, (union AnyValue *)&NNVect, FALSE); @@ -64,7 +64,7 @@ void Cread_int(struct ParseState *Parser, struct Value *ReturnValue, struct Valu { int ix, sign; unsigned char ch; - + ix = 0; sign = 1; while (1) { @@ -85,7 +85,7 @@ void Cread_str(struct ParseState *Parser, struct Value *ReturnValue, struct Valu { int ix; unsigned char ch; - + ix = 0; char *cp = (char *)Param[0]->Val->Pointer; while (1) { @@ -100,9 +100,9 @@ void Cread_str(struct ParseState *Parser, struct Value *ReturnValue, struct Valu cp[ix] = 0; ix--; break; - } + } } - ReturnValue->Val->Integer = ix; + ReturnValue->Val->Integer = ix; } void Cinit_uart1(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // return 0-9 from console input @@ -129,7 +129,7 @@ void Coutput1(struct ParseState *Parser, struct Value *ReturnValue, struct Value void Cdelay(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { int del; - + del = Param[0]->Val->Integer; if ((del < 0) || (del > 1000000)) return; @@ -149,7 +149,7 @@ void Ctime(struct ParseState *Parser, struct Value *ReturnValue, struct Value ** void Ciodir(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { int dir; - + dir = Param[0]->Val->Integer; *pPORTHIO_DIR = ((dir << 10) & 0xFC00) + (*pPORTHIO_DIR & 0x03FF); // H15/14/13/12/11/10 - 1=output, 0=input *pPORTHIO_INEN = (((~dir) << 10) & 0xFC00) + (*pPORTHIO_INEN & 0x03FF); // invert dir bits to enable inputs @@ -171,7 +171,7 @@ void Cpeek(struct ParseState *Parser, struct Value *ReturnValue, struct Value ** unsigned char *cp; unsigned short *sp; unsigned int *ip; - + /* x = peek(addr, size); mask ptr to align with word size */ ptr = Param[0]->Val->Integer; @@ -201,7 +201,7 @@ void Cpoke(struct ParseState *Parser, struct Value *ReturnValue, struct Value ** unsigned char *cp; unsigned short *sp; unsigned int *ip; - + /* x = poke(addr, size, val); mask ptr to align with word size */ ptr = Param[0]->Val->Integer; @@ -228,18 +228,18 @@ void Cpoke(struct ParseState *Parser, struct Value *ReturnValue, struct Value ** void Cencoders(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { unsigned int ix; - - ix = encoders(); // read left and right encoders; save data to C globals lcount, rcount - Elcount = (ix >> 16) & 0x0000FFFF; - Ercount = ix & 0x0000FFFF; + + ix = encoders(); // read left and right encoders; save data to C globals lcount, rcount + Elcount = (ix >> 16) & 0x0000FFFF; + Ercount = ix & 0x0000FFFF; } void Cencoderx(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // return reading from HMC6352 I2C compass { int ix; - + ix = (unsigned char)Param[0]->Val->Integer; - if ((ix<0) || (ix>7)) + if ((ix<0) || (ix>7)) ProgramFail(NULL, "encoderx(): invalid channel"); ReturnValue->Val->Integer = encoder_4wd(ix); } @@ -283,7 +283,7 @@ void Cmotorx(struct ParseState *Parser, struct Value *ReturnValue, struct Value { unsigned char ch; int ls, rs; - + ls = Param[0]->Val->Integer; if ((ls < -100) || (ls > 100)) ProgramFail(NULL, "motors(): left motor value out of range"); @@ -307,7 +307,7 @@ void Cmotorx(struct ParseState *Parser, struct Value *ReturnValue, struct Value void Cservos(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { int lspeed, rspeed; - + lspeed = Param[0]->Val->Integer; if ((lspeed < 0) || (lspeed > 100)) ProgramFail(NULL, "servos(): TMR2 value out of range"); @@ -325,7 +325,7 @@ void Cservos(struct ParseState *Parser, struct Value *ReturnValue, struct Value void Cservos2(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { int lspeed, rspeed; - + lspeed = Param[0]->Val->Integer; if ((lspeed < 0) || (lspeed > 100)) ProgramFail(NULL, "servos2(): TMR6 value out of range"); @@ -380,11 +380,11 @@ void Cbattery(struct ParseState *Parser, struct Value *ReturnValue, struct Value ReturnValue->Val->Integer = 1; // battery voltage okay } -void Cvcolor(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // set color bin - - // vcolor (color, ymin, ymax, umin, umax, vmin, vmax); +void Cvcolor(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // set color bin - + // vcolor (color, ymin, ymax, umin, umax, vmin, vmax); { int ix; - + ix = Param[0]->Val->Integer; ymin[ix] = Param[1]->Val->Integer; ymax[ix] = Param[2]->Val->Integer; @@ -394,7 +394,7 @@ void Cvcolor(struct ParseState *Parser, struct Value *ReturnValue, struct Value vmax[ix] = Param[6]->Val->Integer; } -void Cvcam(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // set camera functions - +void Cvcam(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // set camera functions - // enable/disable AGC(4) / AWB(2) / AEC(1) camera controls // vcam(7) = AGC+AWB+AEC on vcam(0) = AGC+AWB+AEC off { @@ -407,11 +407,11 @@ void Cvcam(struct ParseState *Parser, struct Value *ReturnValue, struct Value ** i2cwrite(0x21, (unsigned char *)i2c_data, 1, SCCB_ON); // OV7725 } -void Cvfind(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // set color bin - - // vfind (color, x1, x2, y1, y2); +void Cvfind(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // set color bin - + // vfind (color, x1, x2, y1, y2); { int ix, x1, x2, y1, y2; - + ix = Param[0]->Val->Integer; x1 = Param[1]->Val->Integer; x2 = Param[2]->Val->Integer; @@ -453,13 +453,13 @@ void Cvscan(struct ParseState *Parser, struct Value *ReturnValue, struct Value * if ((col < 1) || (col > 9)) ProgramFail(NULL, "vscan(): number of columns must be between 1 and 9"); thresh = Param[1]->Val->Integer; - if ((thresh < 0) || (thresh > 9999)) + if ((thresh < 0) || (thresh > 9999)) ProgramFail(NULL, "vscan(): threshold must be between 0 and 9999"); ix = vscan((unsigned char *)SPI_BUFFER1, (unsigned char *)FRAME_BUF, thresh, (unsigned int)col, (unsigned int *)&ScanVect[0]); ReturnValue->Val->Integer = ix; } -void Cvmean(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) +void Cvmean(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { vmean((unsigned char *)FRAME_BUF); Iy1 = mean[0]; @@ -477,7 +477,7 @@ void Cvblob(struct ParseState *Parser, struct Value *ReturnValue, struct Value * iblob = Param[1]->Val->Integer; if (iblob > MAX_BLOBS) ProgramFail(NULL, "blob(): invalid blob index"); - + numblob = vblob((unsigned char *)FRAME_BUF, (unsigned char *)FRAME_BUF3, ix); if ((blobcnt[iblob] == 0) || (numblob == -1)) { @@ -495,14 +495,14 @@ void Cvblob(struct ParseState *Parser, struct Value *ReturnValue, struct Value * void Cvjpeg (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { unsigned int image_size, qual; unsigned char *output_start, *output_end; - + qual = Param[0]->Val->Integer; if ((qual < 1) || (qual > 8)) ProgramFail(NULL, "vjpeg(): quality parameter out of range"); - + output_start = (unsigned char *)JPEG_BUF; - output_end = encode_image((unsigned char *)FRAME_BUF, output_start, qual, - FOUR_TWO_TWO, imgWidth, imgHeight); + output_end = encode_image((unsigned char *)FRAME_BUF, output_start, qual, + FOUR_TWO_TWO, imgWidth, imgHeight); image_size = (unsigned int)(output_end - output_start); ReturnValue->Val->Integer = image_size; @@ -511,15 +511,15 @@ void Cvjpeg (struct ParseState *Parser, struct Value *ReturnValue, struct Value void Cvsend (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { unsigned int ix, image_size; unsigned char *cp; - + image_size = Param[0]->Val->Integer; if ((image_size < 0) || (image_size > 200000)) ProgramFail(NULL, "vsend(): image size out of range"); - + led1_on(); cp = (unsigned char *)JPEG_BUF; - for (ix=0; ixVal->Integer; if ((ix<1) || (ix>3)) ProgramFail(NULL, "tilt(): invalid channel"); @@ -575,7 +575,7 @@ void Ctilt(struct ParseState *Parser, struct Value *ReturnValue, struct Value ** void Canalog(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // return reading from HMC6352 I2C compass { unsigned int ix, channel; - + ix = (unsigned char)Param[0]->Val->Integer; if ((ix<1) || (ix>28)) ProgramFail(NULL, "analog(): invalid channel"); @@ -584,7 +584,7 @@ void Canalog(struct ParseState *Parser, struct Value *ReturnValue, struct Value ProgramFail(NULL, "analog(): invalid channel"); ReturnValue->Val->Integer = analog(ix); } - + /* read analog channel 0-7 from SRV-4WD ( channel 0 = battery level @@ -598,9 +598,9 @@ void Canalog(struct ParseState *Parser, struct Value *ReturnValue, struct Value void Canalogx(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // return reading from HMC6352 I2C compass { int ix; - + ix = (unsigned char)Param[0]->Val->Integer; - if ((ix<0) || (ix>7)) + if ((ix<0) || (ix>7)) ProgramFail(NULL, "analogx(): invalid channel"); ReturnValue->Val->Integer = analog_4wd(ix); } @@ -619,21 +619,21 @@ void Cgps(struct ParseState *Parser, struct Value *ReturnValue, struct Value **P void Creadi2c(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // syntax val = readi2c(device, register); { unsigned char i2c_device, i2c_data[2]; - + i2c_device = (unsigned char)Param[0]->Val->Integer; i2c_data[0] = (unsigned char)Param[1]->Val->Integer; - + i2cread(i2c_device, (unsigned char *)i2c_data, 1, SCCB_OFF); ReturnValue->Val->Integer = ((int)i2c_data[0] & 0x000000FF); } -void Creadi2c2(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // syntax two_byte_val = readi2c(device, register); +void Creadi2c2(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // syntax two_byte_val = readi2c(device, register); { unsigned char i2c_device, i2c_data[2]; i2c_device = (unsigned char)Param[0]->Val->Integer; i2c_data[0] = (unsigned char)Param[1]->Val->Integer; - + i2cread(i2c_device, (unsigned char *)i2c_data, 2, SCCB_OFF); ReturnValue->Val->Integer = (((unsigned int)i2c_data[0] << 8) + i2c_data[1]); } @@ -645,14 +645,14 @@ void Cwritei2c(struct ParseState *Parser, struct Value *ReturnValue, struct Valu i2c_device = (unsigned char)Param[0]->Val->Integer; i2c_data[0] = (unsigned char)Param[1]->Val->Integer; i2c_data[1] = (unsigned char)Param[2]->Val->Integer; - + i2cwrite(i2c_device, (unsigned char *)i2c_data, 1, SCCB_OFF); } void Cabs(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // abs(int) { int ix; - + ix = Param[0]->Val->Integer; // return absolute value of int if (ix < 0) ix = -ix; @@ -661,7 +661,7 @@ void Cabs(struct ParseState *Parser, struct Value *ReturnValue, struct Value **P void Csin(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // sin(angle) { int ix; - + ix = Param[0]->Val->Integer; // input to function is angle in degrees ReturnValue->Val->Integer = sin(ix); } @@ -669,7 +669,7 @@ void Csin(struct ParseState *Parser, struct Value *ReturnValue, struct Value **P void Ccos(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // cos(angle) { int ix; - + ix = Param[0]->Val->Integer; // input to function is angle in degrees ReturnValue->Val->Integer = cos(ix); } @@ -677,7 +677,7 @@ void Ccos(struct ParseState *Parser, struct Value *ReturnValue, struct Value **P void Ctan(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // tan(angle) { int ix; - + ix = Param[0]->Val->Integer; // input to function is angle in degrees ReturnValue->Val->Integer = tan(ix); } @@ -708,7 +708,7 @@ void Catan(struct ParseState *Parser, struct Value *ReturnValue, struct Value ** y = Param[0]->Val->Integer; x = Param[1]->Val->Integer; ReturnValue->Val->Integer = atan(y, x); -} +} void Cgps_head(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // gps_head(lat1, lon1, lat2, lon2) { @@ -718,7 +718,7 @@ void Cgps_head(struct ParseState *Parser, struct Value *ReturnValue, struct Valu lat2 = Param[2]->Val->Integer; lon2 = Param[3]->Val->Integer; ReturnValue->Val->Integer = gps_head(lat1, lon1, lat2, lon2); -} +} void Cgps_dist(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // gps_dist(lat1, lon1, lat2, lon2) { @@ -728,18 +728,18 @@ void Cgps_dist(struct ParseState *Parser, struct Value *ReturnValue, struct Valu lat2 = Param[2]->Val->Integer; lon2 = Param[3]->Val->Integer; ReturnValue->Val->Integer = gps_dist(lat1, lon1, lat2, lon2); -} +} void Csqrt(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) // sqrt(x) { int x; x = Param[0]->Val->Integer; ReturnValue->Val->Integer = isqrt(x); -} +} void Cnnset(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { int ix, i1; - + ix = Param[0]->Val->Integer; if (ix > NUM_NPATTERNS) ProgramFail(NULL, "nnset(): invalid index"); @@ -749,7 +749,7 @@ void Cnnset(struct ParseState *Parser, struct Value *ReturnValue, struct Value * void Cnnshow(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { int ix; - + ix = Param[0]->Val->Integer; if (ix > NUM_NPATTERNS) ProgramFail(NULL, "nnshow(): invalid index"); @@ -767,7 +767,7 @@ void Cnntrain(struct ParseState *Parser, struct Value *ReturnValue, struct Value for (ix=0; ixVal->Integer; @@ -800,9 +800,9 @@ void Cnntest(struct ParseState *Parser, struct Value *ReturnValue, struct Value ReturnValue->Val->Integer = ix; } -void Cnnmatchblob(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { +void Cnnmatchblob(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { int ix, i1, max; - + ix = Param[0]->Val->Integer; if (ix > MAX_BLOBS) ProgramFail(NULL, "nnmatchblob(): invalid blob index"); @@ -812,7 +812,7 @@ void Cnnmatchblob(struct ParseState *Parser, struct Value *ReturnValue, struct V square the aspect ratio of x1, x2, y1, y2 then subsample blob pixels to populate N_IN(0:63) with 0:1024 values then nncalculate_network() and display the N_OUT() results */ - nnscale8x8((unsigned char *)FRAME_BUF3, blobix[ix], blobx1[ix], blobx2[ix], + nnscale8x8((unsigned char *)FRAME_BUF3, blobix[ix], blobx1[ix], blobx2[ix], bloby1[ix], bloby2[ix], imgWidth, imgHeight); nncalculate_network(); ix = 0; @@ -829,13 +829,13 @@ void Cnnmatchblob(struct ParseState *Parser, struct Value *ReturnValue, struct V void Cnnlearnblob (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { int ix; - + ix = Param[0]->Val->Integer; if (ix > NUM_NPATTERNS) ProgramFail(NULL, "nnlearnblob(): invalid index"); if (!blobcnt[0]) ProgramFail(NULL, "nnlearnblob(): no blob to grab"); - nnscale8x8((unsigned char *)FRAME_BUF3, blobix[0], blobx1[0], blobx2[0], + nnscale8x8((unsigned char *)FRAME_BUF3, blobix[0], blobx1[0], blobx2[0], bloby1[0], bloby2[0], imgWidth, imgHeight); nnpack8x8(ix); nndisplay(ix); @@ -844,7 +844,7 @@ void Cnnlearnblob (struct ParseState *Parser, struct Value *ReturnValue, struct void Cautorun (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { int ix, t0; unsigned char ch; - + ix = Param[0]->Val->Integer; t0 = readRTC(); while (readRTC() < (t0 + ix*1000)) { // watch for ESC in 'ix' seconds diff --git a/platform/library_unix.c b/platform/library_unix.c index f95ad3d..c482d8b 100644 --- a/platform/library_unix.c +++ b/platform/library_unix.c @@ -1,16 +1,16 @@ #include "../interpreter.h" 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); 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; } diff --git a/platform/platform_ffox.c b/platform/platform_ffox.c index ea7bd7e..66d5c0d 100644 --- a/platform/platform_ffox.c +++ b/platform/platform_ffox.c @@ -29,7 +29,7 @@ void PlatformPutc(unsigned char OutCh, union OutputStreamInfo *Stream) char *PlatformReadFile(const char *FileName) { // XXX - unimplemented so far - return NULL; + return NULL; } /* read and scan a file for definitions */ diff --git a/platform/platform_msvc.c b/platform/platform_msvc.c index 784058f..dc47bba 100644 --- a/platform/platform_msvc.c +++ b/platform/platform_msvc.c @@ -17,7 +17,7 @@ char *PlatformGetLine(char *Buf, int MaxLen, const char *Prompt) { if (Prompt != NULL) printf("%s", Prompt); - + fflush(stdout); return fgets(Buf, MaxLen, stdin); } @@ -43,25 +43,25 @@ char *PlatformReadFile(Picoc *pc, const char *FileName) FILE *InFile; int BytesRead; char *p; - + if (stat(FileName, &FileInfo)) ProgramFailNoParser(pc, "can't read file %s\n", FileName); - + ReadText = malloc(FileInfo.st_size + 1); if (ReadText == NULL) ProgramFailNoParser(pc, "out of memory\n"); - + InFile = fopen(FileName, "r"); if (InFile == NULL) ProgramFailNoParser(pc, "can't read file %s\n", FileName); - + BytesRead = fread(ReadText, 1, FileInfo.st_size, InFile); if (BytesRead == 0) ProgramFailNoParser(pc, "can't read file %s\n", FileName); ReadText[BytesRead] = '\0'; fclose(InFile); - + if ((ReadText[0] == '#') && (ReadText[1] == '!')) { for (p = ReadText; (*p != '\r') && (*p != '\n'); ++p) @@ -69,8 +69,8 @@ char *PlatformReadFile(Picoc *pc, const char *FileName) *p = ' '; } } - - return ReadText; + + return ReadText; } /* read and scan a file for definitions */ diff --git a/platform/platform_surveyor.c b/platform/platform_surveyor.c index 1557747..4982a6f 100644 --- a/platform/platform_surveyor.c +++ b/platform/platform_surveyor.c @@ -14,12 +14,12 @@ char *PlatformGetLine(char *Buf, int MaxLen, const char *Prompt) { int ix; char ch, *cp; - + printf(Prompt); - + ix = 0; cp = 0; - + // If the first character is \n or \r, eat it ch = getch(); if (ch == '\n' || ch == '\r') @@ -27,7 +27,7 @@ char *PlatformGetLine(char *Buf, int MaxLen, const char *Prompt) // And get the next character ch = getch(); } - + while (ix++ < MaxLen) { if (ch == 0x1B || ch == 0x03) { // ESC character or ctrl-c (to avoid problem with TeraTerm) - exit @@ -51,7 +51,7 @@ void PlatformPutc(unsigned char OutCh, union OutputStreamInfo *Stream) { if (OutCh == '\n') putchar('\r'); - + putchar(OutCh); } diff --git a/platform/platform_unix.c b/platform/platform_unix.c index 50c3119..b09bdf2 100644 --- a/platform/platform_unix.c +++ b/platform/platform_unix.c @@ -45,14 +45,14 @@ char *PlatformGetLine(char *Buf, int MaxLen, const char *Prompt) char *InLine = readline(Prompt); if (InLine == NULL) return NULL; - + Buf[MaxLen-1] = '\0'; strncpy(Buf, InLine, MaxLen-2); strncat(Buf, "\n", MaxLen-2); - + if (InLine[0] != '\0') add_history(InLine); - + free(InLine); return Buf; } @@ -60,7 +60,7 @@ char *PlatformGetLine(char *Buf, int MaxLen, const char *Prompt) if (Prompt != NULL) printf("%s", Prompt); - + fflush(stdout); return fgets(Buf, MaxLen, stdin); } @@ -86,25 +86,25 @@ char *PlatformReadFile(Picoc *pc, const char *FileName) FILE *InFile; int BytesRead; char *p; - + if (stat(FileName, &FileInfo)) ProgramFailNoParser(pc, "can't read file %s\n", FileName); - + ReadText = malloc(FileInfo.st_size + 1); if (ReadText == NULL) ProgramFailNoParser(pc, "out of memory\n"); - + InFile = fopen(FileName, "r"); if (InFile == NULL) ProgramFailNoParser(pc, "can't read file %s\n", FileName); - + BytesRead = fread(ReadText, 1, FileInfo.st_size, InFile); if (BytesRead == 0) ProgramFailNoParser(pc, "can't read file %s\n", FileName); ReadText[BytesRead] = '\0'; fclose(InFile); - + if ((ReadText[0] == '#') && (ReadText[1] == '!')) { for (p = ReadText; (*p != '\r') && (*p != '\n'); ++p) @@ -112,8 +112,8 @@ char *PlatformReadFile(Picoc *pc, const char *FileName) *p = ' '; } } - - return ReadText; + + return ReadText; } /* read and scan a file for definitions */ @@ -122,10 +122,10 @@ void PicocPlatformScanFile(Picoc *pc, const char *FileName) char *SourceStr = PlatformReadFile(pc, FileName); /* ignore "#!/path/to/picoc" .. by replacing the "#!" with "//" */ - if (SourceStr != NULL && SourceStr[0] == '#' && SourceStr[1] == '!') - { - SourceStr[0] = '/'; - SourceStr[1] = '/'; + if (SourceStr != NULL && SourceStr[0] == '#' && SourceStr[1] == '!') + { + SourceStr[0] = '/'; + SourceStr[1] = '/'; } PicocParse(pc, FileName, SourceStr, strlen(SourceStr), TRUE, FALSE, TRUE, TRUE); diff --git a/table.c b/table.c index 748e8f9..50a0dca 100644 --- a/table.c +++ b/table.c @@ -1,6 +1,6 @@ /* picoc hash table module. This hash table code is used for both symbol tables * and the shared string table. */ - + #include "interpreter.h" /* initialise the shared string system */ @@ -16,15 +16,15 @@ static unsigned int TableHash(const char *Key, int Len) unsigned int Hash = Len; int Offset; int Count; - + for (Count = 0, Offset = 8; Count < Len; Count++, Offset+=7) { if (Offset > sizeof(unsigned int) * 8 - 7) Offset -= sizeof(unsigned int) * 8 - 6; - + Hash ^= *Key++ << Offset; } - + return Hash; } @@ -42,24 +42,24 @@ static struct TableEntry *TableSearch(struct Table *Tbl, const char *Key, int *A { struct TableEntry *Entry; int HashValue = ((unsigned long)Key) % Tbl->Size; /* shared strings have unique addresses so we don't need to hash them */ - + for (Entry = Tbl->HashTable[HashValue]; Entry != NULL; Entry = Entry->Next) { if (Entry->p.v.Key == Key) return Entry; /* found */ } - + *AddAt = HashValue; /* didn't find it in the chain */ return NULL; } -/* 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() */ int TableSet(Picoc *pc, struct Table *Tbl, char *Key, struct Value *Val, const char *DeclFileName, int DeclLine, int DeclColumn) { int AddAt; struct TableEntry *FoundEntry = TableSearch(Tbl, Key, &AddAt); - + if (FoundEntry == NULL) { /* add it to the table */ struct TableEntry *NewEntry = VariableAlloc(pc, NULL, sizeof(struct TableEntry), Tbl->OnHeap); @@ -76,7 +76,7 @@ int TableSet(Picoc *pc, struct Table *Tbl, char *Key, struct Value *Val, const c return FALSE; } -/* 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() */ int TableGet(struct Table *Tbl, const char *Key, struct Value **Val, const char **DeclFileName, int *DeclLine, int *DeclColumn) { @@ -84,16 +84,16 @@ int TableGet(struct Table *Tbl, const char *Key, struct Value **Val, const char struct TableEntry *FoundEntry = TableSearch(Tbl, Key, &AddAt); if (FoundEntry == NULL) return FALSE; - + *Val = FoundEntry->p.v.Val; - + if (DeclFileName != NULL) { *DeclFileName = FoundEntry->DeclFileName; *DeclLine = FoundEntry->DeclLine; *DeclColumn = FoundEntry->DeclColumn; } - + return TRUE; } @@ -102,7 +102,7 @@ struct Value *TableDelete(Picoc *pc, struct Table *Tbl, const char *Key) { struct TableEntry **EntryPtr; int HashValue = ((unsigned long)Key) % Tbl->Size; /* shared strings have unique addresses so we don't need to hash them */ - + for (EntryPtr = &Tbl->HashTable[HashValue]; *EntryPtr != NULL; EntryPtr = &(*EntryPtr)->Next) { if ((*EntryPtr)->p.v.Key == Key) @@ -124,13 +124,13 @@ static struct TableEntry *TableSearchIdentifier(struct Table *Tbl, const char *K { struct TableEntry *Entry; int HashValue = TableHash(Key, Len) % Tbl->Size; - + for (Entry = Tbl->HashTable[HashValue]; Entry != NULL; Entry = Entry->Next) { if (strncmp(&Entry->p.Key[0], (char *)Key, Len) == 0 && Entry->p.Key[Len] == '\0') return Entry; /* found */ } - + *AddAt = HashValue; /* didn't find it in the chain */ return NULL; } @@ -140,7 +140,7 @@ char *TableSetIdentifier(Picoc *pc, struct Table *Tbl, const char *Ident, int Id { int AddAt; struct TableEntry *FoundEntry = TableSearchIdentifier(Tbl, Ident, IdentLen, &AddAt); - + if (FoundEntry != NULL) return &FoundEntry->p.Key[0]; else @@ -148,7 +148,7 @@ char *TableSetIdentifier(Picoc *pc, struct Table *Tbl, const char *Ident, int Id struct TableEntry *NewEntry = HeapAllocMem(pc, sizeof(struct TableEntry) - sizeof(union TableEntryPayload) + IdentLen + 1); if (NewEntry == NULL) ProgramFailNoParser(pc, "out of memory"); - + strncpy((char *)&NewEntry->p.Key[0], (char *)Ident, IdentLen); NewEntry->p.Key[IdentLen] = '\0'; NewEntry->Next = Tbl->HashTable[AddAt]; @@ -174,7 +174,7 @@ void TableStrFree(Picoc *pc) struct TableEntry *Entry; struct TableEntry *NextEntry; int Count; - + for (Count = 0; Count < pc->StringTable.Size; Count++) { for (Entry = pc->StringTable.HashTable[Count]; Entry != NULL; Entry = NextEntry) diff --git a/tests/15_recursion.c b/tests/15_recursion.c index 4733c8f..0b66713 100644 --- a/tests/15_recursion.c +++ b/tests/15_recursion.c @@ -1,6 +1,6 @@ #include -int factorial(int i) +int factorial(int i) { if (i < 2) return i; diff --git a/tests/25_quicksort.c b/tests/25_quicksort.c index 724d9c5..cde6dda 100644 --- a/tests/25_quicksort.c +++ b/tests/25_quicksort.c @@ -18,7 +18,7 @@ int partition(int left, int right) int pivotValue = array[pivotIndex]; int index = left; int i; - + swap(pivotIndex, right); for(i = left; i < right; i++) { @@ -29,21 +29,21 @@ int partition(int left, int right) } } swap(right, index); - + return index; } - + //Quicksort the array void quicksort(int left, int right) { if(left >= right) return; - + int index = partition(left, right); quicksort(left, index - 1); quicksort(index + 1, right); } - + void main() { int i; diff --git a/tests/30_hanoi.c b/tests/30_hanoi.c index 5ca6667..b99ac19 100644 --- a/tests/30_hanoi.c +++ b/tests/30_hanoi.c @@ -4,7 +4,7 @@ /* By Terry R. McConnell (12/2/97) */ /* Compile: cc -o hanoi hanoi.c */ -/* This program does no error checking. But then, if it's right, +/* This program does no error checking. But then, if it's right, it's right ... right ? */ @@ -19,7 +19,7 @@ of a smaller one. When the disks have been transferred entirely to another spike the Universe will come to an end in a large thunderclap. This paraphrases the original legend due to DeParville, La Nature, Paris 1884, -Part I, 285-286. For this and further information see: Mathematical +Part I, 285-286. For this and further information see: Mathematical Recreations & Essays, W.W. Rouse Ball, MacMillan, NewYork, 11th Ed. 1967, 303-305. * @@ -33,7 +33,7 @@ Recreations & Essays, W.W. Rouse Ball, MacMillan, NewYork, 11th Ed. 1967, #define FALSE 0 #define N 4 /* This is the number of "disks" on tower A initially. */ - /* Taken to be 64 in the legend. The number of moves + /* Taken to be 64 in the legend. The number of moves required, in general, is 2^N - 1. For N = 64, this is 18,446,744,073,709,551,615 */ @@ -64,7 +64,7 @@ PrintAll() printf("------------------------------------------\n"); return; } - + /* Move the leftmost nonzero element of source to dest, leave behind 0. */ /* Returns the value moved (not used.) */ @@ -97,7 +97,7 @@ Hanoi(int n,int *source, int *dest, int *spare) Hanoi(n-1,source,spare,dest); Move(source,dest); - Hanoi(n-1,spare,dest,source); + Hanoi(n-1,spare,dest,source); return; } @@ -111,7 +111,7 @@ main() for(i=0;i=0;i--){ @@ -259,6 +259,6 @@ int main(int argc, char **argv) printf("%s\n",buf); return 0; - + } #endif diff --git a/tests/47_switch_return.c b/tests/47_switch_return.c index 2fdb8bd..a23ea42 100644 --- a/tests/47_switch_return.c +++ b/tests/47_switch_return.c @@ -8,7 +8,7 @@ void fred(int x) case 2: printf("2\n"); break; case 3: printf("3\n"); return; } - + printf("out\n"); } @@ -17,7 +17,7 @@ int main() fred(1); fred(2); fred(3); - + return 0; -} +} diff --git a/tests/49_bracket_evaluation.c b/tests/49_bracket_evaluation.c index b4303c6..fbb20b4 100644 --- a/tests/49_bracket_evaluation.c +++ b/tests/49_bracket_evaluation.c @@ -11,11 +11,11 @@ struct point point_array[100]; int main() { int my_point = 10; - + point_array[my_point].x = 12.34; point_array[my_point].y = 56.78; - + printf("%f, %f\n", point_array[my_point].x, point_array[my_point].y); - + return 0; } diff --git a/tests/55_array_initialiser.c b/tests/55_array_initialiser.c index 6d3d028..9ed6ec7 100644 --- a/tests/55_array_initialiser.c +++ b/tests/55_array_initialiser.c @@ -4,7 +4,7 @@ int main() { int fred[3] = { 12, 34, 56 }; double joe[] = { 23.4, 56.7, 89.0 }; - + printf("%d %d %d\n", fred[0], fred[1], fred[2]); printf("%f %f %f\n", joe[0], joe[1], joe[2]); diff --git a/tests/57_macro_bug.c b/tests/57_macro_bug.c index 68fb471..9f301ae 100644 --- a/tests/57_macro_bug.c +++ b/tests/57_macro_bug.c @@ -9,9 +9,9 @@ void main() float z; z = MIN(y, 13.5); y = MIN(y, 13); - + float pi = 3.14; int pi_int = pi; - + printf("Macro test: %d %d %f %d \n", x, y, z, pi_int); } diff --git a/tests/59_break_before_loop.c b/tests/59_break_before_loop.c index 2df59c7..f61712b 100644 --- a/tests/59_break_before_loop.c +++ b/tests/59_break_before_loop.c @@ -18,7 +18,7 @@ int main() for (c=0;c<10;c++) printf("c=%d\n",c); } - + printf("\nTest 2\n"); a = 0; c = 0; diff --git a/tests/60_local_vars.c b/tests/60_local_vars.c index e34db00..5fcbcb4 100644 --- a/tests/60_local_vars.c +++ b/tests/60_local_vars.c @@ -25,7 +25,7 @@ void foo() int j = i+1; printf("foo: %d\n", i); } - + while(1) { int i = 5; @@ -54,7 +54,7 @@ void foo() printf("foo: %d\n", j); } } - + float j[10]; } diff --git a/tests/61_initializers.c b/tests/61_initializers.c index 90aefb9..da4844b 100644 --- a/tests/61_initializers.c +++ b/tests/61_initializers.c @@ -144,8 +144,8 @@ int main(int argc, char** argv) printf("soko2=\n"); for (int i = 0; i < 9; i++) printf("%s %c\n", soko2[i], soko2[i][3]); - + func_1(); - + return 0; } diff --git a/tests/63_typedef.c b/tests/63_typedef.c index b5ee053..28e5ec1 100644 --- a/tests/63_typedef.c +++ b/tests/63_typedef.c @@ -30,12 +30,12 @@ void main() uint64_t u64 = 0xFEDCBA98FFFF; char* y = (char*) &x32; - + printf("%d<%ld>\n", x8, sizeof(x8)); printf("%d<%ld>\n", x16, sizeof(x16)); printf("%d<%ld>\n", x32, sizeof(x32)); printf("%ld<%ld>\n", x64, sizeof(x64)); - + printf("%u<%ld>\n", u8, sizeof(x8)); printf("%u<%ld>\n", u16, sizeof(x16)); @@ -43,17 +43,17 @@ void main() printf("%lu<%ld>\n", u64, sizeof(x64)); printf("%d\n", *(int32_t*)y); - + point pt; pt.x = 1; pt.y = 2; - + point pts[2]; pts[0] = pt; pts[1] = pt; - + pt.y = 3; - + point* ptp = (point*) &pts[0]; printf("(%d, %d)\n", pt.x, pt.y); diff --git a/tests/65_typeless.c b/tests/65_typeless.c index 8eae949..4aa2761 100644 --- a/tests/65_typeless.c +++ b/tests/65_typeless.c @@ -12,7 +12,7 @@ void main() printf("%d\n", i); /* this should fail - { + { int q = 5; } q = 3.14; // should say error diff --git a/tests/66_printf_undefined.c b/tests/66_printf_undefined.c index a1723e9..d2e1584 100644 --- a/tests/66_printf_undefined.c +++ b/tests/66_printf_undefined.c @@ -5,7 +5,7 @@ void fred() printf("test\n"); } -void main() +void main() { fred(); } diff --git a/tests/68_return.c b/tests/68_return.c index 46fd7b4..ddbdf99 100644 --- a/tests/68_return.c +++ b/tests/68_return.c @@ -28,7 +28,7 @@ void demo_error() return; } -void main() +void main() { demo_error(); } diff --git a/type.c b/type.c index 21e72db..538e5e9 100644 --- a/type.c +++ b/type.c @@ -1,6 +1,6 @@ /* picoc data type module. This manages a tree of data types and has facilities * for parsing data types. */ - + #include "interpreter.h" /* some basic types */ @@ -23,7 +23,7 @@ struct ValueType *TypeAdd(Picoc *pc, struct ParseState *Parser, struct ValueType NewType->OnHeap = TRUE; NewType->Next = ParentType->DerivedTypeList; ParentType->DerivedTypeList = NewType; - + return NewType; } @@ -36,7 +36,7 @@ struct ValueType *TypeGetMatching(Picoc *pc, struct ParseState *Parser, struct V struct ValueType *ThisType = ParentType->DerivedTypeList; while (ThisType != NULL && (ThisType->Base != Base || ThisType->ArraySize != ArraySize || ThisType->Identifier != Identifier)) ThisType = ThisType->Next; - + if (ThisType != NULL) { if (AllowDuplicates) @@ -44,7 +44,7 @@ struct ValueType *TypeGetMatching(Picoc *pc, struct ParseState *Parser, struct V else ProgramFail(Parser, "data type '%s' is already defined", Identifier); } - + switch (Base) { case TypePointer: Sizeof = sizeof(void *); AlignBytes = PointerAlignBytes; break; @@ -114,10 +114,10 @@ void TypeInit(Picoc *pc) struct DoubleAlign { char x; double y; } da; #endif struct PointerAlign { char x; void *y; } pa; - + IntAlignBytes = (char *)&ia.y - &ia.x; PointerAlignBytes = (char *)&pa.y - &pa.x; - + pc->UberType.DerivedTypeList = NULL; TypeAddBaseType(pc, &pc->IntType, TypeInt, sizeof(int), IntAlignBytes); TypeAddBaseType(pc, &pc->ShortType, TypeShort, sizeof(short), (char *)&sa.y - &sa.x); @@ -148,7 +148,7 @@ void TypeCleanupNode(Picoc *pc, struct ValueType *Typ) { struct ValueType *SubType; struct ValueType *NextSubType; - + /* clean up and free all the sub-nodes */ for (SubType = Typ->DerivedTypeList; SubType != NULL; SubType = NextSubType) { @@ -185,7 +185,7 @@ void TypeParseStruct(struct ParseState *Parser, struct ValueType **Typ, int IsSt enum LexToken Token; int AlignBoundary; Picoc *pc = Parser->pc; - + Token = LexGetToken(Parser, &LexValue, FALSE); if (Token == TokenIdentifier) { @@ -205,42 +205,42 @@ void TypeParseStruct(struct ParseState *Parser, struct ValueType **Typ, int IsSt Token = LexGetToken(Parser, NULL, FALSE); if (Token != TokenLeftBrace) - { + { /* use the already defined structure */ #if 0 if ((*Typ)->Members == NULL) ProgramFail(Parser, "structure '%s' isn't defined", LexValue->Val->Identifier); -#endif +#endif return; } - + if (pc->TopStackFrame != NULL) 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->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 { TypeParse(Parser, &MemberType, &MemberIdentifier, NULL); if (MemberType == NULL || MemberIdentifier == NULL) ProgramFail(Parser, "invalid type in struct"); - + MemberValue = VariableAllocValueAndData(pc, Parser, sizeof(int), FALSE, NULL, TRUE); MemberValue->Typ = MemberType; if (IsStruct) - { + { /* allocate this member's location in the struct */ AlignBoundary = MemberValue->Typ->AlignBytes; if (((*Typ)->Sizeof & (AlignBoundary-1)) != 0) (*Typ)->Sizeof += AlignBoundary - ((*Typ)->Sizeof & (AlignBoundary-1)); - + MemberValue->Val->Integer = (*Typ)->Sizeof; (*Typ)->Sizeof += TypeSizeValue(MemberValue, TRUE); } else - { + { /* union members always start at 0, make sure it's big enough to hold the largest member */ MemberValue->Val->Integer = 0; if (MemberValue->Typ->Sizeof > (*Typ)->Sizeof) @@ -250,21 +250,21 @@ void TypeParseStruct(struct ParseState *Parser, struct ValueType **Typ, int IsSt /* make sure to align to the size of the largest member's alignment */ if ((*Typ)->AlignBytes < MemberValue->Typ->AlignBytes) (*Typ)->AlignBytes = MemberValue->Typ->AlignBytes; - + /* define it */ if (!TableSet(pc, (*Typ)->Members, MemberIdentifier, MemberValue, Parser->FileName, Parser->Line, Parser->CharacterPos)) ProgramFail(Parser, "member '%s' already defined", &MemberIdentifier); - + if (LexGetToken(Parser, NULL, TRUE) != TokenSemicolon) ProgramFail(Parser, "semicolon expected"); - + } while (LexGetToken(Parser, NULL, FALSE) != TokenRightBrace); - + /* now align the structure to the size of its largest member's alignment */ AlignBoundary = (*Typ)->AlignBytes; if (((*Typ)->Sizeof & (AlignBoundary-1)) != 0) (*Typ)->Sizeof += AlignBoundary - ((*Typ)->Sizeof & (AlignBoundary-1)); - + LexGetToken(Parser, NULL, TRUE); } @@ -272,13 +272,13 @@ void TypeParseStruct(struct ParseState *Parser, struct ValueType **Typ, int IsSt 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); - + /* create the (empty) table */ 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)); TableInitTable(Typ->Members, (struct TableEntry **)((char *)Typ->Members + sizeof(struct Table)), STRUCT_TABLE_SIZE, TRUE); Typ->Sizeof = Size; - + return Typ; } @@ -291,7 +291,7 @@ void TypeParseEnum(struct ParseState *Parser, struct ValueType **Typ) int EnumValue = 0; char *EnumIdentifier; Picoc *pc = Parser->pc; - + Token = LexGetToken(Parser, &LexValue, FALSE); if (Token == TokenIdentifier) { @@ -308,18 +308,18 @@ void TypeParseEnum(struct ParseState *Parser, struct ValueType **Typ) TypeGetMatching(pc, Parser, &pc->UberType, TypeEnum, 0, EnumIdentifier, Token != TokenLeftBrace); *Typ = &pc->IntType; if (Token != TokenLeftBrace) - { + { /* use the already defined enum */ if ((*Typ)->Members == NULL) ProgramFail(Parser, "enum '%s' isn't defined", EnumIdentifier); - + return; } - + if (pc->TopStackFrame != NULL) ProgramFail(Parser, "enum definitions can only be globals"); - - LexGetToken(Parser, NULL, TRUE); + + LexGetToken(Parser, NULL, TRUE); (*Typ)->Members = &pc->GlobalTable; memset((void *)&InitValue, '\0', sizeof(struct Value)); InitValue.Typ = &pc->IntType; @@ -327,22 +327,22 @@ void TypeParseEnum(struct ParseState *Parser, struct ValueType **Typ) do { if (LexGetToken(Parser, &LexValue, TRUE) != TokenIdentifier) ProgramFail(Parser, "identifier expected"); - + EnumIdentifier = LexValue->Val->Identifier; if (LexGetToken(Parser, NULL, FALSE) == TokenAssign) { LexGetToken(Parser, NULL, TRUE); EnumValue = ExpressionParseInt(Parser); } - + VariableDefine(pc, Parser, EnumIdentifier, &InitValue, NULL, FALSE); - + Token = LexGetToken(Parser, NULL, TRUE); if (Token != TokenComma && Token != TokenRightBrace) ProgramFail(Parser, "comma expected"); - + EnumValue++; - + } while (Token == TokenComma); } @@ -365,32 +365,32 @@ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ, int *IsSta { if (Token == TokenStaticType) StaticQualifier = TRUE; - + Token = LexGetToken(Parser, &LexerValue, TRUE); } - + if (IsStatic != NULL) *IsStatic = StaticQualifier; - + /* handle signed/unsigned with no trailing type */ if (Token == TokenSignedType || Token == TokenUnsignedType) { enum LexToken FollowToken = LexGetToken(Parser, &LexerValue, FALSE); Unsigned = (Token == TokenUnsignedType); - + if (FollowToken != TokenIntType && FollowToken != TokenLongType && FollowToken != TokenShortType && FollowToken != TokenCharType) { if (Token == TokenUnsignedType) *Typ = &pc->UnsignedIntType; else *Typ = &pc->IntType; - + return TRUE; } - + Token = LexGetToken(Parser, &LexerValue, TRUE); } - + switch (Token) { case TokenIntType: *Typ = Unsigned ? &pc->UnsignedIntType : &pc->IntType; break; @@ -401,21 +401,21 @@ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ, int *IsSta case TokenFloatType: case TokenDoubleType: *Typ = &pc->FPType; break; #endif case TokenVoidType: *Typ = &pc->VoidType; break; - - case TokenStructType: case TokenUnionType: + + case TokenStructType: case TokenUnionType: if (*Typ != NULL) ProgramFail(Parser, "bad type declaration"); - + TypeParseStruct(Parser, Typ, Token == TokenStructType); break; case TokenEnumType: if (*Typ != NULL) ProgramFail(Parser, "bad type declaration"); - + TypeParseEnum(Parser, Typ); break; - + case TokenIdentifier: /* we already know it's a typedef-defined type because we got here */ VariableGet(pc, Parser, LexerValue->Val->Identifier, &VarValue); @@ -424,7 +424,7 @@ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ, int *IsSta default: ParserCopy(Parser, &Before); return FALSE; } - + return TRUE; } @@ -453,10 +453,10 @@ struct ValueType *TypeParseBack(struct ParseState *Parser, struct ValueType *Fro Parser->Mode = RunModeRun; ArraySize = ExpressionParseInt(Parser); Parser->Mode = OldMode; - + if (LexGetToken(Parser, NULL, TRUE) != TokenRightSquareBracket) ProgramFail(Parser, "']' expected"); - + return TypeGetMatching(Parser->pc, Parser, TypeParseBack(Parser, FromType), TypeArray, ArraySize, Parser->pc->StrEmpty, TRUE); } } @@ -477,7 +477,7 @@ void TypeParseIdentPart(struct ParseState *Parser, struct ValueType *BasicTyp, s int Done = FALSE; *Typ = BasicTyp; *Identifier = Parser->pc->StrEmpty; - + while (!Done) { ParserCopy(&Before, Parser); @@ -487,36 +487,36 @@ void TypeParseIdentPart(struct ParseState *Parser, struct ValueType *BasicTyp, s case TokenOpenBracket: if (*Typ != NULL) ProgramFail(Parser, "bad type declaration"); - + TypeParse(Parser, Typ, Identifier, NULL); if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) ProgramFail(Parser, "')' expected"); break; - + case TokenAsterisk: if (*Typ == NULL) ProgramFail(Parser, "bad type declaration"); *Typ = TypeGetMatching(Parser->pc, Parser, *Typ, TypePointer, 0, Parser->pc->StrEmpty, TRUE); break; - + case TokenIdentifier: if (*Typ == NULL || *Identifier != Parser->pc->StrEmpty) ProgramFail(Parser, "bad type declaration"); - + *Identifier = LexValue->Val->Identifier; Done = TRUE; break; - + default: ParserCopy(Parser, &Before); Done = TRUE; break; } } - + if (*Typ == NULL) ProgramFail(Parser, "bad type declaration"); if (*Identifier != Parser->pc->StrEmpty) - { + { /* parse stuff after the identifier */ *Typ = TypeParseBack(Parser, *Typ); } @@ -526,7 +526,7 @@ void TypeParseIdentPart(struct ParseState *Parser, struct ValueType *BasicTyp, s void TypeParse(struct ParseState *Parser, struct ValueType **Typ, char **Identifier, int *IsStatic) { struct ValueType *BasicType; - + TypeParseFront(Parser, &BasicType, IsStatic); TypeParseIdentPart(Parser, BasicType, Typ, Identifier); } @@ -536,9 +536,9 @@ int TypeIsForwardDeclared(struct ParseState *Parser, struct ValueType *Typ) { if (Typ->Base == TypeArray) return TypeIsForwardDeclared(Parser, Typ->FromType); - + if ( (Typ->Base == TypeStruct || Typ->Base == TypeUnion) && Typ->Members == NULL) return TRUE; - + return FALSE; } diff --git a/variable.c b/variable.c index d2b6566..a69b4ff 100644 --- a/variable.c +++ b/variable.c @@ -1,6 +1,6 @@ /* picoc variable storage. This provides ways of defining and accessing * variables */ - + #include "interpreter.h" /* maximum size of a value to temporarily copy while we create a variable */ @@ -44,14 +44,14 @@ void VariableTableCleanup(Picoc *pc, struct Table *HashTable) struct TableEntry *Entry; struct TableEntry *NextEntry; int Count; - + for (Count = 0; Count < HashTable->Size; Count++) { for (Entry = HashTable->HashTable[Count]; Entry != NULL; Entry = NextEntry) { NextEntry = Entry->Next; VariableFree(pc, Entry->p.v.Val); - + /* free the hash table entry */ HeapFreeMem(pc, Entry); } @@ -68,20 +68,20 @@ void VariableCleanup(Picoc *pc) void *VariableAlloc(Picoc *pc, struct ParseState *Parser, int Size, int OnHeap) { void *NewValue; - + if (OnHeap) NewValue = HeapAllocMem(pc, Size); else NewValue = HeapAllocStack(pc, Size); - + if (NewValue == NULL) ProgramFail(Parser, "out of memory"); - + #ifdef DEBUG_HEAP if (!OnHeap) printf("pushing %d at 0x%lx\n", Size, (unsigned long)NewValue); #endif - + return NewValue; } @@ -95,11 +95,11 @@ struct Value *VariableAllocValueAndData(Picoc *pc, struct ParseState *Parser, in NewValue->ValOnStack = !OnHeap; NewValue->IsLValue = IsLValue; NewValue->LValueFrom = LValueFrom; - if (Parser) + if (Parser) NewValue->ScopeID = Parser->ScopeID; NewValue->OutOfScope = 0; - + return NewValue; } @@ -110,7 +110,7 @@ struct Value *VariableAllocValueFromType(Picoc *pc, struct ParseState *Parser, s struct Value *NewValue = VariableAllocValueAndData(pc, Parser, Size, IsLValue, LValueFrom, OnHeap); assert(Size >= 0 || Typ == &pc->VoidType); NewValue->Typ = Typ; - + return NewValue; } @@ -127,7 +127,7 @@ struct Value *VariableAllocValueAndCopy(Picoc *pc, struct ParseState *Parser, st NewValue = VariableAllocValueAndData(pc, Parser, CopySize, FromValue->IsLValue, FromValue->LValueFrom, OnHeap); NewValue->Typ = DType; memcpy((void *)NewValue->Val, (void *)&TmpBuf[0], CopySize); - + return NewValue; } @@ -142,7 +142,7 @@ struct Value *VariableAllocValueFromExistingData(struct ParseState *Parser, stru NewValue->ValOnStack = FALSE; NewValue->IsLValue = IsLValue; NewValue->LValueFrom = LValueFrom; - + return NewValue; } @@ -157,7 +157,7 @@ void VariableRealloc(struct ParseState *Parser, struct Value *FromValue, int New { if (FromValue->AnyValOnHeap) HeapFreeMem(Parser->pc, FromValue->Val); - + FromValue->Val = VariableAlloc(Parser->pc, Parser, NewSize, TRUE); FromValue->AnyValOnHeap = TRUE; } @@ -171,7 +171,7 @@ int VariableScopeBegin(struct ParseState * Parser, int* OldScopeID) #ifdef VAR_SCOPE_DEBUG int FirstPrint = 0; #endif - + struct Table * HashTable = (pc->TopStackFrame == NULL) ? &(pc->GlobalTable) : &(pc->TopStackFrame)->LocalTable; if (Parser->ScopeID == -1) return -1; @@ -181,7 +181,7 @@ int VariableScopeBegin(struct ParseState * Parser, int* OldScopeID) Parser->ScopeID = (int)(intptr_t)(Parser->SourceText) * ((int)(intptr_t)(Parser->Pos) / sizeof(char*)); /* or maybe a more human-readable hash for debugging? */ /* Parser->ScopeID = Parser->Line * 0x10000 + Parser->CharacterPos; */ - + for (Count = 0; Count < HashTable->Size; Count++) { for (Entry = HashTable->HashTable[Count]; Entry != NULL; Entry = NextEntry) @@ -260,24 +260,24 @@ struct Value *VariableDefine(Picoc *pc, struct ParseState *Parser, char *Ident, { struct Value * AssignValue; struct Table * currentTable = (pc->TopStackFrame == NULL) ? &(pc->GlobalTable) : &(pc->TopStackFrame)->LocalTable; - + int ScopeID = Parser ? Parser->ScopeID : -1; #ifdef VAR_SCOPE_DEBUG if (Parser) fprintf(stderr, "def %s %x (%s:%d:%d)\n", Ident, ScopeID, Parser->FileName, Parser->Line, Parser->CharacterPos); #endif - + if (InitValue != NULL) AssignValue = VariableAllocValueAndCopy(pc, Parser, InitValue, pc->TopStackFrame == NULL); else AssignValue = VariableAllocValueFromType(pc, Parser, Typ, MakeWritable, NULL, pc->TopStackFrame == NULL); - + AssignValue->IsLValue = MakeWritable; AssignValue->ScopeID = ScopeID; AssignValue->OutOfScope = FALSE; if (!TableSet(pc, currentTable, Ident, AssignValue, Parser ? ((char *)Parser->FileName) : NULL, Parser ? Parser->Line : 0, Parser ? Parser->CharacterPos : 0)) ProgramFail(Parser, "'%s' is already defined", Ident); - + return AssignValue; } @@ -289,7 +289,7 @@ struct Value *VariableDefineButIgnoreIdentical(struct ParseState *Parser, char * const char *DeclFileName; int DeclLine; int DeclColumn; - + /* is the type a forward declaration? */ if (TypeIsForwardDeclared(Parser, Typ)) ProgramFail(Parser, "type '%t' isn't defined", Typ); @@ -300,13 +300,13 @@ struct Value *VariableDefineButIgnoreIdentical(struct ParseState *Parser, char * char *MNPos = &MangledName[0]; char *MNEnd = &MangledName[LINEBUFFER_MAX-1]; const char *RegisteredMangledName; - + /* make the mangled static name (avoiding using sprintf() to minimise library impact) */ memset((void *)&MangledName, '\0', sizeof(MangledName)); *MNPos++ = '/'; strncpy(MNPos, (char *)Parser->FileName, MNEnd - MNPos); MNPos += strlen(MNPos); - + if (pc->TopStackFrame != NULL) { /* we're inside a function */ @@ -314,11 +314,11 @@ struct Value *VariableDefineButIgnoreIdentical(struct ParseState *Parser, char * strncpy(MNPos, (char *)pc->TopStackFrame->FuncName, MNEnd - MNPos); MNPos += strlen(MNPos); } - + if (MNEnd - MNPos > 0) *MNPos++ = '/'; strncpy(MNPos, Ident, MNEnd - MNPos); RegisteredMangledName = TableStrRegister(pc, MangledName); - + /* is this static already defined? */ if (!TableGet(&pc->GlobalTable, RegisteredMangledName, &ExistingValue, &DeclFileName, &DeclLine, &DeclColumn)) { @@ -346,7 +346,7 @@ struct Value *VariableDefineButIgnoreIdentical(struct ParseState *Parser, char * int VariableDefined(Picoc *pc, const char *Ident) { struct Value *FoundValue; - + if (pc->TopStackFrame == NULL || !TableGet(&pc->TopStackFrame->LocalTable, Ident, &FoundValue, NULL, NULL, NULL)) { if (!TableGet(&pc->GlobalTable, Ident, &FoundValue, NULL, NULL, NULL)) @@ -377,7 +377,7 @@ void VariableDefinePlatformVar(Picoc *pc, struct ParseState *Parser, char *Ident struct Value *SomeValue = VariableAllocValueAndData(pc, NULL, 0, IsWritable, NULL, TRUE); SomeValue->Typ = Typ; SomeValue->Val = FromValue; - + if (!TableSet(pc, (pc->TopStackFrame == NULL) ? &pc->GlobalTable : &pc->TopStackFrame->LocalTable, TableStrRegister(pc, Ident), SomeValue, Parser ? Parser->FileName : NULL, Parser ? Parser->Line : 0, Parser ? Parser->CharacterPos : 0)) ProgramFail(Parser, "'%s' is already defined", Ident); } @@ -386,24 +386,24 @@ void VariableDefinePlatformVar(Picoc *pc, struct ParseState *Parser, char *Ident void VariableStackPop(struct ParseState *Parser, struct Value *Var) { int Success; - + #ifdef DEBUG_HEAP if (Var->ValOnStack) printf("popping %ld at 0x%lx\n", (unsigned long)(sizeof(struct Value) + TypeSizeValue(Var, FALSE)), (unsigned long)Var); #endif - + if (Var->ValOnHeap) - { + { if (Var->Val != NULL) HeapFreeMem(Parser->pc, Var->Val); - + Success = HeapPopStack(Parser->pc, Var, sizeof(struct Value)); /* free from heap */ } else if (Var->ValOnStack) Success = HeapPopStack(Parser->pc, Var, sizeof(struct Value) + TypeSizeValue(Var, FALSE)); /* free from stack */ else Success = HeapPopStack(Parser->pc, Var, sizeof(struct Value)); /* value isn't our problem */ - + if (!Success) ProgramFail(Parser, "stack underrun"); } @@ -412,12 +412,12 @@ void VariableStackPop(struct ParseState *Parser, struct Value *Var) void VariableStackFrameAdd(struct ParseState *Parser, const char *FuncName, int NumParams) { struct StackFrame *NewFrame; - + HeapPushStackFrame(Parser->pc); NewFrame = HeapAllocStack(Parser->pc, sizeof(struct StackFrame) + sizeof(struct Value *) * NumParams); if (NewFrame == NULL) ProgramFail(Parser, "out of memory"); - + ParserCopy(&NewFrame->ReturnParser, Parser); NewFrame->FuncName = FuncName; NewFrame->Parameter = (NumParams > 0) ? ((void *)((char *)NewFrame + sizeof(struct StackFrame))) : NULL; @@ -431,7 +431,7 @@ void VariableStackFramePop(struct ParseState *Parser) { if (Parser->pc->TopStackFrame == NULL) ProgramFail(Parser, "stack is empty - can't go back"); - + ParserCopy(Parser, &Parser->pc->TopStackFrame->ReturnParser); Parser->pc->TopStackFrame = Parser->pc->TopStackFrame->PreviousStackFrame; HeapPopStackFrame(Parser->pc); @@ -459,13 +459,13 @@ void *VariableDereferencePointer(struct ParseState *Parser, struct Value *Pointe { if (DerefVal != NULL) *DerefVal = NULL; - + if (DerefType != NULL) *DerefType = PointerValue->Typ->FromType; - + if (DerefOffset != NULL) *DerefOffset = 0; - + if (DerefIsLValue != NULL) *DerefIsLValue = TRUE;