From a61bd97d9bd917bcd57c3e050b8da3a69eb37f36 Mon Sep 17 00:00:00 2001 From: Joseph Poirier Date: Sat, 6 Jun 2015 23:40:08 -0500 Subject: [PATCH] formatting --- clibrary.c | 235 +++++----- debug.c | 42 +- expression.c | 1273 ++++++++++++++++++++++---------------------------- heap.c | 77 ++- include.c | 30 +- lex.c | 525 +++++++++------------ parse.c | 850 ++++++++++++++------------------- picoc.c | 36 +- platform.c | 72 ++- table.c | 66 ++- type.c | 280 +++++------ variable.c | 153 +++--- 12 files changed, 1574 insertions(+), 2065 deletions(-) diff --git a/clibrary.c b/clibrary.c index d6ca7ca..ef16493 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,10 +37,9 @@ 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++) - { + for (Count = 0; FuncList[Count].Prototype != NULL; Count++) { Tokens = LexAnalyse(pc, IntrinsicName, FuncList[Count].Prototype, strlen((char *)FuncList[Count].Prototype), NULL); LexInitParser(&Parser, pc, FuncList[Count].Prototype, Tokens, IntrinsicName, TRUE, FALSE); TypeParse(&Parser, &ReturnType, &Identifier, NULL); @@ -53,42 +52,41 @@ void LibraryAdd(Picoc *pc, struct Table *GlobalTable, const char *LibraryName, s /* print a type to a stream without using printf/sprintf */ void PrintType(struct ValueType *Typ, IOFILE *Stream) { - switch (Typ->Base) - { - case TypeVoid: PrintStr("void", Stream); break; - case TypeInt: PrintStr("int", Stream); break; - case TypeShort: PrintStr("short", Stream); break; - case TypeChar: PrintStr("char", Stream); break; - case TypeLong: PrintStr("long", Stream); break; - case TypeUnsignedInt: PrintStr("unsigned int", Stream); break; - case TypeUnsignedShort: PrintStr("unsigned short", Stream); break; - case TypeUnsignedLong: PrintStr("unsigned long", Stream); break; - case TypeUnsignedChar: PrintStr("unsigned char", Stream); break; + switch (Typ->Base) { + case TypeVoid: PrintStr("void", Stream); break; + case TypeInt: PrintStr("int", Stream); break; + case TypeShort: PrintStr("short", Stream); break; + case TypeChar: PrintStr("char", Stream); break; + case TypeLong: PrintStr("long", Stream); break; + case TypeUnsignedInt: PrintStr("unsigned int", Stream); break; + case TypeUnsignedShort: PrintStr("unsigned short", Stream); break; + case TypeUnsignedLong: PrintStr("unsigned long", Stream); break; + case TypeUnsignedChar: PrintStr("unsigned char", Stream); break; #ifndef NO_FP - case TypeFP: PrintStr("double", Stream); break; + case TypeFP: PrintStr("double", Stream); break; #endif - case TypeFunction: PrintStr("function", Stream); break; - case TypeMacro: PrintStr("macro", Stream); break; - case TypePointer: if (Typ->FromType) PrintType(Typ->FromType, Stream); PrintCh('*', Stream); break; - case TypeArray: PrintType(Typ->FromType, Stream); PrintCh('[', Stream); if (Typ->ArraySize != 0) PrintSimpleInt(Typ->ArraySize, Stream); PrintCh(']', Stream); break; - case TypeStruct: PrintStr("struct ", Stream); PrintStr( Typ->Identifier, Stream); break; - case TypeUnion: PrintStr("union ", Stream); PrintStr(Typ->Identifier, Stream); break; - case TypeEnum: PrintStr("enum ", Stream); PrintStr(Typ->Identifier, Stream); break; - case TypeGotoLabel: PrintStr("goto label ", Stream); break; - case Type_Type: PrintStr("type ", Stream); break; + case TypeFunction: PrintStr("function", Stream); break; + case TypeMacro: PrintStr("macro", Stream); break; + case TypePointer: if (Typ->FromType) PrintType(Typ->FromType, Stream); PrintCh('*', Stream); break; + case TypeArray: PrintType(Typ->FromType, Stream); PrintCh('[', Stream); if (Typ->ArraySize != 0) PrintSimpleInt(Typ->ArraySize, Stream); PrintCh(']', Stream); break; + case TypeStruct: PrintStr("struct ", Stream); PrintStr( Typ->Identifier, Stream); break; + case TypeUnion: PrintStr("union ", Stream); PrintStr(Typ->Identifier, Stream); break; + case TypeEnum: PrintStr("enum ", Stream); PrintStr(Typ->Identifier, Stream); break; + case TypeGotoLabel: PrintStr("goto label ", Stream); break; + case Type_Type: PrintStr("type ", Stream); break; } } #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,22 +141,21 @@ void PrintUnsigned(unsigned long Num, unsigned int Base, int FieldWidth, int Zer Result[--ResPos] = '\0'; if (Num == 0) Result[--ResPos] = '0'; - - while (Num > 0) - { + + while (Num > 0) { unsigned long NextNum = Num / Base; unsigned long Digit = Num - NextNum * Base; if (Digit < 10) Result[--ResPos] = '0' + Digit; else Result[--ResPos] = 'a' + Digit - 10; - + Num = NextNum; } - + if (FieldWidth > 0 && !LeftJustify) PrintRepeatedChar(ZeroPad ? '0' : ' ', FieldWidth - (sizeof(Result) - 1 - ResPos), Stream); - + PrintStr(&Result[ResPos], Stream); if (FieldWidth > 0 && LeftJustify) @@ -174,14 +171,13 @@ void PrintSimpleInt(long Num, struct OutputStream *Stream) /* print an integer to a stream without using printf/sprintf */ void PrintInt(long Num, int FieldWidth, int ZeroPad, int LeftJustify, struct OutputStream *Stream) { - if (Num < 0) - { + if (Num < 0) { PrintCh('-', Stream); Num = -Num; if (FieldWidth != 0) FieldWidth--; } - + PrintUnsigned((unsigned long)Num, 10, FieldWidth, ZeroPad, LeftJustify, Stream); } @@ -191,32 +187,29 @@ void PrintFP(double Num, struct OutputStream *Stream) { int Exponent = 0; int MaxDecimal; - - if (Num < 0) - { + + 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; - if (abs(Num) >= 1e-7) - { + if (abs(Num) >= 1e-7) { for (MaxDecimal = 6; MaxDecimal > 0 && abs(Num) >= 1e-7; Num = (Num - (long)(Num + 1e-7)) * 10, MaxDecimal--) PrintCh('0' + (long)(Num + 1e-7), Stream); - } - else + } else { PrintCh('0', Stream); - - if (Exponent != 0) - { + } + + if (Exponent != 0) { PrintCh('e', Stream); PrintInt(Exponent, 0, FALSE, FALSE, Stream); } @@ -234,88 +227,79 @@ 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 == '%') - { + + for (FPos = Format; *FPos != '\0'; FPos++) { + if (*FPos == '%') { FPos++; - FieldWidth = 0; - if (*FPos == '-') - { + FieldWidth = 0; + if (*FPos == '-') { /* a leading '-' means left justify */ LeftJustify = TRUE; FPos++; } - - if (*FPos == '0') - { + + if (*FPos == '0') { /* a leading zero means zero pad a decimal number */ ZeroPad = TRUE; FPos++; } - + /* get any field width in the format */ while (isdigit((int)*FPos)) FieldWidth = FieldWidth * 10 + (*FPos++ - '0'); - + /* now check the format type */ - switch (*FPos) - { - case 's': FormatType = CharPtrType; break; - case 'd': case 'u': case 'x': case 'b': case 'c': FormatType = &IntType; break; + switch (*FPos) { + case 's': FormatType = CharPtrType; break; + case 'd': case 'u': case 'x': case 'b': case 'c': FormatType = &IntType; break; #ifndef NO_FP - case 'f': FormatType = &FPType; break; + case 'f': FormatType = &FPType; break; #endif - case '%': PrintCh('%', Stream); FormatType = NULL; break; - case '\0': FPos--; FormatType = NULL; break; - default: PrintCh(*FPos, Stream); FormatType = NULL; break; + case '%': PrintCh('%', Stream); FormatType = NULL; break; + case '\0': FPos--; FormatType = NULL; break; + default: PrintCh(*FPos, Stream); FormatType = NULL; break; } - - if (FormatType != NULL) - { + + if (FormatType != NULL) { /* we have to format something */ if (ArgCount >= NumArgs) PrintStr("XXX", Stream); /* not enough parameters for format */ - else - { + 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 - { - switch (*FPos) - { - case 's': + else { + switch (*FPos) { + case 's': { char *Str; - + if (NextArg->Typ->Base == TypePointer) Str = NextArg->Val->Pointer; else Str = &NextArg->Val->ArrayMem[0]; - + if (Str == NULL) - PrintStr("NULL", Stream); + PrintStr("NULL", Stream); else - PrintStr(Str, Stream); + PrintStr(Str, Stream); break; } - case 'd': PrintInt(ExpressionCoerceInteger(NextArg), FieldWidth, ZeroPad, LeftJustify, Stream); break; - case 'u': PrintUnsigned(ExpressionCoerceUnsignedInteger(NextArg), 10, FieldWidth, ZeroPad, LeftJustify, Stream); break; - case 'x': PrintUnsigned(ExpressionCoerceUnsignedInteger(NextArg), 16, FieldWidth, ZeroPad, LeftJustify, Stream); break; - case 'b': PrintUnsigned(ExpressionCoerceUnsignedInteger(NextArg), 2, FieldWidth, ZeroPad, LeftJustify, Stream); break; - case 'c': PrintCh(ExpressionCoerceUnsignedInteger(NextArg), Stream); break; + case 'd': PrintInt(ExpressionCoerceInteger(NextArg), FieldWidth, ZeroPad, LeftJustify, Stream); break; + case 'u': PrintUnsigned(ExpressionCoerceUnsignedInteger(NextArg), 10, FieldWidth, ZeroPad, LeftJustify, Stream); break; + case 'x': PrintUnsigned(ExpressionCoerceUnsignedInteger(NextArg), 16, FieldWidth, ZeroPad, LeftJustify, Stream); break; + case 'b': PrintUnsigned(ExpressionCoerceUnsignedInteger(NextArg), 2, FieldWidth, ZeroPad, LeftJustify, Stream); break; + case 'c': PrintCh(ExpressionCoerceUnsignedInteger(NextArg), Stream); break; #ifndef NO_FP - case 'f': PrintFP(ExpressionCoerceFP(NextArg), Stream); break; + case 'f': PrintFP(ExpressionCoerceFP(NextArg), Stream); break; #endif } } } - + ArgCount++; } } @@ -328,7 +312,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 +321,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; @@ -351,8 +335,7 @@ void LibSPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Val void LibGets(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Pointer = PlatformGetLine(Param[0]->Val->Pointer, GETS_BUF_MAX, NULL); - if (ReturnValue->Val->Pointer != NULL) - { + if (ReturnValue->Val->Pointer != NULL) { char *EOLPos = strchr(Param[0]->Val->Pointer, '\n'); if (EOLPos != NULL) *EOLPos = '\0'; @@ -490,10 +473,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 +485,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 +498,12 @@ 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; } + + for (StrEnded = FALSE; !StrEnded; StrEnded = (*Str1 == '\0' || *Str2 == '\0'), Str1++, Str2++) { + if (*Str1 < *Str2) { ReturnValue->Val->Integer = -1; return; } else if (*Str1 > *Str2) { ReturnValue->Val->Integer = 1; return; } } - + ReturnValue->Val->Integer = 0; } @@ -531,13 +513,12 @@ 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; } + + for (StrEnded = FALSE; !StrEnded && Len > 0; StrEnded = (*Str1 == '\0' || *Str2 == '\0'), Str1++, Str2++, Len--) { + if (*Str1 < *Str2) { ReturnValue->Val->Integer = -1; return; } else if (*Str1 > *Str2) { ReturnValue->Val->Integer = 1; return; } } - + ReturnValue->Val->Integer = 0; } @@ -545,13 +526,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 +543,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 @@ -575,8 +556,7 @@ void LibRindex(struct ParseState *Parser, struct Value *ReturnValue, struct Valu int SearchChar = Param[1]->Val->Integer; ReturnValue->Val->Pointer = NULL; - for (; *Pos != '\0'; Pos++) - { + for (; *Pos != '\0'; Pos++) { if (*Pos == SearchChar) ReturnValue->Val->Pointer = Pos; } @@ -586,10 +566,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 +590,12 @@ 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; } + + for (; Len > 0; Mem1++, Mem2++, Len--) { + if (*Mem1 < *Mem2) { ReturnValue->Val->Integer = -1; return; } else if (*Mem1 > *Mem2) { ReturnValue->Val->Integer = 1; return; } } - + ReturnValue->Val->Integer = 0; } #endif diff --git a/debug.c b/debug.c index 6e83be9..b76bf5f 100644 --- a/debug.c +++ b/debug.c @@ -19,11 +19,9 @@ void DebugCleanup(Picoc *pc) struct TableEntry *Entry; struct TableEntry *NextEntry; int Count; - - for (Count = 0; Count < pc->BreakpointTable.Size; Count++) - { - for (Entry = pc->BreakpointHashTable[Count]; Entry != NULL; Entry = NextEntry) - { + + for (Count = 0; Count < pc->BreakpointTable.Size; Count++) { + for (Entry = pc->BreakpointHashTable[Count]; Entry != NULL; Entry = NextEntry) { NextEntry = Entry->Next; HeapFreeMem(pc, Entry); } @@ -36,13 +34,12 @@ static struct TableEntry *DebugTableSearchBreakpoint(struct ParseState *Parser, struct TableEntry *Entry; Picoc *pc = Parser->pc; int HashValue = BREAKPOINT_HASH(Parser) % pc->BreakpointTable.Size; - - for (Entry = pc->BreakpointHashTable[HashValue]; Entry != NULL; Entry = Entry->Next) - { + + for (Entry = pc->BreakpointHashTable[HashValue]; Entry != NULL; Entry = Entry->Next) { if (Entry->p.b.FileName == Parser->FileName && Entry->p.b.Line == Parser->Line && Entry->p.b.CharacterPos == Parser->CharacterPos) return Entry; /* found */ } - + *AddAt = HashValue; /* didn't find it in the chain */ return NULL; } @@ -53,14 +50,13 @@ void DebugSetBreakpoint(struct ParseState *Parser) int AddAt; struct TableEntry *FoundEntry = DebugTableSearchBreakpoint(Parser, &AddAt); Picoc *pc = Parser->pc; - - if (FoundEntry == NULL) - { + + if (FoundEntry == NULL) { /* add it to the table */ struct TableEntry *NewEntry = HeapAllocMem(pc, sizeof(struct TableEntry)); if (NewEntry == NULL) ProgramFailNoParser(pc, "out of memory"); - + NewEntry->p.b.FileName = Parser->FileName; NewEntry->p.b.Line = Parser->Line; NewEntry->p.b.CharacterPos = Parser->CharacterPos; @@ -76,12 +72,10 @@ int DebugClearBreakpoint(struct ParseState *Parser) struct TableEntry **EntryPtr; Picoc *pc = Parser->pc; int HashValue = BREAKPOINT_HASH(Parser) % pc->BreakpointTable.Size; - - for (EntryPtr = &pc->BreakpointHashTable[HashValue]; *EntryPtr != NULL; EntryPtr = &(*EntryPtr)->Next) - { + + for (EntryPtr = &pc->BreakpointHashTable[HashValue]; *EntryPtr != NULL; EntryPtr = &(*EntryPtr)->Next) { struct TableEntry *DeleteEntry = *EntryPtr; - if (DeleteEntry->p.b.FileName == Parser->FileName && DeleteEntry->p.b.Line == Parser->Line && DeleteEntry->p.b.CharacterPos == Parser->CharacterPos) - { + if (DeleteEntry->p.b.FileName == Parser->FileName && DeleteEntry->p.b.Line == Parser->Line && DeleteEntry->p.b.CharacterPos == Parser->CharacterPos) { *EntryPtr = DeleteEntry->Next; HeapFreeMem(pc, DeleteEntry); pc->BreakpointCount--; @@ -99,22 +93,20 @@ void DebugCheckStatement(struct ParseState *Parser) int DoBreak = FALSE; int AddAt; Picoc *pc = Parser->pc; - + /* has the user manually pressed break? */ - if (pc->DebugManualBreak) - { + if (pc->DebugManualBreak) { PlatformPrintf(pc->CStdOut, "break\n"); DoBreak = TRUE; pc->DebugManualBreak = FALSE; } - + /* is this a breakpoint location? */ if (Parser->pc->BreakpointCount != 0 && DebugTableSearchBreakpoint(Parser, &AddAt) != NULL) DoBreak = TRUE; - + /* handle a break */ - if (DoBreak) - { + if (DoBreak) { PlatformPrintf(pc->CStdOut, "Handling a break\n"); PicocParseInteractiveNoStartPrompt(pc, FALSE); } diff --git a/expression.c b/expression.c index 60de722..219236a 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,61 +82,56 @@ 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) - { + + 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; - case TypeInt: printf("%d:int", StackTop->Val->Val->Integer); break; - case TypeShort: printf("%d:short", StackTop->Val->Val->ShortInteger); break; - case TypeChar: printf("%d:char", StackTop->Val->Val->Character); break; - case TypeLong: printf("%ld:long", StackTop->Val->Val->LongInteger); break; - case TypeUnsignedShort: printf("%d:unsigned short", StackTop->Val->Val->UnsignedShortInteger); break; - case TypeUnsignedInt: printf("%d:unsigned int", StackTop->Val->Val->UnsignedInteger); break; - case TypeUnsignedLong: printf("%ld:unsigned long", StackTop->Val->Val->UnsignedLongInteger); break; - case TypeFP: printf("%f:fp", StackTop->Val->Val->FP); break; - case TypeFunction: printf("%s:function", StackTop->Val->Val->Identifier); break; - case TypeMacro: printf("%s:macro", StackTop->Val->Val->Identifier); break; - case TypePointer: - if (StackTop->Val->Val->Pointer == NULL) - printf("ptr(NULL)"); - 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); - break; - case TypeArray: printf("array"); break; - case TypeStruct: printf("%s:struct", StackTop->Val->Val->Identifier); break; - case TypeUnion: printf("%s:union", StackTop->Val->Val->Identifier); break; - case TypeEnum: printf("%s:enum", StackTop->Val->Val->Identifier); break; - case Type_Type: PrintType(StackTop->Val->Val->Typ, pc->CStdOut); printf(":type"); break; - default: printf("unknown"); break; + + switch (StackTop->Val->Typ->Base) { + case TypeVoid: printf("void"); break; + case TypeInt: printf("%d:int", StackTop->Val->Val->Integer); break; + case TypeShort: printf("%d:short", StackTop->Val->Val->ShortInteger); break; + case TypeChar: printf("%d:char", StackTop->Val->Val->Character); break; + case TypeLong: printf("%ld:long", StackTop->Val->Val->LongInteger); break; + case TypeUnsignedShort: printf("%d:unsigned short", StackTop->Val->Val->UnsignedShortInteger); break; + case TypeUnsignedInt: printf("%d:unsigned int", StackTop->Val->Val->UnsignedInteger); break; + case TypeUnsignedLong: printf("%ld:unsigned long", StackTop->Val->Val->UnsignedLongInteger); break; + case TypeFP: printf("%f:fp", StackTop->Val->Val->FP); break; + case TypeFunction: printf("%s:function", StackTop->Val->Val->Identifier); break; + case TypeMacro: printf("%s:macro", StackTop->Val->Val->Identifier); break; + case TypePointer: + if (StackTop->Val->Val->Pointer == NULL) + printf("ptr(NULL)"); + 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); + break; + case TypeArray: printf("array"); break; + case TypeStruct: printf("%s:struct", StackTop->Val->Val->Identifier); break; + case TypeUnion: printf("%s:union", StackTop->Val->Val->Identifier); break; + case TypeEnum: printf("%s:enum", StackTop->Val->Val->Identifier); break; + case Type_Type: PrintType(StackTop->Val->Val->Typ, pc->CStdOut); printf(":type"); break; + default: printf("unknown"); break; } printf("[0x%lx,0x%lx]", (long)StackTop, (long)StackTop->Val); - } - else - { + } 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,59 +140,55 @@ 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 */ - { + if (t == TokenIdentifier) {/* see TypeParseFront, case TokenIdentifier and ParseTypedef */ struct Value * VarValue; - if (VariableDefined(Parser->pc, LexValue->Val->Pointer)) - { + if (VariableDefined(Parser->pc, LexValue->Val->Pointer)) { VariableGet(Parser->pc, Parser, LexValue->Val->Pointer, &VarValue); if (VarValue->Typ == &Parser->pc->TypeType) return 1; } } - + return 0; } long ExpressionCoerceInteger(struct Value *Val) { - switch (Val->Typ->Base) - { - case TypeInt: return (long)Val->Val->Integer; - case TypeChar: return (long)Val->Val->Character; - case TypeShort: return (long)Val->Val->ShortInteger; - case TypeLong: return (long)Val->Val->LongInteger; - case TypeUnsignedInt: return (long)Val->Val->UnsignedInteger; - case TypeUnsignedShort: return (long)Val->Val->UnsignedShortInteger; - case TypeUnsignedLong: return (long)Val->Val->UnsignedLongInteger; - case TypeUnsignedChar: return (long)Val->Val->UnsignedCharacter; - case TypePointer: return (long)Val->Val->Pointer; + switch (Val->Typ->Base) { + case TypeInt: return (long)Val->Val->Integer; + case TypeChar: return (long)Val->Val->Character; + case TypeShort: return (long)Val->Val->ShortInteger; + case TypeLong: return (long)Val->Val->LongInteger; + case TypeUnsignedInt: return (long)Val->Val->UnsignedInteger; + case TypeUnsignedShort: return (long)Val->Val->UnsignedShortInteger; + case TypeUnsignedLong: return (long)Val->Val->UnsignedLongInteger; + case TypeUnsignedChar: return (long)Val->Val->UnsignedCharacter; + case TypePointer: return (long)Val->Val->Pointer; #ifndef NO_FP - case TypeFP: return (long)Val->Val->FP; + case TypeFP: return (long)Val->Val->FP; #endif - default: return 0; + default: return 0; } } unsigned long ExpressionCoerceUnsignedInteger(struct Value *Val) { - switch (Val->Typ->Base) - { - case TypeInt: return (unsigned long)Val->Val->Integer; - case TypeChar: return (unsigned long)Val->Val->Character; - case TypeShort: return (unsigned long)Val->Val->ShortInteger; - case TypeLong: return (unsigned long)Val->Val->LongInteger; - case TypeUnsignedInt: return (unsigned long)Val->Val->UnsignedInteger; - case TypeUnsignedShort: return (unsigned long)Val->Val->UnsignedShortInteger; - case TypeUnsignedLong: return (unsigned long)Val->Val->UnsignedLongInteger; - case TypeUnsignedChar: return (unsigned long)Val->Val->UnsignedCharacter; - case TypePointer: return (unsigned long)Val->Val->Pointer; + switch (Val->Typ->Base) { + case TypeInt: return (unsigned long)Val->Val->Integer; + case TypeChar: return (unsigned long)Val->Val->Character; + case TypeShort: return (unsigned long)Val->Val->ShortInteger; + case TypeLong: return (unsigned long)Val->Val->LongInteger; + case TypeUnsignedInt: return (unsigned long)Val->Val->UnsignedInteger; + case TypeUnsignedShort: return (unsigned long)Val->Val->UnsignedShortInteger; + case TypeUnsignedLong: return (unsigned long)Val->Val->UnsignedLongInteger; + case TypeUnsignedChar: return (unsigned long)Val->Val->UnsignedCharacter; + case TypePointer: return (unsigned long)Val->Val->Pointer; #ifndef NO_FP - case TypeFP: return (unsigned long)Val->Val->FP; + case TypeFP: return (unsigned long)Val->Val->FP; #endif - default: return 0; + default: return 0; } } @@ -207,33 +198,31 @@ 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; - case TypeChar: IntVal = Val->Val->Character; return (double)IntVal; - case TypeShort: IntVal = Val->Val->ShortInteger; return (double)IntVal; - case TypeLong: IntVal = Val->Val->LongInteger; return (double)IntVal; - case TypeUnsignedInt: UnsignedVal = Val->Val->UnsignedInteger; return (double)UnsignedVal; - case TypeUnsignedShort: UnsignedVal = Val->Val->UnsignedShortInteger; return (double)UnsignedVal; - case TypeUnsignedLong: UnsignedVal = Val->Val->UnsignedLongInteger; return (double)UnsignedVal; - case TypeUnsignedChar: UnsignedVal = Val->Val->UnsignedCharacter; return (double)UnsignedVal; - case TypeFP: return Val->Val->FP; - default: return 0.0; + + switch (Val->Typ->Base) { + case TypeInt: IntVal = Val->Val->Integer; return (double)IntVal; + case TypeChar: IntVal = Val->Val->Character; return (double)IntVal; + case TypeShort: IntVal = Val->Val->ShortInteger; return (double)IntVal; + case TypeLong: IntVal = Val->Val->LongInteger; return (double)IntVal; + case TypeUnsignedInt: UnsignedVal = Val->Val->UnsignedInteger; return (double)UnsignedVal; + case TypeUnsignedShort: UnsignedVal = Val->Val->UnsignedShortInteger; return (double)UnsignedVal; + case TypeUnsignedLong: UnsignedVal = Val->Val->UnsignedLongInteger; return (double)UnsignedVal; + case TypeUnsignedChar: UnsignedVal = Val->Val->UnsignedCharacter; return (double)UnsignedVal; + case TypeFP: return Val->Val->FP; + default: return 0.0; } #else - switch (Val->Typ->Base) - { - case TypeInt: return (double)Val->Val->Integer; - case TypeChar: return (double)Val->Val->Character; - case TypeShort: return (double)Val->Val->ShortInteger; - case TypeLong: return (double)Val->Val->LongInteger; - case TypeUnsignedInt: return (double)Val->Val->UnsignedInteger; - case TypeUnsignedShort: return (double)Val->Val->UnsignedShortInteger; - case TypeUnsignedLong: return (double)Val->Val->UnsignedLongInteger; - case TypeUnsignedChar: return (double)Val->Val->UnsignedCharacter; - case TypeFP: return (double)Val->Val->FP; - default: return 0.0; + switch (Val->Typ->Base) { + case TypeInt: return (double)Val->Val->Integer; + case TypeChar: return (double)Val->Val->Character; + case TypeShort: return (double)Val->Val->ShortInteger; + case TypeLong: return (double)Val->Val->LongInteger; + case TypeUnsignedInt: return (double)Val->Val->UnsignedInteger; + case TypeUnsignedShort: return (double)Val->Val->UnsignedShortInteger; + case TypeUnsignedLong: return (double)Val->Val->UnsignedLongInteger; + case TypeUnsignedChar: return (double)Val->Val->UnsignedCharacter; + case TypeFP: return (double)Val->Val->FP; + default: return 0.0; } #endif } @@ -243,26 +232,25 @@ 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 Result = FromInt; - switch (DestValue->Typ->Base) - { - case TypeInt: DestValue->Val->Integer = FromInt; break; - case TypeShort: DestValue->Val->ShortInteger = (short)FromInt; break; - case TypeChar: DestValue->Val->Character = (char)FromInt; break; - case TypeLong: DestValue->Val->LongInteger = (long)FromInt; break; - case TypeUnsignedInt: DestValue->Val->UnsignedInteger = (unsigned int)FromInt; break; - case TypeUnsignedShort: DestValue->Val->UnsignedShortInteger = (unsigned short)FromInt; break; - case TypeUnsignedLong: DestValue->Val->UnsignedLongInteger = (unsigned long)FromInt; break; - case TypeUnsignedChar: DestValue->Val->UnsignedCharacter = (unsigned char)FromInt; break; - default: break; + switch (DestValue->Typ->Base) { + case TypeInt: DestValue->Val->Integer = FromInt; break; + case TypeShort: DestValue->Val->ShortInteger = (short)FromInt; break; + case TypeChar: DestValue->Val->Character = (char)FromInt; break; + case TypeLong: DestValue->Val->LongInteger = (long)FromInt; break; + case TypeUnsignedInt: DestValue->Val->UnsignedInteger = (unsigned int)FromInt; break; + case TypeUnsignedShort: DestValue->Val->UnsignedShortInteger = (unsigned short)FromInt; break; + case TypeUnsignedLong: DestValue->Val->UnsignedLongInteger = (unsigned long)FromInt; break; + case TypeUnsignedChar: DestValue->Val->UnsignedCharacter = (unsigned char)FromInt; break; + default: break; } return Result; } @@ -271,9 +259,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 +288,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,130 +341,113 @@ 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)) - { + 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 && - (PointedToType == FromValue->Typ->FromType->FromType || ToValue->Typ == Parser->pc->VoidPtrType) ) - { + } 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 */ ToValue->Val->Pointer = VariableDereferencePointer(Parser, FromValue, NULL, NULL, NULL, NULL); - } - else if (IS_NUMERIC_COERCIBLE(FromValue) && ExpressionCoerceInteger(FromValue) == 0) - { + } else if (IS_NUMERIC_COERCIBLE(FromValue) && ExpressionCoerceInteger(FromValue) == 0) { /* null pointer assignment */ ToValue->Val->Pointer = NULL; - } - else if (AllowPointerCoercion && IS_NUMERIC_COERCIBLE(FromValue)) - { + } else if (AllowPointerCoercion && IS_NUMERIC_COERCIBLE(FromValue)) { /* assign integer to native pointer */ ToValue->Val->Pointer = (void *)(unsigned long)ExpressionCoerceUnsignedInteger(FromValue); - } - else if (AllowPointerCoercion && FromValue->Typ->Base == TypePointer) - { + } else if (AllowPointerCoercion && FromValue->Typ->Base == TypePointer) { /* assign a pointer to a pointer to a different type */ ToValue->Val->Pointer = FromValue->Val->Pointer; - } - else - AssignFail(Parser, "%t from %t", ToValue->Typ, FromValue->Typ, 0, 0, FuncName, ParamNo); + } else + 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); - - switch (DestValue->Typ->Base) - { - case TypeInt: DestValue->Val->Integer = ExpressionCoerceInteger(SourceValue); break; - case TypeShort: DestValue->Val->ShortInteger = (short)ExpressionCoerceInteger(SourceValue); break; - case TypeChar: DestValue->Val->Character = (char)ExpressionCoerceInteger(SourceValue); break; - case TypeLong: DestValue->Val->LongInteger = ExpressionCoerceInteger(SourceValue); break; - case TypeUnsignedInt: DestValue->Val->UnsignedInteger = ExpressionCoerceUnsignedInteger(SourceValue); break; - case TypeUnsignedShort: DestValue->Val->UnsignedShortInteger = (unsigned short)ExpressionCoerceUnsignedInteger(SourceValue); break; - case TypeUnsignedLong: DestValue->Val->UnsignedLongInteger = ExpressionCoerceUnsignedInteger(SourceValue); break; - case TypeUnsignedChar: DestValue->Val->UnsignedCharacter = (unsigned char)ExpressionCoerceUnsignedInteger(SourceValue); break; + AssignFail(Parser, "%t from %t", DestValue->Typ, SourceValue->Typ, 0, 0, FuncName, ParamNo); + switch (DestValue->Typ->Base) { + case TypeInt: DestValue->Val->Integer = ExpressionCoerceInteger(SourceValue); break; + case TypeShort: DestValue->Val->ShortInteger = (short)ExpressionCoerceInteger(SourceValue); break; + case TypeChar: DestValue->Val->Character = (char)ExpressionCoerceInteger(SourceValue); break; + case TypeLong: DestValue->Val->LongInteger = ExpressionCoerceInteger(SourceValue); break; + case TypeUnsignedInt: DestValue->Val->UnsignedInteger = ExpressionCoerceUnsignedInteger(SourceValue); break; + case TypeUnsignedShort: DestValue->Val->UnsignedShortInteger = (unsigned short)ExpressionCoerceUnsignedInteger(SourceValue); break; + case TypeUnsignedLong: DestValue->Val->UnsignedLongInteger = ExpressionCoerceUnsignedInteger(SourceValue); break; + case TypeUnsignedChar: DestValue->Val->UnsignedCharacter = (unsigned char)ExpressionCoerceUnsignedInteger(SourceValue); break; #ifndef NO_FP - case TypeFP: - if (!IS_NUMERIC_COERCIBLE_PLUS_POINTERS(SourceValue, AllowPointerCoercion)) - AssignFail(Parser, "%t from %t", DestValue->Typ, SourceValue->Typ, 0, 0, FuncName, ParamNo); - - DestValue->Val->FP = ExpressionCoerceFP(SourceValue); - break; + case TypeFP: + if (!IS_NUMERIC_COERCIBLE_PLUS_POINTERS(SourceValue, AllowPointerCoercion)) + AssignFail(Parser, "%t from %t", DestValue->Typ, SourceValue->Typ, 0, 0, FuncName, ParamNo); + + DestValue->Val->FP = ExpressionCoerceFP(SourceValue); + break; #endif - case TypePointer: - ExpressionAssignToPointer(Parser, DestValue, SourceValue, FuncName, ParamNo, AllowPointerCoercion); - break; - - 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 */ - DestValue->LValueFrom->Val = DestValue->Val; - DestValue->LValueFrom->AnyValOnHeap = DestValue->AnyValOnHeap; - } + 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 */ + DestValue->LValueFrom->Val = DestValue->Val; + DestValue->LValueFrom->AnyValOnHeap = DestValue->AnyValOnHeap; } + } - /* char array = "abcd" */ - if (DestValue->Typ->FromType->Base == TypeChar && SourceValue->Typ->Base == TypePointer && SourceValue->Typ->FromType->Base == TypeChar) - { - if (DestValue->Typ->ArraySize == 0) /* char x[] = "abcd", x is unsized */ - { - int Size = strlen(SourceValue->Val->Pointer) + 1; - #ifdef DEBUG_ARRAY_INITIALIZER - PRINT_SOURCE_POS; - fprintf(stderr, "str size: %d\n", Size); - #endif - DestValue->Typ = TypeGetMatching(Parser->pc, Parser, DestValue->Typ->FromType, DestValue->Typ->Base, Size, DestValue->Typ->Identifier, TRUE); - VariableRealloc(Parser, DestValue, TypeSizeValue(DestValue, FALSE)); - } - /* else, it's char x[10] = "abcd" */ - + /* char array = "abcd" */ + if (DestValue->Typ->FromType->Base == TypeChar && SourceValue->Typ->Base == TypePointer && SourceValue->Typ->FromType->Base == TypeChar) { + if (DestValue->Typ->ArraySize == 0) { /* char x[] = "abcd", x is unsized */ + int Size = strlen(SourceValue->Val->Pointer) + 1; #ifdef DEBUG_ARRAY_INITIALIZER PRINT_SOURCE_POS; - fprintf(stderr, "char[%d] from char* (len=%d)\n", DestValue->Typ->ArraySize, strlen(SourceValue->Val->Pointer)); + fprintf(stderr, "str size: %d\n", Size); #endif - memcpy((void *)DestValue->Val, SourceValue->Val->Pointer, TypeSizeValue(DestValue, FALSE)); - break; + DestValue->Typ = TypeGetMatching(Parser->pc, Parser, DestValue->Typ->FromType, DestValue->Typ->Base, Size, DestValue->Typ->Identifier, TRUE); + VariableRealloc(Parser, DestValue, TypeSizeValue(DestValue, FALSE)); } + /* else, it's char x[10] = "abcd" */ - if (DestValue->Typ != SourceValue->Typ) - 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); - - memcpy((void *)DestValue->Val, (void *)SourceValue->Val, TypeSizeValue(SourceValue, FALSE)); - break; - - default: - AssignFail(Parser, "%t", DestValue->Typ, NULL, 0, 0, FuncName, ParamNo); + #ifdef DEBUG_ARRAY_INITIALIZER + PRINT_SOURCE_POS; + fprintf(stderr, "char[%d] from char* (len=%d)\n", DestValue->Typ->ArraySize, strlen(SourceValue->Val->Pointer)); + #endif + memcpy((void *)DestValue->Val, SourceValue->Val->Pointer, TypeSizeValue(DestValue, FALSE)); break; + } + + if (DestValue->Typ != SourceValue->Typ) + 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); + + memcpy((void *)DestValue->Val, (void *)SourceValue->Val, TypeSizeValue(SourceValue, FALSE)); + break; + + default: + AssignFail(Parser, "%t", DestValue->Typ, NULL, 0, 0, FuncName, ParamNo); + break; } } @@ -486,13 +457,10 @@ void ExpressionQuestionMarkOperator(struct ParseState *Parser, struct Expression if (!IS_NUMERIC_COERCIBLE(TopValue)) ProgramFail(Parser, "first argument to '?' should be a number"); - if (ExpressionCoerceInteger(TopValue)) - { + if (ExpressionCoerceInteger(TopValue)) { /* the condition's true, return the BottomValue */ ExpressionStackPushValue(Parser, StackTop, BottomValue); - } - else - { + } else { /* the condition's false, return void */ ExpressionStackPushValueByType(Parser, StackTop, &Parser->pc->VoidType); } @@ -501,13 +469,10 @@ void ExpressionQuestionMarkOperator(struct ParseState *Parser, struct Expression /* evaluate the second half of a ternary operator x ? y : z */ void ExpressionColonOperator(struct ParseState *Parser, struct ExpressionStack **StackTop, struct Value *BottomValue, struct Value *TopValue) { - if (TopValue->Typ->Base == TypeVoid) - { + if (TopValue->Typ->Base == TypeVoid) { /* invoke the "else" part - return the BottomValue */ ExpressionStackPushValue(Parser, StackTop, BottomValue); - } - else - { + } else { /* it was a "then" - return the TopValue */ ExpressionStackPushValue(Parser, StackTop, TopValue); } @@ -520,72 +485,64 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack union AnyValue *ValPtr; debugf("ExpressionPrefixOperator()\n"); - switch (Op) - { - case TokenAmpersand: - if (!TopValue->IsLValue) - ProgramFail(Parser, "can't get the address of this"); + switch (Op) { + case TokenAmpersand: + if (!TopValue->IsLValue) + ProgramFail(Parser, "can't get the address of this"); - ValPtr = TopValue->Val; - Result = VariableAllocValueFromType(Parser->pc, Parser, TypeGetMatching(Parser->pc, Parser, TopValue->Typ, TypePointer, 0, Parser->pc->StrEmpty, TRUE), FALSE, NULL, FALSE); - Result->Val->Pointer = (void *)ValPtr; - ExpressionStackPushValueNode(Parser, StackTop, Result); - break; + ValPtr = TopValue->Val; + Result = VariableAllocValueFromType(Parser->pc, Parser, TypeGetMatching(Parser->pc, Parser, TopValue->Typ, TypePointer, 0, Parser->pc->StrEmpty, TRUE), FALSE, NULL, FALSE); + Result->Val->Pointer = (void *)ValPtr; + ExpressionStackPushValueNode(Parser, StackTop, Result); + break; - case TokenAsterisk: - ExpressionStackPushDereference(Parser, StackTop, TopValue); - break; - - case TokenSizeof: - /* return the size of the argument */ - if (TopValue->Typ == &Parser->pc->TypeType) - ExpressionPushInt(Parser, StackTop, TypeSize(TopValue->Val->Typ, TopValue->Val->Typ->ArraySize, TRUE)); - else - ExpressionPushInt(Parser, StackTop, TypeSize(TopValue->Typ, TopValue->Typ->ArraySize, TRUE)); - break; - - default: - /* an arithmetic operator */ + case TokenAsterisk: + ExpressionStackPushDereference(Parser, StackTop, TopValue); + break; + + case TokenSizeof: + /* return the size of the argument */ + if (TopValue->Typ == &Parser->pc->TypeType) + ExpressionPushInt(Parser, StackTop, TypeSize(TopValue->Val->Typ, TopValue->Val->Typ->ArraySize, TRUE)); + else + ExpressionPushInt(Parser, StackTop, TypeSize(TopValue->Typ, TopValue->Typ->ArraySize, TRUE)); + break; + + default: + /* an arithmetic operator */ #ifndef NO_FP - if (TopValue->Typ == &Parser->pc->FPType) - { - /* floating point prefix arithmetic */ - double ResultFP = 0.0; - - switch (Op) - { - case TokenPlus: ResultFP = TopValue->Val->FP; break; - case TokenMinus: ResultFP = -TopValue->Val->FP; break; - case TokenIncrement: ResultFP = ExpressionAssignFP(Parser, TopValue, TopValue->Val->FP+1); break; - case TokenDecrement: ResultFP = ExpressionAssignFP(Parser, TopValue, TopValue->Val->FP-1); break; - case TokenUnaryNot: ResultFP = !TopValue->Val->FP; break; - default: ProgramFail(Parser, "invalid operation"); break; - } - - ExpressionPushFP(Parser, StackTop, ResultFP); + if (TopValue->Typ == &Parser->pc->FPType) { + /* floating point prefix arithmetic */ + double ResultFP = 0.0; + + switch (Op) { + case TokenPlus: ResultFP = TopValue->Val->FP; break; + case TokenMinus: ResultFP = -TopValue->Val->FP; break; + case TokenIncrement: ResultFP = ExpressionAssignFP(Parser, TopValue, TopValue->Val->FP+1); break; + case TokenDecrement: ResultFP = ExpressionAssignFP(Parser, TopValue, TopValue->Val->FP-1); break; + case TokenUnaryNot: ResultFP = !TopValue->Val->FP; break; + default: ProgramFail(Parser, "invalid operation"); break; } - else + + ExpressionPushFP(Parser, StackTop, ResultFP); + } else #endif - if (IS_NUMERIC_COERCIBLE(TopValue)) - { + if (IS_NUMERIC_COERCIBLE(TopValue)) { /* integer prefix arithmetic */ long ResultInt = 0; long TopInt = ExpressionCoerceInteger(TopValue); - switch (Op) - { - case TokenPlus: ResultInt = TopInt; break; - case TokenMinus: ResultInt = -TopInt; break; - case TokenIncrement: ResultInt = ExpressionAssignInt(Parser, TopValue, TopInt+1, FALSE); break; - case TokenDecrement: ResultInt = ExpressionAssignInt(Parser, TopValue, TopInt-1, FALSE); break; - case TokenUnaryNot: ResultInt = !TopInt; break; - case TokenUnaryExor: ResultInt = ~TopInt; break; - default: ProgramFail(Parser, "invalid operation"); break; + switch (Op) { + case TokenPlus: ResultInt = TopInt; break; + case TokenMinus: ResultInt = -TopInt; break; + case TokenIncrement: ResultInt = ExpressionAssignInt(Parser, TopValue, TopInt+1, FALSE); break; + case TokenDecrement: ResultInt = ExpressionAssignInt(Parser, TopValue, TopInt-1, FALSE); break; + case TokenUnaryNot: ResultInt = !TopInt; break; + case TokenUnaryExor: ResultInt = ~TopInt; break; + default: ProgramFail(Parser, "invalid operation"); break; } ExpressionPushInt(Parser, StackTop, ResultInt); - } - else if (TopValue->Typ->Base == TypePointer) - { + } else if (TopValue->Typ->Base == TypePointer) { /* pointer prefix arithmetic */ int Size = TypeSize(TopValue->Typ->FromType, 0, TRUE); struct Value *StackValue; @@ -593,22 +550,20 @@ 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"); - - 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; + + 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; } ResultPtr = TopValue->Val->Pointer; StackValue = ExpressionStackPushValueByType(Parser, StackTop, TopValue->Typ); StackValue->Val->Pointer = ResultPtr; - } - else + } else ProgramFail(Parser, "invalid operation"); break; } @@ -619,57 +574,50 @@ void ExpressionPostfixOperator(struct ParseState *Parser, struct ExpressionStack { debugf("ExpressionPostfixOperator()\n"); #ifndef NO_FP - if (TopValue->Typ == &Parser->pc->FPType) - { + if (TopValue->Typ == &Parser->pc->FPType) { /* 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; + + 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)) - { + if (IS_NUMERIC_COERCIBLE(TopValue)) { long ResultInt = 0; long TopInt = ExpressionCoerceInteger(TopValue); - switch (Op) - { - case TokenIncrement: ResultInt = ExpressionAssignInt(Parser, TopValue, TopInt+1, TRUE); break; - case TokenDecrement: ResultInt = ExpressionAssignInt(Parser, TopValue, TopInt-1, TRUE); break; - case TokenRightSquareBracket: ProgramFail(Parser, "not supported"); break; /* XXX */ - case TokenCloseBracket: ProgramFail(Parser, "not supported"); break; /* XXX */ - default: ProgramFail(Parser, "invalid operation"); break; + switch (Op) { + case TokenIncrement: ResultInt = ExpressionAssignInt(Parser, TopValue, TopInt+1, TRUE); break; + case TokenDecrement: ResultInt = ExpressionAssignInt(Parser, TopValue, TopInt-1, TRUE); break; + case TokenRightSquareBracket: ProgramFail(Parser, "not supported"); break; /* XXX */ + case TokenCloseBracket: ProgramFail(Parser, "not supported"); break; /* XXX */ + default: ProgramFail(Parser, "invalid operation"); break; } - + ExpressionPushInt(Parser, StackTop, ResultInt); - } - else if (TopValue->Typ->Base == TypePointer) - { + } else if (TopValue->Typ->Base == TypePointer) { /* pointer postfix arithmetic */ 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"); - - 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; + + 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,67 +631,62 @@ 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) - { + + 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 */ - switch (BottomValue->Typ->Base) - { - case TypeArray: Result = VariableAllocValueFromExistingData(Parser, BottomValue->Typ->FromType, (union AnyValue *)(&BottomValue->Val->ArrayMem[0] + TypeSize(BottomValue->Typ, ArrayIndex, TRUE)), BottomValue->IsLValue, BottomValue->LValueFrom); break; - case 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); + switch (BottomValue->Typ->Base) { + case TypeArray: Result = VariableAllocValueFromExistingData(Parser, BottomValue->Typ->FromType, (union AnyValue *)(&BottomValue->Val->ArrayMem[0] + TypeSize(BottomValue->Typ, ArrayIndex, TRUE)), BottomValue->IsLValue, BottomValue->LValueFrom); break; + case 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)) || - (IS_NUMERIC_COERCIBLE(TopValue) && BottomValue->Typ == &Parser->pc->FPType) ) - { + (IS_NUMERIC_COERCIBLE(TopValue) && BottomValue->Typ == &Parser->pc->FPType) ) { /* floating point infix arithmetic */ int ResultIsInt = FALSE; double ResultFP = 0.0; double TopFP = (TopValue->Typ == &Parser->pc->FPType) ? TopValue->Val->FP : (double)ExpressionCoerceInteger(TopValue); double BottomFP = (BottomValue->Typ == &Parser->pc->FPType) ? BottomValue->Val->FP : (double)ExpressionCoerceInteger(BottomValue); - switch (Op) - { - case TokenAssign: ASSIGN_FP_OR_INT(TopFP); break; - case TokenAddAssign: ASSIGN_FP_OR_INT(BottomFP + TopFP); break; - case TokenSubtractAssign: ASSIGN_FP_OR_INT(BottomFP - TopFP); break; - case TokenMultiplyAssign: ASSIGN_FP_OR_INT(BottomFP * TopFP); break; - case TokenDivideAssign: ASSIGN_FP_OR_INT(BottomFP / TopFP); break; - case TokenEqual: ResultInt = BottomFP == TopFP; ResultIsInt = TRUE; break; - case TokenNotEqual: ResultInt = BottomFP != TopFP; ResultIsInt = TRUE; break; - case TokenLessThan: ResultInt = BottomFP < TopFP; ResultIsInt = TRUE; break; - case TokenGreaterThan: ResultInt = BottomFP > TopFP; ResultIsInt = TRUE; break; - case TokenLessEqual: ResultInt = BottomFP <= TopFP; ResultIsInt = TRUE; break; - case TokenGreaterEqual: ResultInt = BottomFP >= TopFP; ResultIsInt = TRUE; break; - case TokenPlus: ResultFP = BottomFP + TopFP; break; - case TokenMinus: ResultFP = BottomFP - TopFP; break; - case TokenAsterisk: ResultFP = BottomFP * TopFP; break; - case TokenSlash: ResultFP = BottomFP / TopFP; break; - default: ProgramFail(Parser, "invalid operation"); break; + switch (Op) { + case TokenAssign: ASSIGN_FP_OR_INT(TopFP); break; + case TokenAddAssign: ASSIGN_FP_OR_INT(BottomFP + TopFP); break; + case TokenSubtractAssign: ASSIGN_FP_OR_INT(BottomFP - TopFP); break; + case TokenMultiplyAssign: ASSIGN_FP_OR_INT(BottomFP * TopFP); break; + case TokenDivideAssign: ASSIGN_FP_OR_INT(BottomFP / TopFP); break; + case TokenEqual: ResultInt = BottomFP == TopFP; ResultIsInt = TRUE; break; + case TokenNotEqual: ResultInt = BottomFP != TopFP; ResultIsInt = TRUE; break; + case TokenLessThan: ResultInt = BottomFP < TopFP; ResultIsInt = TRUE; break; + case TokenGreaterThan: ResultInt = BottomFP > TopFP; ResultIsInt = TRUE; break; + case TokenLessEqual: ResultInt = BottomFP <= TopFP; ResultIsInt = TRUE; break; + case TokenGreaterEqual: ResultInt = BottomFP >= TopFP; ResultIsInt = TRUE; break; + case TokenPlus: ResultFP = BottomFP + TopFP; break; + case TokenMinus: ResultFP = BottomFP - TopFP; break; + case TokenAsterisk: ResultFP = BottomFP * TopFP; break; + case TokenSlash: ResultFP = BottomFP / TopFP; break; + default: ProgramFail(Parser, "invalid operation"); break; } if (ResultIsInt) @@ -752,93 +695,82 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack * ExpressionPushFP(Parser, StackTop, ResultFP); } #endif - else if (IS_NUMERIC_COERCIBLE(TopValue) && IS_NUMERIC_COERCIBLE(BottomValue)) - { + else if (IS_NUMERIC_COERCIBLE(TopValue) && IS_NUMERIC_COERCIBLE(BottomValue)) { /* integer operation */ long TopInt = ExpressionCoerceInteger(TopValue); long BottomInt = ExpressionCoerceInteger(BottomValue); - switch (Op) - { - case TokenAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, TopInt, FALSE); break; - case TokenAddAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt + TopInt, FALSE); break; - case TokenSubtractAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt - TopInt, FALSE); break; - case TokenMultiplyAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt * TopInt, FALSE); break; - case TokenDivideAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt / TopInt, FALSE); break; + switch (Op) { + case TokenAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, TopInt, FALSE); break; + case TokenAddAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt + TopInt, FALSE); break; + case TokenSubtractAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt - TopInt, FALSE); break; + case TokenMultiplyAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt * TopInt, FALSE); break; + case TokenDivideAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt / TopInt, FALSE); break; #ifndef NO_MODULUS - case TokenModulusAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt % TopInt, FALSE); break; + case TokenModulusAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt % TopInt, FALSE); break; #endif - case TokenShiftLeftAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt << TopInt, FALSE); break; - case TokenShiftRightAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt >> TopInt, FALSE); break; - case TokenArithmeticAndAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt & TopInt, FALSE); break; - case TokenArithmeticOrAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt | TopInt, FALSE); break; - case TokenArithmeticExorAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt ^ TopInt, FALSE); break; - case TokenLogicalOr: ResultInt = BottomInt || TopInt; break; - case TokenLogicalAnd: ResultInt = BottomInt && TopInt; break; - case TokenArithmeticOr: ResultInt = BottomInt | TopInt; break; - case TokenArithmeticExor: ResultInt = BottomInt ^ TopInt; break; - case TokenAmpersand: ResultInt = BottomInt & TopInt; break; - case TokenEqual: ResultInt = BottomInt == TopInt; break; - case TokenNotEqual: ResultInt = BottomInt != TopInt; break; - case TokenLessThan: ResultInt = BottomInt < TopInt; break; - case TokenGreaterThan: ResultInt = BottomInt > TopInt; break; - case TokenLessEqual: ResultInt = BottomInt <= TopInt; break; - case TokenGreaterEqual: ResultInt = BottomInt >= TopInt; break; - case TokenShiftLeft: ResultInt = BottomInt << TopInt; break; - case TokenShiftRight: ResultInt = BottomInt >> TopInt; break; - case TokenPlus: ResultInt = BottomInt + TopInt; break; - case TokenMinus: ResultInt = BottomInt - TopInt; break; - case TokenAsterisk: ResultInt = BottomInt * TopInt; break; - case TokenSlash: ResultInt = BottomInt / TopInt; break; + case TokenShiftLeftAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt << TopInt, FALSE); break; + case TokenShiftRightAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt >> TopInt, FALSE); break; + case TokenArithmeticAndAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt & TopInt, FALSE); break; + case TokenArithmeticOrAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt | TopInt, FALSE); break; + case TokenArithmeticExorAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt ^ TopInt, FALSE); break; + case TokenLogicalOr: ResultInt = BottomInt || TopInt; break; + case TokenLogicalAnd: ResultInt = BottomInt && TopInt; break; + case TokenArithmeticOr: ResultInt = BottomInt | TopInt; break; + case TokenArithmeticExor: ResultInt = BottomInt ^ TopInt; break; + case TokenAmpersand: ResultInt = BottomInt & TopInt; break; + case TokenEqual: ResultInt = BottomInt == TopInt; break; + case TokenNotEqual: ResultInt = BottomInt != TopInt; break; + case TokenLessThan: ResultInt = BottomInt < TopInt; break; + case TokenGreaterThan: ResultInt = BottomInt > TopInt; break; + case TokenLessEqual: ResultInt = BottomInt <= TopInt; break; + case TokenGreaterEqual: ResultInt = BottomInt >= TopInt; break; + case TokenShiftLeft: ResultInt = BottomInt << TopInt; break; + case TokenShiftRight: ResultInt = BottomInt >> TopInt; break; + case TokenPlus: ResultInt = BottomInt + TopInt; break; + case TokenMinus: ResultInt = BottomInt - TopInt; break; + case TokenAsterisk: ResultInt = BottomInt * TopInt; break; + case TokenSlash: ResultInt = BottomInt / TopInt; break; #ifndef NO_MODULUS - case TokenModulus: ResultInt = BottomInt % TopInt; break; + case TokenModulus: ResultInt = BottomInt % TopInt; break; #endif - default: ProgramFail(Parser, "invalid operation"); break; + default: ProgramFail(Parser, "invalid operation"); break; } - + ExpressionPushInt(Parser, StackTop, ResultInt); - } - else if (BottomValue->Typ->Base == TypePointer && IS_NUMERIC_COERCIBLE(TopValue)) - { + } else if (BottomValue->Typ->Base == TypePointer && IS_NUMERIC_COERCIBLE(TopValue)) { /* pointer/integer infix arithmetic */ long TopInt = ExpressionCoerceInteger(TopValue); - if (Op == TokenEqual || Op == TokenNotEqual) - { + 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 ExpressionPushInt(Parser, StackTop, BottomValue->Val->Pointer != NULL); - } - else if (Op == TokenPlus || Op == TokenMinus) - { + } else if (Op == TokenPlus || Op == TokenMinus) { /* 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; - } - else if (Op == TokenAssign && TopInt == 0) - { + } else if (Op == TokenAssign && TopInt == 0) { /* assign a NULL pointer */ HeapUnpopStack(Parser->pc, sizeof(struct Value)); ExpressionAssign(Parser, BottomValue, TopValue, FALSE, NULL, 0, FALSE); ExpressionStackPushValueNode(Parser, StackTop, BottomValue); - } - else if (Op == TokenAddAssign || Op == TokenSubtractAssign) - { + } else if (Op == TokenAddAssign || Op == TokenSubtractAssign) { /* pointer arithmetic */ int Size = TypeSize(BottomValue->Typ->FromType, 0, TRUE); @@ -854,38 +786,29 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack * HeapUnpopStack(Parser->pc, sizeof(struct Value)); BottomValue->Val->Pointer = Pointer; ExpressionStackPushValueNode(Parser, StackTop, BottomValue); - } - else + } else ProgramFail(Parser, "invalid operation"); - } - else if (BottomValue->Typ->Base == TypePointer && TopValue->Typ->Base == TypePointer && Op != TokenAssign) - { + } else if (BottomValue->Typ->Base == TypePointer && TopValue->Typ->Base == TypePointer && Op != TokenAssign) { /* 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; - case TokenNotEqual: ExpressionPushInt(Parser, StackTop, BottomLoc != TopLoc); break; - case TokenMinus: ExpressionPushInt(Parser, StackTop, BottomLoc - TopLoc); break; - default: ProgramFail(Parser, "invalid operation"); break; + + switch (Op) { + case TokenEqual: ExpressionPushInt(Parser, StackTop, BottomLoc == TopLoc); break; + case TokenNotEqual: ExpressionPushInt(Parser, StackTop, BottomLoc != TopLoc); break; + case TokenMinus: ExpressionPushInt(Parser, StackTop, BottomLoc - TopLoc); break; + default: ProgramFail(Parser, "invalid operation"); break; } - } - else if (Op == TokenAssign) - { + } else if (Op == TokenAssign) { /* assign a non-numeric type */ HeapUnpopStack(Parser->pc, sizeof(struct Value)); /* XXX - possible bug if lvalue is a temp value and takes more than sizeof(struct Value) */ ExpressionAssign(Parser, BottomValue, TopValue, FALSE, NULL, 0, FALSE); ExpressionStackPushValueNode(Parser, StackTop, BottomValue); - } - else if (Op == TokenCast) - { + } else if (Op == TokenCast) { /* cast a value to a different type */ /* XXX - possible bug if the destination type takes more than sizeof(struct Value) + sizeof(struct ValueType *) */ struct Value *ValueLoc = ExpressionStackPushValueByType(Parser, StackTop, BottomValue->Val->Typ); ExpressionAssign(Parser, ValueLoc, TopValue, TRUE, NULL, 0, TRUE); - } - else + } else ProgramFail(Parser, "invalid operation"); } @@ -897,109 +820,96 @@ 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); #endif - while (TopStackNode != NULL && TopStackNode->Next != NULL && FoundPrecedence >= Precedence) - { + while (TopStackNode != NULL && TopStackNode->Next != NULL && FoundPrecedence >= Precedence) { /* find the top operator on the stack */ if (TopStackNode->Order == OrderNone) TopOperatorNode = TopStackNode->Next; else TopOperatorNode = TopStackNode; - + FoundPrecedence = TopOperatorNode->Precedence; - + /* does it have a high enough precedence? */ - if (FoundPrecedence >= Precedence && TopOperatorNode != NULL) - { + if (FoundPrecedence >= Precedence && TopOperatorNode != NULL) { /* execute this operator */ - switch (TopOperatorNode->Order) - { - case OrderPrefix: - /* 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 */ + switch (TopOperatorNode->Order) { + case OrderPrefix: + /* 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 */) { + /* run the operator */ + ExpressionPrefixOperator(Parser, StackTop, TopOperatorNode->Op, TopValue); + } else { + /* we're not running it so just return 0 */ + 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)); + *StackTop = TopStackNode->Next->Next; + + /* do the postfix operation */ + if (Parser->Mode == RunModeRun /* && FoundPrecedence < *IgnorePrecedence */) { + /* run the operator */ + ExpressionPostfixOperator(Parser, StackTop, TopOperatorNode->Op, TopValue); + } else { + /* we're not running it so just return 0 */ + ExpressionPushInt(Parser, StackTop, 0); + } + break; + + case OrderInfix: + /* infix evaluation */ + debugf("infix evaluation\n"); + TopValue = TopStackNode->Val; + 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, TopOperatorNode, sizeof(struct ExpressionStack)); - *StackTop = TopOperatorNode->Next; - - /* do the prefix operation */ - if (Parser->Mode == RunModeRun /* && FoundPrecedence < *IgnorePrecedence */) - { - /* run the operator */ - ExpressionPrefixOperator(Parser, StackTop, TopOperatorNode->Op, TopValue); - } - else - { - /* we're not running it so just return 0 */ - 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)); - *StackTop = TopStackNode->Next->Next; + HeapPopStack(Parser->pc, BottomValue, sizeof(struct ExpressionStack) + sizeof(struct Value) + TypeStackSizeValue(BottomValue)); + *StackTop = TopOperatorNode->Next->Next; - /* do the postfix operation */ - if (Parser->Mode == RunModeRun /* && FoundPrecedence < *IgnorePrecedence */) - { + /* do the infix operation */ + if (Parser->Mode == RunModeRun /* && FoundPrecedence <= *IgnorePrecedence */) { /* run the operator */ - ExpressionPostfixOperator(Parser, StackTop, TopOperatorNode->Op, TopValue); - } - else - { + ExpressionInfixOperator(Parser, StackTop, TopOperatorNode->Op, BottomValue, TopValue); + } else { /* we're not running it so just return 0 */ ExpressionPushInt(Parser, StackTop, 0); } - break; - - case OrderInfix: - /* infix evaluation */ - debugf("infix evaluation\n"); - TopValue = TopStackNode->Val; - 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 */) - { - /* run the operator */ - ExpressionInfixOperator(Parser, StackTop, TopOperatorNode->Op, BottomValue, TopValue); - } - else - { - /* we're not running it so just return 0 */ - ExpressionPushInt(Parser, StackTop, 0); - } - } - else - FoundPrecedence = -1; - break; + } + else + FoundPrecedence = -1; + break; - case OrderNone: - /* this should never happen */ - assert(TopOperatorNode->Order != OrderNone); - break; + case OrderNone: + /* this should never happen */ + 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 +948,12 @@ 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) - { + if (Parser->Mode == RunModeRun) { /* look up the struct element */ struct Value *ParamVal = (*StackTop)->Val; struct Value *StructVal = ParamVal; @@ -1056,17 +965,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,44 +994,39 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) int IgnorePrecedence = DEEP_PRECEDENCE; struct ExpressionStack *StackTop = NULL; int TernaryDepth = 0; - + debugf("ExpressionParse():\n"); - do - { + do { struct ParseState PreState; enum LexToken Token; ParserCopy(&PreState, Parser); Token = LexGetToken(Parser, &LexValue, TRUE); - if ( ( ( (int)Token > TokenComma && (int)Token <= (int)TokenOpenBracket) || - (Token == TokenCloseBracket && BracketPrecedence != 0)) && - (Token != TokenColon || TernaryDepth > 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) - { + 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) - { + 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) ) - { + if (IsTypeToken(Parser, BracketToken, LexValue) && (StackTop == NULL || StackTop->Op != TokenSizeof)) { /* it's a cast - get the new type */ 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; @@ -1131,24 +1035,19 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) CastTypeValue->Val->Typ = CastType; ExpressionStackPushValueNode(Parser, &StackTop, CastTypeValue); ExpressionStackPushOperator(Parser, &StackTop, OrderInfix, TokenCast, Precedence); - } - else - { + } else { /* boost the bracket operator precedence */ BracketPrecedence += BRACKET_PRECEDENCE; } - } - else - { + } 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) - { + 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) @@ -1158,129 +1057,103 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) ExpressionStackCollapse(Parser, &StackTop, Precedence, &IgnorePrecedence); ExpressionStackPushOperator(Parser, &StackTop, OrderPrefix, Token, Precedence + TempPrecedenceBoost); } - } - else - { + } else { /* expect an infix or postfix operator */ - if (OperatorPrecedence[(int)Token].PostfixPrecedence != 0) - { - switch (Token) - { - case TokenCloseBracket: - case TokenRightSquareBracket: - if (BracketPrecedence == 0) - { - /* assume this bracket is after the end of the expression */ - ParserCopy(Parser, &PreState); - Done = TRUE; - } - else - { - /* 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; - ExpressionStackCollapse(Parser, &StackTop, Precedence, &IgnorePrecedence); - ExpressionStackPushOperator(Parser, &StackTop, OrderPostfix, Token, Precedence); - break; + if (OperatorPrecedence[(int)Token].PostfixPrecedence != 0) { + switch (Token) { + case TokenCloseBracket: + case TokenRightSquareBracket: + if (BracketPrecedence == 0) { + /* assume this bracket is after the end of the expression */ + ParserCopy(Parser, &PreState); + Done = TRUE; + } else { + /* 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; + ExpressionStackCollapse(Parser, &StackTop, Precedence, &IgnorePrecedence); + ExpressionStackPushOperator(Parser, &StackTop, OrderPostfix, Token, Precedence); + break; } - } - else if (OperatorPrecedence[(int)Token].InfixPrecedence != 0) - { + } 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) - { + + 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 - { + } 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)) - { + if ( (Token == TokenLogicalOr || Token == TokenLogicalAnd) && IS_NUMERIC_COERCIBLE(StackTop->Val)) { long LHSInt = ExpressionCoerceInteger(StackTop->Val); if ( ( (Token == TokenLogicalOr && LHSInt) || (Token == TokenLogicalAnd && !LHSInt) ) && (IgnorePrecedence > Precedence) ) IgnorePrecedence = Precedence; } - + /* push the operator on the stack */ ExpressionStackPushOperator(Parser, &StackTop, OrderInfix, Token, Precedence); PrefixState = TRUE; - - switch (Token) - { - case TokenQuestionMark: TernaryDepth++; break; - case TokenColon: TernaryDepth--; break; - default: break; + + switch (Token) { + case TokenQuestionMark: TernaryDepth++; break; + case TokenColon: TernaryDepth--; break; + default: break; } } /* treat an open square bracket as an infix array index operator followed by an open bracket */ - if (Token == TokenLeftSquareBracket) - { + if (Token == TokenLeftSquareBracket) { /* boost the bracket operator precedence, then push */ BracketPrecedence += BRACKET_PRECEDENCE; } - } - else + } else ProgramFail(Parser, "operator not expected here"); } - } - else if (Token == TokenIdentifier) - { + } 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) - { + + if (LexGetToken(Parser, NULL, FALSE) == TokenOpenBracket) { ExpressionParseFunctionCall(Parser, &StackTop, LexValue->Val->Identifier, Parser->Mode == RunModeRun && Precedence < IgnorePrecedence); - } - else - { - if (Parser->Mode == RunModeRun /* && Precedence < IgnorePrecedence */) - { + } else { + if (Parser->Mode == RunModeRun /* && Precedence < IgnorePrecedence */) { struct Value *VariableValue = NULL; - + VariableGet(Parser->pc, Parser, LexValue->Val->Identifier, &VariableValue); - if (VariableValue->Typ->Base == TypeMacro) - { + if (VariableValue->Typ->Base == TypeMacro) { /* evaluate a macro as a kind of simple subroutine */ 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) + } else if (VariableValue->Typ == &Parser->pc->VoidType) ProgramFail(Parser, "a void value isn't much use here"); else ExpressionStackPushLValue(Parser, &StackTop, VariableValue, 0); /* it's a value variable */ - } - else /* push a dummy value */ + } else /* push a dummy value */ ExpressionPushInt(Parser, &StackTop, 0); - + } /* if we've successfully ignored the RHS turn ignoring off */ @@ -1288,65 +1161,56 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) IgnorePrecedence = DEEP_PRECEDENCE; PrefixState = FALSE; - } - else if ((int)Token > TokenCloseBracket && (int)Token <= TokenCharacterConstant) - { + } 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); - } - else if (IsTypeToken(Parser, Token, LexValue)) - { + } else if (IsTypeToken(Parser, Token, LexValue)) { /* it's a type. push it on the stack like a value. this is used in sizeof() */ 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); TypeValue = VariableAllocValueFromType(Parser->pc, Parser, &Parser->pc->TypeType, FALSE, NULL, FALSE); TypeValue->Val->Typ = Typ; ExpressionStackPushValueNode(Parser, &StackTop, TypeValue); - } - else - { + } 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) - { + if (StackTop != NULL) { /* all that should be left is a single value on the stack */ - if (Parser->Mode == RunModeRun) - { + if (Parser->Mode == RunModeRun) { if (StackTop->Order != OrderNone || StackTop->Next != NULL) ProgramFail(Parser, "invalid expression"); - + *Result = StackTop->Val; HeapPopStack(Parser->pc, StackTop, sizeof(struct ExpressionStack)); - } - else + } 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 +1227,8 @@ 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 +1237,48 @@ 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 + } else ExpressionPushInt(Parser, StackTop, 0); - + /* parse arguments */ ArgCount = 0; do { - if (ExpressionParse(Parser, &Param)) - { - if (Parser->Mode == RunModeRun) - { + 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 - { + } 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 +1286,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,88 +1304,75 @@ 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) - { + + if (RunIt) { /* get the function definition */ VariableGet(Parser->pc, Parser, FuncName, &FuncValue); - - if (FuncValue->Typ->Base == TypeMacro) - { + + 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"); - } - else - { + } else { 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) - { + + if (ExpressionParse(Parser, &Param)) { + if (RunIt) { + if (ArgCount < FuncValue->Val->FuncDef.NumParams) { ExpressionAssign(Parser, ParamArray[ArgCount], Param, TRUE, FuncName, ArgCount+1, FALSE); VariableStackPop(Parser, Param); - } - else - { + } else { if (!FuncValue->Val->FuncDef.VarArgs) ProgramFail(Parser, "too many arguments to %s()", FuncName); } } - + ArgCount++; Token = LexGetToken(Parser, NULL, TRUE); if (Token != TokenComma && Token != TokenCloseBracket) ProgramFail(Parser, "comma expected"); - } - else - { + } 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) - { + + 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,22 +1385,20 @@ 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 (RunIt) { if (FuncParser.Mode == RunModeRun && FuncValue->Val->FuncDef.ReturnType != &Parser->pc->VoidType) ProgramFail(&FuncParser, "no value returned from a function returning %t", FuncValue->Val->FuncDef.ReturnType); else if (FuncParser.Mode == RunModeGoto) ProgramFail(&FuncParser, "couldn't find goto label '%s'", FuncParser.SearchGotoLabel); } - + VariableStackFramePop(Parser); - } - else + } else FuncValue->Val->FuncDef.Intrinsic(Parser, ReturnValue, ParamArray, ArgCount); HeapPopStackFrame(Parser->pc); @@ -1570,19 +1412,18 @@ long ExpressionParseInt(struct ParseState *Parser) { struct Value *Val; long Result = 0; - + if (!ExpressionParse(Parser, &Val)) ProgramFail(Parser, "expression expected"); - - if (Parser->Mode == RunModeRun) - { + + 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..f0b5cbf 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; } @@ -118,16 +118,14 @@ void HeapPushStackFrame(Picoc *pc) /* pop the current stack frame, freeing all memory in the frame. can return NULL */ int HeapPopStackFrame(Picoc *pc) { - if (*(void **)pc->StackFrame != NULL) - { + if (*(void **)pc->StackFrame != NULL) { pc->HeapStackTop = pc->StackFrame; pc->StackFrame = *(void **)pc->StackFrame; #ifdef DEBUG_HEAP printf("Popping stack frame back to 0x%lx\n", (unsigned long)pc->HeapStackTop); #endif return TRUE; - } - else + } else return FALSE; } @@ -142,19 +140,18 @@ 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) - { + 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); @@ -164,19 +161,15 @@ void *HeapAllocMem(Picoc *pc, int Size) pc->FreeListBucket[Bucket] = *(struct AllocNode **)NewMem; assert(pc->FreeListBucket[Bucket] == NULL || ((unsigned long)pc->FreeListBucket[Bucket] >= (unsigned long)&(pc->HeapMemory)[0] && (unsigned char *)pc->FreeListBucket[Bucket] - &(pc->HeapMemory)[0] < HEAP_SIZE)); NewMem->Size = AllocSize; - } - else if (pc->FreeListBig != NULL) - { + } 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) - { + 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) - { + 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); @@ -184,9 +177,7 @@ void *HeapAllocMem(Picoc *pc, int Size) NewMem = *FreeNode; assert((unsigned long)NewMem >= (unsigned long)&(pc->HeapMemory)[0] && (unsigned char *)NewMem - &(pc->HeapMemory)[0] < HEAP_SIZE); *FreeNode = NewMem->NextFree; - } - else - { + } else { /* split this big memory chunk */ #ifdef DEBUG_HEAP printf("allocating %d(%d) from freelist, split chunk (%d)", Size, AllocSize, (*FreeNode)->Size); @@ -198,21 +189,20 @@ void *HeapAllocMem(Picoc *pc, int Size) } } } - - if (NewMem == NULL) - { + + 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 +220,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 +228,8 @@ void HeapFreeMem(Picoc *pc, void *Mem) assert(MemNode->Size < HEAP_SIZE && MemNode->Size > 0); if (Mem == NULL) return; - - if ((void *)MemNode == pc->HeapBottom) - { + + 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); @@ -249,9 +238,7 @@ void HeapFreeMem(Picoc *pc, void *Mem) #ifdef DEBUG_HEAP ShowBigList(pc); #endif - } - else if (Bucket < FREELIST_BUCKETS) - { + } else if (Bucket < FREELIST_BUCKETS) { /* we can fit it in a bucket */ #ifdef DEBUG_HEAP printf("freeing %d to bucket\n", MemNode->Size); @@ -259,9 +246,7 @@ void HeapFreeMem(Picoc *pc, void *Mem) assert(pc->FreeListBucket[Bucket] == NULL || ((unsigned long)pc->FreeListBucket[Bucket] >= (unsigned long)&(pc->HeapMemory)[0] && (unsigned char *)FreeListBucket[Bucket] - &HeapMemory[0] < HEAP_SIZE)); *(struct AllocNode **)MemNode = pc->FreeListBucket[Bucket]; pc->FreeListBucket[Bucket] = (struct AllocNode *)MemNode; - } - else - { + } 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..ee1821d 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,9 +32,8 @@ void IncludeCleanup(Picoc *pc) { struct IncludeLibrary *ThisInclude = pc->IncludeLibList; struct IncludeLibrary *NextInclude; - - while (ThisInclude != NULL) - { + + while (ThisInclude != NULL) { NextInclude = ThisInclude->NextLib; HeapFreeMem(pc, ThisInclude); ThisInclude = NextInclude; @@ -59,7 +58,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,34 +67,31 @@ 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) - { - if (strcmp(LInclude->IncludeName, FileName) == 0) - { + for (LInclude = pc->IncludeLibList; LInclude != NULL; LInclude = LInclude->NextLib) { + if (strcmp(LInclude->IncludeName, FileName) == 0) { /* found it - protect against multiple inclusion */ - if (!VariableDefined(pc, 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/lex.c b/lex.c index 9524b5b..5eb50bc 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,13 @@ 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++) - { + 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 +118,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,18 +140,16 @@ enum LexToken LexGetNumber(Picoc *pc, struct LexState *Lexer, struct Value *Valu char IsLong = 0; char IsUnsigned = 0; #endif - - if (*Lexer->Pos == '0') - { + + if (*Lexer->Pos == '0') { /* a binary, octal or hex literal */ LEXER_INC(Lexer); - if (Lexer->Pos != Lexer->End) - { - if (*Lexer->Pos == 'x' || *Lexer->Pos == 'X') - { Base = 16; LEXER_INC(Lexer); } - else if (*Lexer->Pos == 'b' || *Lexer->Pos == 'B') - { Base = 2; LEXER_INC(Lexer); } - else if (*Lexer->Pos != '.') + if (Lexer->Pos != Lexer->End) { + if (*Lexer->Pos == 'x' || *Lexer->Pos == 'X') { + Base = 16; LEXER_INC(Lexer); + } else if (*Lexer->Pos == 'b' || *Lexer->Pos == 'B') { + Base = 2; LEXER_INC(Lexer); + } else if (*Lexer->Pos != '.') Base = 8; } } @@ -161,69 +158,60 @@ enum LexToken LexGetNumber(Picoc *pc, struct LexState *Lexer, struct Value *Valu for (; Lexer->Pos != Lexer->End && IS_BASE_DIGIT(*Lexer->Pos, Base); LEXER_INC(Lexer)) Result = Result * Base + GET_BASE_DIGIT(*Lexer->Pos); - if (*Lexer->Pos == 'u' || *Lexer->Pos == 'U') - { + if (*Lexer->Pos == 'u' || *Lexer->Pos == 'U') { LEXER_INC(Lexer); /* IsUnsigned = 1; */ } - if (*Lexer->Pos == 'l' || *Lexer->Pos == 'L') - { + if (*Lexer->Pos == 'l' || *Lexer->Pos == 'L') { 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) - { + if (Lexer->Pos == Lexer->End) { return ResultToken; } - - if (*Lexer->Pos != '.' && *Lexer->Pos != 'e' && *Lexer->Pos != 'E') - { + + if (*Lexer->Pos != '.' && *Lexer->Pos != 'e' && *Lexer->Pos != 'E') { return ResultToken; } - + Value->Typ = &pc->FPType; FPResult = (double)Result; - - if (*Lexer->Pos == '.') - { + + if (*Lexer->Pos == '.') { LEXER_INC(Lexer); - for (FPDiv = 1.0/Base; Lexer->Pos != Lexer->End && IS_BASE_DIGIT(*Lexer->Pos, Base); LEXER_INC(Lexer), FPDiv /= (double)Base) - { + for (FPDiv = 1.0/Base; Lexer->Pos != Lexer->End && IS_BASE_DIGIT(*Lexer->Pos, Base); LEXER_INC(Lexer), FPDiv /= (double)Base) { FPResult += GET_BASE_DIGIT(*Lexer->Pos) * FPDiv; } } - if (Lexer->Pos != Lexer->End && (*Lexer->Pos == 'e' || *Lexer->Pos == 'E')) - { + if (Lexer->Pos != Lexer->End && (*Lexer->Pos == 'e' || *Lexer->Pos == 'E')) { int ExponentSign = 1; - + LEXER_INC(Lexer); - if (Lexer->Pos != Lexer->End && *Lexer->Pos == '-') - { + 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)) - { + while (Lexer->Pos != Lexer->End && IS_BASE_DIGIT(*Lexer->Pos, Base)) { Result = Result * Base + GET_BASE_DIGIT(*Lexer->Pos); LEXER_INC(Lexer); } FPResult *= pow((double)Base, (double)Result * ExponentSign); } - + Value->Val->FP = FPResult; if (*Lexer->Pos == 'f' || *Lexer->Pos == 'F') @@ -240,28 +228,27 @@ 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) - { - case TokenHashInclude: Lexer->Mode = LexModeHashInclude; break; - case TokenHashDefine: Lexer->Mode = LexModeHashDefine; break; - default: break; + switch (Token) { + case TokenHashInclude: Lexer->Mode = LexModeHashInclude; break; + case TokenHashDefine: Lexer->Mode = LexModeHashDefine; break; + default: break; } - + if (Token != TokenNone) return Token; - + if (Lexer->Mode == LexModeHashDefineSpace) Lexer->Mode = LexModeHashDefineSpaceIdent; - + return TokenIdentifier; } @@ -272,7 +259,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,41 +267,39 @@ 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 == '\\') - { + + if (**From == '\\') { /* it's escaped */ (*From)++; if (*From == End) return '\\'; - + ThisChar = *(*From)++; - switch (ThisChar) - { - case '\\': return '\\'; - case '\'': return '\''; - case '"': return '"'; - case 'a': return '\a'; - case 'b': return '\b'; - case 'f': return '\f'; - case 'n': return '\n'; - case 'r': return '\r'; - case 't': return '\t'; - case 'v': return '\v'; - case '0': case '1': case '2': case '3': return LexUnEscapeCharacterConstant(From, End, ThisChar, 8); - case 'x': return LexUnEscapeCharacterConstant(From, End, '0', 16); - default: return ThisChar; + switch (ThisChar) { + case '\\': return '\\'; + case '\'': return '\''; + case '"': return '"'; + case 'a': return '\a'; + case 'b': return '\b'; + case 'f': return '\f'; + case 'n': return '\n'; + case 'r': return '\r'; + case 't': return '\t'; + case 'v': return '\v'; + case '0': case '1': case '2': case '3': return LexUnEscapeCharacterConstant(From, End, ThisChar, 8); + case 'x': return LexUnEscapeCharacterConstant(From, End, '0', 16); + default: return ThisChar; } } else @@ -331,45 +316,40 @@ 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)) - { + + while (Lexer->Pos != Lexer->End && (*Lexer->Pos != EndChar || Escape)) { /* find the end */ - if (Escape) - { + if (Escape) { if (*Lexer->Pos == '\r' && Lexer->Pos+1 != Lexer->End) Lexer->Pos++; - - if (*Lexer->Pos == '\n' && Lexer->Pos+1 != Lexer->End) - { + + if (*Lexer->Pos == '\n' && Lexer->Pos+1 != Lexer->End) { Lexer->Line++; Lexer->Pos++; Lexer->CharacterPos = 0; Lexer->EmitExtraNewlines++; } - + Escape = FALSE; - } - else if (*Lexer->Pos == '\\') + } 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); ArrayValue = VariableStringLiteralGet(pc, RegString); - if (ArrayValue == NULL) - { + if (ArrayValue == NULL) { /* create and store this string literal */ ArrayValue = VariableAllocValueAndData(pc, NULL, 0, FALSE, NULL, TRUE); ArrayValue->Typ = pc->CharArrayType; @@ -382,7 +362,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 +373,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; } @@ -401,8 +381,7 @@ enum LexToken LexGetCharacterConstant(Picoc *pc, struct LexState *Lexer, struct /* skip a comment - used while scanning */ void LexSkipComment(struct LexState *Lexer, char NextChar, enum LexToken *ReturnToken) { - if (NextChar == '*') - { + if (NextChar == '*') { /* conventional C comment */ while (Lexer->Pos != Lexer->End && (*(Lexer->Pos-1) != '*' || *Lexer->Pos != '/')) { @@ -411,14 +390,12 @@ 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 - { + } else { /* C++ style comment */ while (Lexer->Pos != Lexer->End && *Lexer->Pos != '\n') LEXER_INC(Lexer); @@ -431,94 +408,86 @@ 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) - { + if (Lexer->EmitExtraNewlines > 0) { Lexer->EmitExtraNewlines--; return TokenEndOfLine; } - + /* scan for a token */ - do - { + do { *Value = &pc->LexValue; - while (Lexer->Pos != Lexer->End && isspace((int)*Lexer->Pos)) - { - if (*Lexer->Pos == '\n') - { + while (Lexer->Pos != Lexer->End && isspace((int)*Lexer->Pos)) { + if (*Lexer->Pos == '\n') { Lexer->Line++; Lexer->Pos++; Lexer->Mode = LexModeNormal; Lexer->CharacterPos = 0; return TokenEndOfLine; - } - else if (Lexer->Mode == LexModeHashDefine || Lexer->Mode == LexModeHashDefineSpace) + } 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) - { - case '"': GotToken = LexGetStringConstant(pc, Lexer, *Value, '"'); break; - case '\'': GotToken = LexGetCharacterConstant(pc, Lexer, *Value); break; - case '(': if (Lexer->Mode == LexModeHashDefineSpaceIdent) GotToken = TokenOpenMacroBracket; else GotToken = TokenOpenBracket; Lexer->Mode = LexModeNormal; break; - case ')': GotToken = TokenCloseBracket; break; - case '=': NEXTIS('=', TokenEqual, TokenAssign); break; - case '+': NEXTIS3('=', TokenAddAssign, '+', TokenIncrement, TokenPlus); break; - case '-': NEXTIS4('=', TokenSubtractAssign, '>', TokenArrow, '-', TokenDecrement, TokenMinus); break; - case '*': NEXTIS('=', TokenMultiplyAssign, TokenAsterisk); break; - case '/': if (NextChar == '/' || NextChar == '*') { LEXER_INC(Lexer); LexSkipComment(Lexer, NextChar, &GotToken); } else NEXTIS('=', TokenDivideAssign, TokenSlash); break; - case '%': NEXTIS('=', TokenModulusAssign, TokenModulus); break; - case '<': if (Lexer->Mode == LexModeHashInclude) GotToken = LexGetStringConstant(pc, Lexer, *Value, '>'); else { NEXTIS3PLUS('=', TokenLessEqual, '<', TokenShiftLeft, '=', TokenShiftLeftAssign, TokenLessThan); } break; - case '>': NEXTIS3PLUS('=', TokenGreaterEqual, '>', TokenShiftRight, '=', TokenShiftRightAssign, TokenGreaterThan); break; - case ';': GotToken = TokenSemicolon; break; - case '&': NEXTIS3('=', TokenArithmeticAndAssign, '&', TokenLogicalAnd, TokenAmpersand); break; - case '|': NEXTIS3('=', TokenArithmeticOrAssign, '|', TokenLogicalOr, TokenArithmeticOr); break; - case '{': GotToken = TokenLeftBrace; break; - case '}': GotToken = TokenRightBrace; break; - case '[': GotToken = TokenLeftSquareBracket; break; - case ']': GotToken = TokenRightSquareBracket; break; - case '!': NEXTIS('=', TokenNotEqual, TokenUnaryNot); break; - case '^': NEXTIS('=', TokenArithmeticExorAssign, TokenArithmeticExor); break; - case '~': GotToken = TokenUnaryExor; break; - case ',': GotToken = TokenComma; break; - case '.': NEXTISEXACTLY3('.', '.', TokenEllipsis, TokenDot); break; - case '?': GotToken = TokenQuestionMark; break; - case ':': GotToken = TokenColon; break; - default: LexFail(pc, Lexer, "illegal character '%c'", ThisChar); break; + switch (ThisChar) { + case '"': GotToken = LexGetStringConstant(pc, Lexer, *Value, '"'); break; + case '\'': GotToken = LexGetCharacterConstant(pc, Lexer, *Value); break; + case '(': if (Lexer->Mode == LexModeHashDefineSpaceIdent) GotToken = TokenOpenMacroBracket; else GotToken = TokenOpenBracket; Lexer->Mode = LexModeNormal; break; + case ')': GotToken = TokenCloseBracket; break; + case '=': NEXTIS('=', TokenEqual, TokenAssign); break; + case '+': NEXTIS3('=', TokenAddAssign, '+', TokenIncrement, TokenPlus); break; + case '-': NEXTIS4('=', TokenSubtractAssign, '>', TokenArrow, '-', TokenDecrement, TokenMinus); break; + case '*': NEXTIS('=', TokenMultiplyAssign, TokenAsterisk); break; + case '/': if (NextChar == '/' || NextChar == '*') { LEXER_INC(Lexer); LexSkipComment(Lexer, NextChar, &GotToken); } else NEXTIS('=', TokenDivideAssign, TokenSlash); break; + case '%': NEXTIS('=', TokenModulusAssign, TokenModulus); break; + case '<': if (Lexer->Mode == LexModeHashInclude) GotToken = LexGetStringConstant(pc, Lexer, *Value, '>'); else { NEXTIS3PLUS('=', TokenLessEqual, '<', TokenShiftLeft, '=', TokenShiftLeftAssign, TokenLessThan); } break; + case '>': NEXTIS3PLUS('=', TokenGreaterEqual, '>', TokenShiftRight, '=', TokenShiftRightAssign, TokenGreaterThan); break; + case ';': GotToken = TokenSemicolon; break; + case '&': NEXTIS3('=', TokenArithmeticAndAssign, '&', TokenLogicalAnd, TokenAmpersand); break; + case '|': NEXTIS3('=', TokenArithmeticOrAssign, '|', TokenLogicalOr, TokenArithmeticOr); break; + case '{': GotToken = TokenLeftBrace; break; + case '}': GotToken = TokenRightBrace; break; + case '[': GotToken = TokenLeftSquareBracket; break; + case ']': GotToken = TokenRightSquareBracket; break; + case '!': NEXTIS('=', TokenNotEqual, TokenUnaryNot); break; + case '^': NEXTIS('=', TokenArithmeticExorAssign, TokenArithmeticExor); break; + case '~': GotToken = TokenUnaryExor; break; + case ',': GotToken = TokenComma; break; + case '.': NEXTISEXACTLY3('.', '.', TokenEllipsis, TokenDot); break; + case '?': GotToken = TokenQuestionMark; break; + case ':': GotToken = TokenColon; break; + default: LexFail(pc, Lexer, "illegal character '%c'", ThisChar); break; } } while (GotToken == TokenNone); - + return GotToken; } /* what size value goes with each token */ int LexTokenSize(enum LexToken Token) { - switch (Token) - { - case TokenIdentifier: case TokenStringConstant: return sizeof(char *); - case TokenIntegerConstant: return sizeof(long); - case TokenCharacterConstant: return sizeof(unsigned char); - case TokenFPConstant: return sizeof(double); - default: return 0; + switch (Token) { + case TokenIdentifier: case TokenStringConstant: return sizeof(char *); + case TokenIntegerConstant: return sizeof(long); + case TokenCharacterConstant: return sizeof(unsigned char); + case TokenFPConstant: return sizeof(double); + default: return 0; } } @@ -530,16 +499,15 @@ 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 - { + + do { /* store the token at the end of the stack area */ Token = LexScanGetToken(pc, Lexer, &GotValue); @@ -555,22 +523,21 @@ void *LexTokenise(Picoc *pc, struct LexState *Lexer, int *TokenLen) MemUsed++; ValueSize = LexTokenSize(Token); - if (ValueSize > 0) - { + 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 +552,7 @@ void *LexTokenise(Picoc *pc, struct LexState *Lexer, int *TokenLen) #endif if (TokenLen) *TokenLen = MemUsed; - + return HeapMem; } @@ -593,7 +560,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 +569,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,72 +596,61 @@ enum LexToken LexGetRawToken(struct ParseState *Parser, struct Value **Value, in int ValueSize; char *Prompt = NULL; Picoc *pc = Parser->pc; - - do - { + + 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) - { + + if (Parser->FileName != pc->StrEmpty || pc->InteractiveHead != NULL) { /* skip leading newlines */ - while ((Token = (enum LexToken)*(unsigned char *)Parser->Pos) == TokenEndOfLine) - { + while ((Token = (enum LexToken)*(unsigned char *)Parser->Pos) == TokenEndOfLine) { Parser->Line++; Parser->Pos += TOKEN_DATA_OFFSET; } } - - if (Parser->FileName == pc->StrEmpty && (pc->InteractiveHead == NULL || Token == TokenEOF)) - { + + 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]) - { + + if (pc->InteractiveHead == NULL || (unsigned char *)Parser->Pos == &pc->InteractiveTail->Tokens[pc->InteractiveTail->NumBytes-TOKEN_DATA_OFFSET]) { /* get interactive input */ - if (pc->LexUseStatementPrompt) - { + if (pc->LexUseStatementPrompt) { Prompt = INTERACTIVE_PROMPT_STATEMENT; pc->LexUseStatementPrompt = FALSE; - } - else + } 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) - { + if (pc->InteractiveHead == NULL) { /* start a new list */ pc->InteractiveHead = LineNode; Parser->Line = 1; Parser->CharacterPos = 0; - } - else + } else pc->InteractiveTail->Next = LineNode; pc->InteractiveTail = LineNode; pc->InteractiveCurrentLine = LineNode; Parser->Pos = LineTokens; - } - else - { + } else { /* go to the next token line */ - if (Parser->Pos != &pc->InteractiveCurrentLine->Tokens[pc->InteractiveCurrentLine->NumBytes-TOKEN_DATA_OFFSET]) - { + 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); } + 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); + } } assert(pc->InteractiveCurrentLine != NULL); @@ -709,23 +665,20 @@ enum LexToken LexGetRawToken(struct ParseState *Parser, struct Value **Value, in Parser->CharacterPos = *((unsigned char *)Parser->Pos + 1); ValueSize = LexTokenSize(Token); - if (ValueSize > 0) - { + if (ValueSize > 0) { /* this token requires a value - unpack it */ - if (Value != NULL) - { - switch (Token) - { - case TokenStringConstant: pc->LexValue.Typ = pc->CharPtrType; break; - case TokenIdentifier: pc->LexValue.Typ = NULL; break; - case TokenIntegerConstant: pc->LexValue.Typ = &pc->LongType; break; - case TokenCharacterConstant: pc->LexValue.Typ = &pc->CharType; break; + if (Value != NULL) { + switch (Token) { + case TokenStringConstant: pc->LexValue.Typ = pc->CharPtrType; break; + case TokenIdentifier: pc->LexValue.Typ = NULL; break; + case TokenIntegerConstant: pc->LexValue.Typ = &pc->LongType; break; + case TokenCharacterConstant: pc->LexValue.Typ = &pc->CharType; break; #ifndef NO_FP - case TokenFPConstant: pc->LexValue.Typ = &pc->FPType; break; + case TokenFPConstant: pc->LexValue.Typ = &pc->FPType; break; #endif - default: break; + default: break; } - + memcpy((void *)pc->LexValue.Val, (void *)((char *)Parser->Pos + TOKEN_DATA_OFFSET), ValueSize); pc->LexValue.ValOnHeap = FALSE; pc->LexValue.ValOnStack = FALSE; @@ -733,16 +686,14 @@ 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; - } - else - { + } else { 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,18 +716,17 @@ 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)) ) - { + if (Parser->HashIfEvaluateToLevel == Parser->HashIfLevel && ((IsDefined && !IfNot) || (!IsDefined && IfNot))) { /* #if is active, evaluate to this new level */ Parser->HashIfEvaluateToLevel++; } - + Parser->HashIfLevel++; } @@ -789,29 +739,27 @@ void LexHashIf(struct ParseState *Parser) struct ParseState MacroParser; enum LexToken Token = LexGetRawToken(Parser, &IdentValue, TRUE); - if (Token == TokenIdentifier) - { + if (Token == TokenIdentifier) { /* 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 (Parser->HashIfEvaluateToLevel == Parser->HashIfLevel && IdentValue->Val->Character) { /* #if is active, evaluate to this new level */ Parser->HashIfEvaluateToLevel++; } - + Parser->HashIfLevel++; } @@ -820,13 +768,11 @@ 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) - { + 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 +792,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,30 +830,28 @@ enum LexToken LexGetToken(struct ParseState *Parser, struct Value **Value, int I { enum LexToken Token; int TryNextToken; - + /* implements the pre-processor #if commands */ - do - { + do { int WasPreProcToken = TRUE; Token = LexGetRawToken(Parser, Value, IncPos); - switch (Token) - { - case TokenHashIfdef: LexHashIncPos(Parser, IncPos); LexHashIfdef(Parser, FALSE); break; - case TokenHashIfndef: LexHashIncPos(Parser, IncPos); LexHashIfdef(Parser, TRUE); break; - case TokenHashIf: LexHashIncPos(Parser, IncPos); LexHashIf(Parser); break; - case TokenHashElse: LexHashIncPos(Parser, IncPos); LexHashElse(Parser); break; - case TokenHashEndif: LexHashIncPos(Parser, IncPos); LexHashEndif(Parser); break; - default: WasPreProcToken = FALSE; break; + switch (Token) { + case TokenHashIfdef: LexHashIncPos(Parser, IncPos); LexHashIfdef(Parser, FALSE); break; + case TokenHashIfndef: LexHashIncPos(Parser, IncPos); LexHashIfdef(Parser, TRUE); break; + case TokenHashIf: LexHashIncPos(Parser, IncPos); LexHashIf(Parser); break; + case TokenHashElse: LexHashIncPos(Parser, IncPos); LexHashElse(Parser); break; + case TokenHashEndif: LexHashIncPos(Parser, IncPos); LexHashEndif(Parser); break; + default: WasPreProcToken = FALSE; break; } /* if we're going to reject this token, increment the token pointer to the next one */ TryNextToken = (Parser->HashIfEvaluateToLevel < Parser->HashIfLevel && Token != TokenEOF) || WasPreProcToken; if (!IncPos && TryNextToken) LexGetRawToken(Parser, NULL, TRUE); - + } while (TryNextToken); - + return Token; } @@ -920,8 +864,7 @@ enum LexToken LexRawPeekToken(struct ParseState *Parser) /* find the end of the line */ void LexToEndOfLine(struct ParseState *Parser) { - while (TRUE) - { + while (TRUE) { enum LexToken Token = (enum LexToken)*(unsigned char *)Parser->Pos; if (Token == TokenEndOfLine || Token == TokenEOF) return; @@ -940,44 +883,37 @@ void *LexCopyTokens(struct ParseState *StartParser, struct ParseState *EndParser unsigned char *NewTokenPos; struct TokenLine *ILine; Picoc *pc = StartParser->pc; - - if (pc->InteractiveHead == NULL) - { + + 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 - { + } 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]) - { + 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 - { + } 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; - for (ILine = pc->InteractiveCurrentLine->Next; ILine != NULL && (EndParser->Pos < &ILine->Tokens[0] || EndParser->Pos >= &ILine->Tokens[ILine->NumBytes]); ILine = ILine->Next) - { + for (ILine = pc->InteractiveCurrentLine->Next; ILine != NULL && (EndParser->Pos < &ILine->Tokens[0] || EndParser->Pos >= &ILine->Tokens[ILine->NumBytes]); ILine = ILine->Next) { memcpy(NewTokenPos, &ILine->Tokens[0], ILine->NumBytes - TOKEN_DATA_OFFSET); NewTokenPos += ILine->NumBytes-TOKEN_DATA_OFFSET; } @@ -985,19 +921,18 @@ 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; } /* indicate that we've completed up to this point in the interactive input and free expired tokens */ void LexInteractiveClear(Picoc *pc, struct ParseState *Parser) { - while (pc->InteractiveHead != NULL) - { + while (pc->InteractiveHead != NULL) { struct TokenLine *NextLine = pc->InteractiveHead->Next; - + HeapFreeMem(pc, pc->InteractiveHead->Tokens); HeapFreeMem(pc, pc->InteractiveHead); pc->InteractiveHead = NextLine; @@ -1005,24 +940,22 @@ void LexInteractiveClear(Picoc *pc, struct ParseState *Parser) if (Parser != NULL) Parser->Pos = NULL; - + pc->InteractiveTail = NULL; } /* indicate that we've completed up to this point in the interactive input and free expired tokens */ 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])) - { + 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) - { + + 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..a49e85f 100644 --- a/parse.c +++ b/parse.c @@ -6,14 +6,13 @@ /* deallocate any memory */ void ParseCleanup(Picoc *pc) { - while (pc->CleanupTokenList != NULL) - { + 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; } @@ -22,16 +21,14 @@ void ParseCleanup(Picoc *pc) /* parse a statement, but only run it if Condition is TRUE */ enum ParseResult ParseStatementMaybeRun(struct ParseState *Parser, int Condition, int CheckTrailingSemicolon) { - if (Parser->Mode != RunModeSkip && !Condition) - { + if (Parser->Mode != RunModeSkip && !Condition) { enum RunMode OldMode = Parser->Mode; int Result; Parser->Mode = RunModeSkip; Result = ParseStatement(Parser, CheckTrailingSemicolon); Parser->Mode = OldMode; return Result; - } - else + } else return ParseStatement(Parser, CheckTrailingSemicolon); } @@ -39,19 +36,17 @@ 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) - { + if (Token != TokenCloseBracket && Token != TokenEOF) { /* count the number of parameters */ ParamCount++; - while ((Token = LexGetToken(Parser, NULL, TRUE)) != TokenCloseBracket && Token != TokenEOF) - { + while ((Token = LexGetToken(Parser, NULL, TRUE)) != TokenCloseBracket && Token != TokenEOF) { if (Token == TokenComma) ParamCount++; - } + } } - + return ParamCount; } @@ -70,13 +65,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,44 +79,36 @@ 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++) - { + + 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) - { + 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 - { + } else { /* add a parameter */ TypeParse(&ParamParser, &ParamType, &ParamIdentifier, NULL); - if (ParamType->Base == TypeVoid) - { + if (ParamType->Base == TypeVoid) { /* this isn't a real parameter at all - delete it */ ParamCount--; FuncValue->Val->FuncDef.NumParams--; - } - else - { + } else { FuncValue->Val->FuncDef.ParamType[ParamCount] = ParamType; 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) - { + + if (strcmp(Identifier, "main") == 0) { /* make sure it's int main() */ if ( FuncValue->Val->FuncDef.ReturnType != &pc->IntType && FuncValue->Val->FuncDef.ReturnType != &pc->VoidType ) @@ -131,17 +118,16 @@ 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) LexGetToken(Parser, NULL, TRUE); /* it's a prototype, absorb the trailing semicolon */ - else - { + else { /* 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"); @@ -150,21 +136,18 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp FuncValue->Val->FuncDef.Body.Pos = LexCopyTokens(&FuncBody, Parser); /* is this function already in the global table? */ - if (TableGet(&pc->GlobalTable, Identifier, &OldFuncValue, NULL, NULL, NULL)) - { - if (OldFuncValue->Val->FuncDef.Body.Pos == NULL) - { + if (TableGet(&pc->GlobalTable, Identifier, &OldFuncValue, NULL, NULL, NULL)) { + if (OldFuncValue->Val->FuncDef.Body.Pos == NULL) { /* override an old function prototype */ VariableFree(pc, TableDelete(pc, &pc->GlobalTable, Identifier)); - } - else + } else ProgramFail(Parser, "'%s' is already defined", Identifier); } } if (!TableSet(pc, &pc->GlobalTable, Identifier, FuncValue, (char *)Parser->FileName, Parser->Line, Parser->CharacterPos)) ProgramFail(Parser, "'%s' is already defined", Identifier); - + return FuncValue; } @@ -174,80 +157,71 @@ 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) - { + if (DoAssignment && Parser->Mode == RunModeRun) { struct ParseState CountParser; int NumElements; - + ParserCopy(&CountParser, Parser); NumElements = ParseArrayInitialiser(&CountParser, NewVariable, FALSE); if (NewVariable->Typ->Base != TypeArray) AssignFail(Parser, "%t from array initializer", NewVariable->Typ, NULL, 0, 0, NULL, 0); - if (NewVariable->Typ->ArraySize == 0) - { + if (NewVariable->Typ->ArraySize == 0) { NewVariable->Typ = TypeGetMatching(Parser->pc, Parser, NewVariable->Typ->FromType, NewVariable->Typ->Base, NumElements, NewVariable->Typ->Identifier, TRUE); VariableRealloc(Parser, NewVariable, TypeSizeValue(NewVariable, FALSE)); } - #ifdef DEBUG_ARRAY_INITIALIZER +#ifdef DEBUG_ARRAY_INITIALIZER PRINT_SOURCE_POS; printf("array size: %d \n", NewVariable->Typ->ArraySize); - #endif +#endif } - + /* parse the array initialiser */ Token = LexGetToken(Parser, NULL, FALSE); - while (Token != TokenRightBrace) - { - if (LexGetToken(Parser, NULL, FALSE) == TokenLeftBrace) - { + while (Token != TokenRightBrace) { + if (LexGetToken(Parser, NULL, FALSE) == TokenLeftBrace) { /* this is a sub-array initialiser */ int SubArraySize = 0; - struct Value *SubArray = NewVariable; - if (Parser->Mode == RunModeRun && DoAssignment) - { + struct Value *SubArray = NewVariable; + if (Parser->Mode == RunModeRun && DoAssignment) { SubArraySize = TypeSize(NewVariable->Typ->FromType, NewVariable->Typ->FromType->ArraySize, TRUE); SubArray = VariableAllocValueFromExistingData(Parser, NewVariable->Typ->FromType, (union AnyValue *)(&NewVariable->Val->ArrayMem[0] + SubArraySize * ArrayIndex), TRUE, NewVariable); - #ifdef DEBUG_ARRAY_INITIALIZER +#ifdef DEBUG_ARRAY_INITIALIZER int FullArraySize = TypeSize(NewVariable->Typ, NewVariable->Typ->ArraySize, TRUE); PRINT_SOURCE_POS; PRINT_TYPE(NewVariable->Typ) printf("[%d] subarray size: %d (full: %d,%d) \n", ArrayIndex, SubArraySize, FullArraySize, NewVariable->Typ->ArraySize); - #endif +#endif if (ArrayIndex >= NewVariable->Typ->ArraySize) ProgramFail(Parser, "too many array elements"); } LexGetToken(Parser, NULL, TRUE); ParseArrayInitialiser(Parser, SubArray, DoAssignment); - } - else - { + } else { struct Value *ArrayElement = NULL; - - if (Parser->Mode == RunModeRun && DoAssignment) - { + + 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) - { + 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; } ElementSize = TypeSize(ElementType, ElementType->ArraySize, TRUE); - #ifdef DEBUG_ARRAY_INITIALIZER +#ifdef DEBUG_ARRAY_INITIALIZER PRINT_SOURCE_POS; printf("[%d/%d] element size: %d (x%d) \n", ArrayIndex, TotalSize, ElementSize, ElementType->ArraySize); - #endif +#endif if (ArrayIndex >= TotalSize) ProgramFail(Parser, "too many array elements"); ArrayElement = VariableAllocValueFromExistingData(Parser, ElementType, (union AnyValue *)(&NewVariable->Val->ArrayMem[0] + ElementSize * ArrayIndex), TRUE, NewVariable); @@ -257,31 +231,28 @@ int ParseArrayInitialiser(struct ParseState *Parser, struct Value *NewVariable, if (!ExpressionParse(Parser, &CValue)) ProgramFail(Parser, "expression expected"); - if (Parser->Mode == RunModeRun && DoAssignment) - { + if (Parser->Mode == RunModeRun && DoAssignment) { ExpressionAssign(Parser, ArrayElement, CValue, FALSE, NULL, 0, FALSE); VariableStackPop(Parser, CValue); VariableStackPop(Parser, ArrayElement); } } - + ArrayIndex++; Token = LexGetToken(Parser, NULL, FALSE); - if (Token == TokenComma) - { + if (Token == TokenComma) { LexGetToken(Parser, NULL, TRUE); Token = LexGetToken(Parser, NULL, FALSE); - } - else if (Token != TokenRightBrace) + } else if (Token != TokenRightBrace) ProgramFail(Parser, "comma expected"); } - + if (Token == TokenRightBrace) LexGetToken(Parser, NULL, TRUE); else ProgramFail(Parser, "'}' expected"); - + return ArrayIndex; } @@ -290,20 +261,16 @@ void ParseDeclarationAssignment(struct ParseState *Parser, struct Value *NewVari { struct Value *CValue; - if (LexGetToken(Parser, NULL, FALSE) == TokenLeftBrace) - { + if (LexGetToken(Parser, NULL, FALSE) == TokenLeftBrace) { /* this is an array initialiser */ LexGetToken(Parser, NULL, TRUE); ParseArrayInitialiser(Parser, NewVariable, DoAssignment); - } - else - { + } else { /* this is a normal expression initialiser */ if (!ExpressionParse(Parser, &CValue)) ProgramFail(Parser, "expression expected"); - - if (Parser->Mode == RunModeRun && DoAssignment) - { + + if (Parser->Mode == RunModeRun && DoAssignment) { ExpressionAssign(Parser, NewVariable, CValue, FALSE, NULL, 0, FALSE); VariableStackPop(Parser, CValue); } @@ -322,43 +289,38 @@ int ParseDeclaration(struct ParseState *Parser, enum LexToken Token) Picoc *pc = Parser->pc; TypeParseFront(Parser, &BasicType, &IsStatic); - do - { + do { 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) - { + + if (Identifier != pc->StrEmpty) { /* handle function definitions */ if (LexGetToken(Parser, NULL, FALSE) == TokenOpenBracket) { ParseFunctionDefinition(Parser, Typ, Identifier); return FALSE; - } - else - { + } else { 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) - { + + if (LexGetToken(Parser, NULL, FALSE) == TokenAssign) { /* we're assigning an initial value */ LexGetToken(Parser, NULL, TRUE); ParseDeclarationAssignment(Parser, NewVariable, !IsStatic || FirstVisit); } } } - + Token = LexGetToken(Parser, NULL, FALSE); if (Token == TokenComma) LexGetToken(Parser, NULL, TRUE); - + } while (Token == TokenComma); - + return TRUE; } @@ -372,17 +334,16 @@ void ParseMacroDefinition(struct ParseState *Parser) if (LexGetToken(Parser, &MacroName, TRUE) != TokenIdentifier) ProgramFail(Parser, "identifier expected"); - + MacroNameStr = MacroName->Val->Identifier; - - if (LexRawPeekToken(Parser) == TokenOpenMacroBracket) - { + + if (LexRawPeekToken(Parser) == TokenOpenMacroBracket) { /* it's a parameterised macro, read the parameters */ enum LexToken Token = LexGetToken(Parser, NULL, TRUE); 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,37 +351,34 @@ void ParseMacroDefinition(struct ParseState *Parser) MacroValue->Val->MacroDef.ParamName = (char **)((char *)MacroValue->Val + sizeof(struct MacroDef)); Token = LexGetToken(Parser, &ParamName, TRUE); - - while (Token == TokenIdentifier) - { + + 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"); - } - else - { + } else { /* allocate a simple unparameterised macro */ 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 +407,60 @@ 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) - { + + 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) - { + + 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; @@ -521,22 +477,19 @@ enum RunMode ParseBlock(struct ParseState *Parser, int AbsorbOpenBrace, int Cond if (AbsorbOpenBrace && LexGetToken(Parser, NULL, TRUE) != TokenLeftBrace) ProgramFail(Parser, "'{' expected"); - if (Parser->Mode == RunModeSkip || !Condition) - { + if (Parser->Mode == RunModeSkip || !Condition) { /* condition failed - skip this block instead */ enum RunMode OldMode = Parser->Mode; Parser->Mode = RunModeSkip; - while (ParseStatement(Parser, TRUE) == ParseResultOk) - {} + while (ParseStatement(Parser, TRUE) == ParseResultOk) { + } Parser->Mode = OldMode; - } - else - { + } else { /* just run it in its current mode */ - while (ParseStatement(Parser, TRUE) == ParseResultOk) - {} + while (ParseStatement(Parser, TRUE) == ParseResultOk) { + } } - + if (LexGetToken(Parser, NULL, TRUE) != TokenRightBrace) ProgramFail(Parser, "'}' expected"); @@ -552,11 +505,10 @@ void ParseTypedef(struct ParseState *Parser) struct ValueType **TypPtr; char *TypeName; struct Value InitValue; - + TypeParse(Parser, &Typ, &TypeName, NULL); - - if (Parser->Mode == RunModeRun) - { + + if (Parser->Mode == RunModeRun) { TypPtr = &Typ; InitValue.Typ = &Parser->pc->TypeType; InitValue.Val = (union AnyValue *)TypPtr; @@ -573,362 +525,280 @@ 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)) - { - VariableGet(Parser->pc, Parser, LexerValue->Val->Identifier, &VarValue); - if (VarValue->Typ->Base == Type_Type) - { - *Parser = PreState; - ParseDeclaration(Parser, Token); - break; - } - } - else - { - /* it might be a goto label */ - enum LexToken NextToken = LexGetToken(Parser, NULL, FALSE); - if (NextToken == TokenColon) - { - /* declare the identifier as a goto label */ - LexGetToken(Parser, NULL, TRUE); - if (Parser->Mode == RunModeGoto && LexerValue->Val->Identifier == Parser->SearchGotoLabel) - Parser->Mode = RunModeRun; - - CheckTrailingSemicolon = FALSE; - break; - } -#ifdef FEATURE_AUTO_DECLARE_VARIABLES - else /* new_identifier = something */ - { /* try to guess type and declare the variable based on assigned value */ - if (NextToken == TokenAssign && !VariableDefinedAndOutOfScope(Parser->pc, LexerValue->Val->Identifier)) - { - if (Parser->Mode == RunModeRun) - { - struct Value *CValue; - char* Identifier = LexerValue->Val->Identifier; - LexGetToken(Parser, NULL, TRUE); - if (!ExpressionParse(Parser, &CValue)) - { - ProgramFail(Parser, "expected: expression"); - } - - #if 0 - PRINT_SOURCE_POS; - PlatformPrintf(Parser->pc->CStdOut, "%t %s = %d;\n", CValue->Typ, Identifier, CValue->Val->Integer); - printf("%d\n", VariableDefined(Parser->pc, Identifier)); - #endif - VariableDefine(Parser->pc, Parser, Identifier, CValue, CValue->Typ, TRUE); - break; + 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)) { + VariableGet(Parser->pc, Parser, LexerValue->Val->Identifier, &VarValue); + if (VarValue->Typ->Base == Type_Type) { + *Parser = PreState; + ParseDeclaration(Parser, Token); + break; + } + } else { + /* it might be a goto label */ + enum LexToken NextToken = LexGetToken(Parser, NULL, FALSE); + if (NextToken == TokenColon) { + /* declare the identifier as a goto label */ + LexGetToken(Parser, NULL, TRUE); + if (Parser->Mode == RunModeGoto && LexerValue->Val->Identifier == Parser->SearchGotoLabel) + Parser->Mode = RunModeRun; + CheckTrailingSemicolon = FALSE; + break; + } +#ifdef FEATURE_AUTO_DECLARE_VARIABLES + else /* new_identifier = something */ { + /* try to guess type and declare the variable based on assigned value */ + if (NextToken == TokenAssign && !VariableDefinedAndOutOfScope(Parser->pc, LexerValue->Val->Identifier)) { + if (Parser->Mode == RunModeRun) { + struct Value *CValue; + char* Identifier = LexerValue->Val->Identifier; + LexGetToken(Parser, NULL, TRUE); + if (!ExpressionParse(Parser, &CValue)) { + ProgramFail(Parser, "expected: expression"); } +#if 0 + PRINT_SOURCE_POS; + PlatformPrintf(Parser->pc->CStdOut, "%t %s = %d;\n", CValue->Typ, Identifier, CValue->Val->Integer); + printf("%d\n", VariableDefined(Parser->pc, Identifier)); +#endif + VariableDefine(Parser->pc, Parser, Identifier, CValue, CValue->Typ, TRUE); + break; } } -#endif } - /* else fallthrough to expression */ +#endif + } + /* else fallthrough to expression */ /* no break */ - - case TokenAsterisk: - case TokenAmpersand: - case TokenIncrement: - case TokenDecrement: - case TokenOpenBracket: - *Parser = PreState; - ExpressionParse(Parser, &CValue); - if (Parser->Mode == RunModeRun) - VariableStackPop(Parser, CValue); - break; - - case TokenLeftBrace: - ParseBlock(Parser, FALSE, TRUE); - CheckTrailingSemicolon = FALSE; - break; - - case TokenIf: + case TokenAsterisk: + case TokenAmpersand: + case TokenIncrement: + case TokenDecrement: + case TokenOpenBracket: + *Parser = PreState; + ExpressionParse(Parser, &CValue); + 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); + if (ParseStatementMaybeRun(Parser, !Condition, TRUE) != ParseResultOk) + ProgramFail(Parser, "statement expected"); + } + CheckTrailingSemicolon = FALSE; + break; + case TokenWhile: + { + struct ParseState PreConditional; + enum RunMode PreMode = Parser->Mode; 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); - if (ParseStatementMaybeRun(Parser, !Condition, TRUE) != ParseResultOk) + ParserCopyPos(&PreConditional, Parser); + do { + ParserCopyPos(Parser, &PreConditional); + 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 TokenWhile: - { - struct ParseState PreConditional; - enum RunMode PreMode = Parser->Mode; - + } + break; + case TokenDo: + { + struct ParseState PreStatement; + enum RunMode PreMode = Parser->Mode; + ParserCopyPos(&PreStatement, Parser); + do { + 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"); - - ParserCopyPos(&PreConditional, Parser); - do - { - ParserCopyPos(Parser, &PreConditional); - 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; - enum RunMode PreMode = Parser->Mode; - ParserCopyPos(&PreStatement, Parser); - do - { - 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); - - if (Parser->Mode == RunModeBreak) - Parser->Mode = PreMode; - } - break; - - case TokenFor: - ParseFor(Parser); - CheckTrailingSemicolon = FALSE; - break; - - case TokenSemicolon: - CheckTrailingSemicolon = FALSE; - break; - - case TokenIntType: - case TokenShortType: - case TokenCharType: - case TokenLongType: - case TokenFloatType: - case TokenDoubleType: - case TokenVoidType: - case TokenStructType: - case TokenUnionType: - case TokenEnumType: - case TokenSignedType: - case TokenUnsignedType: - case TokenStaticType: - case TokenAutoType: - case TokenRegisterType: - case TokenExternType: - *Parser = PreState; - CheckTrailingSemicolon = ParseDeclaration(Parser, Token); - break; - - case TokenHashDefine: - ParseMacroDefinition(Parser); - CheckTrailingSemicolon = FALSE; - break; - + Condition = ExpressionParseInt(Parser); + if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) + ProgramFail(Parser, "')' expected"); + } while (Condition && Parser->Mode == RunModeRun); + if (Parser->Mode == RunModeBreak) + Parser->Mode = PreMode; + } + break; + case TokenFor: + ParseFor(Parser); + CheckTrailingSemicolon = FALSE; + break; + case TokenSemicolon: + CheckTrailingSemicolon = FALSE; + break; + case TokenIntType: + case TokenShortType: + case TokenCharType: + case TokenLongType: + case TokenFloatType: + case TokenDoubleType: + case TokenVoidType: + case TokenStructType: + case TokenUnionType: + case TokenEnumType: + case TokenSignedType: + case TokenUnsignedType: + case TokenStaticType: + case TokenAutoType: + case TokenRegisterType: + case TokenExternType: + *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; + case TokenHashInclude: + if (LexGetToken(Parser, &LexerValue, TRUE) != TokenStringConstant) + ProgramFail(Parser, "\"filename.h\" expected"); + IncludeFile(Parser->pc, (char *)LexerValue->Val->Pointer); + CheckTrailingSemicolon = FALSE; + break; #endif - - case TokenSwitch: - if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) - ProgramFail(Parser, "'(' expected"); - + 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; + Parser->SearchLabel = OldSearchLabel; + } + CheckTrailingSemicolon = FALSE; + break; + case TokenCase: + if (Parser->Mode == RunModeCaseSearch) { + Parser->Mode = RunModeRun; 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; - - Parser->SearchLabel = OldSearchLabel; - } - - CheckTrailingSemicolon = FALSE; - break; - - case TokenCase: - if (Parser->Mode == RunModeCaseSearch) - { - Parser->Mode = RunModeRun; - Condition = ExpressionParseInt(Parser); - Parser->Mode = RunModeCaseSearch; - } - 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; - - case TokenBreak: - if (Parser->Mode == RunModeRun) - Parser->Mode = RunModeBreak; - break; - - case TokenContinue: - if (Parser->Mode == RunModeRun) - Parser->Mode = RunModeContinue; - break; - - case TokenReturn: - if (Parser->Mode == RunModeRun) - { - if (!Parser->pc->TopStackFrame || Parser->pc->TopStackFrame->ReturnValue->Typ->Base != TypeVoid) - { - 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 - ExpressionAssign(Parser, Parser->pc->TopStackFrame->ReturnValue, CValue, TRUE, NULL, 0, FALSE); - - VariableStackPop(Parser, CValue); - } + Parser->Mode = RunModeCaseSearch; + } 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; + case TokenBreak: + if (Parser->Mode == RunModeRun) + Parser->Mode = RunModeBreak; + break; + case TokenContinue: + if (Parser->Mode == RunModeRun) + Parser->Mode = RunModeContinue; + break; + case TokenReturn: + if (Parser->Mode == RunModeRun) { + if (!Parser->pc->TopStackFrame || Parser->pc->TopStackFrame->ReturnValue->Typ->Base != TypeVoid) { + 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 - { - if (ExpressionParse(Parser, &CValue)) - ProgramFail(Parser, "value in return from a void function"); - } - - Parser->Mode = RunModeReturn; + ExpressionAssign(Parser, Parser->pc->TopStackFrame->ReturnValue, CValue, TRUE, NULL, 0, FALSE); + VariableStackPop(Parser, CValue); + } else { + if (ExpressionParse(Parser, &CValue)) + ProgramFail(Parser, "value in return from a void function"); } - else - ExpressionParse(Parser, &CValue); - break; - - 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: + Parser->Mode = RunModeReturn; + } + else + ExpressionParse(Parser, &CValue); + break; + 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) - { + 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; + default: + *Parser = PreState; + return ParseResultError; } - - if (CheckTrailingSemicolon) - { + + if (CheckTrailingSemicolon) { if (LexGetToken(Parser, NULL, TRUE) != TokenSemicolon) ProgramFail(Parser, "';' expected"); } - + return ParseResultOk; } @@ -939,36 +809,35 @@ 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) - { + 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,22 +848,21 @@ 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); - do - { + do { 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 ed4122f..0098dad 100644 --- a/picoc.c +++ b/picoc.c @@ -20,8 +20,7 @@ int main(int argc, char **argv) int StackSize = getenv("STACKSIZE") ? atoi(getenv("STACKSIZE")) : PICOC_STACK_SIZE; Picoc pc; - if (argc < 2) - { + if (argc < 2) { printf(PICOC_VERSION " \n" "Format: picoc ... [- ...] : run a program (calls main() to start it)\n" " picoc -s ... [- ...] : script mode - runs the program without calling main()\n" @@ -31,22 +30,17 @@ int main(int argc, char **argv) PicocInitialise(&pc, StackSize); - if (strcmp(argv[ParamCount], "-s") == 0 || strcmp(argv[ParamCount], "-m") == 0) - { + if (strcmp(argv[ParamCount], "-s") == 0 || strcmp(argv[ParamCount], "-m") == 0) { DontRunMain = TRUE; PicocIncludeAllSystemHeaders(&pc); ParamCount++; } - if (argc > ParamCount && strcmp(argv[ParamCount], "-i") == 0) - { + if (argc > ParamCount && strcmp(argv[ParamCount], "-i") == 0) { PicocIncludeAllSystemHeaders(&pc); PicocParseInteractive(&pc); - } - else - { - if (PicocPlatformSetExitPoint(&pc)) - { + } else { + if (PicocPlatformSetExitPoint(&pc)) { PicocCleanup(&pc); return pc.PicocExitValue; } @@ -62,11 +56,12 @@ int main(int argc, char **argv) return pc.PicocExitValue; } #elif defined(SURVEYOR_HOST) -# define HEAP_SIZE C_HEAPSIZE -# include -# include "../srv.h" -# include "../print.h" -# include "../string.h" + +#define HEAP_SIZE C_HEAPSIZE +#include +#include "../srv.h" +#include "../print.h" +#include "../string.h" int picoc(char *SourceStr) { @@ -74,12 +69,9 @@ int picoc(char *SourceStr) PicocInitialise(HEAP_SIZE); - if (SourceStr) - { - for (pos = SourceStr; *pos != 0; pos++) - { - if (*pos == 0x1a) - { + if (SourceStr) { + for (pos = SourceStr; *pos != 0; pos++) { + if (*pos == 0x1a) { *pos = 0x20; } } diff --git a/platform.c b/platform.c index 67ae13b..545c94b 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,29 +59,25 @@ 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"); - if (FuncValue->Val->FuncDef.NumParams != 0) - { + if (FuncValue->Val->FuncDef.NumParams != 0) { /* define the arguments */ VariableDefinePlatformVar(pc, NULL, "__argc", &pc->IntType, (union AnyValue *)&argc, FALSE); VariableDefinePlatformVar(pc, NULL, "__argv", pc->CharPtrPtrType, (union AnyValue *)&argv, FALSE); } - if (FuncValue->Val->FuncDef.ReturnType == &pc->VoidType) - { + if (FuncValue->Val->FuncDef.ReturnType == &pc->VoidType) { if (FuncValue->Val->FuncDef.NumParams == 0) PicocParse(pc, "startup", CALL_MAIN_NO_ARGS_RETURN_VOID, strlen(CALL_MAIN_NO_ARGS_RETURN_VOID), TRUE, TRUE, FALSE, TRUE); else PicocParse(pc, "startup", CALL_MAIN_WITH_ARGS_RETURN_VOID, strlen(CALL_MAIN_WITH_ARGS_RETURN_VOID), TRUE, TRUE, FALSE, TRUE); - } - else - { + } 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,38 +92,33 @@ void PrintSourceTextErrorLine(IOFILE *Stream, const char *FileName, const char * const char *LinePos; const char *CPos; int CCount; - - if (SourceText != NULL) - { + + if (SourceText != NULL) { /* find the source line */ - for (LinePos = SourceText, LineCount = 1; *LinePos != '\0' && LineCount < Line; LinePos++) - { + for (LinePos = SourceText, LineCount = 1; *LinePos != '\0' && LineCount < Line; LinePos++) { 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++) - { + for (CPos = LinePos, CCount = 0; *CPos != '\n' && *CPos != '\0' && (CCount < CharacterPos || *CPos == ' '); CPos++, CCount++) { if (*CPos == '\t') PrintCh('\t', Stream); else PrintCh(' ', Stream); } - } - else - { + } else { /* assume we're in interactive mode - try to make the arrow match up with the input text */ for (CCount = 0; CCount < CharacterPos + (int)strlen(INTERACTIVE_PROMPT_STATEMENT); CCount++) PrintCh(' ', Stream); } PlatformPrintf(Stream, "^\n%s:%d:%d ", FileName, Line, CharacterPos); - + } /* exit with a message */ @@ -159,18 +150,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 +183,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,14 +192,11 @@ 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 == '%') - { + + for (FPos = Format; *FPos != '\0'; FPos++) { + if (*FPos == '%') { FPos++; - switch (*FPos) - { + switch (*FPos) { case 's': PrintStr(va_arg(Args, char *), Stream); break; case 'd': PrintSimpleInt(va_arg(Args, int), Stream); break; case 'c': PrintCh(va_arg(Args, int), Stream); break; @@ -230,16 +218,12 @@ 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') - { + + while (CPos > 1) { + if (TempNameBuffer[CPos] < '9') { TempNameBuffer[CPos]++; return TableStrRegister(pc, TempNameBuffer); - } - else - { + } else { TempNameBuffer[CPos] = '0'; CPos--; } diff --git a/table.c b/table.c index 748e8f9..c748519 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,14 @@ 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) - { + + 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,26 +41,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) - { + + 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 */ + + if (FoundEntry == NULL) { /* add it to the table */ struct TableEntry *NewEntry = VariableAlloc(pc, NULL, sizeof(struct TableEntry), Tbl->OnHeap); NewEntry->DeclFileName = DeclFileName; NewEntry->DeclLine = DeclLine; @@ -76,7 +73,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 +81,15 @@ 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) - { + + if (DeclFileName != NULL) { *DeclFileName = FoundEntry->DeclFileName; *DeclLine = FoundEntry->DeclLine; *DeclColumn = FoundEntry->DeclColumn; } - + return TRUE; } @@ -102,11 +98,9 @@ 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) - { + + for (EntryPtr = &Tbl->HashTable[HashValue]; *EntryPtr != NULL; EntryPtr = &(*EntryPtr)->Next) { + if ((*EntryPtr)->p.v.Key == Key) { struct TableEntry *DeleteEntry = *EntryPtr; struct Value *Val = DeleteEntry->p.v.Val; *EntryPtr = DeleteEntry->Next; @@ -124,13 +118,12 @@ 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) - { + + 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,15 +133,14 @@ 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 - { /* add it to the table - we economise by not allocating the whole structure here */ + else { /* add it to the table - we economise by not allocating the whole structure here */ 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,11 +166,9 @@ 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) - { + + for (Count = 0; Count < pc->StringTable.Size; Count++) { + for (Entry = pc->StringTable.HashTable[Count]; Entry != NULL; Entry = NextEntry) { NextEntry = Entry->Next; HeapFreeMem(pc, Entry); } diff --git a/type.c b/type.c index 21e72db..fdd9b2f 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,21 +36,19 @@ 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 (ThisType != NULL) { if (AllowDuplicates) return ThisType; else ProgramFail(Parser, "data type '%s' is already defined", Identifier); } - - switch (Base) - { - case TypePointer: Sizeof = sizeof(void *); AlignBytes = PointerAlignBytes; break; - case TypeArray: Sizeof = ArraySize * ParentType->Sizeof; AlignBytes = ParentType->AlignBytes; break; - case TypeEnum: Sizeof = sizeof(int); AlignBytes = IntAlignBytes; break; - default: Sizeof = 0; AlignBytes = 0; break; /* structs and unions will get bigger when we add members to them */ + + switch (Base) { + case TypePointer: Sizeof = sizeof(void *); AlignBytes = PointerAlignBytes; break; + case TypeArray: Sizeof = ArraySize * ParentType->Sizeof; AlignBytes = ParentType->AlignBytes; break; + case TypeEnum: Sizeof = sizeof(int); AlignBytes = IntAlignBytes; break; + default: Sizeof = 0; AlignBytes = 0; break; /* structs and unions will get bigger when we add members to them */ } return TypeAdd(pc, Parser, ParentType, Base, ArraySize, Identifier, Sizeof, AlignBytes); @@ -114,10 +112,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,17 +146,14 @@ 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) - { + for (SubType = Typ->DerivedTypeList; SubType != NULL; SubType = NextSubType) { NextSubType = SubType->Next; TypeCleanupNode(pc, SubType); - if (SubType->OnHeap) - { + if (SubType->OnHeap) { /* if it's a struct or union deallocate all the member values */ - if (SubType->Members != NULL) - { + if (SubType->Members != NULL) { VariableTableCleanup(pc, SubType->Members); HeapFreeMem(pc, SubType->Members); } @@ -185,16 +180,13 @@ 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) - { + if (Token == TokenIdentifier) { LexGetToken(Parser, &LexValue, TRUE); StructIdentifier = LexValue->Val->Identifier; Token = LexGetToken(Parser, NULL, FALSE); - } - else - { + } else { static char TempNameBuf[7] = "^s0000"; StructIdentifier = PlatformMakeTempName(pc, TempNameBuf); } @@ -204,43 +196,39 @@ void TypeParseStruct(struct ParseState *Parser, struct ValueType **Typ, int IsSt ProgramFail(Parser, "data type '%t' is already defined", *Typ); Token = LexGetToken(Parser, NULL, FALSE); - if (Token != TokenLeftBrace) - { + 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) - { + 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 - { + } 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 +238,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 +260,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,35 +279,31 @@ 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) - { + if (Token == TokenIdentifier) { LexGetToken(Parser, &LexValue, TRUE); EnumIdentifier = LexValue->Val->Identifier; Token = LexGetToken(Parser, NULL, FALSE); - } - else - { + } else { static char TempNameBuf[7] = "^e0000"; EnumIdentifier = PlatformMakeTempName(pc, TempNameBuf); } TypeGetMatching(pc, Parser, &pc->UberType, TypeEnum, 0, EnumIdentifier, Token != TokenLeftBrace); *Typ = &pc->IntType; - if (Token != TokenLeftBrace) - { + 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 +311,20 @@ 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) - { + 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); } @@ -361,70 +343,65 @@ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ, int *IsSta /* ignore leading type qualifiers */ ParserCopy(&Before, Parser); Token = LexGetToken(Parser, &LexerValue, TRUE); - while (Token == TokenStaticType || Token == TokenAutoType || Token == TokenRegisterType || Token == TokenExternType) - { + while (Token == TokenStaticType || Token == TokenAutoType || Token == TokenRegisterType || Token == TokenExternType) { 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) - { + 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 (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; - case TokenShortType: *Typ = Unsigned ? &pc->UnsignedShortType : &pc->ShortType; break; - case TokenCharType: *Typ = Unsigned ? &pc->UnsignedCharType : &pc->CharType; break; - case TokenLongType: *Typ = Unsigned ? &pc->UnsignedLongType : &pc->LongType; break; + + switch (Token) { + case TokenIntType: *Typ = Unsigned ? &pc->UnsignedIntType : &pc->IntType; break; + case TokenShortType: *Typ = Unsigned ? &pc->UnsignedShortType : &pc->ShortType; break; + case TokenCharType: *Typ = Unsigned ? &pc->UnsignedCharType : &pc->CharType; break; + case TokenLongType: *Typ = Unsigned ? &pc->UnsignedLongType : &pc->LongType; break; #ifndef NO_FP - case TokenFloatType: case TokenDoubleType: *Typ = &pc->FPType; break; + case TokenFloatType: case TokenDoubleType: *Typ = &pc->FPType; break; #endif - case TokenVoidType: *Typ = &pc->VoidType; break; - - case TokenStructType: case TokenUnionType: - if (*Typ != NULL) - ProgramFail(Parser, "bad type declaration"); - - TypeParseStruct(Parser, Typ, Token == TokenStructType); - break; + case TokenVoidType: *Typ = &pc->VoidType; break; + case TokenStructType: case TokenUnionType: + if (*Typ != NULL) + ProgramFail(Parser, "bad type declaration"); - 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); - *Typ = VarValue->Val->Typ; - break; + TypeParseStruct(Parser, Typ, Token == TokenStructType); + break; - default: ParserCopy(Parser, &Before); return FALSE; + 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); + *Typ = VarValue->Val->Typ; + break; + + default: ParserCopy(Parser, &Before); return FALSE; } - + return TRUE; } @@ -436,32 +413,26 @@ struct ValueType *TypeParseBack(struct ParseState *Parser, struct ValueType *Fro ParserCopy(&Before, Parser); Token = LexGetToken(Parser, NULL, TRUE); - if (Token == TokenLeftSquareBracket) - { + if (Token == TokenLeftSquareBracket) { /* add another array bound */ - if (LexGetToken(Parser, NULL, FALSE) == TokenRightSquareBracket) - { + if (LexGetToken(Parser, NULL, FALSE) == TokenRightSquareBracket) { /* an unsized array */ LexGetToken(Parser, NULL, TRUE); return TypeGetMatching(Parser->pc, Parser, TypeParseBack(Parser, FromType), TypeArray, 0, Parser->pc->StrEmpty, TRUE); - } - else - { + } else { /* get a numeric array size */ enum RunMode OldMode = Parser->Mode; int ArraySize; 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); } - } - else - { + } else { /* the type specification has finished */ ParserCopy(Parser, &Before); return FromType; @@ -477,46 +448,43 @@ void TypeParseIdentPart(struct ParseState *Parser, struct ValueType *BasicTyp, s int Done = FALSE; *Typ = BasicTyp; *Identifier = Parser->pc->StrEmpty; - - while (!Done) - { + + while (!Done) { ParserCopy(&Before, Parser); Token = LexGetToken(Parser, &LexValue, TRUE); - switch (Token) - { - 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"); + switch (Token) { + case TokenOpenBracket: + 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; + 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) - { + if (*Identifier != Parser->pc->StrEmpty) { /* parse stuff after the identifier */ *Typ = TypeParseBack(Parser, *Typ); } @@ -526,7 +494,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 +504,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..0f0bd4a 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 */ @@ -18,8 +18,7 @@ void VariableInit(Picoc *pc) /* deallocate the contents of a variable */ void VariableFree(Picoc *pc, struct Value *Val) { - if (Val->ValOnHeap || Val->AnyValOnHeap) - { + if (Val->ValOnHeap || Val->AnyValOnHeap) { /* free function bodies */ if (Val->Typ == &pc->FunctionType && Val->Val->FuncDef.Intrinsic == NULL && Val->Val->FuncDef.Body.Pos != NULL) HeapFreeMem(pc, (void *)Val->Val->FuncDef.Body.Pos); @@ -44,14 +43,12 @@ 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) - { + + 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 +65,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 +92,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 +107,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 +124,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 +139,7 @@ struct Value *VariableAllocValueFromExistingData(struct ParseState *Parser, stru NewValue->ValOnStack = FALSE; NewValue->IsLValue = IsLValue; NewValue->LValueFrom = LValueFrom; - + return NewValue; } @@ -157,7 +154,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; } @@ -168,10 +165,10 @@ int VariableScopeBegin(struct ParseState * Parser, int* OldScopeID) struct TableEntry *NextEntry; Picoc * pc = Parser->pc; int Count; - #ifdef VAR_SCOPE_DEBUG +#ifdef VAR_SCOPE_DEBUG int FirstPrint = 0; - #endif - +#endif + struct Table * HashTable = (pc->TopStackFrame == NULL) ? &(pc->GlobalTable) : &(pc->TopStackFrame)->LocalTable; if (Parser->ScopeID == -1) return -1; @@ -181,21 +178,18 @@ 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) - { + + for (Count = 0; Count < HashTable->Size; Count++) { + for (Entry = HashTable->HashTable[Count]; Entry != NULL; Entry = NextEntry) { NextEntry = Entry->Next; - if (Entry->p.v.Val->ScopeID == Parser->ScopeID && Entry->p.v.Val->OutOfScope) - { + if (Entry->p.v.Val->ScopeID == Parser->ScopeID && Entry->p.v.Val->OutOfScope) { Entry->p.v.Val->OutOfScope = FALSE; Entry->p.v.Key = (char*)((intptr_t)Entry->p.v.Key & ~1); - #ifdef VAR_SCOPE_DEBUG +#ifdef VAR_SCOPE_DEBUG if (!FirstPrint) { PRINT_SOURCE_POS; } FirstPrint = 1; printf(">>> back into scope: %s %x %d\n", Entry->p.v.Key, Entry->p.v.Val->ScopeID, Entry->p.v.Val->Val->Integer); - #endif +#endif } } } @@ -209,26 +203,25 @@ void VariableScopeEnd(struct ParseState * Parser, int ScopeID, int PrevScopeID) struct TableEntry *NextEntry; Picoc * pc = Parser->pc; int Count; - #ifdef VAR_SCOPE_DEBUG +#ifdef VAR_SCOPE_DEBUG int FirstPrint = 0; - #endif +#endif struct Table * HashTable = (pc->TopStackFrame == NULL) ? &(pc->GlobalTable) : &(pc->TopStackFrame)->LocalTable; if (ScopeID == -1) return; - for (Count = 0; Count < HashTable->Size; Count++) - { - for (Entry = HashTable->HashTable[Count]; Entry != NULL; Entry = NextEntry) - { + for (Count = 0; Count < HashTable->Size; Count++) { + for (Entry = HashTable->HashTable[Count]; Entry != NULL; Entry = NextEntry) { NextEntry = Entry->Next; - if (Entry->p.v.Val->ScopeID == ScopeID && !Entry->p.v.Val->OutOfScope) - { - #ifdef VAR_SCOPE_DEBUG - if (!FirstPrint) { PRINT_SOURCE_POS; } + if (Entry->p.v.Val->ScopeID == ScopeID && !Entry->p.v.Val->OutOfScope) { +#ifdef VAR_SCOPE_DEBUG + if (!FirstPrint) { + PRINT_SOURCE_POS; + } FirstPrint = 1; printf(">>> out of scope: %s %x %d\n", Entry->p.v.Key, Entry->p.v.Val->ScopeID, Entry->p.v.Val->Val->Integer); - #endif +#endif Entry->p.v.Val->OutOfScope = TRUE; Entry->p.v.Key = (char*)((intptr_t)Entry->p.v.Key | 1); /* alter the key so it won't be found by normal searches */ } @@ -244,10 +237,8 @@ int VariableDefinedAndOutOfScope(Picoc * pc, const char* Ident) int Count; struct Table * HashTable = (pc->TopStackFrame == NULL) ? &(pc->GlobalTable) : &(pc->TopStackFrame)->LocalTable; - for (Count = 0; Count < HashTable->Size; Count++) - { - for (Entry = HashTable->HashTable[Count]; Entry != NULL; Entry = Entry->Next) - { + for (Count = 0; Count < HashTable->Size; Count++) { + for (Entry = HashTable->HashTable[Count]; Entry != NULL; Entry = Entry->Next) { if (Entry->p.v.Val->OutOfScope && (char*)((intptr_t)Entry->p.v.Key & ~1) == Ident) return TRUE; } @@ -260,24 +251,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,39 +280,36 @@ 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); - if (IsStatic) - { + if (IsStatic) { char MangledName[LINEBUFFER_MAX]; 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) - { + + if (pc->TopStackFrame != NULL) { /* we're inside a function */ if (MNEnd - MNPos > 0) *MNPos++ = '/'; 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)) - { + if (!TableGet(&pc->GlobalTable, RegisteredMangledName, &ExistingValue, &DeclFileName, &DeclLine, &DeclColumn)) { /* define the mangled-named static variable store in the global scope */ ExistingValue = VariableAllocValueFromType(Parser->pc, Parser, Typ, TRUE, NULL, TRUE); TableSet(pc, &pc->GlobalTable, (char *)RegisteredMangledName, ExistingValue, (char *)Parser->FileName, Parser->Line, Parser->CharacterPos); @@ -331,9 +319,7 @@ struct Value *VariableDefineButIgnoreIdentical(struct ParseState *Parser, char * /* static variable exists in the global scope - now make a mirroring variable in our own scope with the short name */ VariableDefinePlatformVar(Parser->pc, Parser, Ident, ExistingValue->Typ, ExistingValue->Val, TRUE); return ExistingValue; - } - else - { + } else { if (Parser->Line != 0 && TableGet((pc->TopStackFrame == NULL) ? &pc->GlobalTable : &pc->TopStackFrame->LocalTable, Ident, &ExistingValue, &DeclFileName, &DeclLine, &DeclColumn) && DeclFileName == Parser->FileName && DeclLine == Parser->Line && DeclColumn == Parser->CharacterPos) return ExistingValue; @@ -346,9 +332,8 @@ 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 (pc->TopStackFrame == NULL || !TableGet(&pc->TopStackFrame->LocalTable, Ident, &FoundValue, NULL, NULL, NULL)) { if (!TableGet(&pc->GlobalTable, Ident, &FoundValue, NULL, NULL, NULL)) return FALSE; } @@ -359,10 +344,8 @@ int VariableDefined(Picoc *pc, const char *Ident) /* get the value of a variable. must be defined. Ident must be registered */ void VariableGet(Picoc *pc, struct ParseState *Parser, const char *Ident, struct Value **LVal) { - if (pc->TopStackFrame == NULL || !TableGet(&pc->TopStackFrame->LocalTable, Ident, LVal, NULL, NULL, NULL)) - { - if (!TableGet(&pc->GlobalTable, Ident, LVal, NULL, NULL, NULL)) - { + if (pc->TopStackFrame == NULL || !TableGet(&pc->TopStackFrame->LocalTable, Ident, LVal, NULL, NULL, NULL)) { + if (!TableGet(&pc->GlobalTable, Ident, LVal, NULL, NULL, NULL)) { if (VariableDefinedAndOutOfScope(pc, Ident)) ProgramFail(Parser, "'%s' is out of scope", Ident); else @@ -377,7 +360,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 +369,22 @@ 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->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) + } 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 +393,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 +412,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 +440,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;