formatting

This commit is contained in:
Joseph Poirier 2015-06-06 23:40:08 -05:00
parent c8c01cd1f5
commit a61bd97d9b
12 changed files with 1574 additions and 2065 deletions

View file

@ -39,8 +39,7 @@ void LibraryAdd(Picoc *pc, struct Table *GlobalTable, const char *LibraryName, s
char *IntrinsicName = TableStrRegister(pc, "c library"); char *IntrinsicName = TableStrRegister(pc, "c library");
/* read all the library definitions */ /* read all the library definitions */
for (Count = 0; FuncList[Count].Prototype != NULL; Count++) for (Count = 0; FuncList[Count].Prototype != NULL; Count++) {
{
Tokens = LexAnalyse(pc, IntrinsicName, FuncList[Count].Prototype, strlen((char *)FuncList[Count].Prototype), NULL); Tokens = LexAnalyse(pc, IntrinsicName, FuncList[Count].Prototype, strlen((char *)FuncList[Count].Prototype), NULL);
LexInitParser(&Parser, pc, FuncList[Count].Prototype, Tokens, IntrinsicName, TRUE, FALSE); LexInitParser(&Parser, pc, FuncList[Count].Prototype, Tokens, IntrinsicName, TRUE, FALSE);
TypeParse(&Parser, &ReturnType, &Identifier, NULL); TypeParse(&Parser, &ReturnType, &Identifier, NULL);
@ -53,8 +52,7 @@ void LibraryAdd(Picoc *pc, struct Table *GlobalTable, const char *LibraryName, s
/* print a type to a stream without using printf/sprintf */ /* print a type to a stream without using printf/sprintf */
void PrintType(struct ValueType *Typ, IOFILE *Stream) void PrintType(struct ValueType *Typ, IOFILE *Stream)
{ {
switch (Typ->Base) switch (Typ->Base) {
{
case TypeVoid: PrintStr("void", Stream); break; case TypeVoid: PrintStr("void", Stream); break;
case TypeInt: PrintStr("int", Stream); break; case TypeInt: PrintStr("int", Stream); break;
case TypeShort: PrintStr("short", Stream); break; case TypeShort: PrintStr("short", Stream); break;
@ -144,8 +142,7 @@ void PrintUnsigned(unsigned long Num, unsigned int Base, int FieldWidth, int Zer
if (Num == 0) if (Num == 0)
Result[--ResPos] = '0'; Result[--ResPos] = '0';
while (Num > 0) while (Num > 0) {
{
unsigned long NextNum = Num / Base; unsigned long NextNum = Num / Base;
unsigned long Digit = Num - NextNum * Base; unsigned long Digit = Num - NextNum * Base;
if (Digit < 10) if (Digit < 10)
@ -174,8 +171,7 @@ void PrintSimpleInt(long Num, struct OutputStream *Stream)
/* print an integer to a stream without using printf/sprintf */ /* print an integer to a stream without using printf/sprintf */
void PrintInt(long Num, int FieldWidth, int ZeroPad, int LeftJustify, struct OutputStream *Stream) void PrintInt(long Num, int FieldWidth, int ZeroPad, int LeftJustify, struct OutputStream *Stream)
{ {
if (Num < 0) if (Num < 0) {
{
PrintCh('-', Stream); PrintCh('-', Stream);
Num = -Num; Num = -Num;
if (FieldWidth != 0) if (FieldWidth != 0)
@ -192,8 +188,7 @@ void PrintFP(double Num, struct OutputStream *Stream)
int Exponent = 0; int Exponent = 0;
int MaxDecimal; int MaxDecimal;
if (Num < 0) if (Num < 0) {
{
PrintCh('-', Stream); PrintCh('-', Stream);
Num = -Num; Num = -Num;
} }
@ -207,16 +202,14 @@ void PrintFP(double Num, struct OutputStream *Stream)
PrintInt((long)Num, 0, FALSE, FALSE, Stream); PrintInt((long)Num, 0, FALSE, FALSE, Stream);
PrintCh('.', Stream); PrintCh('.', Stream);
Num = (Num - (long)Num) * 10; 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--) for (MaxDecimal = 6; MaxDecimal > 0 && abs(Num) >= 1e-7; Num = (Num - (long)(Num + 1e-7)) * 10, MaxDecimal--)
PrintCh('0' + (long)(Num + 1e-7), Stream); PrintCh('0' + (long)(Num + 1e-7), Stream);
} } else {
else
PrintCh('0', Stream); PrintCh('0', Stream);
}
if (Exponent != 0) if (Exponent != 0) {
{
PrintCh('e', Stream); PrintCh('e', Stream);
PrintInt(Exponent, 0, FALSE, FALSE, Stream); PrintInt(Exponent, 0, FALSE, FALSE, Stream);
} }
@ -235,21 +228,17 @@ void GenericPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct
int FieldWidth = 0; int FieldWidth = 0;
char *Format = Param[0]->Val->Pointer; char *Format = Param[0]->Val->Pointer;
for (FPos = Format; *FPos != '\0'; FPos++) for (FPos = Format; *FPos != '\0'; FPos++) {
{ if (*FPos == '%') {
if (*FPos == '%')
{
FPos++; FPos++;
FieldWidth = 0; FieldWidth = 0;
if (*FPos == '-') if (*FPos == '-') {
{
/* a leading '-' means left justify */ /* a leading '-' means left justify */
LeftJustify = TRUE; LeftJustify = TRUE;
FPos++; FPos++;
} }
if (*FPos == '0') if (*FPos == '0') {
{
/* a leading zero means zero pad a decimal number */ /* a leading zero means zero pad a decimal number */
ZeroPad = TRUE; ZeroPad = TRUE;
FPos++; FPos++;
@ -260,8 +249,7 @@ void GenericPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct
FieldWidth = FieldWidth * 10 + (*FPos++ - '0'); FieldWidth = FieldWidth * 10 + (*FPos++ - '0');
/* now check the format type */ /* now check the format type */
switch (*FPos) switch (*FPos) {
{
case 's': FormatType = CharPtrType; break; case 's': FormatType = CharPtrType; break;
case 'd': case 'u': case 'x': case 'b': case 'c': FormatType = &IntType; break; case 'd': case 'u': case 'x': case 'b': case 'c': FormatType = &IntType; break;
#ifndef NO_FP #ifndef NO_FP
@ -272,23 +260,19 @@ void GenericPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct
default: PrintCh(*FPos, Stream); FormatType = NULL; break; default: PrintCh(*FPos, Stream); FormatType = NULL; break;
} }
if (FormatType != NULL) if (FormatType != NULL) {
{
/* we have to format something */ /* we have to format something */
if (ArgCount >= NumArgs) if (ArgCount >= NumArgs)
PrintStr("XXX", Stream); /* not enough parameters for format */ PrintStr("XXX", Stream); /* not enough parameters for format */
else else {
{
NextArg = (struct Value *)((char *)NextArg + MEM_ALIGN(sizeof(struct Value) + TypeStackSizeValue(NextArg))); 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 == &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) ) ) ) (NextArg->Typ->Base == TypeArray && NextArg->Typ->FromType->Base == TypeChar) ) ) )
PrintStr("XXX", Stream); /* bad type for format */ PrintStr("XXX", Stream); /* bad type for format */
else else {
{ switch (*FPos) {
switch (*FPos)
{
case 's': case 's':
{ {
char *Str; char *Str;
@ -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) 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); 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'); char *EOLPos = strchr(Param[0]->Val->Pointer, '\n');
if (EOLPos != NULL) if (EOLPos != NULL)
*EOLPos = '\0'; *EOLPos = '\0';
@ -516,8 +499,7 @@ void LibStrcmp(struct ParseState *Parser, struct Value *ReturnValue, struct Valu
char *Str2 = (char *)Param[1]->Val->Pointer; char *Str2 = (char *)Param[1]->Val->Pointer;
int StrEnded; int StrEnded;
for (StrEnded = FALSE; !StrEnded; StrEnded = (*Str1 == '\0' || *Str2 == '\0'), Str1++, Str2++) for (StrEnded = FALSE; !StrEnded; StrEnded = (*Str1 == '\0' || *Str2 == '\0'), Str1++, Str2++) {
{
if (*Str1 < *Str2) { ReturnValue->Val->Integer = -1; return; } if (*Str1 < *Str2) { ReturnValue->Val->Integer = -1; return; }
else if (*Str1 > *Str2) { ReturnValue->Val->Integer = 1; return; } else if (*Str1 > *Str2) { ReturnValue->Val->Integer = 1; return; }
} }
@ -532,8 +514,7 @@ void LibStrncmp(struct ParseState *Parser, struct Value *ReturnValue, struct Val
int Len = Param[2]->Val->Integer; int Len = Param[2]->Val->Integer;
int StrEnded; int StrEnded;
for (StrEnded = FALSE; !StrEnded && Len > 0; StrEnded = (*Str1 == '\0' || *Str2 == '\0'), Str1++, Str2++, Len--) for (StrEnded = FALSE; !StrEnded && Len > 0; StrEnded = (*Str1 == '\0' || *Str2 == '\0'), Str1++, Str2++, Len--) {
{
if (*Str1 < *Str2) { ReturnValue->Val->Integer = -1; return; } if (*Str1 < *Str2) { ReturnValue->Val->Integer = -1; return; }
else if (*Str1 > *Str2) { ReturnValue->Val->Integer = 1; return; } else if (*Str1 > *Str2) { ReturnValue->Val->Integer = 1; return; }
} }
@ -575,8 +556,7 @@ void LibRindex(struct ParseState *Parser, struct Value *ReturnValue, struct Valu
int SearchChar = Param[1]->Val->Integer; int SearchChar = Param[1]->Val->Integer;
ReturnValue->Val->Pointer = NULL; ReturnValue->Val->Pointer = NULL;
for (; *Pos != '\0'; Pos++) for (; *Pos != '\0'; Pos++) {
{
if (*Pos == SearchChar) if (*Pos == SearchChar)
ReturnValue->Val->Pointer = Pos; ReturnValue->Val->Pointer = Pos;
} }
@ -611,8 +591,7 @@ void LibMemcmp(struct ParseState *Parser, struct Value *ReturnValue, struct Valu
unsigned char *Mem2 = (unsigned char *)Param[1]->Val->Pointer; unsigned char *Mem2 = (unsigned char *)Param[1]->Val->Pointer;
int Len = Param[2]->Val->Integer; int Len = Param[2]->Val->Integer;
for (; Len > 0; Mem1++, Mem2++, Len--) for (; Len > 0; Mem1++, Mem2++, Len--) {
{
if (*Mem1 < *Mem2) { ReturnValue->Val->Integer = -1; return; } if (*Mem1 < *Mem2) { ReturnValue->Val->Integer = -1; return; }
else if (*Mem1 > *Mem2) { ReturnValue->Val->Integer = 1; return; } else if (*Mem1 > *Mem2) { ReturnValue->Val->Integer = 1; return; }
} }

24
debug.c
View file

@ -20,10 +20,8 @@ void DebugCleanup(Picoc *pc)
struct TableEntry *NextEntry; struct TableEntry *NextEntry;
int Count; int Count;
for (Count = 0; Count < pc->BreakpointTable.Size; Count++) for (Count = 0; Count < pc->BreakpointTable.Size; Count++) {
{ for (Entry = pc->BreakpointHashTable[Count]; Entry != NULL; Entry = NextEntry) {
for (Entry = pc->BreakpointHashTable[Count]; Entry != NULL; Entry = NextEntry)
{
NextEntry = Entry->Next; NextEntry = Entry->Next;
HeapFreeMem(pc, Entry); HeapFreeMem(pc, Entry);
} }
@ -37,8 +35,7 @@ static struct TableEntry *DebugTableSearchBreakpoint(struct ParseState *Parser,
Picoc *pc = Parser->pc; Picoc *pc = Parser->pc;
int HashValue = BREAKPOINT_HASH(Parser) % pc->BreakpointTable.Size; 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) if (Entry->p.b.FileName == Parser->FileName && Entry->p.b.Line == Parser->Line && Entry->p.b.CharacterPos == Parser->CharacterPos)
return Entry; /* found */ return Entry; /* found */
} }
@ -54,8 +51,7 @@ void DebugSetBreakpoint(struct ParseState *Parser)
struct TableEntry *FoundEntry = DebugTableSearchBreakpoint(Parser, &AddAt); struct TableEntry *FoundEntry = DebugTableSearchBreakpoint(Parser, &AddAt);
Picoc *pc = Parser->pc; Picoc *pc = Parser->pc;
if (FoundEntry == NULL) if (FoundEntry == NULL) {
{
/* add it to the table */ /* add it to the table */
struct TableEntry *NewEntry = HeapAllocMem(pc, sizeof(struct TableEntry)); struct TableEntry *NewEntry = HeapAllocMem(pc, sizeof(struct TableEntry));
if (NewEntry == NULL) if (NewEntry == NULL)
@ -77,11 +73,9 @@ int DebugClearBreakpoint(struct ParseState *Parser)
Picoc *pc = Parser->pc; Picoc *pc = Parser->pc;
int HashValue = BREAKPOINT_HASH(Parser) % pc->BreakpointTable.Size; 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; 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; *EntryPtr = DeleteEntry->Next;
HeapFreeMem(pc, DeleteEntry); HeapFreeMem(pc, DeleteEntry);
pc->BreakpointCount--; pc->BreakpointCount--;
@ -101,8 +95,7 @@ void DebugCheckStatement(struct ParseState *Parser)
Picoc *pc = Parser->pc; Picoc *pc = Parser->pc;
/* has the user manually pressed break? */ /* has the user manually pressed break? */
if (pc->DebugManualBreak) if (pc->DebugManualBreak) {
{
PlatformPrintf(pc->CStdOut, "break\n"); PlatformPrintf(pc->CStdOut, "break\n");
DoBreak = TRUE; DoBreak = TRUE;
pc->DebugManualBreak = FALSE; pc->DebugManualBreak = FALSE;
@ -113,8 +106,7 @@ void DebugCheckStatement(struct ParseState *Parser)
DoBreak = TRUE; DoBreak = TRUE;
/* handle a break */ /* handle a break */
if (DoBreak) if (DoBreak) {
{
PlatformPrintf(pc->CStdOut, "Handling a break\n"); PlatformPrintf(pc->CStdOut, "Handling a break\n");
PicocParseInteractiveNoStartPrompt(pc, FALSE); PicocParseInteractiveNoStartPrompt(pc, FALSE);
} }

View file

@ -83,18 +83,15 @@ void ExpressionStackShow(Picoc *pc, struct ExpressionStack *StackTop)
{ {
printf("Expression stack [0x%lx,0x%lx]: ", (long)pc->HeapStackTop, (long)StackTop); printf("Expression stack [0x%lx,0x%lx]: ", (long)pc->HeapStackTop, (long)StackTop);
while (StackTop != NULL) while (StackTop != NULL) {
{ if (StackTop->Order == OrderNone) {
if (StackTop->Order == OrderNone)
{
/* it's a value */ /* it's a value */
if (StackTop->Val->IsLValue) if (StackTop->Val->IsLValue)
printf("lvalue="); printf("lvalue=");
else else
printf("value="); printf("value=");
switch (StackTop->Val->Typ->Base) switch (StackTop->Val->Typ->Base) {
{
case TypeVoid: printf("void"); break; case TypeVoid: printf("void"); break;
case TypeInt: printf("%d:int", StackTop->Val->Val->Integer); break; case TypeInt: printf("%d:int", StackTop->Val->Val->Integer); break;
case TypeShort: printf("%d:short", StackTop->Val->Val->ShortInteger); break; case TypeShort: printf("%d:short", StackTop->Val->Val->ShortInteger); break;
@ -122,9 +119,7 @@ void ExpressionStackShow(Picoc *pc, struct ExpressionStack *StackTop)
default: printf("unknown"); break; default: printf("unknown"); break;
} }
printf("[0x%lx,0x%lx]", (long)StackTop, (long)StackTop->Val); printf("[0x%lx,0x%lx]", (long)StackTop, (long)StackTop->Val);
} } else {
else
{
/* it's an operator */ /* it's an operator */
printf("op='%s' %s %d", OperatorPrecedence[(int)StackTop->Op].Name, printf("op='%s' %s %d", OperatorPrecedence[(int)StackTop->Op].Name,
(StackTop->Order == OrderPrefix) ? "prefix" : ((StackTop->Order == OrderPostfix) ? "postfix" : "infix"), (StackTop->Order == OrderPrefix) ? "prefix" : ((StackTop->Order == OrderPostfix) ? "postfix" : "infix"),
@ -147,11 +142,9 @@ int IsTypeToken(struct ParseState * Parser, enum LexToken t, struct Value * LexV
return 1; /* base type */ return 1; /* base type */
/* typedef'ed 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; 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); VariableGet(Parser->pc, Parser, LexValue->Val->Pointer, &VarValue);
if (VarValue->Typ == &Parser->pc->TypeType) if (VarValue->Typ == &Parser->pc->TypeType)
return 1; return 1;
@ -163,8 +156,7 @@ int IsTypeToken(struct ParseState * Parser, enum LexToken t, struct Value * LexV
long ExpressionCoerceInteger(struct Value *Val) long ExpressionCoerceInteger(struct Value *Val)
{ {
switch (Val->Typ->Base) switch (Val->Typ->Base) {
{
case TypeInt: return (long)Val->Val->Integer; case TypeInt: return (long)Val->Val->Integer;
case TypeChar: return (long)Val->Val->Character; case TypeChar: return (long)Val->Val->Character;
case TypeShort: return (long)Val->Val->ShortInteger; case TypeShort: return (long)Val->Val->ShortInteger;
@ -183,8 +175,7 @@ long ExpressionCoerceInteger(struct Value *Val)
unsigned long ExpressionCoerceUnsignedInteger(struct Value *Val) unsigned long ExpressionCoerceUnsignedInteger(struct Value *Val)
{ {
switch (Val->Typ->Base) switch (Val->Typ->Base) {
{
case TypeInt: return (unsigned long)Val->Val->Integer; case TypeInt: return (unsigned long)Val->Val->Integer;
case TypeChar: return (unsigned long)Val->Val->Character; case TypeChar: return (unsigned long)Val->Val->Character;
case TypeShort: return (unsigned long)Val->Val->ShortInteger; case TypeShort: return (unsigned long)Val->Val->ShortInteger;
@ -208,8 +199,7 @@ double ExpressionCoerceFP(struct Value *Val)
int IntVal; int IntVal;
unsigned UnsignedVal; unsigned UnsignedVal;
switch (Val->Typ->Base) switch (Val->Typ->Base) {
{
case TypeInt: IntVal = Val->Val->Integer; return (double)IntVal; case TypeInt: IntVal = Val->Val->Integer; return (double)IntVal;
case TypeChar: IntVal = Val->Val->Character; return (double)IntVal; case TypeChar: IntVal = Val->Val->Character; return (double)IntVal;
case TypeShort: IntVal = Val->Val->ShortInteger; return (double)IntVal; case TypeShort: IntVal = Val->Val->ShortInteger; return (double)IntVal;
@ -222,8 +212,7 @@ double ExpressionCoerceFP(struct Value *Val)
default: return 0.0; default: return 0.0;
} }
#else #else
switch (Val->Typ->Base) switch (Val->Typ->Base) {
{
case TypeInt: return (double)Val->Val->Integer; case TypeInt: return (double)Val->Val->Integer;
case TypeChar: return (double)Val->Val->Character; case TypeChar: return (double)Val->Val->Character;
case TypeShort: return (double)Val->Val->ShortInteger; case TypeShort: return (double)Val->Val->ShortInteger;
@ -252,8 +241,7 @@ long ExpressionAssignInt(struct ParseState *Parser, struct Value *DestValue, lon
else else
Result = FromInt; Result = FromInt;
switch (DestValue->Typ->Base) switch (DestValue->Typ->Base) {
{
case TypeInt: DestValue->Val->Integer = FromInt; break; case TypeInt: DestValue->Val->Integer = FromInt; break;
case TypeShort: DestValue->Val->ShortInteger = (short)FromInt; break; case TypeShort: DestValue->Val->ShortInteger = (short)FromInt; break;
case TypeChar: DestValue->Val->Character = (char)FromInt; break; case TypeChar: DestValue->Val->Character = (char)FromInt; break;
@ -356,34 +344,23 @@ void ExpressionAssignToPointer(struct ParseState *Parser, struct Value *ToValue,
if (FromValue->Typ == ToValue->Typ || FromValue->Typ == Parser->pc->VoidPtrType || (ToValue->Typ == Parser->pc->VoidPtrType && FromValue->Typ->Base == TypePointer)) 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 */ 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 */ /* the form is: blah *x = array of blah */
ToValue->Val->Pointer = (void *)&FromValue->Val->ArrayMem[0]; ToValue->Val->Pointer = (void *)&FromValue->Val->ArrayMem[0];
} } else if (FromValue->Typ->Base == TypePointer && FromValue->Typ->FromType->Base == TypeArray &&
else if (FromValue->Typ->Base == TypePointer && FromValue->Typ->FromType->Base == TypeArray && (PointedToType == FromValue->Typ->FromType->FromType || ToValue->Typ == Parser->pc->VoidPtrType) ) {
(PointedToType == FromValue->Typ->FromType->FromType || ToValue->Typ == Parser->pc->VoidPtrType) )
{
/* the form is: blah *x = pointer to array of blah */ /* the form is: blah *x = pointer to array of blah */
ToValue->Val->Pointer = VariableDereferencePointer(Parser, FromValue, NULL, NULL, NULL, NULL); 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 */ /* null pointer assignment */
ToValue->Val->Pointer = NULL; ToValue->Val->Pointer = NULL;
} } else if (AllowPointerCoercion && IS_NUMERIC_COERCIBLE(FromValue)) {
else if (AllowPointerCoercion && IS_NUMERIC_COERCIBLE(FromValue))
{
/* assign integer to native pointer */ /* assign integer to native pointer */
ToValue->Val->Pointer = (void *)(unsigned long)ExpressionCoerceUnsignedInteger(FromValue); 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 */ /* assign a pointer to a pointer to a different type */
ToValue->Val->Pointer = FromValue->Val->Pointer; ToValue->Val->Pointer = FromValue->Val->Pointer;
} } else
else
AssignFail(Parser, "%t from %t", ToValue->Typ, FromValue->Typ, 0, 0, FuncName, ParamNo); AssignFail(Parser, "%t from %t", ToValue->Typ, FromValue->Typ, 0, 0, FuncName, ParamNo);
} }
@ -396,8 +373,7 @@ void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, struct
if (IS_NUMERIC_COERCIBLE(DestValue) && !IS_NUMERIC_COERCIBLE_PLUS_POINTERS(SourceValue, AllowPointerCoercion)) if (IS_NUMERIC_COERCIBLE(DestValue) && !IS_NUMERIC_COERCIBLE_PLUS_POINTERS(SourceValue, AllowPointerCoercion))
AssignFail(Parser, "%t from %t", DestValue->Typ, SourceValue->Typ, 0, 0, FuncName, ParamNo); AssignFail(Parser, "%t from %t", DestValue->Typ, SourceValue->Typ, 0, 0, FuncName, ParamNo);
switch (DestValue->Typ->Base) switch (DestValue->Typ->Base) {
{
case TypeInt: DestValue->Val->Integer = ExpressionCoerceInteger(SourceValue); break; case TypeInt: DestValue->Val->Integer = ExpressionCoerceInteger(SourceValue); break;
case TypeShort: DestValue->Val->ShortInteger = (short)ExpressionCoerceInteger(SourceValue); break; case TypeShort: DestValue->Val->ShortInteger = (short)ExpressionCoerceInteger(SourceValue); break;
case TypeChar: DestValue->Val->Character = (char)ExpressionCoerceInteger(SourceValue); break; case TypeChar: DestValue->Val->Character = (char)ExpressionCoerceInteger(SourceValue); break;
@ -406,7 +382,6 @@ void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, struct
case TypeUnsignedShort: DestValue->Val->UnsignedShortInteger = (unsigned short)ExpressionCoerceUnsignedInteger(SourceValue); break; case TypeUnsignedShort: DestValue->Val->UnsignedShortInteger = (unsigned short)ExpressionCoerceUnsignedInteger(SourceValue); break;
case TypeUnsignedLong: DestValue->Val->UnsignedLongInteger = ExpressionCoerceUnsignedInteger(SourceValue); break; case TypeUnsignedLong: DestValue->Val->UnsignedLongInteger = ExpressionCoerceUnsignedInteger(SourceValue); break;
case TypeUnsignedChar: DestValue->Val->UnsignedCharacter = (unsigned char)ExpressionCoerceUnsignedInteger(SourceValue); break; case TypeUnsignedChar: DestValue->Val->UnsignedCharacter = (unsigned char)ExpressionCoerceUnsignedInteger(SourceValue); break;
#ifndef NO_FP #ifndef NO_FP
case TypeFP: case TypeFP:
if (!IS_NUMERIC_COERCIBLE_PLUS_POINTERS(SourceValue, AllowPointerCoercion)) if (!IS_NUMERIC_COERCIBLE_PLUS_POINTERS(SourceValue, AllowPointerCoercion))
@ -420,14 +395,12 @@ void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, struct
break; break;
case TypeArray: case TypeArray:
if (SourceValue->Typ->Base == TypeArray && DestValue->Typ->FromType == DestValue->Typ->FromType && DestValue->Typ->ArraySize == 0) 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 */ /* destination array is unsized - need to resize the destination array to the same size as the source array */
DestValue->Typ = SourceValue->Typ; DestValue->Typ = SourceValue->Typ;
VariableRealloc(Parser, DestValue, TypeSizeValue(DestValue, FALSE)); VariableRealloc(Parser, DestValue, TypeSizeValue(DestValue, FALSE));
if (DestValue->LValueFrom != NULL) if (DestValue->LValueFrom != NULL) {
{
/* copy the resized value back to the LValue */ /* copy the resized value back to the LValue */
DestValue->LValueFrom->Val = DestValue->Val; DestValue->LValueFrom->Val = DestValue->Val;
DestValue->LValueFrom->AnyValOnHeap = DestValue->AnyValOnHeap; DestValue->LValueFrom->AnyValOnHeap = DestValue->AnyValOnHeap;
@ -435,10 +408,8 @@ void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, struct
} }
/* char array = "abcd" */ /* char array = "abcd" */
if (DestValue->Typ->FromType->Base == TypeChar && SourceValue->Typ->Base == TypePointer && SourceValue->Typ->FromType->Base == TypeChar) 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 */
if (DestValue->Typ->ArraySize == 0) /* char x[] = "abcd", x is unsized */
{
int Size = strlen(SourceValue->Val->Pointer) + 1; int Size = strlen(SourceValue->Val->Pointer) + 1;
#ifdef DEBUG_ARRAY_INITIALIZER #ifdef DEBUG_ARRAY_INITIALIZER
PRINT_SOURCE_POS; PRINT_SOURCE_POS;
@ -486,13 +457,10 @@ void ExpressionQuestionMarkOperator(struct ParseState *Parser, struct Expression
if (!IS_NUMERIC_COERCIBLE(TopValue)) if (!IS_NUMERIC_COERCIBLE(TopValue))
ProgramFail(Parser, "first argument to '?' should be a number"); ProgramFail(Parser, "first argument to '?' should be a number");
if (ExpressionCoerceInteger(TopValue)) if (ExpressionCoerceInteger(TopValue)) {
{
/* the condition's true, return the BottomValue */ /* the condition's true, return the BottomValue */
ExpressionStackPushValue(Parser, StackTop, BottomValue); ExpressionStackPushValue(Parser, StackTop, BottomValue);
} } else {
else
{
/* the condition's false, return void */ /* the condition's false, return void */
ExpressionStackPushValueByType(Parser, StackTop, &Parser->pc->VoidType); 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 */ /* evaluate the second half of a ternary operator x ? y : z */
void ExpressionColonOperator(struct ParseState *Parser, struct ExpressionStack **StackTop, struct Value *BottomValue, struct Value *TopValue) void ExpressionColonOperator(struct ParseState *Parser, struct ExpressionStack **StackTop, struct Value *BottomValue, struct Value *TopValue)
{ {
if (TopValue->Typ->Base == TypeVoid) if (TopValue->Typ->Base == TypeVoid) {
{
/* invoke the "else" part - return the BottomValue */ /* invoke the "else" part - return the BottomValue */
ExpressionStackPushValue(Parser, StackTop, BottomValue); ExpressionStackPushValue(Parser, StackTop, BottomValue);
} } else {
else
{
/* it was a "then" - return the TopValue */ /* it was a "then" - return the TopValue */
ExpressionStackPushValue(Parser, StackTop, TopValue); ExpressionStackPushValue(Parser, StackTop, TopValue);
} }
@ -520,8 +485,7 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack
union AnyValue *ValPtr; union AnyValue *ValPtr;
debugf("ExpressionPrefixOperator()\n"); debugf("ExpressionPrefixOperator()\n");
switch (Op) switch (Op) {
{
case TokenAmpersand: case TokenAmpersand:
if (!TopValue->IsLValue) if (!TopValue->IsLValue)
ProgramFail(Parser, "can't get the address of this"); ProgramFail(Parser, "can't get the address of this");
@ -547,13 +511,11 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack
default: default:
/* an arithmetic operator */ /* an arithmetic operator */
#ifndef NO_FP #ifndef NO_FP
if (TopValue->Typ == &Parser->pc->FPType) if (TopValue->Typ == &Parser->pc->FPType) {
{
/* floating point prefix arithmetic */ /* floating point prefix arithmetic */
double ResultFP = 0.0; double ResultFP = 0.0;
switch (Op) switch (Op) {
{
case TokenPlus: ResultFP = TopValue->Val->FP; break; case TokenPlus: ResultFP = TopValue->Val->FP; break;
case TokenMinus: ResultFP = -TopValue->Val->FP; break; case TokenMinus: ResultFP = -TopValue->Val->FP; break;
case TokenIncrement: ResultFP = ExpressionAssignFP(Parser, TopValue, TopValue->Val->FP+1); break; case TokenIncrement: ResultFP = ExpressionAssignFP(Parser, TopValue, TopValue->Val->FP+1); break;
@ -563,16 +525,13 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack
} }
ExpressionPushFP(Parser, StackTop, ResultFP); ExpressionPushFP(Parser, StackTop, ResultFP);
} } else
else
#endif #endif
if (IS_NUMERIC_COERCIBLE(TopValue)) if (IS_NUMERIC_COERCIBLE(TopValue)) {
{
/* integer prefix arithmetic */ /* integer prefix arithmetic */
long ResultInt = 0; long ResultInt = 0;
long TopInt = ExpressionCoerceInteger(TopValue); long TopInt = ExpressionCoerceInteger(TopValue);
switch (Op) switch (Op) {
{
case TokenPlus: ResultInt = TopInt; break; case TokenPlus: ResultInt = TopInt; break;
case TokenMinus: ResultInt = -TopInt; break; case TokenMinus: ResultInt = -TopInt; break;
case TokenIncrement: ResultInt = ExpressionAssignInt(Parser, TopValue, TopInt+1, FALSE); break; case TokenIncrement: ResultInt = ExpressionAssignInt(Parser, TopValue, TopInt+1, FALSE); break;
@ -583,9 +542,7 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack
} }
ExpressionPushInt(Parser, StackTop, ResultInt); ExpressionPushInt(Parser, StackTop, ResultInt);
} } else if (TopValue->Typ->Base == TypePointer) {
else if (TopValue->Typ->Base == TypePointer)
{
/* pointer prefix arithmetic */ /* pointer prefix arithmetic */
int Size = TypeSize(TopValue->Typ->FromType, 0, TRUE); int Size = TypeSize(TopValue->Typ->FromType, 0, TRUE);
struct Value *StackValue; struct Value *StackValue;
@ -597,8 +554,7 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack
if (!TopValue->IsLValue) if (!TopValue->IsLValue)
ProgramFail(Parser, "can't assign to this"); ProgramFail(Parser, "can't assign to this");
switch (Op) switch (Op) {
{
case TokenIncrement: TopValue->Val->Pointer = (void *)((char *)TopValue->Val->Pointer + Size); break; case TokenIncrement: TopValue->Val->Pointer = (void *)((char *)TopValue->Val->Pointer + Size); break;
case TokenDecrement: 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; default: ProgramFail(Parser, "invalid operation"); break;
@ -607,8 +563,7 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack
ResultPtr = TopValue->Val->Pointer; ResultPtr = TopValue->Val->Pointer;
StackValue = ExpressionStackPushValueByType(Parser, StackTop, TopValue->Typ); StackValue = ExpressionStackPushValueByType(Parser, StackTop, TopValue->Typ);
StackValue->Val->Pointer = ResultPtr; StackValue->Val->Pointer = ResultPtr;
} } else
else
ProgramFail(Parser, "invalid operation"); ProgramFail(Parser, "invalid operation");
break; break;
} }
@ -619,13 +574,11 @@ void ExpressionPostfixOperator(struct ParseState *Parser, struct ExpressionStack
{ {
debugf("ExpressionPostfixOperator()\n"); debugf("ExpressionPostfixOperator()\n");
#ifndef NO_FP #ifndef NO_FP
if (TopValue->Typ == &Parser->pc->FPType) if (TopValue->Typ == &Parser->pc->FPType) {
{
/* floating point prefix arithmetic */ /* floating point prefix arithmetic */
double ResultFP = 0.0; double ResultFP = 0.0;
switch (Op) switch (Op) {
{
case TokenIncrement: ResultFP = ExpressionAssignFP(Parser, TopValue, TopValue->Val->FP+1); break; case TokenIncrement: ResultFP = ExpressionAssignFP(Parser, TopValue, TopValue->Val->FP+1); break;
case TokenDecrement: 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; default: ProgramFail(Parser, "invalid operation"); break;
@ -635,12 +588,10 @@ void ExpressionPostfixOperator(struct ParseState *Parser, struct ExpressionStack
} }
else else
#endif #endif
if (IS_NUMERIC_COERCIBLE(TopValue)) if (IS_NUMERIC_COERCIBLE(TopValue)) {
{
long ResultInt = 0; long ResultInt = 0;
long TopInt = ExpressionCoerceInteger(TopValue); long TopInt = ExpressionCoerceInteger(TopValue);
switch (Op) switch (Op) {
{
case TokenIncrement: ResultInt = ExpressionAssignInt(Parser, TopValue, TopInt+1, TRUE); break; case TokenIncrement: ResultInt = ExpressionAssignInt(Parser, TopValue, TopInt+1, TRUE); break;
case TokenDecrement: 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 TokenRightSquareBracket: ProgramFail(Parser, "not supported"); break; /* XXX */
@ -649,9 +600,7 @@ void ExpressionPostfixOperator(struct ParseState *Parser, struct ExpressionStack
} }
ExpressionPushInt(Parser, StackTop, ResultInt); ExpressionPushInt(Parser, StackTop, ResultInt);
} } else if (TopValue->Typ->Base == TypePointer) {
else if (TopValue->Typ->Base == TypePointer)
{
/* pointer postfix arithmetic */ /* pointer postfix arithmetic */
int Size = TypeSize(TopValue->Typ->FromType, 0, TRUE); int Size = TypeSize(TopValue->Typ->FromType, 0, TRUE);
struct Value *StackValue; struct Value *StackValue;
@ -663,8 +612,7 @@ void ExpressionPostfixOperator(struct ParseState *Parser, struct ExpressionStack
if (!TopValue->IsLValue) if (!TopValue->IsLValue)
ProgramFail(Parser, "can't assign to this"); ProgramFail(Parser, "can't assign to this");
switch (Op) switch (Op) {
{
case TokenIncrement: TopValue->Val->Pointer = (void *)((char *)TopValue->Val->Pointer + Size); break; case TokenIncrement: TopValue->Val->Pointer = (void *)((char *)TopValue->Val->Pointer + Size); break;
case TokenDecrement: 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; default: ProgramFail(Parser, "invalid operation"); break;
@ -688,8 +636,7 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
if (BottomValue == NULL || TopValue == NULL) if (BottomValue == NULL || TopValue == NULL)
ProgramFail(Parser, "invalid expression"); ProgramFail(Parser, "invalid expression");
if (Op == TokenLeftSquareBracket) if (Op == TokenLeftSquareBracket) {
{
/* array index */ /* array index */
int ArrayIndex; int ArrayIndex;
struct Value *Result = NULL; struct Value *Result = NULL;
@ -700,8 +647,7 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
ArrayIndex = ExpressionCoerceInteger(TopValue); ArrayIndex = ExpressionCoerceInteger(TopValue);
/* make the array element result */ /* make the array element result */
switch (BottomValue->Typ->Base) switch (BottomValue->Typ->Base) {
{
case TypeArray: Result = VariableAllocValueFromExistingData(Parser, BottomValue->Typ->FromType, (union AnyValue *)(&BottomValue->Val->ArrayMem[0] + TypeSize(BottomValue->Typ, ArrayIndex, TRUE)), BottomValue->IsLValue, BottomValue->LValueFrom); break; case TypeArray: 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; case TypePointer: Result = VariableAllocValueFromExistingData(Parser, BottomValue->Typ->FromType, (union AnyValue *)((char *)BottomValue->Val->Pointer + TypeSize(BottomValue->Typ->FromType, 0, TRUE) * ArrayIndex), BottomValue->IsLValue, BottomValue->LValueFrom); break;
default: ProgramFail(Parser, "this %t is not an array", BottomValue->Typ); default: ProgramFail(Parser, "this %t is not an array", BottomValue->Typ);
@ -714,20 +660,17 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
else if (Op == TokenColon) else if (Op == TokenColon)
ExpressionColonOperator(Parser, StackTop, TopValue, BottomValue); ExpressionColonOperator(Parser, StackTop, TopValue, BottomValue);
#ifndef NO_FP #ifndef NO_FP
else if ( (TopValue->Typ == &Parser->pc->FPType && BottomValue->Typ == &Parser->pc->FPType) || else if ( (TopValue->Typ == &Parser->pc->FPType && BottomValue->Typ == &Parser->pc->FPType) ||
(TopValue->Typ == &Parser->pc->FPType && IS_NUMERIC_COERCIBLE(BottomValue)) || (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 */ /* floating point infix arithmetic */
int ResultIsInt = FALSE; int ResultIsInt = FALSE;
double ResultFP = 0.0; double ResultFP = 0.0;
double TopFP = (TopValue->Typ == &Parser->pc->FPType) ? TopValue->Val->FP : (double)ExpressionCoerceInteger(TopValue); 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); double BottomFP = (BottomValue->Typ == &Parser->pc->FPType) ? BottomValue->Val->FP : (double)ExpressionCoerceInteger(BottomValue);
switch (Op) switch (Op) {
{
case TokenAssign: ASSIGN_FP_OR_INT(TopFP); break; case TokenAssign: ASSIGN_FP_OR_INT(TopFP); break;
case TokenAddAssign: ASSIGN_FP_OR_INT(BottomFP + TopFP); break; case TokenAddAssign: ASSIGN_FP_OR_INT(BottomFP + TopFP); break;
case TokenSubtractAssign: ASSIGN_FP_OR_INT(BottomFP - TopFP); break; case TokenSubtractAssign: ASSIGN_FP_OR_INT(BottomFP - TopFP); break;
@ -752,13 +695,11 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
ExpressionPushFP(Parser, StackTop, ResultFP); ExpressionPushFP(Parser, StackTop, ResultFP);
} }
#endif #endif
else if (IS_NUMERIC_COERCIBLE(TopValue) && IS_NUMERIC_COERCIBLE(BottomValue)) else if (IS_NUMERIC_COERCIBLE(TopValue) && IS_NUMERIC_COERCIBLE(BottomValue)) {
{
/* integer operation */ /* integer operation */
long TopInt = ExpressionCoerceInteger(TopValue); long TopInt = ExpressionCoerceInteger(TopValue);
long BottomInt = ExpressionCoerceInteger(BottomValue); long BottomInt = ExpressionCoerceInteger(BottomValue);
switch (Op) switch (Op) {
{
case TokenAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, TopInt, FALSE); break; case TokenAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, TopInt, FALSE); break;
case TokenAddAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt + TopInt, FALSE); break; case TokenAddAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt + TopInt, FALSE); break;
case TokenSubtractAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt - TopInt, FALSE); break; case TokenSubtractAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt - TopInt, FALSE); break;
@ -796,14 +737,11 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
} }
ExpressionPushInt(Parser, StackTop, ResultInt); 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 */ /* pointer/integer infix arithmetic */
long TopInt = ExpressionCoerceInteger(TopValue); long TopInt = ExpressionCoerceInteger(TopValue);
if (Op == TokenEqual || Op == TokenNotEqual) if (Op == TokenEqual || Op == TokenNotEqual) {
{
/* comparison to a NULL pointer */ /* comparison to a NULL pointer */
if (TopInt != 0) if (TopInt != 0)
ProgramFail(Parser, "invalid operation"); ProgramFail(Parser, "invalid operation");
@ -812,9 +750,7 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
ExpressionPushInt(Parser, StackTop, BottomValue->Val->Pointer == NULL); ExpressionPushInt(Parser, StackTop, BottomValue->Val->Pointer == NULL);
else else
ExpressionPushInt(Parser, StackTop, BottomValue->Val->Pointer != NULL); ExpressionPushInt(Parser, StackTop, BottomValue->Val->Pointer != NULL);
} } else if (Op == TokenPlus || Op == TokenMinus) {
else if (Op == TokenPlus || Op == TokenMinus)
{
/* pointer arithmetic */ /* pointer arithmetic */
int Size = TypeSize(BottomValue->Typ->FromType, 0, TRUE); int Size = TypeSize(BottomValue->Typ->FromType, 0, TRUE);
@ -829,16 +765,12 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
StackValue = ExpressionStackPushValueByType(Parser, StackTop, BottomValue->Typ); StackValue = ExpressionStackPushValueByType(Parser, StackTop, BottomValue->Typ);
StackValue->Val->Pointer = Pointer; StackValue->Val->Pointer = Pointer;
} } else if (Op == TokenAssign && TopInt == 0) {
else if (Op == TokenAssign && TopInt == 0)
{
/* assign a NULL pointer */ /* assign a NULL pointer */
HeapUnpopStack(Parser->pc, sizeof(struct Value)); HeapUnpopStack(Parser->pc, sizeof(struct Value));
ExpressionAssign(Parser, BottomValue, TopValue, FALSE, NULL, 0, FALSE); ExpressionAssign(Parser, BottomValue, TopValue, FALSE, NULL, 0, FALSE);
ExpressionStackPushValueNode(Parser, StackTop, BottomValue); ExpressionStackPushValueNode(Parser, StackTop, BottomValue);
} } else if (Op == TokenAddAssign || Op == TokenSubtractAssign) {
else if (Op == TokenAddAssign || Op == TokenSubtractAssign)
{
/* pointer arithmetic */ /* pointer arithmetic */
int Size = TypeSize(BottomValue->Typ->FromType, 0, TRUE); 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)); HeapUnpopStack(Parser->pc, sizeof(struct Value));
BottomValue->Val->Pointer = Pointer; BottomValue->Val->Pointer = Pointer;
ExpressionStackPushValueNode(Parser, StackTop, BottomValue); ExpressionStackPushValueNode(Parser, StackTop, BottomValue);
} } else
else
ProgramFail(Parser, "invalid operation"); 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 */ /* pointer/pointer operations */
char *TopLoc = (char *)TopValue->Val->Pointer; char *TopLoc = (char *)TopValue->Val->Pointer;
char *BottomLoc = (char *)BottomValue->Val->Pointer; char *BottomLoc = (char *)BottomValue->Val->Pointer;
switch (Op) switch (Op) {
{
case TokenEqual: ExpressionPushInt(Parser, StackTop, BottomLoc == TopLoc); break; case TokenEqual: ExpressionPushInt(Parser, StackTop, BottomLoc == TopLoc); break;
case TokenNotEqual: ExpressionPushInt(Parser, StackTop, BottomLoc != TopLoc); break; case TokenNotEqual: ExpressionPushInt(Parser, StackTop, BottomLoc != TopLoc); break;
case TokenMinus: ExpressionPushInt(Parser, StackTop, BottomLoc - TopLoc); break; case TokenMinus: ExpressionPushInt(Parser, StackTop, BottomLoc - TopLoc); break;
default: ProgramFail(Parser, "invalid operation"); break; default: ProgramFail(Parser, "invalid operation"); break;
} }
} } else if (Op == TokenAssign) {
else if (Op == TokenAssign)
{
/* assign a non-numeric type */ /* 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) */ 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); ExpressionAssign(Parser, BottomValue, TopValue, FALSE, NULL, 0, FALSE);
ExpressionStackPushValueNode(Parser, StackTop, BottomValue); ExpressionStackPushValueNode(Parser, StackTop, BottomValue);
} } else if (Op == TokenCast) {
else if (Op == TokenCast)
{
/* cast a value to a different type */ /* XXX - possible bug if the destination type takes more than sizeof(struct Value) + sizeof(struct ValueType *) */ /* cast a value to a different type */ /* XXX - possible bug if the destination type takes more than sizeof(struct Value) + sizeof(struct ValueType *) */
struct Value *ValueLoc = ExpressionStackPushValueByType(Parser, StackTop, BottomValue->Val->Typ); struct Value *ValueLoc = ExpressionStackPushValueByType(Parser, StackTop, BottomValue->Val->Typ);
ExpressionAssign(Parser, ValueLoc, TopValue, TRUE, NULL, 0, TRUE); ExpressionAssign(Parser, ValueLoc, TopValue, TRUE, NULL, 0, TRUE);
} } else
else
ProgramFail(Parser, "invalid operation"); ProgramFail(Parser, "invalid operation");
} }
@ -902,8 +825,7 @@ void ExpressionStackCollapse(struct ParseState *Parser, struct ExpressionStack *
#ifdef DEBUG_EXPRESSIONS #ifdef DEBUG_EXPRESSIONS
ExpressionStackShow(Parser->pc, *StackTop); ExpressionStackShow(Parser->pc, *StackTop);
#endif #endif
while (TopStackNode != NULL && TopStackNode->Next != NULL && FoundPrecedence >= Precedence) while (TopStackNode != NULL && TopStackNode->Next != NULL && FoundPrecedence >= Precedence) {
{
/* find the top operator on the stack */ /* find the top operator on the stack */
if (TopStackNode->Order == OrderNone) if (TopStackNode->Order == OrderNone)
TopOperatorNode = TopStackNode->Next; TopOperatorNode = TopStackNode->Next;
@ -913,11 +835,9 @@ void ExpressionStackCollapse(struct ParseState *Parser, struct ExpressionStack *
FoundPrecedence = TopOperatorNode->Precedence; FoundPrecedence = TopOperatorNode->Precedence;
/* does it have a high enough precedence? */ /* does it have a high enough precedence? */
if (FoundPrecedence >= Precedence && TopOperatorNode != NULL) if (FoundPrecedence >= Precedence && TopOperatorNode != NULL) {
{
/* execute this operator */ /* execute this operator */
switch (TopOperatorNode->Order) switch (TopOperatorNode->Order) {
{
case OrderPrefix: case OrderPrefix:
/* prefix evaluation */ /* prefix evaluation */
debugf("prefix evaluation\n"); debugf("prefix evaluation\n");
@ -929,13 +849,10 @@ void ExpressionStackCollapse(struct ParseState *Parser, struct ExpressionStack *
*StackTop = TopOperatorNode->Next; *StackTop = TopOperatorNode->Next;
/* do the prefix operation */ /* do the prefix operation */
if (Parser->Mode == RunModeRun /* && FoundPrecedence < *IgnorePrecedence */) if (Parser->Mode == RunModeRun /* && FoundPrecedence < *IgnorePrecedence */) {
{
/* run the operator */ /* run the operator */
ExpressionPrefixOperator(Parser, StackTop, TopOperatorNode->Op, TopValue); ExpressionPrefixOperator(Parser, StackTop, TopOperatorNode->Op, TopValue);
} } else {
else
{
/* we're not running it so just return 0 */ /* we're not running it so just return 0 */
ExpressionPushInt(Parser, StackTop, 0); ExpressionPushInt(Parser, StackTop, 0);
} }
@ -952,13 +869,10 @@ void ExpressionStackCollapse(struct ParseState *Parser, struct ExpressionStack *
*StackTop = TopStackNode->Next->Next; *StackTop = TopStackNode->Next->Next;
/* do the postfix operation */ /* do the postfix operation */
if (Parser->Mode == RunModeRun /* && FoundPrecedence < *IgnorePrecedence */) if (Parser->Mode == RunModeRun /* && FoundPrecedence < *IgnorePrecedence */) {
{
/* run the operator */ /* run the operator */
ExpressionPostfixOperator(Parser, StackTop, TopOperatorNode->Op, TopValue); ExpressionPostfixOperator(Parser, StackTop, TopOperatorNode->Op, TopValue);
} } else {
else
{
/* we're not running it so just return 0 */ /* we're not running it so just return 0 */
ExpressionPushInt(Parser, StackTop, 0); ExpressionPushInt(Parser, StackTop, 0);
} }
@ -968,8 +882,7 @@ void ExpressionStackCollapse(struct ParseState *Parser, struct ExpressionStack *
/* infix evaluation */ /* infix evaluation */
debugf("infix evaluation\n"); debugf("infix evaluation\n");
TopValue = TopStackNode->Val; TopValue = TopStackNode->Val;
if (TopValue != NULL) if (TopValue != NULL) {
{
BottomValue = TopOperatorNode->Next->Val; BottomValue = TopOperatorNode->Next->Val;
/* pop a value, the operator and another value - assume they'll still be there until we're done */ /* pop a value, the operator and another value - assume they'll still be there until we're done */
@ -979,13 +892,10 @@ void ExpressionStackCollapse(struct ParseState *Parser, struct ExpressionStack *
*StackTop = TopOperatorNode->Next->Next; *StackTop = TopOperatorNode->Next->Next;
/* do the infix operation */ /* do the infix operation */
if (Parser->Mode == RunModeRun /* && FoundPrecedence <= *IgnorePrecedence */) if (Parser->Mode == RunModeRun /* && FoundPrecedence <= *IgnorePrecedence */) {
{
/* run the operator */ /* run the operator */
ExpressionInfixOperator(Parser, StackTop, TopOperatorNode->Op, BottomValue, TopValue); ExpressionInfixOperator(Parser, StackTop, TopOperatorNode->Op, BottomValue, TopValue);
} } else {
else
{
/* we're not running it so just return 0 */ /* we're not running it so just return 0 */
ExpressionPushInt(Parser, StackTop, 0); ExpressionPushInt(Parser, StackTop, 0);
} }
@ -1043,8 +953,7 @@ void ExpressionGetStructElement(struct ParseState *Parser, struct ExpressionStac
if (LexGetToken(Parser, &Ident, TRUE) != TokenIdentifier) if (LexGetToken(Parser, &Ident, TRUE) != TokenIdentifier)
ProgramFail(Parser, "need an structure or union member after '%s'", (Token == TokenDot) ? "." : "->"); ProgramFail(Parser, "need an structure or union member after '%s'", (Token == TokenDot) ? "." : "->");
if (Parser->Mode == RunModeRun) if (Parser->Mode == RunModeRun) {
{
/* look up the struct element */ /* look up the struct element */
struct Value *ParamVal = (*StackTop)->Val; struct Value *ParamVal = (*StackTop)->Val;
struct Value *StructVal = ParamVal; struct Value *StructVal = ParamVal;
@ -1087,8 +996,7 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
int TernaryDepth = 0; int TernaryDepth = 0;
debugf("ExpressionParse():\n"); debugf("ExpressionParse():\n");
do do {
{
struct ParseState PreState; struct ParseState PreState;
enum LexToken Token; enum LexToken Token;
@ -1096,11 +1004,9 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
Token = LexGetToken(Parser, &LexValue, TRUE); Token = LexGetToken(Parser, &LexValue, TRUE);
if ( ( ( (int)Token > TokenComma && (int)Token <= (int)TokenOpenBracket) || if ( ( ( (int)Token > TokenComma && (int)Token <= (int)TokenOpenBracket) ||
(Token == TokenCloseBracket && BracketPrecedence != 0)) && (Token == TokenCloseBracket && BracketPrecedence != 0)) &&
(Token != TokenColon || TernaryDepth > 0) ) (Token != TokenColon || TernaryDepth > 0) ) {
{
/* it's an operator with precedence */ /* it's an operator with precedence */
if (PrefixState) if (PrefixState) {
{
/* expect a prefix operator */ /* expect a prefix operator */
if (OperatorPrecedence[(int)Token].PrefixPrecedence == 0) if (OperatorPrecedence[(int)Token].PrefixPrecedence == 0)
ProgramFail(Parser, "operator not expected here"); ProgramFail(Parser, "operator not expected here");
@ -1108,12 +1014,10 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
LocalPrecedence = OperatorPrecedence[(int)Token].PrefixPrecedence; LocalPrecedence = OperatorPrecedence[(int)Token].PrefixPrecedence;
Precedence = BracketPrecedence + LocalPrecedence; Precedence = BracketPrecedence + LocalPrecedence;
if (Token == TokenOpenBracket) if (Token == TokenOpenBracket) {
{
/* it's either a new bracket level or a cast */ /* it's either a new bracket level or a cast */
enum LexToken BracketToken = LexGetToken(Parser, &LexValue, FALSE); 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 */ /* it's a cast - get the new type */
struct ValueType *CastType; struct ValueType *CastType;
char *CastIdentifier; char *CastIdentifier;
@ -1131,22 +1035,17 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
CastTypeValue->Val->Typ = CastType; CastTypeValue->Val->Typ = CastType;
ExpressionStackPushValueNode(Parser, &StackTop, CastTypeValue); ExpressionStackPushValueNode(Parser, &StackTop, CastTypeValue);
ExpressionStackPushOperator(Parser, &StackTop, OrderInfix, TokenCast, Precedence); ExpressionStackPushOperator(Parser, &StackTop, OrderInfix, TokenCast, Precedence);
} } else {
else
{
/* boost the bracket operator precedence */ /* boost the bracket operator precedence */
BracketPrecedence += BRACKET_PRECEDENCE; BracketPrecedence += BRACKET_PRECEDENCE;
} }
} } else {
else
{
/* scan and collapse the stack to the precedence of this operator, then push */ /* scan and collapse the stack to the precedence of this operator, then push */
/* take some extra care for double prefix operators, e.g. x = - -5, or x = **y */ /* take some extra care for double prefix operators, e.g. x = - -5, or x = **y */
int NextToken = LexGetToken(Parser, NULL, FALSE); int NextToken = LexGetToken(Parser, NULL, FALSE);
int TempPrecedenceBoost = 0; int TempPrecedenceBoost = 0;
if (NextToken > TokenComma && NextToken < TokenOpenBracket) if (NextToken > TokenComma && NextToken < TokenOpenBracket) {
{
int NextPrecedence = OperatorPrecedence[(int)NextToken].PrefixPrecedence; int NextPrecedence = OperatorPrecedence[(int)NextToken].PrefixPrecedence;
/* two prefix operators with equal precedence? make sure the innermost one runs first */ /* two prefix operators with equal precedence? make sure the innermost one runs first */
@ -1158,30 +1057,22 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
ExpressionStackCollapse(Parser, &StackTop, Precedence, &IgnorePrecedence); ExpressionStackCollapse(Parser, &StackTop, Precedence, &IgnorePrecedence);
ExpressionStackPushOperator(Parser, &StackTop, OrderPrefix, Token, Precedence + TempPrecedenceBoost); ExpressionStackPushOperator(Parser, &StackTop, OrderPrefix, Token, Precedence + TempPrecedenceBoost);
} }
} } else {
else
{
/* expect an infix or postfix operator */ /* expect an infix or postfix operator */
if (OperatorPrecedence[(int)Token].PostfixPrecedence != 0) if (OperatorPrecedence[(int)Token].PostfixPrecedence != 0) {
{ switch (Token) {
switch (Token)
{
case TokenCloseBracket: case TokenCloseBracket:
case TokenRightSquareBracket: case TokenRightSquareBracket:
if (BracketPrecedence == 0) if (BracketPrecedence == 0) {
{
/* assume this bracket is after the end of the expression */ /* assume this bracket is after the end of the expression */
ParserCopy(Parser, &PreState); ParserCopy(Parser, &PreState);
Done = TRUE; Done = TRUE;
} } else {
else
{
/* collapse to the bracket precedence */ /* collapse to the bracket precedence */
ExpressionStackCollapse(Parser, &StackTop, BracketPrecedence, &IgnorePrecedence); ExpressionStackCollapse(Parser, &StackTop, BracketPrecedence, &IgnorePrecedence);
BracketPrecedence -= BRACKET_PRECEDENCE; BracketPrecedence -= BRACKET_PRECEDENCE;
} }
break; break;
default: default:
/* scan and collapse the stack to the precedence of this operator, then push */ /* scan and collapse the stack to the precedence of this operator, then push */
Precedence = BracketPrecedence + OperatorPrecedence[(int)Token].PostfixPrecedence; Precedence = BracketPrecedence + OperatorPrecedence[(int)Token].PostfixPrecedence;
@ -1189,9 +1080,7 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
ExpressionStackPushOperator(Parser, &StackTop, OrderPostfix, Token, Precedence); ExpressionStackPushOperator(Parser, &StackTop, OrderPostfix, Token, Precedence);
break; break;
} }
} } else if (OperatorPrecedence[(int)Token].InfixPrecedence != 0) {
else if (OperatorPrecedence[(int)Token].InfixPrecedence != 0)
{
/* scan and collapse the stack, then push */ /* scan and collapse the stack, then push */
Precedence = BracketPrecedence + OperatorPrecedence[(int)Token].InfixPrecedence; Precedence = BracketPrecedence + OperatorPrecedence[(int)Token].InfixPrecedence;
@ -1202,15 +1091,11 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
else else
ExpressionStackCollapse(Parser, &StackTop, Precedence+1, &IgnorePrecedence); ExpressionStackCollapse(Parser, &StackTop, Precedence+1, &IgnorePrecedence);
if (Token == TokenDot || Token == TokenArrow) if (Token == TokenDot || Token == TokenArrow) {
{
ExpressionGetStructElement(Parser, &StackTop, Token); /* this operator is followed by a struct element so handle it as a special case */ 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 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); long LHSInt = ExpressionCoerceInteger(StackTop->Val);
if ( ( (Token == TokenLogicalOr && LHSInt) || (Token == TokenLogicalAnd && !LHSInt) ) && if ( ( (Token == TokenLogicalOr && LHSInt) || (Token == TokenLogicalAnd && !LHSInt) ) &&
(IgnorePrecedence > Precedence) ) (IgnorePrecedence > Precedence) )
@ -1221,8 +1106,7 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
ExpressionStackPushOperator(Parser, &StackTop, OrderInfix, Token, Precedence); ExpressionStackPushOperator(Parser, &StackTop, OrderInfix, Token, Precedence);
PrefixState = TRUE; PrefixState = TRUE;
switch (Token) switch (Token) {
{
case TokenQuestionMark: TernaryDepth++; break; case TokenQuestionMark: TernaryDepth++; break;
case TokenColon: TernaryDepth--; break; case TokenColon: TernaryDepth--; break;
default: break; default: break;
@ -1230,35 +1114,26 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
} }
/* treat an open square bracket as an infix array index operator followed by an open bracket */ /* 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 */ /* boost the bracket operator precedence, then push */
BracketPrecedence += BRACKET_PRECEDENCE; BracketPrecedence += BRACKET_PRECEDENCE;
} }
} } else
else
ProgramFail(Parser, "operator not expected here"); ProgramFail(Parser, "operator not expected here");
} }
} } else if (Token == TokenIdentifier) {
else if (Token == TokenIdentifier)
{
/* it's a variable, function or a macro */ /* it's a variable, function or a macro */
if (!PrefixState) if (!PrefixState)
ProgramFail(Parser, "identifier not expected here"); ProgramFail(Parser, "identifier not expected here");
if (LexGetToken(Parser, NULL, FALSE) == TokenOpenBracket) if (LexGetToken(Parser, NULL, FALSE) == TokenOpenBracket) {
{
ExpressionParseFunctionCall(Parser, &StackTop, LexValue->Val->Identifier, Parser->Mode == RunModeRun && Precedence < IgnorePrecedence); ExpressionParseFunctionCall(Parser, &StackTop, LexValue->Val->Identifier, Parser->Mode == RunModeRun && Precedence < IgnorePrecedence);
} } else {
else if (Parser->Mode == RunModeRun /* && Precedence < IgnorePrecedence */) {
{
if (Parser->Mode == RunModeRun /* && Precedence < IgnorePrecedence */)
{
struct Value *VariableValue = NULL; struct Value *VariableValue = NULL;
VariableGet(Parser->pc, Parser, LexValue->Val->Identifier, &VariableValue); VariableGet(Parser->pc, Parser, LexValue->Val->Identifier, &VariableValue);
if (VariableValue->Typ->Base == TypeMacro) if (VariableValue->Typ->Base == TypeMacro) {
{
/* evaluate a macro as a kind of simple subroutine */ /* evaluate a macro as a kind of simple subroutine */
struct ParseState MacroParser; struct ParseState MacroParser;
struct Value *MacroResult; struct Value *MacroResult;
@ -1272,13 +1147,11 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
ProgramFail(&MacroParser, "expression expected"); ProgramFail(&MacroParser, "expression expected");
ExpressionStackPushValueNode(Parser, &StackTop, MacroResult); 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"); ProgramFail(Parser, "a void value isn't much use here");
else else
ExpressionStackPushLValue(Parser, &StackTop, VariableValue, 0); /* it's a value variable */ ExpressionStackPushLValue(Parser, &StackTop, VariableValue, 0); /* it's a value variable */
} } else /* push a dummy value */
else /* push a dummy value */
ExpressionPushInt(Parser, &StackTop, 0); ExpressionPushInt(Parser, &StackTop, 0);
} }
@ -1288,18 +1161,14 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
IgnorePrecedence = DEEP_PRECEDENCE; IgnorePrecedence = DEEP_PRECEDENCE;
PrefixState = FALSE; 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 */ /* it's a value of some sort, push it */
if (!PrefixState) if (!PrefixState)
ProgramFail(Parser, "value not expected here"); ProgramFail(Parser, "value not expected here");
PrefixState = FALSE; PrefixState = FALSE;
ExpressionStackPushValue(Parser, &StackTop, LexValue); 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() */ /* it's a type. push it on the stack like a value. this is used in sizeof() */
struct ValueType *Typ; struct ValueType *Typ;
char *Identifier; char *Identifier;
@ -1314,9 +1183,7 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
TypeValue = VariableAllocValueFromType(Parser->pc, Parser, &Parser->pc->TypeType, FALSE, NULL, FALSE); TypeValue = VariableAllocValueFromType(Parser->pc, Parser, &Parser->pc->TypeType, FALSE, NULL, FALSE);
TypeValue->Val->Typ = Typ; TypeValue->Val->Typ = Typ;
ExpressionStackPushValueNode(Parser, &StackTop, TypeValue); ExpressionStackPushValueNode(Parser, &StackTop, TypeValue);
} } else {
else
{
/* it isn't a token from an expression */ /* it isn't a token from an expression */
ParserCopy(Parser, &PreState); ParserCopy(Parser, &PreState);
Done = TRUE; Done = TRUE;
@ -1332,18 +1199,15 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
ExpressionStackCollapse(Parser, &StackTop, 0, &IgnorePrecedence); ExpressionStackCollapse(Parser, &StackTop, 0, &IgnorePrecedence);
/* fix up the stack and return the result if we're in run mode */ /* 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 */ /* 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) if (StackTop->Order != OrderNone || StackTop->Next != NULL)
ProgramFail(Parser, "invalid expression"); ProgramFail(Parser, "invalid expression");
*Result = StackTop->Val; *Result = StackTop->Val;
HeapPopStack(Parser->pc, StackTop, sizeof(struct ExpressionStack)); HeapPopStack(Parser->pc, StackTop, sizeof(struct ExpressionStack));
} } else
else
HeapPopStack(Parser->pc, StackTop->Val, sizeof(struct ExpressionStack) + sizeof(struct Value) + TypeStackSizeValue(StackTop->Val)); HeapPopStack(Parser->pc, StackTop->Val, sizeof(struct ExpressionStack) + sizeof(struct Value) + TypeStackSizeValue(StackTop->Val));
} }
@ -1364,8 +1228,7 @@ void ExpressionParseMacroCall(struct ParseState *Parser, struct ExpressionStack
int ArgCount; int ArgCount;
enum LexToken Token; enum LexToken Token;
if (Parser->Mode == RunModeRun) if (Parser->Mode == RunModeRun) {
{
/* create a stack frame for this macro */ /* create a stack frame for this macro */
#ifndef NO_FP #ifndef NO_FP
ExpressionStackPushValueByType(Parser, StackTop, &Parser->pc->FPType); /* largest return type there is */ ExpressionStackPushValueByType(Parser, StackTop, &Parser->pc->FPType); /* largest return type there is */
@ -1377,17 +1240,14 @@ void ExpressionParseMacroCall(struct ParseState *Parser, struct ExpressionStack
ParamArray = HeapAllocStack(Parser->pc, sizeof(struct Value *) * MDef->NumParams); ParamArray = HeapAllocStack(Parser->pc, sizeof(struct Value *) * MDef->NumParams);
if (ParamArray == NULL) if (ParamArray == NULL)
ProgramFail(Parser, "out of memory"); ProgramFail(Parser, "out of memory");
} } else
else
ExpressionPushInt(Parser, StackTop, 0); ExpressionPushInt(Parser, StackTop, 0);
/* parse arguments */ /* parse arguments */
ArgCount = 0; ArgCount = 0;
do { do {
if (ExpressionParse(Parser, &Param)) if (ExpressionParse(Parser, &Param)) {
{ if (Parser->Mode == RunModeRun) {
if (Parser->Mode == RunModeRun)
{
if (ArgCount < MDef->NumParams) if (ArgCount < MDef->NumParams)
ParamArray[ArgCount] = Param; ParamArray[ArgCount] = Param;
else else
@ -1398,9 +1258,7 @@ void ExpressionParseMacroCall(struct ParseState *Parser, struct ExpressionStack
Token = LexGetToken(Parser, NULL, TRUE); Token = LexGetToken(Parser, NULL, TRUE);
if (Token != TokenComma && Token != TokenCloseBracket) if (Token != TokenComma && Token != TokenCloseBracket)
ProgramFail(Parser, "comma expected"); ProgramFail(Parser, "comma expected");
} } else {
else
{
/* end of argument list? */ /* end of argument list? */
Token = LexGetToken(Parser, NULL, TRUE); Token = LexGetToken(Parser, NULL, TRUE);
if (!TokenCloseBracket) if (!TokenCloseBracket)
@ -1409,8 +1267,7 @@ void ExpressionParseMacroCall(struct ParseState *Parser, struct ExpressionStack
} while (Token != TokenCloseBracket); } while (Token != TokenCloseBracket);
if (Parser->Mode == RunModeRun) if (Parser->Mode == RunModeRun) {
{
/* evaluate the macro */ /* evaluate the macro */
struct ParseState MacroParser; struct ParseState MacroParser;
int Count; int Count;
@ -1448,13 +1305,11 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
enum LexToken Token = LexGetToken(Parser, NULL, TRUE); /* open bracket */ enum LexToken Token = LexGetToken(Parser, NULL, TRUE); /* open bracket */
enum RunMode OldMode = Parser->Mode; enum RunMode OldMode = Parser->Mode;
if (RunIt) if (RunIt) {
{
/* get the function definition */ /* get the function definition */
VariableGet(Parser->pc, Parser, FuncName, &FuncValue); VariableGet(Parser->pc, Parser, FuncName, &FuncValue);
if (FuncValue->Typ->Base == TypeMacro) if (FuncValue->Typ->Base == TypeMacro) {
{
/* this is actually a macro, not a function */ /* this is actually a macro, not a function */
ExpressionParseMacroCall(Parser, StackTop, FuncName, &FuncValue->Val->MacroDef); ExpressionParseMacroCall(Parser, StackTop, FuncName, &FuncValue->Val->MacroDef);
return; return;
@ -1469,9 +1324,7 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
ParamArray = HeapAllocStack(Parser->pc, sizeof(struct Value *) * FuncValue->Val->FuncDef.NumParams); ParamArray = HeapAllocStack(Parser->pc, sizeof(struct Value *) * FuncValue->Val->FuncDef.NumParams);
if (ParamArray == NULL) if (ParamArray == NULL)
ProgramFail(Parser, "out of memory"); ProgramFail(Parser, "out of memory");
} } else {
else
{
ExpressionPushInt(Parser, StackTop, 0); ExpressionPushInt(Parser, StackTop, 0);
Parser->Mode = RunModeSkip; Parser->Mode = RunModeSkip;
} }
@ -1482,17 +1335,12 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
if (RunIt && ArgCount < FuncValue->Val->FuncDef.NumParams) if (RunIt && ArgCount < FuncValue->Val->FuncDef.NumParams)
ParamArray[ArgCount] = VariableAllocValueFromType(Parser->pc, Parser, FuncValue->Val->FuncDef.ParamType[ArgCount], FALSE, NULL, FALSE); ParamArray[ArgCount] = VariableAllocValueFromType(Parser->pc, Parser, FuncValue->Val->FuncDef.ParamType[ArgCount], FALSE, NULL, FALSE);
if (ExpressionParse(Parser, &Param)) if (ExpressionParse(Parser, &Param)) {
{ if (RunIt) {
if (RunIt) if (ArgCount < FuncValue->Val->FuncDef.NumParams) {
{
if (ArgCount < FuncValue->Val->FuncDef.NumParams)
{
ExpressionAssign(Parser, ParamArray[ArgCount], Param, TRUE, FuncName, ArgCount+1, FALSE); ExpressionAssign(Parser, ParamArray[ArgCount], Param, TRUE, FuncName, ArgCount+1, FALSE);
VariableStackPop(Parser, Param); VariableStackPop(Parser, Param);
} } else {
else
{
if (!FuncValue->Val->FuncDef.VarArgs) if (!FuncValue->Val->FuncDef.VarArgs)
ProgramFail(Parser, "too many arguments to %s()", FuncName); ProgramFail(Parser, "too many arguments to %s()", FuncName);
} }
@ -1502,9 +1350,7 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
Token = LexGetToken(Parser, NULL, TRUE); Token = LexGetToken(Parser, NULL, TRUE);
if (Token != TokenComma && Token != TokenCloseBracket) if (Token != TokenComma && Token != TokenCloseBracket)
ProgramFail(Parser, "comma expected"); ProgramFail(Parser, "comma expected");
} } else {
else
{
/* end of argument list? */ /* end of argument list? */
Token = LexGetToken(Parser, NULL, TRUE); Token = LexGetToken(Parser, NULL, TRUE);
if (!TokenCloseBracket) if (!TokenCloseBracket)
@ -1513,14 +1359,12 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
} while (Token != TokenCloseBracket); } while (Token != TokenCloseBracket);
if (RunIt) if (RunIt) {
{
/* run the function */ /* run the function */
if (ArgCount < FuncValue->Val->FuncDef.NumParams) if (ArgCount < FuncValue->Val->FuncDef.NumParams)
ProgramFail(Parser, "not enough arguments to '%s'", FuncName); 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 */ /* run a user-defined function */
struct ParseState FuncParser; struct ParseState FuncParser;
int Count; int Count;
@ -1545,8 +1389,7 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
if (ParseStatement(&FuncParser, TRUE) != ParseResultOk) if (ParseStatement(&FuncParser, TRUE) != ParseResultOk)
ProgramFail(&FuncParser, "function body expected"); ProgramFail(&FuncParser, "function body expected");
if (RunIt) if (RunIt) {
{
if (FuncParser.Mode == RunModeRun && FuncValue->Val->FuncDef.ReturnType != &Parser->pc->VoidType) if (FuncParser.Mode == RunModeRun && FuncValue->Val->FuncDef.ReturnType != &Parser->pc->VoidType)
ProgramFail(&FuncParser, "no value returned from a function returning %t", FuncValue->Val->FuncDef.ReturnType); ProgramFail(&FuncParser, "no value returned from a function returning %t", FuncValue->Val->FuncDef.ReturnType);
@ -1555,8 +1398,7 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
} }
VariableStackFramePop(Parser); VariableStackFramePop(Parser);
} } else
else
FuncValue->Val->FuncDef.Intrinsic(Parser, ReturnValue, ParamArray, ArgCount); FuncValue->Val->FuncDef.Intrinsic(Parser, ReturnValue, ParamArray, ArgCount);
HeapPopStackFrame(Parser->pc); HeapPopStackFrame(Parser->pc);
@ -1574,8 +1416,7 @@ long ExpressionParseInt(struct ParseState *Parser)
if (!ExpressionParse(Parser, &Val)) if (!ExpressionParse(Parser, &Val))
ProgramFail(Parser, "expression expected"); ProgramFail(Parser, "expression expected");
if (Parser->Mode == RunModeRun) if (Parser->Mode == RunModeRun) {
{
if (!IS_NUMERIC_COERCIBLE(Val)) if (!IS_NUMERIC_COERCIBLE(Val))
ProgramFail(Parser, "integer value expected instead of %t", Val->Typ); ProgramFail(Parser, "integer value expected instead of %t", Val->Typ);

41
heap.c
View file

@ -118,16 +118,14 @@ void HeapPushStackFrame(Picoc *pc)
/* pop the current stack frame, freeing all memory in the frame. can return NULL */ /* pop the current stack frame, freeing all memory in the frame. can return NULL */
int HeapPopStackFrame(Picoc *pc) int HeapPopStackFrame(Picoc *pc)
{ {
if (*(void **)pc->StackFrame != NULL) if (*(void **)pc->StackFrame != NULL) {
{
pc->HeapStackTop = pc->StackFrame; pc->HeapStackTop = pc->StackFrame;
pc->StackFrame = *(void **)pc->StackFrame; pc->StackFrame = *(void **)pc->StackFrame;
#ifdef DEBUG_HEAP #ifdef DEBUG_HEAP
printf("Popping stack frame back to 0x%lx\n", (unsigned long)pc->HeapStackTop); printf("Popping stack frame back to 0x%lx\n", (unsigned long)pc->HeapStackTop);
#endif #endif
return TRUE; return TRUE;
} } else
else
return FALSE; return FALSE;
} }
@ -153,8 +151,7 @@ void *HeapAllocMem(Picoc *pc, int Size)
AllocSize = sizeof(struct AllocNode); AllocSize = sizeof(struct AllocNode);
Bucket = AllocSize >> 2; 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 */ /* try to allocate from a freelist bucket first */
#ifdef DEBUG_HEAP #ifdef DEBUG_HEAP
printf("allocating %d(%d) from bucket", Size, AllocSize); printf("allocating %d(%d) from bucket", Size, AllocSize);
@ -164,19 +161,15 @@ void *HeapAllocMem(Picoc *pc, int Size)
pc->FreeListBucket[Bucket] = *(struct AllocNode **)NewMem; 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)); 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; 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 */ /* grab the first item from the "big" freelist we can fit in */
for (FreeNode = &pc->FreeListBig; *FreeNode != NULL && (*FreeNode)->Size < AllocSize; FreeNode = &(*FreeNode)->NextFree) for (FreeNode = &pc->FreeListBig; *FreeNode != NULL && (*FreeNode)->Size < AllocSize; FreeNode = &(*FreeNode)->NextFree) {
{} }
if (*FreeNode != NULL) if (*FreeNode != NULL) {
{
assert((unsigned long)*FreeNode >= (unsigned long)&(pc->HeapMemory)[0] && (unsigned char *)*FreeNode - &(pc->HeapMemory)[0] < HEAP_SIZE); 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); 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 */ /* close in size - reduce fragmentation by not splitting */
#ifdef DEBUG_HEAP #ifdef DEBUG_HEAP
printf("allocating %d(%d) from freelist, no split (%d)", Size, AllocSize, (*FreeNode)->Size); 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; NewMem = *FreeNode;
assert((unsigned long)NewMem >= (unsigned long)&(pc->HeapMemory)[0] && (unsigned char *)NewMem - &(pc->HeapMemory)[0] < HEAP_SIZE); assert((unsigned long)NewMem >= (unsigned long)&(pc->HeapMemory)[0] && (unsigned char *)NewMem - &(pc->HeapMemory)[0] < HEAP_SIZE);
*FreeNode = NewMem->NextFree; *FreeNode = NewMem->NextFree;
} } else {
else
{
/* split this big memory chunk */ /* split this big memory chunk */
#ifdef DEBUG_HEAP #ifdef DEBUG_HEAP
printf("allocating %d(%d) from freelist, split chunk (%d)", Size, AllocSize, (*FreeNode)->Size); printf("allocating %d(%d) from freelist, split chunk (%d)", Size, AllocSize, (*FreeNode)->Size);
@ -199,8 +190,7 @@ 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 */ /* couldn't allocate from a freelist - try to increase the size of the heap area */
#ifdef DEBUG_HEAP #ifdef DEBUG_HEAP
printf("allocating %d(%d) at bottom of heap (0x%lx-0x%lx)", Size, AllocSize, (long)((char *)pc->HeapBottom - AllocSize), (long)HeapBottom); printf("allocating %d(%d) at bottom of heap (0x%lx-0x%lx)", Size, AllocSize, (long)((char *)pc->HeapBottom - AllocSize), (long)HeapBottom);
@ -239,8 +229,7 @@ void HeapFreeMem(Picoc *pc, void *Mem)
if (Mem == NULL) if (Mem == NULL)
return; return;
if ((void *)MemNode == pc->HeapBottom) if ((void *)MemNode == pc->HeapBottom) {
{
/* pop it off the bottom of the heap, reducing the heap size */ /* pop it off the bottom of the heap, reducing the heap size */
#ifdef DEBUG_HEAP #ifdef DEBUG_HEAP
printf("freeing %d from bottom of heap\n", MemNode->Size); printf("freeing %d from bottom of heap\n", MemNode->Size);
@ -249,9 +238,7 @@ void HeapFreeMem(Picoc *pc, void *Mem)
#ifdef DEBUG_HEAP #ifdef DEBUG_HEAP
ShowBigList(pc); ShowBigList(pc);
#endif #endif
} } else if (Bucket < FREELIST_BUCKETS) {
else if (Bucket < FREELIST_BUCKETS)
{
/* we can fit it in a bucket */ /* we can fit it in a bucket */
#ifdef DEBUG_HEAP #ifdef DEBUG_HEAP
printf("freeing %d to bucket\n", MemNode->Size); 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)); 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]; *(struct AllocNode **)MemNode = pc->FreeListBucket[Bucket];
pc->FreeListBucket[Bucket] = (struct AllocNode *)MemNode; pc->FreeListBucket[Bucket] = (struct AllocNode *)MemNode;
} } else {
else
{
/* put it in the big memory freelist */ /* put it in the big memory freelist */
#ifdef DEBUG_HEAP #ifdef DEBUG_HEAP
printf("freeing %lx:%d to freelist\n", (unsigned long)Mem, MemNode->Size); printf("freeing %lx:%d to freelist\n", (unsigned long)Mem, MemNode->Size);

View file

@ -33,8 +33,7 @@ void IncludeCleanup(Picoc *pc)
struct IncludeLibrary *ThisInclude = pc->IncludeLibList; struct IncludeLibrary *ThisInclude = pc->IncludeLibList;
struct IncludeLibrary *NextInclude; struct IncludeLibrary *NextInclude;
while (ThisInclude != NULL) while (ThisInclude != NULL) {
{
NextInclude = ThisInclude->NextLib; NextInclude = ThisInclude->NextLib;
HeapFreeMem(pc, ThisInclude); HeapFreeMem(pc, ThisInclude);
ThisInclude = NextInclude; ThisInclude = NextInclude;
@ -70,13 +69,10 @@ void IncludeFile(Picoc *pc, char *FileName)
struct IncludeLibrary *LInclude; struct IncludeLibrary *LInclude;
/* scan for the include file name to see if it's in our list of predefined includes */ /* 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) for (LInclude = pc->IncludeLibList; LInclude != NULL; LInclude = LInclude->NextLib) {
{ if (strcmp(LInclude->IncludeName, FileName) == 0) {
if (strcmp(LInclude->IncludeName, FileName) == 0)
{
/* found it - protect against multiple inclusion */ /* found it - protect against multiple inclusion */
if (!VariableDefined(pc, FileName)) if (!VariableDefined(pc, FileName)) {
{
VariableDefine(pc, NULL, FileName, NULL, &pc->VoidType, FALSE); VariableDefine(pc, NULL, FileName, NULL, &pc->VoidType, FALSE);
/* run an extra startup function if there is one */ /* run an extra startup function if there is one */

209
lex.c
View file

@ -90,8 +90,7 @@ void LexInit(Picoc *pc)
TableInitTable(&pc->ReservedWordTable, &pc->ReservedWordHashTable[0], sizeof(ReservedWords) / sizeof(struct ReservedWord) * 2, TRUE); TableInitTable(&pc->ReservedWordTable, &pc->ReservedWordHashTable[0], sizeof(ReservedWords) / sizeof(struct ReservedWord) * 2, TRUE);
for (Count = 0; Count < sizeof(ReservedWords) / sizeof(struct ReservedWord); Count++) for (Count = 0; Count < sizeof(ReservedWords) / sizeof(struct ReservedWord); Count++) {
{
TableSet(pc, &pc->ReservedWordTable, TableStrRegister(pc, ReservedWords[Count].Word), (struct Value *)&ReservedWords[Count], NULL, 0, 0); TableSet(pc, &pc->ReservedWordTable, TableStrRegister(pc, ReservedWords[Count].Word), (struct Value *)&ReservedWords[Count], NULL, 0, 0);
} }
@ -142,17 +141,15 @@ enum LexToken LexGetNumber(Picoc *pc, struct LexState *Lexer, struct Value *Valu
char IsUnsigned = 0; char IsUnsigned = 0;
#endif #endif
if (*Lexer->Pos == '0') if (*Lexer->Pos == '0') {
{
/* a binary, octal or hex literal */ /* a binary, octal or hex literal */
LEXER_INC(Lexer); LEXER_INC(Lexer);
if (Lexer->Pos != Lexer->End) if (Lexer->Pos != Lexer->End) {
{ if (*Lexer->Pos == 'x' || *Lexer->Pos == 'X') {
if (*Lexer->Pos == 'x' || *Lexer->Pos == 'X') Base = 16; LEXER_INC(Lexer);
{ Base = 16; LEXER_INC(Lexer); } } else if (*Lexer->Pos == 'b' || *Lexer->Pos == 'B') {
else if (*Lexer->Pos == 'b' || *Lexer->Pos == 'B') Base = 2; LEXER_INC(Lexer);
{ Base = 2; LEXER_INC(Lexer); } } else if (*Lexer->Pos != '.')
else if (*Lexer->Pos != '.')
Base = 8; Base = 8;
} }
} }
@ -161,13 +158,11 @@ 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)) for (; Lexer->Pos != Lexer->End && IS_BASE_DIGIT(*Lexer->Pos, Base); LEXER_INC(Lexer))
Result = Result * Base + GET_BASE_DIGIT(*Lexer->Pos); 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); LEXER_INC(Lexer);
/* IsUnsigned = 1; */ /* IsUnsigned = 1; */
} }
if (*Lexer->Pos == 'l' || *Lexer->Pos == 'L') if (*Lexer->Pos == 'l' || *Lexer->Pos == 'L') {
{
LEXER_INC(Lexer); LEXER_INC(Lexer);
/* IsLong = 1; */ /* IsLong = 1; */
} }
@ -181,42 +176,35 @@ enum LexToken LexGetNumber(Picoc *pc, struct LexState *Lexer, struct Value *Valu
return ResultToken; return ResultToken;
#ifndef NO_FP #ifndef NO_FP
if (Lexer->Pos == Lexer->End) if (Lexer->Pos == Lexer->End) {
{
return ResultToken; return ResultToken;
} }
if (*Lexer->Pos != '.' && *Lexer->Pos != 'e' && *Lexer->Pos != 'E') if (*Lexer->Pos != '.' && *Lexer->Pos != 'e' && *Lexer->Pos != 'E') {
{
return ResultToken; return ResultToken;
} }
Value->Typ = &pc->FPType; Value->Typ = &pc->FPType;
FPResult = (double)Result; FPResult = (double)Result;
if (*Lexer->Pos == '.') if (*Lexer->Pos == '.') {
{
LEXER_INC(Lexer); LEXER_INC(Lexer);
for (FPDiv = 1.0/Base; Lexer->Pos != Lexer->End && IS_BASE_DIGIT(*Lexer->Pos, Base); LEXER_INC(Lexer), FPDiv /= (double)Base) for (FPDiv = 1.0/Base; Lexer->Pos != Lexer->End && IS_BASE_DIGIT(*Lexer->Pos, Base); LEXER_INC(Lexer), FPDiv /= (double)Base) {
{
FPResult += GET_BASE_DIGIT(*Lexer->Pos) * FPDiv; FPResult += GET_BASE_DIGIT(*Lexer->Pos) * FPDiv;
} }
} }
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; int ExponentSign = 1;
LEXER_INC(Lexer); LEXER_INC(Lexer);
if (Lexer->Pos != Lexer->End && *Lexer->Pos == '-') if (Lexer->Pos != Lexer->End && *Lexer->Pos == '-') {
{
ExponentSign = -1; ExponentSign = -1;
LEXER_INC(Lexer); LEXER_INC(Lexer);
} }
Result = 0; 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); Result = Result * Base + GET_BASE_DIGIT(*Lexer->Pos);
LEXER_INC(Lexer); LEXER_INC(Lexer);
} }
@ -249,8 +237,7 @@ enum LexToken LexGetWord(Picoc *pc, struct LexState *Lexer, struct Value *Value)
Value->Val->Identifier = TableStrRegister2(pc, StartPos, Lexer->Pos - StartPos); Value->Val->Identifier = TableStrRegister2(pc, StartPos, Lexer->Pos - StartPos);
Token = LexCheckReservedWord(pc, Value->Val->Identifier); Token = LexCheckReservedWord(pc, Value->Val->Identifier);
switch (Token) switch (Token) {
{
case TokenHashInclude: Lexer->Mode = LexModeHashInclude; break; case TokenHashInclude: Lexer->Mode = LexModeHashInclude; break;
case TokenHashDefine: Lexer->Mode = LexModeHashDefine; break; case TokenHashDefine: Lexer->Mode = LexModeHashDefine; break;
default: break; default: break;
@ -292,16 +279,14 @@ unsigned char LexUnEscapeCharacter(const char **From, const char *End)
if (*From == End) if (*From == End)
return '\\'; return '\\';
if (**From == '\\') if (**From == '\\') {
{
/* it's escaped */ /* it's escaped */
(*From)++; (*From)++;
if (*From == End) if (*From == End)
return '\\'; return '\\';
ThisChar = *(*From)++; ThisChar = *(*From)++;
switch (ThisChar) switch (ThisChar) {
{
case '\\': return '\\'; case '\\': return '\\';
case '\'': return '\''; case '\'': return '\'';
case '"': return '"'; case '"': return '"';
@ -332,16 +317,13 @@ enum LexToken LexGetStringConstant(Picoc *pc, struct LexState *Lexer, struct Val
char *RegString; char *RegString;
struct Value *ArrayValue; struct Value *ArrayValue;
while (Lexer->Pos != Lexer->End && (*Lexer->Pos != EndChar || Escape)) while (Lexer->Pos != Lexer->End && (*Lexer->Pos != EndChar || Escape)) {
{
/* find the end */ /* find the end */
if (Escape) if (Escape) {
{
if (*Lexer->Pos == '\r' && Lexer->Pos+1 != Lexer->End) if (*Lexer->Pos == '\r' && Lexer->Pos+1 != Lexer->End)
Lexer->Pos++; Lexer->Pos++;
if (*Lexer->Pos == '\n' && Lexer->Pos+1 != Lexer->End) if (*Lexer->Pos == '\n' && Lexer->Pos+1 != Lexer->End) {
{
Lexer->Line++; Lexer->Line++;
Lexer->Pos++; Lexer->Pos++;
Lexer->CharacterPos = 0; Lexer->CharacterPos = 0;
@ -349,8 +331,7 @@ enum LexToken LexGetStringConstant(Picoc *pc, struct LexState *Lexer, struct Val
} }
Escape = FALSE; Escape = FALSE;
} } else if (*Lexer->Pos == '\\')
else if (*Lexer->Pos == '\\')
Escape = TRUE; Escape = TRUE;
LEXER_INC(Lexer); LEXER_INC(Lexer);
@ -368,8 +349,7 @@ enum LexToken LexGetStringConstant(Picoc *pc, struct LexState *Lexer, struct Val
RegString = TableStrRegister2(pc, EscBuf, EscBufPos - EscBuf); RegString = TableStrRegister2(pc, EscBuf, EscBufPos - EscBuf);
HeapPopStack(pc, EscBuf, EndPos - StartPos); HeapPopStack(pc, EscBuf, EndPos - StartPos);
ArrayValue = VariableStringLiteralGet(pc, RegString); ArrayValue = VariableStringLiteralGet(pc, RegString);
if (ArrayValue == NULL) if (ArrayValue == NULL) {
{
/* create and store this string literal */ /* create and store this string literal */
ArrayValue = VariableAllocValueAndData(pc, NULL, 0, FALSE, NULL, TRUE); ArrayValue = VariableAllocValueAndData(pc, NULL, 0, FALSE, NULL, TRUE);
ArrayValue->Typ = pc->CharArrayType; ArrayValue->Typ = pc->CharArrayType;
@ -401,8 +381,7 @@ enum LexToken LexGetCharacterConstant(Picoc *pc, struct LexState *Lexer, struct
/* skip a comment - used while scanning */ /* skip a comment - used while scanning */
void LexSkipComment(struct LexState *Lexer, char NextChar, enum LexToken *ReturnToken) void LexSkipComment(struct LexState *Lexer, char NextChar, enum LexToken *ReturnToken)
{ {
if (NextChar == '*') if (NextChar == '*') {
{
/* conventional C comment */ /* conventional C comment */
while (Lexer->Pos != Lexer->End && (*(Lexer->Pos-1) != '*' || *Lexer->Pos != '/')) while (Lexer->Pos != Lexer->End && (*(Lexer->Pos-1) != '*' || *Lexer->Pos != '/'))
{ {
@ -416,9 +395,7 @@ void LexSkipComment(struct LexState *Lexer, char NextChar, enum LexToken *Return
LEXER_INC(Lexer); LEXER_INC(Lexer);
Lexer->Mode = LexModeNormal; Lexer->Mode = LexModeNormal;
} } else {
else
{
/* C++ style comment */ /* C++ style comment */
while (Lexer->Pos != Lexer->End && *Lexer->Pos != '\n') while (Lexer->Pos != Lexer->End && *Lexer->Pos != '\n')
LEXER_INC(Lexer); LEXER_INC(Lexer);
@ -433,29 +410,23 @@ enum LexToken LexScanGetToken(Picoc *pc, struct LexState *Lexer, struct Value **
enum LexToken GotToken = TokenNone; enum LexToken GotToken = TokenNone;
/* handle cases line multi-line comments or string constants which mess up the line count */ /* 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--; Lexer->EmitExtraNewlines--;
return TokenEndOfLine; return TokenEndOfLine;
} }
/* scan for a token */ /* scan for a token */
do do {
{
*Value = &pc->LexValue; *Value = &pc->LexValue;
while (Lexer->Pos != Lexer->End && isspace((int)*Lexer->Pos)) while (Lexer->Pos != Lexer->End && isspace((int)*Lexer->Pos)) {
{ if (*Lexer->Pos == '\n') {
if (*Lexer->Pos == '\n')
{
Lexer->Line++; Lexer->Line++;
Lexer->Pos++; Lexer->Pos++;
Lexer->Mode = LexModeNormal; Lexer->Mode = LexModeNormal;
Lexer->CharacterPos = 0; Lexer->CharacterPos = 0;
return TokenEndOfLine; return TokenEndOfLine;
} } else if (Lexer->Mode == LexModeHashDefine || Lexer->Mode == LexModeHashDefineSpace)
else if (Lexer->Mode == LexModeHashDefine || Lexer->Mode == LexModeHashDefineSpace)
Lexer->Mode = LexModeHashDefineSpace; Lexer->Mode = LexModeHashDefineSpace;
else if (Lexer->Mode == LexModeHashDefineSpaceIdent) else if (Lexer->Mode == LexModeHashDefineSpaceIdent)
Lexer->Mode = LexModeNormal; Lexer->Mode = LexModeNormal;
@ -474,8 +445,7 @@ enum LexToken LexScanGetToken(Picoc *pc, struct LexState *Lexer, struct Value **
NextChar = (Lexer->Pos+1 != Lexer->End) ? *(Lexer->Pos+1) : 0; NextChar = (Lexer->Pos+1 != Lexer->End) ? *(Lexer->Pos+1) : 0;
LEXER_INC(Lexer); LEXER_INC(Lexer);
switch (ThisChar) switch (ThisChar) {
{
case '"': GotToken = LexGetStringConstant(pc, Lexer, *Value, '"'); break; case '"': GotToken = LexGetStringConstant(pc, Lexer, *Value, '"'); break;
case '\'': GotToken = LexGetCharacterConstant(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 '(': if (Lexer->Mode == LexModeHashDefineSpaceIdent) GotToken = TokenOpenMacroBracket; else GotToken = TokenOpenBracket; Lexer->Mode = LexModeNormal; break;
@ -512,8 +482,7 @@ enum LexToken LexScanGetToken(Picoc *pc, struct LexState *Lexer, struct Value **
/* what size value goes with each token */ /* what size value goes with each token */
int LexTokenSize(enum LexToken Token) int LexTokenSize(enum LexToken Token)
{ {
switch (Token) switch (Token) {
{
case TokenIdentifier: case TokenStringConstant: return sizeof(char *); case TokenIdentifier: case TokenStringConstant: return sizeof(char *);
case TokenIntegerConstant: return sizeof(long); case TokenIntegerConstant: return sizeof(long);
case TokenCharacterConstant: return sizeof(unsigned char); case TokenCharacterConstant: return sizeof(unsigned char);
@ -538,8 +507,7 @@ void *LexTokenise(Picoc *pc, struct LexState *Lexer, int *TokenLen)
if (TokenSpace == NULL) if (TokenSpace == NULL)
LexFail(pc, Lexer, "out of memory"); LexFail(pc, Lexer, "out of memory");
do do {
{
/* store the token at the end of the stack area */ /* store the token at the end of the stack area */
Token = LexScanGetToken(pc, Lexer, &GotValue); Token = LexScanGetToken(pc, Lexer, &GotValue);
@ -555,8 +523,7 @@ void *LexTokenise(Picoc *pc, struct LexState *Lexer, int *TokenLen)
MemUsed++; MemUsed++;
ValueSize = LexTokenSize(Token); ValueSize = LexTokenSize(Token);
if (ValueSize > 0) if (ValueSize > 0) {
{
/* store a value as well */ /* store a value as well */
memcpy((void *)TokenPos, (void *)GotValue->Val, ValueSize); memcpy((void *)TokenPos, (void *)GotValue->Val, ValueSize);
TokenPos += ValueSize; TokenPos += ValueSize;
@ -630,39 +597,32 @@ enum LexToken LexGetRawToken(struct ParseState *Parser, struct Value **Value, in
char *Prompt = NULL; char *Prompt = NULL;
Picoc *pc = Parser->pc; Picoc *pc = Parser->pc;
do do {
{
/* get the next token */ /* get the next token */
if (Parser->Pos == NULL && pc->InteractiveHead != NULL) if (Parser->Pos == NULL && pc->InteractiveHead != NULL)
Parser->Pos = pc->InteractiveHead->Tokens; Parser->Pos = pc->InteractiveHead->Tokens;
if (Parser->FileName != pc->StrEmpty || pc->InteractiveHead != NULL) if (Parser->FileName != pc->StrEmpty || pc->InteractiveHead != NULL) {
{
/* skip leading newlines */ /* skip leading newlines */
while ((Token = (enum LexToken)*(unsigned char *)Parser->Pos) == TokenEndOfLine) while ((Token = (enum LexToken)*(unsigned char *)Parser->Pos) == TokenEndOfLine) {
{
Parser->Line++; Parser->Line++;
Parser->Pos += TOKEN_DATA_OFFSET; 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 */ /* we're at the end of an interactive input token list */
char LineBuffer[LINEBUFFER_MAX]; char LineBuffer[LINEBUFFER_MAX];
void *LineTokens; void *LineTokens;
int LineBytes; int LineBytes;
struct TokenLine *LineNode; struct TokenLine *LineNode;
if (pc->InteractiveHead == NULL || (unsigned char *)Parser->Pos == &pc->InteractiveTail->Tokens[pc->InteractiveTail->NumBytes-TOKEN_DATA_OFFSET]) if (pc->InteractiveHead == NULL || (unsigned char *)Parser->Pos == &pc->InteractiveTail->Tokens[pc->InteractiveTail->NumBytes-TOKEN_DATA_OFFSET]) {
{
/* get interactive input */ /* get interactive input */
if (pc->LexUseStatementPrompt) if (pc->LexUseStatementPrompt) {
{
Prompt = INTERACTIVE_PROMPT_STATEMENT; Prompt = INTERACTIVE_PROMPT_STATEMENT;
pc->LexUseStatementPrompt = FALSE; pc->LexUseStatementPrompt = FALSE;
} } else
else
Prompt = INTERACTIVE_PROMPT_LINE; Prompt = INTERACTIVE_PROMPT_LINE;
if (PlatformGetLine(&LineBuffer[0], LINEBUFFER_MAX, Prompt) == NULL) if (PlatformGetLine(&LineBuffer[0], LINEBUFFER_MAX, Prompt) == NULL)
@ -673,28 +633,24 @@ enum LexToken LexGetRawToken(struct ParseState *Parser, struct Value **Value, in
LineNode = VariableAlloc(pc, Parser, sizeof(struct TokenLine), TRUE); LineNode = VariableAlloc(pc, Parser, sizeof(struct TokenLine), TRUE);
LineNode->Tokens = LineTokens; LineNode->Tokens = LineTokens;
LineNode->NumBytes = LineBytes; LineNode->NumBytes = LineBytes;
if (pc->InteractiveHead == NULL) if (pc->InteractiveHead == NULL) {
{
/* start a new list */ /* start a new list */
pc->InteractiveHead = LineNode; pc->InteractiveHead = LineNode;
Parser->Line = 1; Parser->Line = 1;
Parser->CharacterPos = 0; Parser->CharacterPos = 0;
} } else
else
pc->InteractiveTail->Next = LineNode; pc->InteractiveTail->Next = LineNode;
pc->InteractiveTail = LineNode; pc->InteractiveTail = LineNode;
pc->InteractiveCurrentLine = LineNode; pc->InteractiveCurrentLine = LineNode;
Parser->Pos = LineTokens; Parser->Pos = LineTokens;
} } else {
else
{
/* go to the next token line */ /* 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 */ /* 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) 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->Next != NULL);
}
} }
assert(pc->InteractiveCurrentLine != NULL); assert(pc->InteractiveCurrentLine != NULL);
@ -709,13 +665,10 @@ enum LexToken LexGetRawToken(struct ParseState *Parser, struct Value **Value, in
Parser->CharacterPos = *((unsigned char *)Parser->Pos + 1); Parser->CharacterPos = *((unsigned char *)Parser->Pos + 1);
ValueSize = LexTokenSize(Token); ValueSize = LexTokenSize(Token);
if (ValueSize > 0) if (ValueSize > 0) {
{
/* this token requires a value - unpack it */ /* this token requires a value - unpack it */
if (Value != NULL) if (Value != NULL) {
{ switch (Token) {
switch (Token)
{
case TokenStringConstant: pc->LexValue.Typ = pc->CharPtrType; break; case TokenStringConstant: pc->LexValue.Typ = pc->CharPtrType; break;
case TokenIdentifier: pc->LexValue.Typ = NULL; break; case TokenIdentifier: pc->LexValue.Typ = NULL; break;
case TokenIntegerConstant: pc->LexValue.Typ = &pc->LongType; break; case TokenIntegerConstant: pc->LexValue.Typ = &pc->LongType; break;
@ -736,9 +689,7 @@ enum LexToken LexGetRawToken(struct ParseState *Parser, struct Value **Value, in
if (IncPos) if (IncPos)
Parser->Pos += ValueSize + TOKEN_DATA_OFFSET; Parser->Pos += ValueSize + TOKEN_DATA_OFFSET;
} } else {
else
{
if (IncPos && Token != TokenEOF) if (IncPos && Token != TokenEOF)
Parser->Pos += TOKEN_DATA_OFFSET; Parser->Pos += TOKEN_DATA_OFFSET;
} }
@ -771,8 +722,7 @@ void LexHashIfdef(struct ParseState *Parser, int IfNot)
/* is the identifier defined? */ /* is the identifier defined? */
IsDefined = TableGet(&Parser->pc->GlobalTable, IdentValue->Val->Identifier, &SavedValue, NULL, NULL, NULL); IsDefined = TableGet(&Parser->pc->GlobalTable, IdentValue->Val->Identifier, &SavedValue, NULL, NULL, NULL);
if (Parser->HashIfEvaluateToLevel == Parser->HashIfLevel && ( (IsDefined && !IfNot) || (!IsDefined && IfNot)) ) if (Parser->HashIfEvaluateToLevel == Parser->HashIfLevel && ((IsDefined && !IfNot) || (!IsDefined && IfNot))) {
{
/* #if is active, evaluate to this new level */ /* #if is active, evaluate to this new level */
Parser->HashIfEvaluateToLevel++; Parser->HashIfEvaluateToLevel++;
} }
@ -789,8 +739,7 @@ void LexHashIf(struct ParseState *Parser)
struct ParseState MacroParser; struct ParseState MacroParser;
enum LexToken Token = LexGetRawToken(Parser, &IdentValue, TRUE); enum LexToken Token = LexGetRawToken(Parser, &IdentValue, TRUE);
if (Token == TokenIdentifier) if (Token == TokenIdentifier) {
{
/* look up a value from a macro definition */ /* look up a value from a macro definition */
if (!TableGet(&Parser->pc->GlobalTable, IdentValue->Val->Identifier, &SavedValue, NULL, NULL, NULL)) if (!TableGet(&Parser->pc->GlobalTable, IdentValue->Val->Identifier, &SavedValue, NULL, NULL, NULL))
ProgramFail(Parser, "'%s' is undefined", IdentValue->Val->Identifier); ProgramFail(Parser, "'%s' is undefined", IdentValue->Val->Identifier);
@ -806,8 +755,7 @@ void LexHashIf(struct ParseState *Parser)
ProgramFail(Parser, "value expected"); ProgramFail(Parser, "value expected");
/* is the identifier defined? */ /* 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 */ /* #if is active, evaluate to this new level */
Parser->HashIfEvaluateToLevel++; Parser->HashIfEvaluateToLevel++;
} }
@ -820,9 +768,7 @@ void LexHashElse(struct ParseState *Parser)
{ {
if (Parser->HashIfEvaluateToLevel == Parser->HashIfLevel - 1) if (Parser->HashIfEvaluateToLevel == Parser->HashIfLevel - 1)
Parser->HashIfEvaluateToLevel++; /* #if was not active, make this next section active */ 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 was active, now go inactive */
if (Parser->HashIfLevel == 0) if (Parser->HashIfLevel == 0)
ProgramFail(Parser, "#else without #if"); ProgramFail(Parser, "#else without #if");
@ -886,13 +832,11 @@ enum LexToken LexGetToken(struct ParseState *Parser, struct Value **Value, int I
int TryNextToken; int TryNextToken;
/* implements the pre-processor #if commands */ /* implements the pre-processor #if commands */
do do {
{
int WasPreProcToken = TRUE; int WasPreProcToken = TRUE;
Token = LexGetRawToken(Parser, Value, IncPos); Token = LexGetRawToken(Parser, Value, IncPos);
switch (Token) switch (Token) {
{
case TokenHashIfdef: LexHashIncPos(Parser, IncPos); LexHashIfdef(Parser, FALSE); break; case TokenHashIfdef: LexHashIncPos(Parser, IncPos); LexHashIfdef(Parser, FALSE); break;
case TokenHashIfndef: LexHashIncPos(Parser, IncPos); LexHashIfdef(Parser, TRUE); break; case TokenHashIfndef: LexHashIncPos(Parser, IncPos); LexHashIfdef(Parser, TRUE); break;
case TokenHashIf: LexHashIncPos(Parser, IncPos); LexHashIf(Parser); break; case TokenHashIf: LexHashIncPos(Parser, IncPos); LexHashIf(Parser); break;
@ -920,8 +864,7 @@ enum LexToken LexRawPeekToken(struct ParseState *Parser)
/* find the end of the line */ /* find the end of the line */
void LexToEndOfLine(struct ParseState *Parser) void LexToEndOfLine(struct ParseState *Parser)
{ {
while (TRUE) while (TRUE) {
{
enum LexToken Token = (enum LexToken)*(unsigned char *)Parser->Pos; enum LexToken Token = (enum LexToken)*(unsigned char *)Parser->Pos;
if (Token == TokenEndOfLine || Token == TokenEOF) if (Token == TokenEndOfLine || Token == TokenEOF)
return; return;
@ -941,28 +884,22 @@ void *LexCopyTokens(struct ParseState *StartParser, struct ParseState *EndParser
struct TokenLine *ILine; struct TokenLine *ILine;
Picoc *pc = StartParser->pc; Picoc *pc = StartParser->pc;
if (pc->InteractiveHead == NULL) if (pc->InteractiveHead == NULL) {
{
/* non-interactive mode - copy the tokens */ /* non-interactive mode - copy the tokens */
MemSize = EndParser->Pos - StartParser->Pos; MemSize = EndParser->Pos - StartParser->Pos;
NewTokens = VariableAlloc(pc, StartParser, MemSize + TOKEN_DATA_OFFSET, TRUE); NewTokens = VariableAlloc(pc, StartParser, MemSize + TOKEN_DATA_OFFSET, TRUE);
memcpy(NewTokens, (void *)StartParser->Pos, MemSize); memcpy(NewTokens, (void *)StartParser->Pos, MemSize);
} } else {
else
{
/* we're in interactive mode - add up line by line */ /* 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) 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 */ } /* find the line we just counted */
if (EndParser->Pos >= StartParser->Pos && EndParser->Pos < &pc->InteractiveCurrentLine->Tokens[pc->InteractiveCurrentLine->NumBytes]) if (EndParser->Pos >= StartParser->Pos && EndParser->Pos < &pc->InteractiveCurrentLine->Tokens[pc->InteractiveCurrentLine->NumBytes]) {
{
/* all on a single line */ /* all on a single line */
MemSize = EndParser->Pos - StartParser->Pos; MemSize = EndParser->Pos - StartParser->Pos;
NewTokens = VariableAlloc(pc, StartParser, MemSize + TOKEN_DATA_OFFSET, TRUE); NewTokens = VariableAlloc(pc, StartParser, MemSize + TOKEN_DATA_OFFSET, TRUE);
memcpy(NewTokens, (void *)StartParser->Pos, MemSize); memcpy(NewTokens, (void *)StartParser->Pos, MemSize);
} } else {
else
{
/* it's spread across multiple lines */ /* it's spread across multiple lines */
MemSize = &pc->InteractiveCurrentLine->Tokens[pc->InteractiveCurrentLine->NumBytes-TOKEN_DATA_OFFSET] - Pos; MemSize = &pc->InteractiveCurrentLine->Tokens[pc->InteractiveCurrentLine->NumBytes-TOKEN_DATA_OFFSET] - Pos;
@ -976,8 +913,7 @@ void *LexCopyTokens(struct ParseState *StartParser, struct ParseState *EndParser
CopySize = &pc->InteractiveCurrentLine->Tokens[pc->InteractiveCurrentLine->NumBytes-TOKEN_DATA_OFFSET] - Pos; CopySize = &pc->InteractiveCurrentLine->Tokens[pc->InteractiveCurrentLine->NumBytes-TOKEN_DATA_OFFSET] - Pos;
memcpy(NewTokens, Pos, CopySize); memcpy(NewTokens, Pos, CopySize);
NewTokenPos = NewTokens + 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); memcpy(NewTokenPos, &ILine->Tokens[0], ILine->NumBytes - TOKEN_DATA_OFFSET);
NewTokenPos += ILine->NumBytes-TOKEN_DATA_OFFSET; NewTokenPos += ILine->NumBytes-TOKEN_DATA_OFFSET;
} }
@ -994,8 +930,7 @@ void *LexCopyTokens(struct ParseState *StartParser, struct ParseState *EndParser
/* indicate that we've completed up to this point in the interactive input and free expired tokens */ /* indicate that we've completed up to this point in the interactive input and free expired tokens */
void LexInteractiveClear(Picoc *pc, struct ParseState *Parser) void LexInteractiveClear(Picoc *pc, struct ParseState *Parser)
{ {
while (pc->InteractiveHead != NULL) while (pc->InteractiveHead != NULL) {
{
struct TokenLine *NextLine = pc->InteractiveHead->Next; struct TokenLine *NextLine = pc->InteractiveHead->Next;
HeapFreeMem(pc, pc->InteractiveHead->Tokens); HeapFreeMem(pc, pc->InteractiveHead->Tokens);
@ -1012,8 +947,7 @@ void LexInteractiveClear(Picoc *pc, struct ParseState *Parser)
/* indicate that we've completed up to this point in the interactive input and free expired tokens */ /* indicate that we've completed up to this point in the interactive input and free expired tokens */
void LexInteractiveCompleted(Picoc *pc, struct ParseState *Parser) void LexInteractiveCompleted(Picoc *pc, struct ParseState *Parser)
{ {
while (pc->InteractiveHead != NULL && !(Parser->Pos >= &pc->InteractiveHead->Tokens[0] && Parser->Pos < &pc->InteractiveHead->Tokens[pc->InteractiveHead->NumBytes])) 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 */ /* this token line is no longer needed - free it */
struct TokenLine *NextLine = pc->InteractiveHead->Next; struct TokenLine *NextLine = pc->InteractiveHead->Next;
@ -1021,8 +955,7 @@ void LexInteractiveCompleted(Picoc *pc, struct ParseState *Parser)
HeapFreeMem(pc, pc->InteractiveHead); HeapFreeMem(pc, pc->InteractiveHead);
pc->InteractiveHead = NextLine; pc->InteractiveHead = NextLine;
if (pc->InteractiveHead == NULL) if (pc->InteractiveHead == NULL) {
{
/* we've emptied the list */ /* we've emptied the list */
Parser->Pos = NULL; Parser->Pos = NULL;
pc->InteractiveTail = NULL; pc->InteractiveTail = NULL;

268
parse.c
View file

@ -6,8 +6,7 @@
/* deallocate any memory */ /* deallocate any memory */
void ParseCleanup(Picoc *pc) void ParseCleanup(Picoc *pc)
{ {
while (pc->CleanupTokenList != NULL) while (pc->CleanupTokenList != NULL) {
{
struct CleanupTokenNode *Next = pc->CleanupTokenList->Next; struct CleanupTokenNode *Next = pc->CleanupTokenList->Next;
HeapFreeMem(pc, pc->CleanupTokenList->Tokens); HeapFreeMem(pc, pc->CleanupTokenList->Tokens);
@ -22,16 +21,14 @@ void ParseCleanup(Picoc *pc)
/* parse a statement, but only run it if Condition is TRUE */ /* parse a statement, but only run it if Condition is TRUE */
enum ParseResult ParseStatementMaybeRun(struct ParseState *Parser, int Condition, int CheckTrailingSemicolon) enum ParseResult ParseStatementMaybeRun(struct ParseState *Parser, int Condition, int CheckTrailingSemicolon)
{ {
if (Parser->Mode != RunModeSkip && !Condition) if (Parser->Mode != RunModeSkip && !Condition) {
{
enum RunMode OldMode = Parser->Mode; enum RunMode OldMode = Parser->Mode;
int Result; int Result;
Parser->Mode = RunModeSkip; Parser->Mode = RunModeSkip;
Result = ParseStatement(Parser, CheckTrailingSemicolon); Result = ParseStatement(Parser, CheckTrailingSemicolon);
Parser->Mode = OldMode; Parser->Mode = OldMode;
return Result; return Result;
} } else
else
return ParseStatement(Parser, CheckTrailingSemicolon); return ParseStatement(Parser, CheckTrailingSemicolon);
} }
@ -41,12 +38,10 @@ int ParseCountParams(struct ParseState *Parser)
int ParamCount = 0; int ParamCount = 0;
enum LexToken Token = LexGetToken(Parser, NULL, TRUE); enum LexToken Token = LexGetToken(Parser, NULL, TRUE);
if (Token != TokenCloseBracket && Token != TokenEOF) if (Token != TokenCloseBracket && Token != TokenEOF) {
{
/* count the number of parameters */ /* count the number of parameters */
ParamCount++; ParamCount++;
while ((Token = LexGetToken(Parser, NULL, TRUE)) != TokenCloseBracket && Token != TokenEOF) while ((Token = LexGetToken(Parser, NULL, TRUE)) != TokenCloseBracket && Token != TokenEOF) {
{
if (Token == TokenComma) if (Token == TokenComma)
ParamCount++; ParamCount++;
} }
@ -85,28 +80,21 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp
FuncValue->Val->FuncDef.ParamType = (struct ValueType **)((char *)FuncValue->Val + sizeof(struct FuncDef)); 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); FuncValue->Val->FuncDef.ParamName = (char **)((char *)FuncValue->Val->FuncDef.ParamType + sizeof(struct ValueType *) * ParamCount);
for (ParamCount = 0; ParamCount < FuncValue->Val->FuncDef.NumParams; ParamCount++) for (ParamCount = 0; ParamCount < FuncValue->Val->FuncDef.NumParams; ParamCount++) {
{
/* harvest the parameters into the function definition */ /* harvest the parameters into the function definition */
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 */ /* ellipsis at end */
FuncValue->Val->FuncDef.NumParams--; FuncValue->Val->FuncDef.NumParams--;
FuncValue->Val->FuncDef.VarArgs = TRUE; FuncValue->Val->FuncDef.VarArgs = TRUE;
break; break;
} } else {
else
{
/* add a parameter */ /* add a parameter */
TypeParse(&ParamParser, &ParamType, &ParamIdentifier, NULL); TypeParse(&ParamParser, &ParamType, &ParamIdentifier, NULL);
if (ParamType->Base == TypeVoid) if (ParamType->Base == TypeVoid) {
{
/* this isn't a real parameter at all - delete it */ /* this isn't a real parameter at all - delete it */
ParamCount--; ParamCount--;
FuncValue->Val->FuncDef.NumParams--; FuncValue->Val->FuncDef.NumParams--;
} } else {
else
{
FuncValue->Val->FuncDef.ParamType[ParamCount] = ParamType; FuncValue->Val->FuncDef.ParamType[ParamCount] = ParamType;
FuncValue->Val->FuncDef.ParamName[ParamCount] = ParamIdentifier; FuncValue->Val->FuncDef.ParamName[ParamCount] = ParamIdentifier;
} }
@ -120,8 +108,7 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp
if (FuncValue->Val->FuncDef.NumParams != 0 && Token != TokenCloseBracket && Token != TokenComma && Token != TokenEllipsis) if (FuncValue->Val->FuncDef.NumParams != 0 && Token != TokenCloseBracket && Token != TokenComma && Token != TokenEllipsis)
ProgramFail(&ParamParser, "bad parameter"); ProgramFail(&ParamParser, "bad parameter");
if (strcmp(Identifier, "main") == 0) if (strcmp(Identifier, "main") == 0) {
{
/* make sure it's int main() */ /* make sure it's int main() */
if ( FuncValue->Val->FuncDef.ReturnType != &pc->IntType && if ( FuncValue->Val->FuncDef.ReturnType != &pc->IntType &&
FuncValue->Val->FuncDef.ReturnType != &pc->VoidType ) FuncValue->Val->FuncDef.ReturnType != &pc->VoidType )
@ -136,8 +123,7 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp
Token = LexGetToken(Parser, NULL, FALSE); Token = LexGetToken(Parser, NULL, FALSE);
if (Token == TokenSemicolon) if (Token == TokenSemicolon)
LexGetToken(Parser, NULL, TRUE); /* it's a prototype, absorb the trailing semicolon */ LexGetToken(Parser, NULL, TRUE); /* it's a prototype, absorb the trailing semicolon */
else else {
{
/* it's a full function definition with a body */ /* it's a full function definition with a body */
if (Token != TokenLeftBrace) if (Token != TokenLeftBrace)
ProgramFail(Parser, "bad function definition"); ProgramFail(Parser, "bad function definition");
@ -150,14 +136,11 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp
FuncValue->Val->FuncDef.Body.Pos = LexCopyTokens(&FuncBody, Parser); FuncValue->Val->FuncDef.Body.Pos = LexCopyTokens(&FuncBody, Parser);
/* is this function already in the global table? */ /* is this function already in the global table? */
if (TableGet(&pc->GlobalTable, Identifier, &OldFuncValue, NULL, NULL, NULL)) if (TableGet(&pc->GlobalTable, Identifier, &OldFuncValue, NULL, NULL, NULL)) {
{ if (OldFuncValue->Val->FuncDef.Body.Pos == NULL) {
if (OldFuncValue->Val->FuncDef.Body.Pos == NULL)
{
/* override an old function prototype */ /* override an old function prototype */
VariableFree(pc, TableDelete(pc, &pc->GlobalTable, Identifier)); VariableFree(pc, TableDelete(pc, &pc->GlobalTable, Identifier));
} } else
else
ProgramFail(Parser, "'%s' is already defined", Identifier); ProgramFail(Parser, "'%s' is already defined", Identifier);
} }
} }
@ -176,8 +159,7 @@ int ParseArrayInitialiser(struct ParseState *Parser, struct Value *NewVariable,
struct Value *CValue; struct Value *CValue;
/* count the number of elements in the array */ /* count the number of elements in the array */
if (DoAssignment && Parser->Mode == RunModeRun) if (DoAssignment && Parser->Mode == RunModeRun) {
{
struct ParseState CountParser; struct ParseState CountParser;
int NumElements; int NumElements;
@ -187,8 +169,7 @@ int ParseArrayInitialiser(struct ParseState *Parser, struct Value *NewVariable,
if (NewVariable->Typ->Base != TypeArray) if (NewVariable->Typ->Base != TypeArray)
AssignFail(Parser, "%t from array initializer", NewVariable->Typ, NULL, 0, 0, NULL, 0); AssignFail(Parser, "%t from array initializer", NewVariable->Typ, NULL, 0, 0, NULL, 0);
if (NewVariable->Typ->ArraySize == 0) if (NewVariable->Typ->ArraySize == 0) {
{
NewVariable->Typ = TypeGetMatching(Parser->pc, Parser, NewVariable->Typ->FromType, NewVariable->Typ->Base, NumElements, NewVariable->Typ->Identifier, TRUE); NewVariable->Typ = TypeGetMatching(Parser->pc, Parser, NewVariable->Typ->FromType, NewVariable->Typ->Base, NumElements, NewVariable->Typ->Identifier, TRUE);
VariableRealloc(Parser, NewVariable, TypeSizeValue(NewVariable, FALSE)); VariableRealloc(Parser, NewVariable, TypeSizeValue(NewVariable, FALSE));
} }
@ -200,15 +181,12 @@ int ParseArrayInitialiser(struct ParseState *Parser, struct Value *NewVariable,
/* parse the array initialiser */ /* parse the array initialiser */
Token = LexGetToken(Parser, NULL, FALSE); Token = LexGetToken(Parser, NULL, FALSE);
while (Token != TokenRightBrace) while (Token != TokenRightBrace) {
{ if (LexGetToken(Parser, NULL, FALSE) == TokenLeftBrace) {
if (LexGetToken(Parser, NULL, FALSE) == TokenLeftBrace)
{
/* this is a sub-array initialiser */ /* this is a sub-array initialiser */
int SubArraySize = 0; int SubArraySize = 0;
struct Value *SubArray = NewVariable; struct Value *SubArray = NewVariable;
if (Parser->Mode == RunModeRun && DoAssignment) if (Parser->Mode == RunModeRun && DoAssignment) {
{
SubArraySize = TypeSize(NewVariable->Typ->FromType, NewVariable->Typ->FromType->ArraySize, TRUE); SubArraySize = TypeSize(NewVariable->Typ->FromType, NewVariable->Typ->FromType->ArraySize, TRUE);
SubArray = VariableAllocValueFromExistingData(Parser, NewVariable->Typ->FromType, (union AnyValue *)(&NewVariable->Val->ArrayMem[0] + SubArraySize * ArrayIndex), TRUE, NewVariable); SubArray = VariableAllocValueFromExistingData(Parser, NewVariable->Typ->FromType, (union AnyValue *)(&NewVariable->Val->ArrayMem[0] + SubArraySize * ArrayIndex), TRUE, NewVariable);
#ifdef DEBUG_ARRAY_INITIALIZER #ifdef DEBUG_ARRAY_INITIALIZER
@ -222,20 +200,16 @@ int ParseArrayInitialiser(struct ParseState *Parser, struct Value *NewVariable,
} }
LexGetToken(Parser, NULL, TRUE); LexGetToken(Parser, NULL, TRUE);
ParseArrayInitialiser(Parser, SubArray, DoAssignment); ParseArrayInitialiser(Parser, SubArray, DoAssignment);
} } else {
else
{
struct Value *ArrayElement = NULL; struct Value *ArrayElement = NULL;
if (Parser->Mode == RunModeRun && DoAssignment) if (Parser->Mode == RunModeRun && DoAssignment) {
{
struct ValueType * ElementType = NewVariable->Typ; struct ValueType * ElementType = NewVariable->Typ;
int TotalSize = 1; int TotalSize = 1;
int ElementSize = 0; int ElementSize = 0;
/* int x[3][3] = {1,2,3,4} => handle it just like int x[9] = {1,2,3,4} */ /* 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; TotalSize *= ElementType->ArraySize;
ElementType = ElementType->FromType; ElementType = ElementType->FromType;
@ -257,8 +231,7 @@ int ParseArrayInitialiser(struct ParseState *Parser, struct Value *NewVariable,
if (!ExpressionParse(Parser, &CValue)) if (!ExpressionParse(Parser, &CValue))
ProgramFail(Parser, "expression expected"); ProgramFail(Parser, "expression expected");
if (Parser->Mode == RunModeRun && DoAssignment) if (Parser->Mode == RunModeRun && DoAssignment) {
{
ExpressionAssign(Parser, ArrayElement, CValue, FALSE, NULL, 0, FALSE); ExpressionAssign(Parser, ArrayElement, CValue, FALSE, NULL, 0, FALSE);
VariableStackPop(Parser, CValue); VariableStackPop(Parser, CValue);
VariableStackPop(Parser, ArrayElement); VariableStackPop(Parser, ArrayElement);
@ -268,12 +241,10 @@ int ParseArrayInitialiser(struct ParseState *Parser, struct Value *NewVariable,
ArrayIndex++; ArrayIndex++;
Token = LexGetToken(Parser, NULL, FALSE); Token = LexGetToken(Parser, NULL, FALSE);
if (Token == TokenComma) if (Token == TokenComma) {
{
LexGetToken(Parser, NULL, TRUE); LexGetToken(Parser, NULL, TRUE);
Token = LexGetToken(Parser, NULL, FALSE); Token = LexGetToken(Parser, NULL, FALSE);
} } else if (Token != TokenRightBrace)
else if (Token != TokenRightBrace)
ProgramFail(Parser, "comma expected"); ProgramFail(Parser, "comma expected");
} }
@ -290,20 +261,16 @@ void ParseDeclarationAssignment(struct ParseState *Parser, struct Value *NewVari
{ {
struct Value *CValue; struct Value *CValue;
if (LexGetToken(Parser, NULL, FALSE) == TokenLeftBrace) if (LexGetToken(Parser, NULL, FALSE) == TokenLeftBrace) {
{
/* this is an array initialiser */ /* this is an array initialiser */
LexGetToken(Parser, NULL, TRUE); LexGetToken(Parser, NULL, TRUE);
ParseArrayInitialiser(Parser, NewVariable, DoAssignment); ParseArrayInitialiser(Parser, NewVariable, DoAssignment);
} } else {
else
{
/* this is a normal expression initialiser */ /* this is a normal expression initialiser */
if (!ExpressionParse(Parser, &CValue)) if (!ExpressionParse(Parser, &CValue))
ProgramFail(Parser, "expression expected"); ProgramFail(Parser, "expression expected");
if (Parser->Mode == RunModeRun && DoAssignment) if (Parser->Mode == RunModeRun && DoAssignment) {
{
ExpressionAssign(Parser, NewVariable, CValue, FALSE, NULL, 0, FALSE); ExpressionAssign(Parser, NewVariable, CValue, FALSE, NULL, 0, FALSE);
VariableStackPop(Parser, CValue); VariableStackPop(Parser, CValue);
} }
@ -322,30 +289,25 @@ int ParseDeclaration(struct ParseState *Parser, enum LexToken Token)
Picoc *pc = Parser->pc; Picoc *pc = Parser->pc;
TypeParseFront(Parser, &BasicType, &IsStatic); TypeParseFront(Parser, &BasicType, &IsStatic);
do do {
{
TypeParseIdentPart(Parser, BasicType, &Typ, &Identifier); TypeParseIdentPart(Parser, BasicType, &Typ, &Identifier);
if ((Token != TokenVoidType && Token != TokenStructType && Token != TokenUnionType && Token != TokenEnumType) && Identifier == pc->StrEmpty) if ((Token != TokenVoidType && Token != TokenStructType && Token != TokenUnionType && Token != TokenEnumType) && Identifier == pc->StrEmpty)
ProgramFail(Parser, "identifier expected"); ProgramFail(Parser, "identifier expected");
if (Identifier != pc->StrEmpty) if (Identifier != pc->StrEmpty) {
{
/* handle function definitions */ /* handle function definitions */
if (LexGetToken(Parser, NULL, FALSE) == TokenOpenBracket) if (LexGetToken(Parser, NULL, FALSE) == TokenOpenBracket)
{ {
ParseFunctionDefinition(Parser, Typ, Identifier); ParseFunctionDefinition(Parser, Typ, Identifier);
return FALSE; return FALSE;
} } else {
else
{
if (Typ == &pc->VoidType && Identifier != pc->StrEmpty) if (Typ == &pc->VoidType && Identifier != pc->StrEmpty)
ProgramFail(Parser, "can't define a void variable"); ProgramFail(Parser, "can't define a void variable");
if (Parser->Mode == RunModeRun || Parser->Mode == RunModeGoto) if (Parser->Mode == RunModeRun || Parser->Mode == RunModeGoto)
NewVariable = VariableDefineButIgnoreIdentical(Parser, Identifier, Typ, IsStatic, &FirstVisit); NewVariable = VariableDefineButIgnoreIdentical(Parser, Identifier, Typ, IsStatic, &FirstVisit);
if (LexGetToken(Parser, NULL, FALSE) == TokenAssign) if (LexGetToken(Parser, NULL, FALSE) == TokenAssign) {
{
/* we're assigning an initial value */ /* we're assigning an initial value */
LexGetToken(Parser, NULL, TRUE); LexGetToken(Parser, NULL, TRUE);
ParseDeclarationAssignment(Parser, NewVariable, !IsStatic || FirstVisit); ParseDeclarationAssignment(Parser, NewVariable, !IsStatic || FirstVisit);
@ -375,8 +337,7 @@ void ParseMacroDefinition(struct ParseState *Parser)
MacroNameStr = MacroName->Val->Identifier; MacroNameStr = MacroName->Val->Identifier;
if (LexRawPeekToken(Parser) == TokenOpenMacroBracket) if (LexRawPeekToken(Parser) == TokenOpenMacroBracket) {
{
/* it's a parameterised macro, read the parameters */ /* it's a parameterised macro, read the parameters */
enum LexToken Token = LexGetToken(Parser, NULL, TRUE); enum LexToken Token = LexGetToken(Parser, NULL, TRUE);
struct ParseState ParamParser; struct ParseState ParamParser;
@ -391,8 +352,7 @@ void ParseMacroDefinition(struct ParseState *Parser)
Token = LexGetToken(Parser, &ParamName, TRUE); Token = LexGetToken(Parser, &ParamName, TRUE);
while (Token == TokenIdentifier) while (Token == TokenIdentifier) {
{
/* store a parameter name */ /* store a parameter name */
MacroValue->Val->MacroDef.ParamName[ParamCount++] = ParamName->Val->Identifier; MacroValue->Val->MacroDef.ParamName[ParamCount++] = ParamName->Val->Identifier;
@ -407,9 +367,7 @@ void ParseMacroDefinition(struct ParseState *Parser)
if (Token != TokenCloseBracket) if (Token != TokenCloseBracket)
ProgramFail(Parser, "close bracket expected"); ProgramFail(Parser, "close bracket expected");
} } else {
else
{
/* allocate a simple unparameterised macro */ /* allocate a simple unparameterised macro */
MacroValue = VariableAllocValueAndData(Parser->pc, Parser, sizeof(struct MacroDef), FALSE, NULL, TRUE); MacroValue = VariableAllocValueAndData(Parser->pc, Parser, sizeof(struct MacroDef), FALSE, NULL, TRUE);
MacroValue->Val->MacroDef.NumParams = 0; MacroValue->Val->MacroDef.NumParams = 0;
@ -484,8 +442,7 @@ void ParseFor(struct ParseState *Parser)
ParserCopyPos(&After, Parser); ParserCopyPos(&After, Parser);
while (Condition && Parser->Mode == RunModeRun) while (Condition && Parser->Mode == RunModeRun) {
{
ParserCopyPos(Parser, &PreIncrement); ParserCopyPos(Parser, &PreIncrement);
ParseStatement(Parser, FALSE); ParseStatement(Parser, FALSE);
@ -495,8 +452,7 @@ void ParseFor(struct ParseState *Parser)
else else
Condition = ExpressionParseInt(Parser); Condition = ExpressionParseInt(Parser);
if (Condition) if (Condition) {
{
ParserCopyPos(Parser, &PreStatement); ParserCopyPos(Parser, &PreStatement);
ParseStatement(Parser, TRUE); ParseStatement(Parser, TRUE);
@ -521,20 +477,17 @@ enum RunMode ParseBlock(struct ParseState *Parser, int AbsorbOpenBrace, int Cond
if (AbsorbOpenBrace && LexGetToken(Parser, NULL, TRUE) != TokenLeftBrace) if (AbsorbOpenBrace && LexGetToken(Parser, NULL, TRUE) != TokenLeftBrace)
ProgramFail(Parser, "'{' expected"); ProgramFail(Parser, "'{' expected");
if (Parser->Mode == RunModeSkip || !Condition) if (Parser->Mode == RunModeSkip || !Condition) {
{
/* condition failed - skip this block instead */ /* condition failed - skip this block instead */
enum RunMode OldMode = Parser->Mode; enum RunMode OldMode = Parser->Mode;
Parser->Mode = RunModeSkip; Parser->Mode = RunModeSkip;
while (ParseStatement(Parser, TRUE) == ParseResultOk) while (ParseStatement(Parser, TRUE) == ParseResultOk) {
{}
Parser->Mode = OldMode;
} }
else Parser->Mode = OldMode;
{ } else {
/* just run it in its current mode */ /* just run it in its current mode */
while (ParseStatement(Parser, TRUE) == ParseResultOk) while (ParseStatement(Parser, TRUE) == ParseResultOk) {
{} }
} }
if (LexGetToken(Parser, NULL, TRUE) != TokenRightBrace) if (LexGetToken(Parser, NULL, TRUE) != TokenRightBrace)
@ -555,8 +508,7 @@ void ParseTypedef(struct ParseState *Parser)
TypeParse(Parser, &Typ, &TypeName, NULL); TypeParse(Parser, &Typ, &TypeName, NULL);
if (Parser->Mode == RunModeRun) if (Parser->Mode == RunModeRun) {
{
TypPtr = &Typ; TypPtr = &Typ;
InitValue.Typ = &Parser->pc->TypeType; InitValue.Typ = &Parser->pc->TypeType;
InitValue.Val = (union AnyValue *)TypPtr; InitValue.Val = (union AnyValue *)TypPtr;
@ -582,53 +534,40 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi
ParserCopy(&PreState, Parser); ParserCopy(&PreState, Parser);
Token = LexGetToken(Parser, &LexerValue, TRUE); Token = LexGetToken(Parser, &LexerValue, TRUE);
switch (Token) switch (Token) {
{
case TokenEOF: case TokenEOF:
return ParseResultEOF; return ParseResultEOF;
case TokenIdentifier: case TokenIdentifier:
/* might be a typedef-typed variable declaration or it might be an expression */ /* might be a typedef-typed variable declaration or it might be an expression */
if (VariableDefined(Parser->pc, LexerValue->Val->Identifier)) if (VariableDefined(Parser->pc, LexerValue->Val->Identifier)) {
{
VariableGet(Parser->pc, Parser, LexerValue->Val->Identifier, &VarValue); VariableGet(Parser->pc, Parser, LexerValue->Val->Identifier, &VarValue);
if (VarValue->Typ->Base == Type_Type) if (VarValue->Typ->Base == Type_Type) {
{
*Parser = PreState; *Parser = PreState;
ParseDeclaration(Parser, Token); ParseDeclaration(Parser, Token);
break; break;
} }
} } else {
else
{
/* it might be a goto label */ /* it might be a goto label */
enum LexToken NextToken = LexGetToken(Parser, NULL, FALSE); enum LexToken NextToken = LexGetToken(Parser, NULL, FALSE);
if (NextToken == TokenColon) if (NextToken == TokenColon) {
{
/* declare the identifier as a goto label */ /* declare the identifier as a goto label */
LexGetToken(Parser, NULL, TRUE); LexGetToken(Parser, NULL, TRUE);
if (Parser->Mode == RunModeGoto && LexerValue->Val->Identifier == Parser->SearchGotoLabel) if (Parser->Mode == RunModeGoto && LexerValue->Val->Identifier == Parser->SearchGotoLabel)
Parser->Mode = RunModeRun; Parser->Mode = RunModeRun;
CheckTrailingSemicolon = FALSE; CheckTrailingSemicolon = FALSE;
break; break;
} }
#ifdef FEATURE_AUTO_DECLARE_VARIABLES #ifdef FEATURE_AUTO_DECLARE_VARIABLES
else /* new_identifier = something */ else /* new_identifier = something */ {
{ /* try to guess type and declare the variable based on assigned value */ /* try to guess type and declare the variable based on assigned value */
if (NextToken == TokenAssign && !VariableDefinedAndOutOfScope(Parser->pc, LexerValue->Val->Identifier)) if (NextToken == TokenAssign && !VariableDefinedAndOutOfScope(Parser->pc, LexerValue->Val->Identifier)) {
{ if (Parser->Mode == RunModeRun) {
if (Parser->Mode == RunModeRun)
{
struct Value *CValue; struct Value *CValue;
char* Identifier = LexerValue->Val->Identifier; char* Identifier = LexerValue->Val->Identifier;
LexGetToken(Parser, NULL, TRUE); LexGetToken(Parser, NULL, TRUE);
if (!ExpressionParse(Parser, &CValue)) if (!ExpressionParse(Parser, &CValue)) {
{
ProgramFail(Parser, "expected: expression"); ProgramFail(Parser, "expected: expression");
} }
#if 0 #if 0
PRINT_SOURCE_POS; PRINT_SOURCE_POS;
PlatformPrintf(Parser->pc->CStdOut, "%t %s = %d;\n", CValue->Typ, Identifier, CValue->Val->Integer); PlatformPrintf(Parser->pc->CStdOut, "%t %s = %d;\n", CValue->Typ, Identifier, CValue->Val->Integer);
@ -643,7 +582,6 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi
} }
/* else fallthrough to expression */ /* else fallthrough to expression */
/* no break */ /* no break */
case TokenAsterisk: case TokenAsterisk:
case TokenAmpersand: case TokenAmpersand:
case TokenIncrement: case TokenIncrement:
@ -654,104 +592,77 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi
if (Parser->Mode == RunModeRun) if (Parser->Mode == RunModeRun)
VariableStackPop(Parser, CValue); VariableStackPop(Parser, CValue);
break; break;
case TokenLeftBrace: case TokenLeftBrace:
ParseBlock(Parser, FALSE, TRUE); ParseBlock(Parser, FALSE, TRUE);
CheckTrailingSemicolon = FALSE; CheckTrailingSemicolon = FALSE;
break; break;
case TokenIf: case TokenIf:
if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket)
ProgramFail(Parser, "'(' expected"); ProgramFail(Parser, "'(' expected");
Condition = ExpressionParseInt(Parser); Condition = ExpressionParseInt(Parser);
if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket)
ProgramFail(Parser, "')' expected"); ProgramFail(Parser, "')' expected");
if (ParseStatementMaybeRun(Parser, Condition, TRUE) != ParseResultOk) if (ParseStatementMaybeRun(Parser, Condition, TRUE) != ParseResultOk)
ProgramFail(Parser, "statement expected"); ProgramFail(Parser, "statement expected");
if (LexGetToken(Parser, NULL, FALSE) == TokenElse) {
if (LexGetToken(Parser, NULL, FALSE) == TokenElse)
{
LexGetToken(Parser, NULL, TRUE); LexGetToken(Parser, NULL, TRUE);
if (ParseStatementMaybeRun(Parser, !Condition, TRUE) != ParseResultOk) if (ParseStatementMaybeRun(Parser, !Condition, TRUE) != ParseResultOk)
ProgramFail(Parser, "statement expected"); ProgramFail(Parser, "statement expected");
} }
CheckTrailingSemicolon = FALSE; CheckTrailingSemicolon = FALSE;
break; break;
case TokenWhile: case TokenWhile:
{ {
struct ParseState PreConditional; struct ParseState PreConditional;
enum RunMode PreMode = Parser->Mode; enum RunMode PreMode = Parser->Mode;
if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket)
ProgramFail(Parser, "'(' expected"); ProgramFail(Parser, "'(' expected");
ParserCopyPos(&PreConditional, Parser); ParserCopyPos(&PreConditional, Parser);
do do {
{
ParserCopyPos(Parser, &PreConditional); ParserCopyPos(Parser, &PreConditional);
Condition = ExpressionParseInt(Parser); Condition = ExpressionParseInt(Parser);
if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket)
ProgramFail(Parser, "')' expected"); ProgramFail(Parser, "')' expected");
if (ParseStatementMaybeRun(Parser, Condition, TRUE) != ParseResultOk) if (ParseStatementMaybeRun(Parser, Condition, TRUE) != ParseResultOk)
ProgramFail(Parser, "statement expected"); ProgramFail(Parser, "statement expected");
if (Parser->Mode == RunModeContinue) if (Parser->Mode == RunModeContinue)
Parser->Mode = PreMode; Parser->Mode = PreMode;
} while (Parser->Mode == RunModeRun && Condition); } while (Parser->Mode == RunModeRun && Condition);
if (Parser->Mode == RunModeBreak) if (Parser->Mode == RunModeBreak)
Parser->Mode = PreMode; Parser->Mode = PreMode;
CheckTrailingSemicolon = FALSE; CheckTrailingSemicolon = FALSE;
} }
break; break;
case TokenDo: case TokenDo:
{ {
struct ParseState PreStatement; struct ParseState PreStatement;
enum RunMode PreMode = Parser->Mode; enum RunMode PreMode = Parser->Mode;
ParserCopyPos(&PreStatement, Parser); ParserCopyPos(&PreStatement, Parser);
do do {
{
ParserCopyPos(Parser, &PreStatement); ParserCopyPos(Parser, &PreStatement);
if (ParseStatement(Parser, TRUE) != ParseResultOk) if (ParseStatement(Parser, TRUE) != ParseResultOk)
ProgramFail(Parser, "statement expected"); ProgramFail(Parser, "statement expected");
if (Parser->Mode == RunModeContinue) if (Parser->Mode == RunModeContinue)
Parser->Mode = PreMode; Parser->Mode = PreMode;
if (LexGetToken(Parser, NULL, TRUE) != TokenWhile) if (LexGetToken(Parser, NULL, TRUE) != TokenWhile)
ProgramFail(Parser, "'while' expected"); ProgramFail(Parser, "'while' expected");
if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket)
ProgramFail(Parser, "'(' expected"); ProgramFail(Parser, "'(' expected");
Condition = ExpressionParseInt(Parser); Condition = ExpressionParseInt(Parser);
if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket)
ProgramFail(Parser, "')' expected"); ProgramFail(Parser, "')' expected");
} while (Condition && Parser->Mode == RunModeRun); } while (Condition && Parser->Mode == RunModeRun);
if (Parser->Mode == RunModeBreak) if (Parser->Mode == RunModeBreak)
Parser->Mode = PreMode; Parser->Mode = PreMode;
} }
break; break;
case TokenFor: case TokenFor:
ParseFor(Parser); ParseFor(Parser);
CheckTrailingSemicolon = FALSE; CheckTrailingSemicolon = FALSE;
break; break;
case TokenSemicolon: case TokenSemicolon:
CheckTrailingSemicolon = FALSE; CheckTrailingSemicolon = FALSE;
break; break;
case TokenIntType: case TokenIntType:
case TokenShortType: case TokenShortType:
case TokenCharType: case TokenCharType:
@ -771,145 +682,106 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi
*Parser = PreState; *Parser = PreState;
CheckTrailingSemicolon = ParseDeclaration(Parser, Token); CheckTrailingSemicolon = ParseDeclaration(Parser, Token);
break; break;
case TokenHashDefine: case TokenHashDefine:
ParseMacroDefinition(Parser); ParseMacroDefinition(Parser);
CheckTrailingSemicolon = FALSE; CheckTrailingSemicolon = FALSE;
break; break;
#ifndef NO_HASH_INCLUDE #ifndef NO_HASH_INCLUDE
case TokenHashInclude: case TokenHashInclude:
if (LexGetToken(Parser, &LexerValue, TRUE) != TokenStringConstant) if (LexGetToken(Parser, &LexerValue, TRUE) != TokenStringConstant)
ProgramFail(Parser, "\"filename.h\" expected"); ProgramFail(Parser, "\"filename.h\" expected");
IncludeFile(Parser->pc, (char *)LexerValue->Val->Pointer); IncludeFile(Parser->pc, (char *)LexerValue->Val->Pointer);
CheckTrailingSemicolon = FALSE; CheckTrailingSemicolon = FALSE;
break; break;
#endif #endif
case TokenSwitch: case TokenSwitch:
if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket)
ProgramFail(Parser, "'(' expected"); ProgramFail(Parser, "'(' expected");
Condition = ExpressionParseInt(Parser); Condition = ExpressionParseInt(Parser);
if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket)
ProgramFail(Parser, "')' expected"); ProgramFail(Parser, "')' expected");
if (LexGetToken(Parser, NULL, FALSE) != TokenLeftBrace) if (LexGetToken(Parser, NULL, FALSE) != TokenLeftBrace)
ProgramFail(Parser, "'{' expected"); ProgramFail(Parser, "'{' expected");
{ {
/* new block so we can store parser state */ /* new block so we can store parser state */
enum RunMode OldMode = Parser->Mode; enum RunMode OldMode = Parser->Mode;
int OldSearchLabel = Parser->SearchLabel; int OldSearchLabel = Parser->SearchLabel;
Parser->Mode = RunModeCaseSearch; Parser->Mode = RunModeCaseSearch;
Parser->SearchLabel = Condition; Parser->SearchLabel = Condition;
ParseBlock(Parser, TRUE, (OldMode != RunModeSkip) && (OldMode != RunModeReturn)); ParseBlock(Parser, TRUE, (OldMode != RunModeSkip) && (OldMode != RunModeReturn));
if (Parser->Mode != RunModeReturn) if (Parser->Mode != RunModeReturn)
Parser->Mode = OldMode; Parser->Mode = OldMode;
Parser->SearchLabel = OldSearchLabel; Parser->SearchLabel = OldSearchLabel;
} }
CheckTrailingSemicolon = FALSE; CheckTrailingSemicolon = FALSE;
break; break;
case TokenCase: case TokenCase:
if (Parser->Mode == RunModeCaseSearch) if (Parser->Mode == RunModeCaseSearch) {
{
Parser->Mode = RunModeRun; Parser->Mode = RunModeRun;
Condition = ExpressionParseInt(Parser); Condition = ExpressionParseInt(Parser);
Parser->Mode = RunModeCaseSearch; Parser->Mode = RunModeCaseSearch;
} } else
else
Condition = ExpressionParseInt(Parser); Condition = ExpressionParseInt(Parser);
if (LexGetToken(Parser, NULL, TRUE) != TokenColon) if (LexGetToken(Parser, NULL, TRUE) != TokenColon)
ProgramFail(Parser, "':' expected"); ProgramFail(Parser, "':' expected");
if (Parser->Mode == RunModeCaseSearch && Condition == Parser->SearchLabel) if (Parser->Mode == RunModeCaseSearch && Condition == Parser->SearchLabel)
Parser->Mode = RunModeRun; Parser->Mode = RunModeRun;
CheckTrailingSemicolon = FALSE; CheckTrailingSemicolon = FALSE;
break; break;
case TokenDefault: case TokenDefault:
if (LexGetToken(Parser, NULL, TRUE) != TokenColon) if (LexGetToken(Parser, NULL, TRUE) != TokenColon)
ProgramFail(Parser, "':' expected"); ProgramFail(Parser, "':' expected");
if (Parser->Mode == RunModeCaseSearch) if (Parser->Mode == RunModeCaseSearch)
Parser->Mode = RunModeRun; Parser->Mode = RunModeRun;
CheckTrailingSemicolon = FALSE; CheckTrailingSemicolon = FALSE;
break; break;
case TokenBreak: case TokenBreak:
if (Parser->Mode == RunModeRun) if (Parser->Mode == RunModeRun)
Parser->Mode = RunModeBreak; Parser->Mode = RunModeBreak;
break; break;
case TokenContinue: case TokenContinue:
if (Parser->Mode == RunModeRun) if (Parser->Mode == RunModeRun)
Parser->Mode = RunModeContinue; Parser->Mode = RunModeContinue;
break; break;
case TokenReturn: case TokenReturn:
if (Parser->Mode == RunModeRun) if (Parser->Mode == RunModeRun) {
{ if (!Parser->pc->TopStackFrame || Parser->pc->TopStackFrame->ReturnValue->Typ->Base != TypeVoid) {
if (!Parser->pc->TopStackFrame || Parser->pc->TopStackFrame->ReturnValue->Typ->Base != TypeVoid)
{
if (!ExpressionParse(Parser, &CValue)) if (!ExpressionParse(Parser, &CValue))
ProgramFail(Parser, "value required in return"); ProgramFail(Parser, "value required in return");
if (!Parser->pc->TopStackFrame) /* return from top-level program? */ if (!Parser->pc->TopStackFrame) /* return from top-level program? */
PlatformExit(Parser->pc, ExpressionCoerceInteger(CValue)); PlatformExit(Parser->pc, ExpressionCoerceInteger(CValue));
else else
ExpressionAssign(Parser, Parser->pc->TopStackFrame->ReturnValue, CValue, TRUE, NULL, 0, FALSE); ExpressionAssign(Parser, Parser->pc->TopStackFrame->ReturnValue, CValue, TRUE, NULL, 0, FALSE);
VariableStackPop(Parser, CValue); VariableStackPop(Parser, CValue);
} } else {
else
{
if (ExpressionParse(Parser, &CValue)) if (ExpressionParse(Parser, &CValue))
ProgramFail(Parser, "value in return from a void function"); ProgramFail(Parser, "value in return from a void function");
} }
Parser->Mode = RunModeReturn; Parser->Mode = RunModeReturn;
} }
else else
ExpressionParse(Parser, &CValue); ExpressionParse(Parser, &CValue);
break; break;
case TokenTypedef: case TokenTypedef:
ParseTypedef(Parser); ParseTypedef(Parser);
break; break;
case TokenGoto: case TokenGoto:
if (LexGetToken(Parser, &LexerValue, TRUE) != TokenIdentifier) if (LexGetToken(Parser, &LexerValue, TRUE) != TokenIdentifier)
ProgramFail(Parser, "identifier expected"); ProgramFail(Parser, "identifier expected");
if (Parser->Mode == RunModeRun) {
if (Parser->Mode == RunModeRun)
{
/* start scanning for the goto label */ /* start scanning for the goto label */
Parser->SearchGotoLabel = LexerValue->Val->Identifier; Parser->SearchGotoLabel = LexerValue->Val->Identifier;
Parser->Mode = RunModeGoto; Parser->Mode = RunModeGoto;
} }
break; break;
case TokenDelete: case TokenDelete:
{ {
/* try it as a function or variable name to delete */ /* try it as a function or variable name to delete */
if (LexGetToken(Parser, &LexerValue, TRUE) != TokenIdentifier) if (LexGetToken(Parser, &LexerValue, TRUE) != TokenIdentifier)
ProgramFail(Parser, "identifier expected"); ProgramFail(Parser, "identifier expected");
if (Parser->Mode == RunModeRun) {
if (Parser->Mode == RunModeRun)
{
/* delete this variable or function */ /* delete this variable or function */
CValue = TableDelete(Parser->pc, &Parser->pc->GlobalTable, LexerValue->Val->Identifier); CValue = TableDelete(Parser->pc, &Parser->pc->GlobalTable, LexerValue->Val->Identifier);
if (CValue == NULL) if (CValue == NULL)
ProgramFail(Parser, "'%s' is not defined", LexerValue->Val->Identifier); ProgramFail(Parser, "'%s' is not defined", LexerValue->Val->Identifier);
@ -917,14 +789,12 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi
} }
break; break;
} }
default: default:
*Parser = PreState; *Parser = PreState;
return ParseResultError; return ParseResultError;
} }
if (CheckTrailingSemicolon) if (CheckTrailingSemicolon) {
{
if (LexGetToken(Parser, NULL, TRUE) != TokenSemicolon) if (LexGetToken(Parser, NULL, TRUE) != TokenSemicolon)
ProgramFail(Parser, "';' expected"); ProgramFail(Parser, "';' expected");
} }
@ -943,8 +813,7 @@ void PicocParse(Picoc *pc, const char *FileName, const char *Source, int SourceL
void *Tokens = LexAnalyse(pc, RegFileName, Source, SourceLen, NULL); void *Tokens = LexAnalyse(pc, RegFileName, Source, SourceLen, NULL);
/* allocate a cleanup node so we can clean up the tokens later */ /* allocate a cleanup node so we can clean up the tokens later */
if (!CleanupNow) if (!CleanupNow) {
{
NewCleanupNode = HeapAllocMem(pc, sizeof(struct CleanupTokenNode)); NewCleanupNode = HeapAllocMem(pc, sizeof(struct CleanupTokenNode));
if (NewCleanupNode == NULL) if (NewCleanupNode == NULL)
ProgramFailNoParser(pc, "out of memory"); ProgramFailNoParser(pc, "out of memory");
@ -984,8 +853,7 @@ void PicocParseInteractiveNoStartPrompt(Picoc *pc, int EnableDebugger)
PicocPlatformSetExitPoint(pc); PicocPlatformSetExitPoint(pc);
LexInteractiveClear(pc, &Parser); LexInteractiveClear(pc, &Parser);
do do {
{
LexInteractiveStatementPrompt(pc); LexInteractiveStatementPrompt(pc);
Ok = ParseStatement(&Parser, TRUE); Ok = ParseStatement(&Parser, TRUE);
LexInteractiveCompleted(pc, &Parser); LexInteractiveCompleted(pc, &Parser);

26
picoc.c
View file

@ -20,8 +20,7 @@ int main(int argc, char **argv)
int StackSize = getenv("STACKSIZE") ? atoi(getenv("STACKSIZE")) : PICOC_STACK_SIZE; int StackSize = getenv("STACKSIZE") ? atoi(getenv("STACKSIZE")) : PICOC_STACK_SIZE;
Picoc pc; Picoc pc;
if (argc < 2) if (argc < 2) {
{
printf(PICOC_VERSION " \n" printf(PICOC_VERSION " \n"
"Format: picoc <file1.c>... [- <arg1>...] : run a program (calls main() to start it)\n" "Format: picoc <file1.c>... [- <arg1>...] : run a program (calls main() to start it)\n"
" picoc -s <file1.c>... [- <arg1>...] : script mode - runs the program without calling main()\n" " picoc -s <file1.c>... [- <arg1>...] : script mode - runs the program without calling main()\n"
@ -31,22 +30,17 @@ int main(int argc, char **argv)
PicocInitialise(&pc, StackSize); 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; DontRunMain = TRUE;
PicocIncludeAllSystemHeaders(&pc); PicocIncludeAllSystemHeaders(&pc);
ParamCount++; ParamCount++;
} }
if (argc > ParamCount && strcmp(argv[ParamCount], "-i") == 0) if (argc > ParamCount && strcmp(argv[ParamCount], "-i") == 0) {
{
PicocIncludeAllSystemHeaders(&pc); PicocIncludeAllSystemHeaders(&pc);
PicocParseInteractive(&pc); PicocParseInteractive(&pc);
} } else {
else if (PicocPlatformSetExitPoint(&pc)) {
{
if (PicocPlatformSetExitPoint(&pc))
{
PicocCleanup(&pc); PicocCleanup(&pc);
return pc.PicocExitValue; return pc.PicocExitValue;
} }
@ -62,6 +56,7 @@ int main(int argc, char **argv)
return pc.PicocExitValue; return pc.PicocExitValue;
} }
#elif defined(SURVEYOR_HOST) #elif defined(SURVEYOR_HOST)
#define HEAP_SIZE C_HEAPSIZE #define HEAP_SIZE C_HEAPSIZE
#include <setjmp.h> #include <setjmp.h>
#include "../srv.h" #include "../srv.h"
@ -74,12 +69,9 @@ int picoc(char *SourceStr)
PicocInitialise(HEAP_SIZE); PicocInitialise(HEAP_SIZE);
if (SourceStr) if (SourceStr) {
{ for (pos = SourceStr; *pos != 0; pos++) {
for (pos = SourceStr; *pos != 0; pos++) if (*pos == 0x1a) {
{
if (*pos == 0x1a)
{
*pos = 0x20; *pos = 0x20;
} }
} }

View file

@ -64,22 +64,18 @@ void PicocCallMain(Picoc *pc, int argc, char **argv)
if (FuncValue->Typ->Base != TypeFunction) if (FuncValue->Typ->Base != TypeFunction)
ProgramFailNoParser(pc, "main is not a function - can't call it"); 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 */ /* define the arguments */
VariableDefinePlatformVar(pc, NULL, "__argc", &pc->IntType, (union AnyValue *)&argc, FALSE); VariableDefinePlatformVar(pc, NULL, "__argc", &pc->IntType, (union AnyValue *)&argc, FALSE);
VariableDefinePlatformVar(pc, NULL, "__argv", pc->CharPtrPtrType, (union AnyValue *)&argv, FALSE); VariableDefinePlatformVar(pc, NULL, "__argv", pc->CharPtrPtrType, (union AnyValue *)&argv, FALSE);
} }
if (FuncValue->Val->FuncDef.ReturnType == &pc->VoidType) if (FuncValue->Val->FuncDef.ReturnType == &pc->VoidType) {
{
if (FuncValue->Val->FuncDef.NumParams == 0) if (FuncValue->Val->FuncDef.NumParams == 0)
PicocParse(pc, "startup", CALL_MAIN_NO_ARGS_RETURN_VOID, strlen(CALL_MAIN_NO_ARGS_RETURN_VOID), TRUE, TRUE, FALSE, TRUE); PicocParse(pc, "startup", CALL_MAIN_NO_ARGS_RETURN_VOID, strlen(CALL_MAIN_NO_ARGS_RETURN_VOID), TRUE, TRUE, FALSE, TRUE);
else else
PicocParse(pc, "startup", CALL_MAIN_WITH_ARGS_RETURN_VOID, strlen(CALL_MAIN_WITH_ARGS_RETURN_VOID), TRUE, TRUE, FALSE, TRUE); 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); VariableDefinePlatformVar(pc, NULL, "__exit_value", &pc->IntType, (union AnyValue *)&pc->PicocExitValue, TRUE);
if (FuncValue->Val->FuncDef.NumParams == 0) if (FuncValue->Val->FuncDef.NumParams == 0)
@ -97,11 +93,9 @@ void PrintSourceTextErrorLine(IOFILE *Stream, const char *FileName, const char *
const char *CPos; const char *CPos;
int CCount; int CCount;
if (SourceText != NULL) if (SourceText != NULL) {
{
/* find the source line */ /* 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') if (*LinePos == '\n')
LineCount++; LineCount++;
} }
@ -112,16 +106,13 @@ void PrintSourceTextErrorLine(IOFILE *Stream, const char *FileName, const char *
PrintCh('\n', Stream); PrintCh('\n', Stream);
/* display the error position */ /* 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') if (*CPos == '\t')
PrintCh('\t', Stream); PrintCh('\t', Stream);
else else
PrintCh(' ', Stream); PrintCh(' ', Stream);
} }
} } else {
else
{
/* assume we're in interactive mode - try to make the arrow match up with the input text */ /* assume we're in interactive mode - try to make the arrow match up with the input text */
for (CCount = 0; CCount < CharacterPos + (int)strlen(INTERACTIVE_PROMPT_STATEMENT); CCount++) for (CCount = 0; CCount < CharacterPos + (int)strlen(INTERACTIVE_PROMPT_STATEMENT); CCount++)
PrintCh(' ', Stream); PrintCh(' ', Stream);
@ -202,13 +193,10 @@ void PlatformVPrintf(IOFILE *Stream, const char *Format, va_list Args)
{ {
const char *FPos; const char *FPos;
for (FPos = Format; *FPos != '\0'; FPos++) for (FPos = Format; *FPos != '\0'; FPos++) {
{ if (*FPos == '%') {
if (*FPos == '%')
{
FPos++; FPos++;
switch (*FPos) switch (*FPos) {
{
case 's': PrintStr(va_arg(Args, char *), Stream); break; case 's': PrintStr(va_arg(Args, char *), Stream); break;
case 'd': PrintSimpleInt(va_arg(Args, int), Stream); break; case 'd': PrintSimpleInt(va_arg(Args, int), Stream); break;
case 'c': PrintCh(va_arg(Args, int), Stream); break; case 'c': PrintCh(va_arg(Args, int), Stream); break;
@ -231,15 +219,11 @@ char *PlatformMakeTempName(Picoc *pc, char *TempNameBuffer)
{ {
int CPos = 5; int CPos = 5;
while (CPos > 1) while (CPos > 1) {
{ if (TempNameBuffer[CPos] < '9') {
if (TempNameBuffer[CPos] < '9')
{
TempNameBuffer[CPos]++; TempNameBuffer[CPos]++;
return TableStrRegister(pc, TempNameBuffer); return TableStrRegister(pc, TempNameBuffer);
} } else {
else
{
TempNameBuffer[CPos] = '0'; TempNameBuffer[CPos] = '0';
CPos--; CPos--;
} }

30
table.c
View file

@ -17,8 +17,7 @@ static unsigned int TableHash(const char *Key, int Len)
int Offset; int Offset;
int Count; 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) if (Offset > sizeof(unsigned int) * 8 - 7)
Offset -= sizeof(unsigned int) * 8 - 6; Offset -= sizeof(unsigned int) * 8 - 6;
@ -43,8 +42,7 @@ static struct TableEntry *TableSearch(struct Table *Tbl, const char *Key, int *A
struct TableEntry *Entry; struct TableEntry *Entry;
int HashValue = ((unsigned long)Key) % Tbl->Size; /* shared strings have unique addresses so we don't need to hash them */ 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) if (Entry->p.v.Key == Key)
return Entry; /* found */ return Entry; /* found */
} }
@ -60,8 +58,7 @@ int TableSet(Picoc *pc, struct Table *Tbl, char *Key, struct Value *Val, const c
int AddAt; int AddAt;
struct TableEntry *FoundEntry = TableSearch(Tbl, Key, &AddAt); struct TableEntry *FoundEntry = TableSearch(Tbl, Key, &AddAt);
if (FoundEntry == NULL) if (FoundEntry == NULL) { /* add it to the table */
{ /* add it to the table */
struct TableEntry *NewEntry = VariableAlloc(pc, NULL, sizeof(struct TableEntry), Tbl->OnHeap); struct TableEntry *NewEntry = VariableAlloc(pc, NULL, sizeof(struct TableEntry), Tbl->OnHeap);
NewEntry->DeclFileName = DeclFileName; NewEntry->DeclFileName = DeclFileName;
NewEntry->DeclLine = DeclLine; NewEntry->DeclLine = DeclLine;
@ -87,8 +84,7 @@ int TableGet(struct Table *Tbl, const char *Key, struct Value **Val, const char
*Val = FoundEntry->p.v.Val; *Val = FoundEntry->p.v.Val;
if (DeclFileName != NULL) if (DeclFileName != NULL) {
{
*DeclFileName = FoundEntry->DeclFileName; *DeclFileName = FoundEntry->DeclFileName;
*DeclLine = FoundEntry->DeclLine; *DeclLine = FoundEntry->DeclLine;
*DeclColumn = FoundEntry->DeclColumn; *DeclColumn = FoundEntry->DeclColumn;
@ -103,10 +99,8 @@ struct Value *TableDelete(Picoc *pc, struct Table *Tbl, const char *Key)
struct TableEntry **EntryPtr; struct TableEntry **EntryPtr;
int HashValue = ((unsigned long)Key) % Tbl->Size; /* shared strings have unique addresses so we don't need to hash them */ 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) for (EntryPtr = &Tbl->HashTable[HashValue]; *EntryPtr != NULL; EntryPtr = &(*EntryPtr)->Next) {
{ if ((*EntryPtr)->p.v.Key == Key) {
if ((*EntryPtr)->p.v.Key == Key)
{
struct TableEntry *DeleteEntry = *EntryPtr; struct TableEntry *DeleteEntry = *EntryPtr;
struct Value *Val = DeleteEntry->p.v.Val; struct Value *Val = DeleteEntry->p.v.Val;
*EntryPtr = DeleteEntry->Next; *EntryPtr = DeleteEntry->Next;
@ -125,8 +119,7 @@ static struct TableEntry *TableSearchIdentifier(struct Table *Tbl, const char *K
struct TableEntry *Entry; struct TableEntry *Entry;
int HashValue = TableHash(Key, Len) % Tbl->Size; 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') if (strncmp(&Entry->p.Key[0], (char *)Key, Len) == 0 && Entry->p.Key[Len] == '\0')
return Entry; /* found */ return Entry; /* found */
} }
@ -143,8 +136,7 @@ char *TableSetIdentifier(Picoc *pc, struct Table *Tbl, const char *Ident, int Id
if (FoundEntry != NULL) if (FoundEntry != NULL)
return &FoundEntry->p.Key[0]; return &FoundEntry->p.Key[0];
else else { /* add it to the table - we economise by not allocating the whole structure here */
{ /* 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); struct TableEntry *NewEntry = HeapAllocMem(pc, sizeof(struct TableEntry) - sizeof(union TableEntryPayload) + IdentLen + 1);
if (NewEntry == NULL) if (NewEntry == NULL)
ProgramFailNoParser(pc, "out of memory"); ProgramFailNoParser(pc, "out of memory");
@ -175,10 +167,8 @@ void TableStrFree(Picoc *pc)
struct TableEntry *NextEntry; struct TableEntry *NextEntry;
int Count; int Count;
for (Count = 0; Count < pc->StringTable.Size; Count++) for (Count = 0; Count < pc->StringTable.Size; Count++) {
{ for (Entry = pc->StringTable.HashTable[Count]; Entry != NULL; Entry = NextEntry) {
for (Entry = pc->StringTable.HashTable[Count]; Entry != NULL; Entry = NextEntry)
{
NextEntry = Entry->Next; NextEntry = Entry->Next;
HeapFreeMem(pc, Entry); HeapFreeMem(pc, Entry);
} }

82
type.c
View file

@ -37,16 +37,14 @@ struct ValueType *TypeGetMatching(Picoc *pc, struct ParseState *Parser, struct V
while (ThisType != NULL && (ThisType->Base != Base || ThisType->ArraySize != ArraySize || ThisType->Identifier != Identifier)) while (ThisType != NULL && (ThisType->Base != Base || ThisType->ArraySize != ArraySize || ThisType->Identifier != Identifier))
ThisType = ThisType->Next; ThisType = ThisType->Next;
if (ThisType != NULL) if (ThisType != NULL) {
{
if (AllowDuplicates) if (AllowDuplicates)
return ThisType; return ThisType;
else else
ProgramFail(Parser, "data type '%s' is already defined", Identifier); ProgramFail(Parser, "data type '%s' is already defined", Identifier);
} }
switch (Base) switch (Base) {
{
case TypePointer: Sizeof = sizeof(void *); AlignBytes = PointerAlignBytes; break; case TypePointer: Sizeof = sizeof(void *); AlignBytes = PointerAlignBytes; break;
case TypeArray: Sizeof = ArraySize * ParentType->Sizeof; AlignBytes = ParentType->AlignBytes; break; case TypeArray: Sizeof = ArraySize * ParentType->Sizeof; AlignBytes = ParentType->AlignBytes; break;
case TypeEnum: Sizeof = sizeof(int); AlignBytes = IntAlignBytes; break; case TypeEnum: Sizeof = sizeof(int); AlignBytes = IntAlignBytes; break;
@ -150,15 +148,12 @@ void TypeCleanupNode(Picoc *pc, struct ValueType *Typ)
struct ValueType *NextSubType; struct ValueType *NextSubType;
/* clean up and free all the sub-nodes */ /* 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; NextSubType = SubType->Next;
TypeCleanupNode(pc, SubType); TypeCleanupNode(pc, SubType);
if (SubType->OnHeap) if (SubType->OnHeap) {
{
/* if it's a struct or union deallocate all the member values */ /* if it's a struct or union deallocate all the member values */
if (SubType->Members != NULL) if (SubType->Members != NULL) {
{
VariableTableCleanup(pc, SubType->Members); VariableTableCleanup(pc, SubType->Members);
HeapFreeMem(pc, SubType->Members); HeapFreeMem(pc, SubType->Members);
} }
@ -187,14 +182,11 @@ void TypeParseStruct(struct ParseState *Parser, struct ValueType **Typ, int IsSt
Picoc *pc = Parser->pc; Picoc *pc = Parser->pc;
Token = LexGetToken(Parser, &LexValue, FALSE); Token = LexGetToken(Parser, &LexValue, FALSE);
if (Token == TokenIdentifier) if (Token == TokenIdentifier) {
{
LexGetToken(Parser, &LexValue, TRUE); LexGetToken(Parser, &LexValue, TRUE);
StructIdentifier = LexValue->Val->Identifier; StructIdentifier = LexValue->Val->Identifier;
Token = LexGetToken(Parser, NULL, FALSE); Token = LexGetToken(Parser, NULL, FALSE);
} } else {
else
{
static char TempNameBuf[7] = "^s0000"; static char TempNameBuf[7] = "^s0000";
StructIdentifier = PlatformMakeTempName(pc, TempNameBuf); StructIdentifier = PlatformMakeTempName(pc, TempNameBuf);
} }
@ -204,8 +196,7 @@ void TypeParseStruct(struct ParseState *Parser, struct ValueType **Typ, int IsSt
ProgramFail(Parser, "data type '%t' is already defined", *Typ); ProgramFail(Parser, "data type '%t' is already defined", *Typ);
Token = LexGetToken(Parser, NULL, FALSE); Token = LexGetToken(Parser, NULL, FALSE);
if (Token != TokenLeftBrace) if (Token != TokenLeftBrace) {
{
/* use the already defined structure */ /* use the already defined structure */
#if 0 #if 0
if ((*Typ)->Members == NULL) if ((*Typ)->Members == NULL)
@ -229,8 +220,7 @@ void TypeParseStruct(struct ParseState *Parser, struct ValueType **Typ, int IsSt
MemberValue = VariableAllocValueAndData(pc, Parser, sizeof(int), FALSE, NULL, TRUE); MemberValue = VariableAllocValueAndData(pc, Parser, sizeof(int), FALSE, NULL, TRUE);
MemberValue->Typ = MemberType; MemberValue->Typ = MemberType;
if (IsStruct) if (IsStruct) {
{
/* allocate this member's location in the struct */ /* allocate this member's location in the struct */
AlignBoundary = MemberValue->Typ->AlignBytes; AlignBoundary = MemberValue->Typ->AlignBytes;
if (((*Typ)->Sizeof & (AlignBoundary-1)) != 0) if (((*Typ)->Sizeof & (AlignBoundary-1)) != 0)
@ -238,9 +228,7 @@ void TypeParseStruct(struct ParseState *Parser, struct ValueType **Typ, int IsSt
MemberValue->Val->Integer = (*Typ)->Sizeof; MemberValue->Val->Integer = (*Typ)->Sizeof;
(*Typ)->Sizeof += TypeSizeValue(MemberValue, TRUE); (*Typ)->Sizeof += TypeSizeValue(MemberValue, TRUE);
} } else {
else
{
/* union members always start at 0, make sure it's big enough to hold the largest member */ /* union members always start at 0, make sure it's big enough to hold the largest member */
MemberValue->Val->Integer = 0; MemberValue->Val->Integer = 0;
if (MemberValue->Typ->Sizeof > (*Typ)->Sizeof) if (MemberValue->Typ->Sizeof > (*Typ)->Sizeof)
@ -293,22 +281,18 @@ void TypeParseEnum(struct ParseState *Parser, struct ValueType **Typ)
Picoc *pc = Parser->pc; Picoc *pc = Parser->pc;
Token = LexGetToken(Parser, &LexValue, FALSE); Token = LexGetToken(Parser, &LexValue, FALSE);
if (Token == TokenIdentifier) if (Token == TokenIdentifier) {
{
LexGetToken(Parser, &LexValue, TRUE); LexGetToken(Parser, &LexValue, TRUE);
EnumIdentifier = LexValue->Val->Identifier; EnumIdentifier = LexValue->Val->Identifier;
Token = LexGetToken(Parser, NULL, FALSE); Token = LexGetToken(Parser, NULL, FALSE);
} } else {
else
{
static char TempNameBuf[7] = "^e0000"; static char TempNameBuf[7] = "^e0000";
EnumIdentifier = PlatformMakeTempName(pc, TempNameBuf); EnumIdentifier = PlatformMakeTempName(pc, TempNameBuf);
} }
TypeGetMatching(pc, Parser, &pc->UberType, TypeEnum, 0, EnumIdentifier, Token != TokenLeftBrace); TypeGetMatching(pc, Parser, &pc->UberType, TypeEnum, 0, EnumIdentifier, Token != TokenLeftBrace);
*Typ = &pc->IntType; *Typ = &pc->IntType;
if (Token != TokenLeftBrace) if (Token != TokenLeftBrace) {
{
/* use the already defined enum */ /* use the already defined enum */
if ((*Typ)->Members == NULL) if ((*Typ)->Members == NULL)
ProgramFail(Parser, "enum '%s' isn't defined", EnumIdentifier); ProgramFail(Parser, "enum '%s' isn't defined", EnumIdentifier);
@ -329,8 +313,7 @@ void TypeParseEnum(struct ParseState *Parser, struct ValueType **Typ)
ProgramFail(Parser, "identifier expected"); ProgramFail(Parser, "identifier expected");
EnumIdentifier = LexValue->Val->Identifier; EnumIdentifier = LexValue->Val->Identifier;
if (LexGetToken(Parser, NULL, FALSE) == TokenAssign) if (LexGetToken(Parser, NULL, FALSE) == TokenAssign) {
{
LexGetToken(Parser, NULL, TRUE); LexGetToken(Parser, NULL, TRUE);
EnumValue = ExpressionParseInt(Parser); EnumValue = ExpressionParseInt(Parser);
} }
@ -342,7 +325,6 @@ void TypeParseEnum(struct ParseState *Parser, struct ValueType **Typ)
ProgramFail(Parser, "comma expected"); ProgramFail(Parser, "comma expected");
EnumValue++; EnumValue++;
} while (Token == TokenComma); } while (Token == TokenComma);
} }
@ -361,8 +343,7 @@ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ, int *IsSta
/* ignore leading type qualifiers */ /* ignore leading type qualifiers */
ParserCopy(&Before, Parser); ParserCopy(&Before, Parser);
Token = LexGetToken(Parser, &LexerValue, TRUE); 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) if (Token == TokenStaticType)
StaticQualifier = TRUE; StaticQualifier = TRUE;
@ -373,13 +354,11 @@ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ, int *IsSta
*IsStatic = StaticQualifier; *IsStatic = StaticQualifier;
/* handle signed/unsigned with no trailing type */ /* handle signed/unsigned with no trailing type */
if (Token == TokenSignedType || Token == TokenUnsignedType) if (Token == TokenSignedType || Token == TokenUnsignedType) {
{
enum LexToken FollowToken = LexGetToken(Parser, &LexerValue, FALSE); enum LexToken FollowToken = LexGetToken(Parser, &LexerValue, FALSE);
Unsigned = (Token == TokenUnsignedType); Unsigned = (Token == TokenUnsignedType);
if (FollowToken != TokenIntType && FollowToken != TokenLongType && FollowToken != TokenShortType && FollowToken != TokenCharType) if (FollowToken != TokenIntType && FollowToken != TokenLongType && FollowToken != TokenShortType && FollowToken != TokenCharType) {
{
if (Token == TokenUnsignedType) if (Token == TokenUnsignedType)
*Typ = &pc->UnsignedIntType; *Typ = &pc->UnsignedIntType;
else else
@ -391,8 +370,7 @@ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ, int *IsSta
Token = LexGetToken(Parser, &LexerValue, TRUE); Token = LexGetToken(Parser, &LexerValue, TRUE);
} }
switch (Token) switch (Token) {
{
case TokenIntType: *Typ = Unsigned ? &pc->UnsignedIntType : &pc->IntType; break; case TokenIntType: *Typ = Unsigned ? &pc->UnsignedIntType : &pc->IntType; break;
case TokenShortType: *Typ = Unsigned ? &pc->UnsignedShortType : &pc->ShortType; break; case TokenShortType: *Typ = Unsigned ? &pc->UnsignedShortType : &pc->ShortType; break;
case TokenCharType: *Typ = Unsigned ? &pc->UnsignedCharType : &pc->CharType; break; case TokenCharType: *Typ = Unsigned ? &pc->UnsignedCharType : &pc->CharType; break;
@ -401,7 +379,6 @@ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ, int *IsSta
case TokenFloatType: case TokenDoubleType: *Typ = &pc->FPType; break; case TokenFloatType: case TokenDoubleType: *Typ = &pc->FPType; break;
#endif #endif
case TokenVoidType: *Typ = &pc->VoidType; break; case TokenVoidType: *Typ = &pc->VoidType; break;
case TokenStructType: case TokenUnionType: case TokenStructType: case TokenUnionType:
if (*Typ != NULL) if (*Typ != NULL)
ProgramFail(Parser, "bad type declaration"); ProgramFail(Parser, "bad type declaration");
@ -436,17 +413,13 @@ struct ValueType *TypeParseBack(struct ParseState *Parser, struct ValueType *Fro
ParserCopy(&Before, Parser); ParserCopy(&Before, Parser);
Token = LexGetToken(Parser, NULL, TRUE); Token = LexGetToken(Parser, NULL, TRUE);
if (Token == TokenLeftSquareBracket) if (Token == TokenLeftSquareBracket) {
{
/* add another array bound */ /* add another array bound */
if (LexGetToken(Parser, NULL, FALSE) == TokenRightSquareBracket) if (LexGetToken(Parser, NULL, FALSE) == TokenRightSquareBracket) {
{
/* an unsized array */ /* an unsized array */
LexGetToken(Parser, NULL, TRUE); LexGetToken(Parser, NULL, TRUE);
return TypeGetMatching(Parser->pc, Parser, TypeParseBack(Parser, FromType), TypeArray, 0, Parser->pc->StrEmpty, TRUE); return TypeGetMatching(Parser->pc, Parser, TypeParseBack(Parser, FromType), TypeArray, 0, Parser->pc->StrEmpty, TRUE);
} } else {
else
{
/* get a numeric array size */ /* get a numeric array size */
enum RunMode OldMode = Parser->Mode; enum RunMode OldMode = Parser->Mode;
int ArraySize; int ArraySize;
@ -459,9 +432,7 @@ struct ValueType *TypeParseBack(struct ParseState *Parser, struct ValueType *Fro
return TypeGetMatching(Parser->pc, Parser, TypeParseBack(Parser, FromType), TypeArray, ArraySize, Parser->pc->StrEmpty, TRUE); return TypeGetMatching(Parser->pc, Parser, TypeParseBack(Parser, FromType), TypeArray, ArraySize, Parser->pc->StrEmpty, TRUE);
} }
} } else {
else
{
/* the type specification has finished */ /* the type specification has finished */
ParserCopy(Parser, &Before); ParserCopy(Parser, &Before);
return FromType; return FromType;
@ -478,12 +449,10 @@ void TypeParseIdentPart(struct ParseState *Parser, struct ValueType *BasicTyp, s
*Typ = BasicTyp; *Typ = BasicTyp;
*Identifier = Parser->pc->StrEmpty; *Identifier = Parser->pc->StrEmpty;
while (!Done) while (!Done) {
{
ParserCopy(&Before, Parser); ParserCopy(&Before, Parser);
Token = LexGetToken(Parser, &LexValue, TRUE); Token = LexGetToken(Parser, &LexValue, TRUE);
switch (Token) switch (Token) {
{
case TokenOpenBracket: case TokenOpenBracket:
if (*Typ != NULL) if (*Typ != NULL)
ProgramFail(Parser, "bad type declaration"); ProgramFail(Parser, "bad type declaration");
@ -515,8 +484,7 @@ void TypeParseIdentPart(struct ParseState *Parser, struct ValueType *BasicTyp, s
if (*Typ == NULL) if (*Typ == NULL)
ProgramFail(Parser, "bad type declaration"); ProgramFail(Parser, "bad type declaration");
if (*Identifier != Parser->pc->StrEmpty) if (*Identifier != Parser->pc->StrEmpty) {
{
/* parse stuff after the identifier */ /* parse stuff after the identifier */
*Typ = TypeParseBack(Parser, *Typ); *Typ = TypeParseBack(Parser, *Typ);
} }

View file

@ -18,8 +18,7 @@ void VariableInit(Picoc *pc)
/* deallocate the contents of a variable */ /* deallocate the contents of a variable */
void VariableFree(Picoc *pc, struct Value *Val) void VariableFree(Picoc *pc, struct Value *Val)
{ {
if (Val->ValOnHeap || Val->AnyValOnHeap) if (Val->ValOnHeap || Val->AnyValOnHeap) {
{
/* free function bodies */ /* free function bodies */
if (Val->Typ == &pc->FunctionType && Val->Val->FuncDef.Intrinsic == NULL && Val->Val->FuncDef.Body.Pos != NULL) if (Val->Typ == &pc->FunctionType && Val->Val->FuncDef.Intrinsic == NULL && Val->Val->FuncDef.Body.Pos != NULL)
HeapFreeMem(pc, (void *)Val->Val->FuncDef.Body.Pos); HeapFreeMem(pc, (void *)Val->Val->FuncDef.Body.Pos);
@ -45,10 +44,8 @@ void VariableTableCleanup(Picoc *pc, struct Table *HashTable)
struct TableEntry *NextEntry; struct TableEntry *NextEntry;
int Count; int Count;
for (Count = 0; Count < HashTable->Size; Count++) for (Count = 0; Count < HashTable->Size; Count++) {
{ for (Entry = HashTable->HashTable[Count]; Entry != NULL; Entry = NextEntry) {
for (Entry = HashTable->HashTable[Count]; Entry != NULL; Entry = NextEntry)
{
NextEntry = Entry->Next; NextEntry = Entry->Next;
VariableFree(pc, Entry->p.v.Val); VariableFree(pc, Entry->p.v.Val);
@ -182,13 +179,10 @@ int VariableScopeBegin(struct ParseState * Parser, int* OldScopeID)
/* or maybe a more human-readable hash for debugging? */ /* or maybe a more human-readable hash for debugging? */
/* Parser->ScopeID = Parser->Line * 0x10000 + Parser->CharacterPos; */ /* Parser->ScopeID = Parser->Line * 0x10000 + Parser->CharacterPos; */
for (Count = 0; Count < HashTable->Size; Count++) for (Count = 0; Count < HashTable->Size; Count++) {
{ for (Entry = HashTable->HashTable[Count]; Entry != NULL; Entry = NextEntry) {
for (Entry = HashTable->HashTable[Count]; Entry != NULL; Entry = NextEntry)
{
NextEntry = Entry->Next; 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.Val->OutOfScope = FALSE;
Entry->p.v.Key = (char*)((intptr_t)Entry->p.v.Key & ~1); Entry->p.v.Key = (char*)((intptr_t)Entry->p.v.Key & ~1);
#ifdef VAR_SCOPE_DEBUG #ifdef VAR_SCOPE_DEBUG
@ -217,15 +211,14 @@ void VariableScopeEnd(struct ParseState * Parser, int ScopeID, int PrevScopeID)
if (ScopeID == -1) return; if (ScopeID == -1) return;
for (Count = 0; Count < HashTable->Size; Count++) for (Count = 0; Count < HashTable->Size; Count++) {
{ for (Entry = HashTable->HashTable[Count]; Entry != NULL; Entry = NextEntry) {
for (Entry = HashTable->HashTable[Count]; Entry != NULL; Entry = NextEntry)
{
NextEntry = Entry->Next; NextEntry = Entry->Next;
if (Entry->p.v.Val->ScopeID == ScopeID && !Entry->p.v.Val->OutOfScope) if (Entry->p.v.Val->ScopeID == ScopeID && !Entry->p.v.Val->OutOfScope) {
{
#ifdef VAR_SCOPE_DEBUG #ifdef VAR_SCOPE_DEBUG
if (!FirstPrint) { PRINT_SOURCE_POS; } if (!FirstPrint) {
PRINT_SOURCE_POS;
}
FirstPrint = 1; FirstPrint = 1;
printf(">>> out of scope: %s %x %d\n", Entry->p.v.Key, Entry->p.v.Val->ScopeID, Entry->p.v.Val->Val->Integer); printf(">>> out of scope: %s %x %d\n", Entry->p.v.Key, Entry->p.v.Val->ScopeID, Entry->p.v.Val->Val->Integer);
#endif #endif
@ -244,10 +237,8 @@ int VariableDefinedAndOutOfScope(Picoc * pc, const char* Ident)
int Count; int Count;
struct Table * HashTable = (pc->TopStackFrame == NULL) ? &(pc->GlobalTable) : &(pc->TopStackFrame)->LocalTable; struct Table * HashTable = (pc->TopStackFrame == NULL) ? &(pc->GlobalTable) : &(pc->TopStackFrame)->LocalTable;
for (Count = 0; Count < HashTable->Size; Count++) for (Count = 0; Count < HashTable->Size; Count++) {
{ for (Entry = HashTable->HashTable[Count]; Entry != NULL; Entry = Entry->Next) {
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) if (Entry->p.v.Val->OutOfScope && (char*)((intptr_t)Entry->p.v.Key & ~1) == Ident)
return TRUE; return TRUE;
} }
@ -294,8 +285,7 @@ struct Value *VariableDefineButIgnoreIdentical(struct ParseState *Parser, char *
if (TypeIsForwardDeclared(Parser, Typ)) if (TypeIsForwardDeclared(Parser, Typ))
ProgramFail(Parser, "type '%t' isn't defined", Typ); ProgramFail(Parser, "type '%t' isn't defined", Typ);
if (IsStatic) if (IsStatic) {
{
char MangledName[LINEBUFFER_MAX]; char MangledName[LINEBUFFER_MAX];
char *MNPos = &MangledName[0]; char *MNPos = &MangledName[0];
char *MNEnd = &MangledName[LINEBUFFER_MAX-1]; char *MNEnd = &MangledName[LINEBUFFER_MAX-1];
@ -307,8 +297,7 @@ struct Value *VariableDefineButIgnoreIdentical(struct ParseState *Parser, char *
strncpy(MNPos, (char *)Parser->FileName, MNEnd - MNPos); strncpy(MNPos, (char *)Parser->FileName, MNEnd - MNPos);
MNPos += strlen(MNPos); MNPos += strlen(MNPos);
if (pc->TopStackFrame != NULL) if (pc->TopStackFrame != NULL) {
{
/* we're inside a function */ /* we're inside a function */
if (MNEnd - MNPos > 0) *MNPos++ = '/'; if (MNEnd - MNPos > 0) *MNPos++ = '/';
strncpy(MNPos, (char *)pc->TopStackFrame->FuncName, MNEnd - MNPos); strncpy(MNPos, (char *)pc->TopStackFrame->FuncName, MNEnd - MNPos);
@ -320,8 +309,7 @@ struct Value *VariableDefineButIgnoreIdentical(struct ParseState *Parser, char *
RegisteredMangledName = TableStrRegister(pc, MangledName); RegisteredMangledName = TableStrRegister(pc, MangledName);
/* is this static already defined? */ /* 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 */ /* define the mangled-named static variable store in the global scope */
ExistingValue = VariableAllocValueFromType(Parser->pc, Parser, Typ, TRUE, NULL, TRUE); ExistingValue = VariableAllocValueFromType(Parser->pc, Parser, Typ, TRUE, NULL, TRUE);
TableSet(pc, &pc->GlobalTable, (char *)RegisteredMangledName, ExistingValue, (char *)Parser->FileName, Parser->Line, Parser->CharacterPos); 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 */ /* 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); VariableDefinePlatformVar(Parser->pc, Parser, Ident, ExistingValue->Typ, ExistingValue->Val, TRUE);
return ExistingValue; return ExistingValue;
} } else {
else
{
if (Parser->Line != 0 && TableGet((pc->TopStackFrame == NULL) ? &pc->GlobalTable : &pc->TopStackFrame->LocalTable, Ident, &ExistingValue, &DeclFileName, &DeclLine, &DeclColumn) 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) && DeclFileName == Parser->FileName && DeclLine == Parser->Line && DeclColumn == Parser->CharacterPos)
return ExistingValue; return ExistingValue;
@ -347,8 +333,7 @@ int VariableDefined(Picoc *pc, const char *Ident)
{ {
struct Value *FoundValue; struct Value *FoundValue;
if (pc->TopStackFrame == NULL || !TableGet(&pc->TopStackFrame->LocalTable, Ident, &FoundValue, NULL, NULL, NULL)) if (pc->TopStackFrame == NULL || !TableGet(&pc->TopStackFrame->LocalTable, Ident, &FoundValue, NULL, NULL, NULL)) {
{
if (!TableGet(&pc->GlobalTable, Ident, &FoundValue, NULL, NULL, NULL)) if (!TableGet(&pc->GlobalTable, Ident, &FoundValue, NULL, NULL, NULL))
return FALSE; return FALSE;
} }
@ -359,10 +344,8 @@ int VariableDefined(Picoc *pc, const char *Ident)
/* get the value of a variable. must be defined. Ident must be registered */ /* get the value of a variable. must be defined. Ident must be registered */
void VariableGet(Picoc *pc, struct ParseState *Parser, const char *Ident, struct Value **LVal) void VariableGet(Picoc *pc, struct ParseState *Parser, const char *Ident, struct Value **LVal)
{ {
if (pc->TopStackFrame == NULL || !TableGet(&pc->TopStackFrame->LocalTable, Ident, LVal, NULL, NULL, NULL)) if (pc->TopStackFrame == NULL || !TableGet(&pc->TopStackFrame->LocalTable, Ident, LVal, NULL, NULL, NULL)) {
{ if (!TableGet(&pc->GlobalTable, Ident, LVal, NULL, NULL, NULL)) {
if (!TableGet(&pc->GlobalTable, Ident, LVal, NULL, NULL, NULL))
{
if (VariableDefinedAndOutOfScope(pc, Ident)) if (VariableDefinedAndOutOfScope(pc, Ident))
ProgramFail(Parser, "'%s' is out of scope", Ident); ProgramFail(Parser, "'%s' is out of scope", Ident);
else else
@ -392,14 +375,12 @@ void VariableStackPop(struct ParseState *Parser, struct Value *Var)
printf("popping %ld at 0x%lx\n", (unsigned long)(sizeof(struct Value) + TypeSizeValue(Var, FALSE)), (unsigned long)Var); printf("popping %ld at 0x%lx\n", (unsigned long)(sizeof(struct Value) + TypeSizeValue(Var, FALSE)), (unsigned long)Var);
#endif #endif
if (Var->ValOnHeap) if (Var->ValOnHeap) {
{
if (Var->Val != NULL) if (Var->Val != NULL)
HeapFreeMem(Parser->pc, Var->Val); HeapFreeMem(Parser->pc, Var->Val);
Success = HeapPopStack(Parser->pc, Var, sizeof(struct Value)); /* free from heap */ Success = HeapPopStack(Parser->pc, Var, sizeof(struct Value)); /* free from heap */
} } else if (Var->ValOnStack)
else if (Var->ValOnStack)
Success = HeapPopStack(Parser->pc, Var, sizeof(struct Value) + TypeSizeValue(Var, FALSE)); /* free from stack */ Success = HeapPopStack(Parser->pc, Var, sizeof(struct Value) + TypeSizeValue(Var, FALSE)); /* free from stack */
else else
Success = HeapPopStack(Parser->pc, Var, sizeof(struct Value)); /* value isn't our problem */ Success = HeapPopStack(Parser->pc, Var, sizeof(struct Value)); /* value isn't our problem */