formatting
This commit is contained in:
parent
3ba3fa5997
commit
890694a14a
59
clibrary.c
59
clibrary.c
|
@ -57,22 +57,47 @@ void LibraryAdd(Picoc *pc, struct LibraryFunction *FuncList)
|
||||||
void PrintType(struct ValueType *Typ, IOFILE *Stream)
|
void PrintType(struct ValueType *Typ, IOFILE *Stream)
|
||||||
{
|
{
|
||||||
switch (Typ->Base) {
|
switch (Typ->Base) {
|
||||||
case TypeVoid: PrintStr("void", Stream); break;
|
case TypeVoid:
|
||||||
case TypeInt: PrintStr("int", Stream); break;
|
PrintStr("void", Stream);
|
||||||
case TypeShort: PrintStr("short", Stream); break;
|
break;
|
||||||
case TypeChar: PrintStr("char", Stream); break;
|
case TypeInt:
|
||||||
case TypeLong: PrintStr("long", Stream); break;
|
PrintStr("int", Stream);
|
||||||
case TypeUnsignedInt: PrintStr("unsigned int", Stream); break;
|
break;
|
||||||
case TypeUnsignedShort: PrintStr("unsigned short", Stream); break;
|
case TypeShort:
|
||||||
case TypeUnsignedLong: PrintStr("unsigned long", Stream); break;
|
PrintStr("short", Stream);
|
||||||
case TypeUnsignedChar: PrintStr("unsigned char", Stream); break;
|
break;
|
||||||
case TypeFP: PrintStr("double", Stream); break;
|
case TypeChar:
|
||||||
case TypeFunction: PrintStr("function", Stream); break;
|
PrintStr("char", Stream);
|
||||||
case TypeMacro: PrintStr("macro", Stream); break;
|
break;
|
||||||
|
case TypeLong:
|
||||||
|
PrintStr("long", Stream);
|
||||||
|
break;
|
||||||
|
case TypeUnsignedInt:
|
||||||
|
PrintStr("unsigned int", Stream);
|
||||||
|
break;
|
||||||
|
case TypeUnsignedShort:
|
||||||
|
PrintStr("unsigned short", Stream);
|
||||||
|
break;
|
||||||
|
case TypeUnsignedLong:
|
||||||
|
PrintStr("unsigned long", Stream);
|
||||||
|
break;
|
||||||
|
case TypeUnsignedChar:
|
||||||
|
PrintStr("unsigned char", Stream);
|
||||||
|
break;
|
||||||
|
case TypeFP:
|
||||||
|
PrintStr("double", Stream);
|
||||||
|
break;
|
||||||
|
case TypeFunction:
|
||||||
|
PrintStr("function", Stream);
|
||||||
|
break;
|
||||||
|
case TypeMacro:
|
||||||
|
PrintStr("macro", Stream);
|
||||||
|
break;
|
||||||
case TypePointer:
|
case TypePointer:
|
||||||
if (Typ->FromType)
|
if (Typ->FromType)
|
||||||
PrintType(Typ->FromType, Stream);
|
PrintType(Typ->FromType, Stream);
|
||||||
PrintCh('*', Stream); break;
|
PrintCh('*', Stream);
|
||||||
|
break;
|
||||||
case TypeArray:
|
case TypeArray:
|
||||||
PrintType(Typ->FromType, Stream);
|
PrintType(Typ->FromType, Stream);
|
||||||
PrintCh('[', Stream);
|
PrintCh('[', Stream);
|
||||||
|
@ -92,8 +117,12 @@ void PrintType(struct ValueType *Typ, IOFILE *Stream)
|
||||||
PrintStr("enum ", Stream);
|
PrintStr("enum ", Stream);
|
||||||
PrintStr(Typ->Identifier, Stream);
|
PrintStr(Typ->Identifier, Stream);
|
||||||
break;
|
break;
|
||||||
case TypeGotoLabel: PrintStr("goto label ", Stream); break;
|
case TypeGotoLabel:
|
||||||
case Type_Type: PrintStr("type ", Stream); break;
|
PrintStr("goto label ", Stream);
|
||||||
|
break;
|
||||||
|
case Type_Type:
|
||||||
|
PrintStr("type ", Stream);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
152
expression.c
152
expression.c
|
@ -243,34 +243,56 @@ int IsTypeToken(struct ParseState * Parser, enum LexToken t,
|
||||||
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:
|
||||||
case TypeChar: return (long)Val->Val->Character;
|
return (long)Val->Val->Integer;
|
||||||
case TypeShort: return (long)Val->Val->ShortInteger;
|
case TypeChar:
|
||||||
case TypeLong: return (long)Val->Val->LongInteger;
|
return (long)Val->Val->Character;
|
||||||
case TypeUnsignedInt: return (long)Val->Val->UnsignedInteger;
|
case TypeShort:
|
||||||
case TypeUnsignedShort: return (long)Val->Val->UnsignedShortInteger;
|
return (long)Val->Val->ShortInteger;
|
||||||
case TypeUnsignedLong: return (long)Val->Val->UnsignedLongInteger;
|
case TypeLong:
|
||||||
case TypeUnsignedChar: return (long)Val->Val->UnsignedCharacter;
|
return (long)Val->Val->LongInteger;
|
||||||
case TypePointer: return (long)Val->Val->Pointer;
|
case TypeUnsignedInt:
|
||||||
case TypeFP: return (long)Val->Val->FP;
|
return (long)Val->Val->UnsignedInteger;
|
||||||
default: return 0;
|
case TypeUnsignedShort:
|
||||||
|
return (long)Val->Val->UnsignedShortInteger;
|
||||||
|
case TypeUnsignedLong:
|
||||||
|
return (long)Val->Val->UnsignedLongInteger;
|
||||||
|
case TypeUnsignedChar:
|
||||||
|
return (long)Val->Val->UnsignedCharacter;
|
||||||
|
case TypePointer:
|
||||||
|
return (long)Val->Val->Pointer;
|
||||||
|
case TypeFP:
|
||||||
|
return (long)Val->Val->FP;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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:
|
||||||
case TypeChar: return (unsigned long)Val->Val->Character;
|
return (unsigned long)Val->Val->Integer;
|
||||||
case TypeShort: return (unsigned long)Val->Val->ShortInteger;
|
case TypeChar:
|
||||||
case TypeLong: return (unsigned long)Val->Val->LongInteger;
|
return (unsigned long)Val->Val->Character;
|
||||||
case TypeUnsignedInt: return (unsigned long)Val->Val->UnsignedInteger;
|
case TypeShort:
|
||||||
case TypeUnsignedShort: return (unsigned long)Val->Val->UnsignedShortInteger;
|
return (unsigned long)Val->Val->ShortInteger;
|
||||||
case TypeUnsignedLong: return (unsigned long)Val->Val->UnsignedLongInteger;
|
case TypeLong:
|
||||||
case TypeUnsignedChar: return (unsigned long)Val->Val->UnsignedCharacter;
|
return (unsigned long)Val->Val->LongInteger;
|
||||||
case TypePointer: return (unsigned long)Val->Val->Pointer;
|
case TypeUnsignedInt:
|
||||||
case TypeFP: return (unsigned long)Val->Val->FP;
|
return (unsigned long)Val->Val->UnsignedInteger;
|
||||||
default: return 0;
|
case TypeUnsignedShort:
|
||||||
|
return (unsigned long)Val->Val->UnsignedShortInteger;
|
||||||
|
case TypeUnsignedLong:
|
||||||
|
return (unsigned long)Val->Val->UnsignedLongInteger;
|
||||||
|
case TypeUnsignedChar:
|
||||||
|
return (unsigned long)Val->Val->UnsignedCharacter;
|
||||||
|
case TypePointer:
|
||||||
|
return (unsigned long)Val->Val->Pointer;
|
||||||
|
case TypeFP:
|
||||||
|
return (unsigned long)Val->Val->FP;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,15 +337,32 @@ long ExpressionAssignInt(struct ParseState *Parser, struct Value *DestValue,
|
||||||
Result = FromInt;
|
Result = FromInt;
|
||||||
|
|
||||||
switch (DestValue->Typ->Base) {
|
switch (DestValue->Typ->Base) {
|
||||||
case TypeInt: DestValue->Val->Integer = (int)FromInt; break;
|
case TypeInt:
|
||||||
case TypeShort: DestValue->Val->ShortInteger = (short)FromInt; break;
|
DestValue->Val->Integer = (int)FromInt;
|
||||||
case TypeChar: DestValue->Val->Character = (char)FromInt; break;
|
break;
|
||||||
case TypeLong: DestValue->Val->LongInteger = (long)FromInt; break;
|
case TypeShort:
|
||||||
case TypeUnsignedInt: DestValue->Val->UnsignedInteger = (unsigned int)FromInt; break;
|
DestValue->Val->ShortInteger = (short)FromInt;
|
||||||
case TypeUnsignedShort: DestValue->Val->UnsignedShortInteger = (unsigned short)FromInt; break;
|
break;
|
||||||
case TypeUnsignedLong: DestValue->Val->UnsignedLongInteger = (unsigned long)FromInt; break;
|
case TypeChar:
|
||||||
case TypeUnsignedChar: DestValue->Val->UnsignedCharacter = (unsigned char)FromInt; break;
|
DestValue->Val->Character = (char)FromInt;
|
||||||
default: break;
|
break;
|
||||||
|
case TypeLong:
|
||||||
|
DestValue->Val->LongInteger = (long)FromInt;
|
||||||
|
break;
|
||||||
|
case TypeUnsignedInt:
|
||||||
|
DestValue->Val->UnsignedInteger = (unsigned int)FromInt;
|
||||||
|
break;
|
||||||
|
case TypeUnsignedShort:
|
||||||
|
DestValue->Val->UnsignedShortInteger = (unsigned short)FromInt;
|
||||||
|
break;
|
||||||
|
case TypeUnsignedLong:
|
||||||
|
DestValue->Val->UnsignedLongInteger = (unsigned long)FromInt;
|
||||||
|
break;
|
||||||
|
case TypeUnsignedChar:
|
||||||
|
DestValue->Val->UnsignedCharacter = (unsigned char)FromInt;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
@ -909,22 +948,28 @@ void ExpressionInfixOperator(struct ParseState *Parser,
|
||||||
ASSIGN_FP_OR_INT(BottomFP / TopFP);
|
ASSIGN_FP_OR_INT(BottomFP / TopFP);
|
||||||
break;
|
break;
|
||||||
case TokenEqual:
|
case TokenEqual:
|
||||||
ResultInt = BottomFP == TopFP; ResultIsInt = true;
|
ResultInt = BottomFP == TopFP;
|
||||||
|
ResultIsInt = true;
|
||||||
break;
|
break;
|
||||||
case TokenNotEqual:
|
case TokenNotEqual:
|
||||||
ResultInt = BottomFP != TopFP; ResultIsInt = true;
|
ResultInt = BottomFP != TopFP;
|
||||||
|
ResultIsInt = true;
|
||||||
break;
|
break;
|
||||||
case TokenLessThan:
|
case TokenLessThan:
|
||||||
ResultInt = BottomFP < TopFP; ResultIsInt = true;
|
ResultInt = BottomFP < TopFP;
|
||||||
|
ResultIsInt = true;
|
||||||
break;
|
break;
|
||||||
case TokenGreaterThan:
|
case TokenGreaterThan:
|
||||||
ResultInt = BottomFP > TopFP; ResultIsInt = true;
|
ResultInt = BottomFP > TopFP;
|
||||||
|
ResultIsInt = true;
|
||||||
break;
|
break;
|
||||||
case TokenLessEqual:
|
case TokenLessEqual:
|
||||||
ResultInt = BottomFP <= TopFP; ResultIsInt = true;
|
ResultInt = BottomFP <= TopFP;
|
||||||
|
ResultIsInt = true;
|
||||||
break;
|
break;
|
||||||
case TokenGreaterEqual:
|
case TokenGreaterEqual:
|
||||||
ResultInt = BottomFP >= TopFP; ResultIsInt = true;
|
ResultInt = BottomFP >= TopFP;
|
||||||
|
ResultIsInt = true;
|
||||||
break;
|
break;
|
||||||
case TokenPlus:
|
case TokenPlus:
|
||||||
ResultFP = BottomFP + TopFP;
|
ResultFP = BottomFP + TopFP;
|
||||||
|
@ -1079,9 +1124,9 @@ void ExpressionInfixOperator(struct ParseState *Parser,
|
||||||
ProgramFail(Parser, "invalid use of a NULL pointer");
|
ProgramFail(Parser, "invalid use of a NULL pointer");
|
||||||
|
|
||||||
if (Op == TokenPlus)
|
if (Op == TokenPlus)
|
||||||
Pointer = (void *)((char *)Pointer + TopInt * Size);
|
Pointer = (void*)((char*)Pointer + TopInt * Size);
|
||||||
else
|
else
|
||||||
Pointer = (void *)((char *)Pointer - TopInt * Size);
|
Pointer = (void*)((char*)Pointer - TopInt * Size);
|
||||||
|
|
||||||
StackValue = ExpressionStackPushValueByType(Parser, StackTop,
|
StackValue = ExpressionStackPushValueByType(Parser, StackTop,
|
||||||
BottomValue->Typ);
|
BottomValue->Typ);
|
||||||
|
@ -1100,9 +1145,9 @@ void ExpressionInfixOperator(struct ParseState *Parser,
|
||||||
ProgramFail(Parser, "invalid use of a NULL pointer");
|
ProgramFail(Parser, "invalid use of a NULL pointer");
|
||||||
|
|
||||||
if (Op == TokenAddAssign)
|
if (Op == TokenAddAssign)
|
||||||
Pointer = (void *)((char *)Pointer + TopInt * Size);
|
Pointer = (void*)((char*)Pointer + TopInt * Size);
|
||||||
else
|
else
|
||||||
Pointer = (void *)((char *)Pointer - TopInt * Size);
|
Pointer = (void*)((char*)Pointer - TopInt * Size);
|
||||||
|
|
||||||
HeapUnpopStack(Parser->pc, sizeof(struct Value));
|
HeapUnpopStack(Parser->pc, sizeof(struct Value));
|
||||||
BottomValue->Val->Pointer = Pointer;
|
BottomValue->Val->Pointer = Pointer;
|
||||||
|
@ -1112,8 +1157,8 @@ void ExpressionInfixOperator(struct ParseState *Parser,
|
||||||
} else if (BottomValue->Typ->Base == TypePointer &&
|
} else if (BottomValue->Typ->Base == TypePointer &&
|
||||||
TopValue->Typ->Base == TypePointer && Op != TokenAssign) {
|
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:
|
case TokenEqual:
|
||||||
|
@ -1210,7 +1255,8 @@ void ExpressionStackCollapse(struct ParseState *Parser,
|
||||||
#endif
|
#endif
|
||||||
TopValue = TopStackNode->Next->Val;
|
TopValue = TopStackNode->Next->Val;
|
||||||
|
|
||||||
/* pop the postfix operator and then the value - assume they'll still be there until we're done */
|
/* pop the postfix operator and then the value - assume
|
||||||
|
they'll still be there until we're done */
|
||||||
HeapPopStack(Parser->pc, NULL, sizeof(struct ExpressionStack));
|
HeapPopStack(Parser->pc, NULL, sizeof(struct ExpressionStack));
|
||||||
HeapPopStack(Parser->pc, TopValue,
|
HeapPopStack(Parser->pc, TopValue,
|
||||||
sizeof(struct ExpressionStack) +
|
sizeof(struct ExpressionStack) +
|
||||||
|
@ -1337,7 +1383,8 @@ void ExpressionGetStructElement(struct ParseState *Parser,
|
||||||
NULL, &StructType, NULL);
|
NULL, &StructType, NULL);
|
||||||
|
|
||||||
if (StructType->Base != TypeStruct && StructType->Base != TypeUnion)
|
if (StructType->Base != TypeStruct && StructType->Base != TypeUnion)
|
||||||
ProgramFail(Parser, "can't use '%s' on something that's not a struct or union %s : it's a %t",
|
ProgramFail(Parser,
|
||||||
|
"can't use '%s' on something that's not a struct or union %s : it's a %t",
|
||||||
(Token == TokenDot) ? "." : "->",
|
(Token == TokenDot) ? "." : "->",
|
||||||
(Token == TokenArrow) ? "pointer" : "", ParamVal->Typ);
|
(Token == TokenArrow) ? "pointer" : "", ParamVal->Typ);
|
||||||
|
|
||||||
|
@ -1519,8 +1566,12 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
|
||||||
PrefixState = true;
|
PrefixState = true;
|
||||||
|
|
||||||
switch (Token) {
|
switch (Token) {
|
||||||
case TokenQuestionMark: TernaryDepth++; break;
|
case TokenQuestionMark:
|
||||||
case TokenColon: TernaryDepth--; break;
|
TernaryDepth++;
|
||||||
|
break;
|
||||||
|
case TokenColon:
|
||||||
|
TernaryDepth--;
|
||||||
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1655,7 +1706,8 @@ void ExpressionParseMacroCall(struct ParseState *Parser,
|
||||||
|
|
||||||
if (Parser->Mode == RunModeRun) {
|
if (Parser->Mode == RunModeRun) {
|
||||||
/* create a stack frame for this macro */
|
/* create a stack frame for this macro */
|
||||||
ExpressionStackPushValueByType(Parser, StackTop, &Parser->pc->FPType); /* largest return type there is */
|
/* largest return type there is */
|
||||||
|
ExpressionStackPushValueByType(Parser, StackTop, &Parser->pc->FPType);
|
||||||
ReturnValue = (*StackTop)->Val;
|
ReturnValue = (*StackTop)->Val;
|
||||||
HeapPushStackFrame(Parser->pc);
|
HeapPushStackFrame(Parser->pc);
|
||||||
ParamArray = HeapAllocStack(Parser->pc,
|
ParamArray = HeapAllocStack(Parser->pc,
|
||||||
|
@ -1803,7 +1855,9 @@ void ExpressionParseFunctionCall(struct ParseState *Parser,
|
||||||
struct ParseState FuncParser;
|
struct ParseState FuncParser;
|
||||||
|
|
||||||
if (FuncValue->Val->FuncDef.Body.Pos == NULL)
|
if (FuncValue->Val->FuncDef.Body.Pos == NULL)
|
||||||
ProgramFail(Parser, "ExpressionParseFunctionCall FuncName: '%s' is undefined", FuncName);
|
ProgramFail(Parser,
|
||||||
|
"ExpressionParseFunctionCall FuncName: '%s' is undefined",
|
||||||
|
FuncName);
|
||||||
|
|
||||||
ParserCopy(&FuncParser, &FuncValue->Val->FuncDef.Body);
|
ParserCopy(&FuncParser, &FuncValue->Val->FuncDef.Body);
|
||||||
VariableStackFrameAdd(Parser, FuncName,
|
VariableStackFrameAdd(Parser, FuncName,
|
||||||
|
|
|
@ -66,8 +66,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
|
||||||
for (LInclude = pc->IncludeLibList; LInclude != NULL; LInclude = LInclude->NextLib) {
|
of predefined includes */
|
||||||
|
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)) {
|
||||||
|
|
144
lex.c
144
lex.c
|
@ -83,7 +83,8 @@ void LexInit(Picoc *pc)
|
||||||
TableInitTable(&pc->ReservedWordTable, &pc->ReservedWordHashTable[0],
|
TableInitTable(&pc->ReservedWordTable, &pc->ReservedWordHashTable[0],
|
||||||
sizeof(ReservedWords) / sizeof(struct ReservedWord) * 2, true);
|
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,
|
TableSet(pc, &pc->ReservedWordTable,
|
||||||
TableStrRegister(pc, ReservedWords[Count].Word),
|
TableStrRegister(pc, ReservedWords[Count].Word),
|
||||||
(struct Value *)&ReservedWords[Count], NULL, 0, 0);
|
(struct Value *)&ReservedWords[Count], NULL, 0, 0);
|
||||||
|
@ -105,7 +106,8 @@ void LexCleanup(Picoc *pc)
|
||||||
|
|
||||||
LexInteractiveClear(pc, NULL);
|
LexInteractiveClear(pc, NULL);
|
||||||
|
|
||||||
for (Count = 0; Count < sizeof(ReservedWords) / sizeof(struct ReservedWord); Count++)
|
for (Count = 0; Count < sizeof(ReservedWords) / sizeof(struct ReservedWord);
|
||||||
|
Count++)
|
||||||
TableDelete(pc, &pc->ReservedWordTable,
|
TableDelete(pc, &pc->ReservedWordTable,
|
||||||
TableStrRegister(pc, ReservedWords[Count].Word));
|
TableStrRegister(pc, ReservedWords[Count].Word));
|
||||||
}
|
}
|
||||||
|
@ -149,7 +151,8 @@ enum LexToken LexGetNumber(Picoc *pc, struct LexState *Lexer, struct Value *Valu
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the value */
|
/* get the value */
|
||||||
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') {
|
||||||
|
@ -183,7 +186,7 @@ enum LexToken LexGetNumber(Picoc *pc, struct LexState *Lexer, struct Value *Valu
|
||||||
if (*Lexer->Pos == '.') {
|
if (*Lexer->Pos == '.') {
|
||||||
LEXER_INC(Lexer);
|
LEXER_INC(Lexer);
|
||||||
for (FPDiv = 1.0/Base; Lexer->Pos != Lexer->End && IS_BASE_DIGIT(*Lexer->Pos, Base);
|
for (FPDiv = 1.0/Base; Lexer->Pos != Lexer->End && IS_BASE_DIGIT(*Lexer->Pos, Base);
|
||||||
LEXER_INC(Lexer), FPDiv /= (double)Base) {
|
LEXER_INC(Lexer), FPDiv /= (double)Base) {
|
||||||
FPResult += GET_BASE_DIGIT(*Lexer->Pos) * FPDiv;
|
FPResult += GET_BASE_DIGIT(*Lexer->Pos) * FPDiv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -229,9 +232,14 @@ enum LexToken LexGetWord(Picoc *pc, struct LexState *Lexer, struct Value *Value)
|
||||||
|
|
||||||
Token = LexCheckReservedWord(pc, Value->Val->Identifier);
|
Token = LexCheckReservedWord(pc, Value->Val->Identifier);
|
||||||
switch (Token) {
|
switch (Token) {
|
||||||
case TokenHashInclude: Lexer->Mode = LexModeHashInclude; break;
|
case TokenHashInclude:
|
||||||
case TokenHashDefine: Lexer->Mode = LexModeHashDefine; break;
|
Lexer->Mode = LexModeHashInclude;
|
||||||
default: break;
|
break;
|
||||||
|
case TokenHashDefine:
|
||||||
|
Lexer->Mode = LexModeHashDefine;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Token != TokenNone)
|
if (Token != TokenNone)
|
||||||
|
@ -262,12 +270,12 @@ unsigned char LexUnEscapeCharacter(const char **From, const char *End)
|
||||||
|
|
||||||
while ( *From != End && **From == '\\' &&
|
while ( *From != End && **From == '\\' &&
|
||||||
&(*From)[1] != End && (*From)[1] == '\n' )
|
&(*From)[1] != End && (*From)[1] == '\n' )
|
||||||
(*From) += 2; /* skip escaped end of lines with LF line termination */
|
(*From) += 2; /* skip escaped end of lines with LF line termination */
|
||||||
|
|
||||||
while ( *From != End && **From == '\\' &&
|
while ( *From != End && **From == '\\' &&
|
||||||
&(*From)[1] != End &&
|
&(*From)[1] != End &&
|
||||||
&(*From)[2] != End && (*From)[1] == '\r' && (*From)[2] == '\n')
|
&(*From)[2] != End && (*From)[1] == '\r' && (*From)[2] == '\n')
|
||||||
(*From) += 3; /* skip escaped end of lines with CR/LF line termination */
|
(*From) += 3; /* skip escaped end of lines with CR/LF line termination */
|
||||||
|
|
||||||
if (*From == End)
|
if (*From == End)
|
||||||
return '\\';
|
return '\\';
|
||||||
|
@ -505,7 +513,7 @@ enum LexToken LexScanGetToken(Picoc *pc, struct LexState *Lexer,
|
||||||
NEXTIS3PLUS('=', TokenLessEqual, '<', TokenShiftLeft, '=',
|
NEXTIS3PLUS('=', TokenLessEqual, '<', TokenShiftLeft, '=',
|
||||||
TokenShiftLeftAssign, TokenLessThan);
|
TokenShiftLeftAssign, TokenLessThan);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '>':
|
case '>':
|
||||||
NEXTIS3PLUS('=', TokenGreaterEqual, '>', TokenShiftRight, '=',
|
NEXTIS3PLUS('=', TokenGreaterEqual, '>', TokenShiftRight, '=',
|
||||||
TokenShiftRightAssign, TokenGreaterThan);
|
TokenShiftRightAssign, TokenGreaterThan);
|
||||||
|
@ -692,7 +700,7 @@ enum LexToken LexGetRawToken(struct ParseState *Parser, struct Value **Value,
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
@ -849,7 +857,7 @@ void LexHashIf(struct ParseState *Parser)
|
||||||
if (Token == TokenIdentifier) {
|
if (Token == TokenIdentifier) {
|
||||||
/* look up a value from a macro definition */
|
/* look up a value from a macro definition */
|
||||||
if (!TableGet(&Parser->pc->GlobalTable, IdentValue->Val->Identifier,
|
if (!TableGet(&Parser->pc->GlobalTable, IdentValue->Val->Identifier,
|
||||||
&SavedValue, NULL, NULL, NULL))
|
&SavedValue, NULL, NULL, NULL))
|
||||||
ProgramFail(Parser, "'%s' is undefined", IdentValue->Val->Identifier);
|
ProgramFail(Parser, "'%s' is undefined", IdentValue->Val->Identifier);
|
||||||
|
|
||||||
if (SavedValue->Typ->Base != TypeMacro)
|
if (SavedValue->Typ->Base != TypeMacro)
|
||||||
|
@ -876,7 +884,8 @@ void LexHashIf(struct ParseState *Parser)
|
||||||
void LexHashElse(struct ParseState *Parser)
|
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)
|
||||||
|
@ -903,32 +912,101 @@ void LexPrintToken(enum LexToken Token)
|
||||||
char* TokenNames[] = {
|
char* TokenNames[] = {
|
||||||
/* 0x00 */ "None",
|
/* 0x00 */ "None",
|
||||||
/* 0x01 */ "Comma",
|
/* 0x01 */ "Comma",
|
||||||
/* 0x02 */ "Assign", "AddAssign", "SubtractAssign", "MultiplyAssign", "DivideAssign", "ModulusAssign",
|
/* 0x02 */ "Assign",
|
||||||
/* 0x08 */ "ShiftLeftAssign", "ShiftRightAssign", "ArithmeticAndAssign", "ArithmeticOrAssign", "ArithmeticExorAssign",
|
"AddAssign",
|
||||||
/* 0x0d */ "QuestionMark", "Colon",
|
"SubtractAssign",
|
||||||
|
"MultiplyAssign",
|
||||||
|
"DivideAssign",
|
||||||
|
"ModulusAssign",
|
||||||
|
/* 0x08 */ "ShiftLeftAssign",
|
||||||
|
"ShiftRightAssign",
|
||||||
|
"ArithmeticAndAssign",
|
||||||
|
"ArithmeticOrAssign",
|
||||||
|
"ArithmeticExorAssign",
|
||||||
|
/* 0x0d */ "QuestionMark",
|
||||||
|
"Colon",
|
||||||
/* 0x0f */ "LogicalOr",
|
/* 0x0f */ "LogicalOr",
|
||||||
/* 0x10 */ "LogicalAnd",
|
/* 0x10 */ "LogicalAnd",
|
||||||
/* 0x11 */ "ArithmeticOr",
|
/* 0x11 */ "ArithmeticOr",
|
||||||
/* 0x12 */ "ArithmeticExor",
|
/* 0x12 */ "ArithmeticExor",
|
||||||
/* 0x13 */ "Ampersand",
|
/* 0x13 */ "Ampersand",
|
||||||
/* 0x14 */ "Equal", "NotEqual",
|
/* 0x14 */ "Equal",
|
||||||
/* 0x16 */ "LessThan", "GreaterThan", "LessEqual", "GreaterEqual",
|
"NotEqual",
|
||||||
/* 0x1a */ "ShiftLeft", "ShiftRight",
|
/* 0x16 */ "LessThan",
|
||||||
/* 0x1c */ "Plus", "Minus",
|
"GreaterThan",
|
||||||
/* 0x1e */ "Asterisk", "Slash", "Modulus",
|
"LessEqual",
|
||||||
/* 0x21 */ "Increment", "Decrement", "UnaryNot", "UnaryExor", "Sizeof", "Cast",
|
"GreaterEqual",
|
||||||
/* 0x27 */ "LeftSquareBracket", "RightSquareBracket", "Dot", "Arrow",
|
/* 0x1a */ "ShiftLeft",
|
||||||
/* 0x2b */ "OpenBracket", "CloseBracket",
|
"ShiftRight",
|
||||||
/* 0x2d */ "Identifier", "IntegerConstant", "FPConstant", "StringConstant", "CharacterConstant",
|
/* 0x1c */ "Plus",
|
||||||
/* 0x32 */ "Semicolon", "Ellipsis",
|
"Minus",
|
||||||
/* 0x34 */ "LeftBrace", "RightBrace",
|
/* 0x1e */ "Asterisk",
|
||||||
/* 0x36 */ "IntType", "CharType", "FloatType", "DoubleType", "VoidType", "EnumType",
|
"Slash",
|
||||||
/* 0x3c */ "LongType", "SignedType", "ShortType", "StaticType", "AutoType", "RegisterType", "ExternType", "StructType", "UnionType", "UnsignedType", "Typedef",
|
"Modulus",
|
||||||
/* 0x46 */ "Continue", "Do", "Else", "For", "Goto", "If", "While", "Break", "Switch", "Case", "Default", "Return",
|
/* 0x21 */ "Increment",
|
||||||
/* 0x52 */ "HashDefine", "HashInclude", "HashIf", "HashIfdef", "HashIfndef", "HashElse", "HashEndif",
|
"Decrement",
|
||||||
/* 0x59 */ "New", "Delete",
|
"UnaryNot",
|
||||||
|
"UnaryExor",
|
||||||
|
"Sizeof",
|
||||||
|
"Cast",
|
||||||
|
/* 0x27 */ "LeftSquareBracket",
|
||||||
|
"RightSquareBracket",
|
||||||
|
"Dot",
|
||||||
|
"Arrow",
|
||||||
|
/* 0x2b */ "OpenBracket",
|
||||||
|
"CloseBracket",
|
||||||
|
/* 0x2d */ "Identifier",
|
||||||
|
"IntegerConstant",
|
||||||
|
"FPConstant",
|
||||||
|
"StringConstant",
|
||||||
|
"CharacterConstant",
|
||||||
|
/* 0x32 */ "Semicolon",
|
||||||
|
"Ellipsis",
|
||||||
|
/* 0x34 */ "LeftBrace",
|
||||||
|
"RightBrace",
|
||||||
|
/* 0x36 */ "IntType",
|
||||||
|
"CharType",
|
||||||
|
"FloatType",
|
||||||
|
"DoubleType",
|
||||||
|
"VoidType",
|
||||||
|
"EnumType",
|
||||||
|
/* 0x3c */ "LongType",
|
||||||
|
"SignedType",
|
||||||
|
"ShortType",
|
||||||
|
"StaticType",
|
||||||
|
"AutoType",
|
||||||
|
"RegisterType",
|
||||||
|
"ExternType",
|
||||||
|
"StructType",
|
||||||
|
"UnionType",
|
||||||
|
"UnsignedType",
|
||||||
|
"Typedef",
|
||||||
|
/* 0x46 */ "Continue",
|
||||||
|
"Do",
|
||||||
|
"Else",
|
||||||
|
"For",
|
||||||
|
"Goto",
|
||||||
|
"If",
|
||||||
|
"While",
|
||||||
|
"Break",
|
||||||
|
"Switch",
|
||||||
|
"Case",
|
||||||
|
"Default",
|
||||||
|
"Return",
|
||||||
|
/* 0x52 */
|
||||||
|
"HashDefine",
|
||||||
|
"HashInclude",
|
||||||
|
"HashIf",
|
||||||
|
"HashIfdef",
|
||||||
|
"HashIfndef",
|
||||||
|
"HashElse",
|
||||||
|
"HashEndif",
|
||||||
|
/* 0x59 */ "New",
|
||||||
|
"Delete",
|
||||||
/* 0x5b */ "OpenMacroBracket",
|
/* 0x5b */ "OpenMacroBracket",
|
||||||
/* 0x5c */ "EOF", "EndOfLine", "EndOfFunction"
|
/* 0x5c */ "EOF",
|
||||||
|
"EndOfLine",
|
||||||
|
"EndOfFunction"
|
||||||
};
|
};
|
||||||
printf("{%s}", TokenNames[Token]);
|
printf("{%s}", TokenNames[Token]);
|
||||||
}
|
}
|
||||||
|
|
27
parse.c
27
parse.c
|
@ -93,7 +93,8 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser,
|
||||||
FuncValue->Val->FuncDef.ParamType =
|
FuncValue->Val->FuncDef.ParamType =
|
||||||
(struct ValueType**)((char*)FuncValue->Val+sizeof(struct FuncDef));
|
(struct ValueType**)((char*)FuncValue->Val+sizeof(struct FuncDef));
|
||||||
FuncValue->Val->FuncDef.ParamName =
|
FuncValue->Val->FuncDef.ParamName =
|
||||||
(char**)((char*)FuncValue->Val->FuncDef.ParamType+sizeof(struct ValueType*)*ParamCount);
|
(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 */
|
||||||
|
@ -140,7 +141,8 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser,
|
||||||
/* look for a function body */
|
/* look for a function body */
|
||||||
Token = LexGetToken(Parser, NULL, false);
|
Token = LexGetToken(Parser, NULL, false);
|
||||||
if (Token == TokenSemicolon)
|
if (Token == TokenSemicolon)
|
||||||
LexGetToken(Parser, NULL, true); /* it's a prototype, absorb the trailing semicolon */
|
LexGetToken(Parser, NULL, true); /* it's a prototype, absorb
|
||||||
|
the trailing semicolon */
|
||||||
else {
|
else {
|
||||||
/* it's a full function definition with a body */
|
/* it's a full function definition with a body */
|
||||||
if (Token != TokenLeftBrace)
|
if (Token != TokenLeftBrace)
|
||||||
|
@ -214,7 +216,8 @@ int ParseArrayInitialiser(struct ParseState *Parser, struct Value *NewVariable,
|
||||||
NewVariable->Typ->FromType->ArraySize, true);
|
NewVariable->Typ->FromType->ArraySize, true);
|
||||||
SubArray = VariableAllocValueFromExistingData(Parser,
|
SubArray = VariableAllocValueFromExistingData(Parser,
|
||||||
NewVariable->Typ->FromType,
|
NewVariable->Typ->FromType,
|
||||||
(union AnyValue*)(&NewVariable->Val->ArrayMem[0]+SubArraySize*ArrayIndex),
|
(union AnyValue*)(&NewVariable->Val->ArrayMem[0] +
|
||||||
|
SubArraySize*ArrayIndex),
|
||||||
true, NewVariable);
|
true, NewVariable);
|
||||||
#ifdef DEBUG_ARRAY_INITIALIZER
|
#ifdef DEBUG_ARRAY_INITIALIZER
|
||||||
int FullArraySize = TypeSize(NewVariable->Typ,
|
int FullArraySize = TypeSize(NewVariable->Typ,
|
||||||
|
@ -237,12 +240,14 @@ int ParseArrayInitialiser(struct ParseState *Parser, struct Value *NewVariable,
|
||||||
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;
|
||||||
|
|
||||||
/* char x[10][10] = {"abc", "def"} => assign "abc" to x[0], "def" to x[1] etc */
|
/* char x[10][10] = {"abc", "def"} => assign "abc" to
|
||||||
|
x[0], "def" to x[1] etc */
|
||||||
if (LexGetToken(Parser, NULL, false) == TokenStringConstant &&
|
if (LexGetToken(Parser, NULL, false) == TokenStringConstant &&
|
||||||
ElementType->FromType->Base == TypeChar)
|
ElementType->FromType->Base == TypeChar)
|
||||||
break;
|
break;
|
||||||
|
@ -257,7 +262,8 @@ int ParseArrayInitialiser(struct ParseState *Parser, struct Value *NewVariable,
|
||||||
ProgramFail(Parser, "too many array elements");
|
ProgramFail(Parser, "too many array elements");
|
||||||
ArrayElement = VariableAllocValueFromExistingData(Parser,
|
ArrayElement = VariableAllocValueFromExistingData(Parser,
|
||||||
ElementType,
|
ElementType,
|
||||||
(union AnyValue*)(&NewVariable->Val->ArrayMem[0]+ElementSize*ArrayIndex),
|
(union AnyValue*)(&NewVariable->Val->ArrayMem[0] +
|
||||||
|
ElementSize*ArrayIndex),
|
||||||
true, NewVariable);
|
true, NewVariable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,7 +272,8 @@ int ParseArrayInitialiser(struct ParseState *Parser, struct Value *NewVariable,
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -389,7 +396,8 @@ void ParseMacroDefinition(struct ParseState *Parser)
|
||||||
sizeof(struct MacroDef) + sizeof(const char*) * NumParams,
|
sizeof(struct MacroDef) + sizeof(const char*) * NumParams,
|
||||||
false, NULL, true);
|
false, NULL, true);
|
||||||
MacroValue->Val->MacroDef.NumParams = NumParams;
|
MacroValue->Val->MacroDef.NumParams = NumParams;
|
||||||
MacroValue->Val->MacroDef.ParamName = (char**)((char*)MacroValue->Val+sizeof(struct MacroDef));
|
MacroValue->Val->MacroDef.ParamName = (char**)((char*)MacroValue->Val +
|
||||||
|
sizeof(struct MacroDef));
|
||||||
|
|
||||||
Token = LexGetToken(Parser, &ParamName, true);
|
Token = LexGetToken(Parser, &ParamName, true);
|
||||||
|
|
||||||
|
@ -595,7 +603,8 @@ enum ParseResult ParseStatement(struct ParseState *Parser,
|
||||||
/* might be a typedef-typed variable declaration or it might
|
/* might be a typedef-typed variable declaration or it might
|
||||||
be an expression */
|
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);
|
||||||
|
|
37
platform.c
37
platform.c
|
@ -145,7 +145,7 @@ void ProgramFail(struct ParseState *Parser, const char *Message, ...)
|
||||||
va_list Args;
|
va_list Args;
|
||||||
|
|
||||||
PrintSourceTextErrorLine(Parser->pc->CStdOut, Parser->FileName,
|
PrintSourceTextErrorLine(Parser->pc->CStdOut, Parser->FileName,
|
||||||
Parser->SourceText, Parser->Line, Parser->CharacterPos);
|
Parser->SourceText, Parser->Line, Parser->CharacterPos);
|
||||||
va_start(Args, Message);
|
va_start(Args, Message);
|
||||||
PlatformVPrintf(Parser->pc->CStdOut, Message, Args);
|
PlatformVPrintf(Parser->pc->CStdOut, Message, Args);
|
||||||
va_end(Args);
|
va_end(Args);
|
||||||
|
@ -173,7 +173,7 @@ void AssignFail(struct ParseState *Parser, const char *Format,
|
||||||
IOFILE *Stream = Parser->pc->CStdOut;
|
IOFILE *Stream = Parser->pc->CStdOut;
|
||||||
|
|
||||||
PrintSourceTextErrorLine(Parser->pc->CStdOut, Parser->FileName,
|
PrintSourceTextErrorLine(Parser->pc->CStdOut, Parser->FileName,
|
||||||
Parser->SourceText, Parser->Line, Parser->CharacterPos);
|
Parser->SourceText, Parser->Line, Parser->CharacterPos);
|
||||||
PlatformPrintf(Stream, "can't %s ", (FuncName == NULL) ? "assign" : "set");
|
PlatformPrintf(Stream, "can't %s ", (FuncName == NULL) ? "assign" : "set");
|
||||||
|
|
||||||
if (Type1 != NULL)
|
if (Type1 != NULL)
|
||||||
|
@ -195,7 +195,7 @@ void LexFail(Picoc *pc, struct LexState *Lexer, const char *Message, ...)
|
||||||
va_list Args;
|
va_list Args;
|
||||||
|
|
||||||
PrintSourceTextErrorLine(pc->CStdOut, Lexer->FileName, Lexer->SourceText,
|
PrintSourceTextErrorLine(pc->CStdOut, Lexer->FileName, Lexer->SourceText,
|
||||||
Lexer->Line, Lexer->CharacterPos);
|
Lexer->Line, Lexer->CharacterPos);
|
||||||
va_start(Args, Message);
|
va_start(Args, Message);
|
||||||
PlatformVPrintf(pc->CStdOut, Message, Args);
|
PlatformVPrintf(pc->CStdOut, Message, Args);
|
||||||
va_end(Args);
|
va_end(Args);
|
||||||
|
@ -221,14 +221,29 @@ void PlatformVPrintf(IOFILE *Stream, const char *Format, va_list Args)
|
||||||
if (*FPos == '%') {
|
if (*FPos == '%') {
|
||||||
FPos++;
|
FPos++;
|
||||||
switch (*FPos) {
|
switch (*FPos) {
|
||||||
case 's': PrintStr(va_arg(Args, char *), Stream); break;
|
case 's':
|
||||||
case 'd': PrintSimpleInt(va_arg(Args, int), Stream); break;
|
PrintStr(va_arg(Args, char *), Stream);
|
||||||
case 'c': PrintCh(va_arg(Args, int), Stream); break;
|
break;
|
||||||
case 't': PrintType(va_arg(Args, struct ValueType *), Stream); break;
|
case 'd':
|
||||||
case 'f': PrintFP(va_arg(Args, double), Stream); break;
|
PrintSimpleInt(va_arg(Args, int), Stream);
|
||||||
case '%': PrintCh('%', Stream); break;
|
break;
|
||||||
case '\0': FPos--; break;
|
case 'c':
|
||||||
default: break;
|
PrintCh(va_arg(Args, int), Stream);
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
PrintType(va_arg(Args, struct ValueType *), Stream);
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
PrintFP(va_arg(Args, double), Stream);
|
||||||
|
break;
|
||||||
|
case '%':
|
||||||
|
PrintCh('%', Stream);
|
||||||
|
break;
|
||||||
|
case '\0':
|
||||||
|
FPos--;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
9
table.c
9
table.c
|
@ -130,7 +130,8 @@ static struct TableEntry *TableSearchIdentifier(struct Table *Tbl,
|
||||||
struct TableEntry *Entry;
|
struct TableEntry *Entry;
|
||||||
|
|
||||||
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 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,10 +140,12 @@ static struct TableEntry *TableSearchIdentifier(struct Table *Tbl,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set an identifier and return the identifier. share if possible */
|
/* set an identifier and return the identifier. share if possible */
|
||||||
char *TableSetIdentifier(Picoc *pc, struct Table *Tbl, const char *Ident, int IdentLen)
|
char *TableSetIdentifier(Picoc *pc, struct Table *Tbl, const char *Ident,
|
||||||
|
int IdentLen)
|
||||||
{
|
{
|
||||||
int AddAt;
|
int AddAt;
|
||||||
struct TableEntry *FoundEntry = TableSearchIdentifier(Tbl, Ident, IdentLen, &AddAt);
|
struct TableEntry *FoundEntry = TableSearchIdentifier(Tbl, Ident, IdentLen,
|
||||||
|
&AddAt);
|
||||||
|
|
||||||
if (FoundEntry != NULL)
|
if (FoundEntry != NULL)
|
||||||
return &FoundEntry->p.Key[0];
|
return &FoundEntry->p.Key[0];
|
||||||
|
|
15
type.c
15
type.c
|
@ -65,7 +65,8 @@ struct ValueType *TypeGetMatching(Picoc *pc, struct ParseState *Parser,
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Sizeof = 0; AlignBytes = 0;
|
Sizeof = 0; AlignBytes = 0;
|
||||||
break; /* structs and unions will get bigger when we add members to them */
|
break; /* structs and unions will get bigger
|
||||||
|
when we add members to them */
|
||||||
}
|
}
|
||||||
|
|
||||||
return TypeAdd(pc, Parser, ParentType, Base, ArraySize, Identifier, Sizeof,
|
return TypeAdd(pc, Parser, ParentType, Base, ArraySize, Identifier, Sizeof,
|
||||||
|
@ -150,10 +151,12 @@ void TypeInit(Picoc *pc)
|
||||||
TypeAddBaseType(pc, &pc->UnsignedCharType, TypeUnsignedChar,
|
TypeAddBaseType(pc, &pc->UnsignedCharType, TypeUnsignedChar,
|
||||||
sizeof(unsigned char), (char*)&ca.y - &ca.x);
|
sizeof(unsigned char), (char*)&ca.y - &ca.x);
|
||||||
TypeAddBaseType(pc, &pc->VoidType, TypeVoid, 0, 1);
|
TypeAddBaseType(pc, &pc->VoidType, TypeVoid, 0, 1);
|
||||||
TypeAddBaseType(pc, &pc->FunctionType, TypeFunction, sizeof(int), IntAlignBytes);
|
TypeAddBaseType(pc, &pc->FunctionType, TypeFunction, sizeof(int),
|
||||||
|
IntAlignBytes);
|
||||||
TypeAddBaseType(pc, &pc->MacroType, TypeMacro, sizeof(int), IntAlignBytes);
|
TypeAddBaseType(pc, &pc->MacroType, TypeMacro, sizeof(int), IntAlignBytes);
|
||||||
TypeAddBaseType(pc, &pc->GotoLabelType, TypeGotoLabel, 0, 1);
|
TypeAddBaseType(pc, &pc->GotoLabelType, TypeGotoLabel, 0, 1);
|
||||||
TypeAddBaseType(pc, &pc->FPType, TypeFP, sizeof(double), (char*)&da.y - &da.x);
|
TypeAddBaseType(pc, &pc->FPType, TypeFP, sizeof(double),
|
||||||
|
(char*)&da.y - &da.x);
|
||||||
TypeAddBaseType(pc, &pc->TypeType, Type_Type, sizeof(double),
|
TypeAddBaseType(pc, &pc->TypeType, Type_Type, sizeof(double),
|
||||||
(char*)&da.y - &da.x); /* must be large enough to cast to a double */
|
(char*)&da.y - &da.x); /* must be large enough to cast to a double */
|
||||||
pc->CharArrayType = TypeAdd(pc, NULL, &pc->CharType, TypeArray, 0,
|
pc->CharArrayType = TypeAdd(pc, NULL, &pc->CharType, TypeArray, 0,
|
||||||
|
@ -173,7 +176,8 @@ 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) {
|
||||||
|
@ -257,7 +261,8 @@ void TypeParseStruct(struct ParseState *Parser, struct ValueType **Typ,
|
||||||
/* 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)
|
||||||
(*Typ)->Sizeof += AlignBoundary - ((*Typ)->Sizeof & (AlignBoundary-1));
|
(*Typ)->Sizeof +=
|
||||||
|
AlignBoundary - ((*Typ)->Sizeof & (AlignBoundary-1));
|
||||||
|
|
||||||
MemberValue->Val->Integer = (*Typ)->Sizeof;
|
MemberValue->Val->Integer = (*Typ)->Sizeof;
|
||||||
(*Typ)->Sizeof += TypeSizeValue(MemberValue, true);
|
(*Typ)->Sizeof += TypeSizeValue(MemberValue, true);
|
||||||
|
|
33
variable.c
33
variable.c
|
@ -11,9 +11,9 @@
|
||||||
void VariableInit(Picoc *pc)
|
void VariableInit(Picoc *pc)
|
||||||
{
|
{
|
||||||
TableInitTable(&(pc->GlobalTable), &(pc->GlobalHashTable)[0],
|
TableInitTable(&(pc->GlobalTable), &(pc->GlobalHashTable)[0],
|
||||||
GLOBAL_TABLE_SIZE, true);
|
GLOBAL_TABLE_SIZE, true);
|
||||||
TableInitTable(&pc->StringLiteralTable, &pc->StringLiteralHashTable[0],
|
TableInitTable(&pc->StringLiteralTable, &pc->StringLiteralHashTable[0],
|
||||||
STRING_LITERAL_TABLE_SIZE, true);
|
STRING_LITERAL_TABLE_SIZE, true);
|
||||||
pc->TopStackFrame = NULL;
|
pc->TopStackFrame = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,9 +95,9 @@ struct Value *VariableAllocValueAndData(Picoc *pc, struct ParseState *Parser,
|
||||||
int DataSize, int IsLValue, struct Value *LValueFrom, int OnHeap)
|
int DataSize, int IsLValue, struct Value *LValueFrom, int OnHeap)
|
||||||
{
|
{
|
||||||
struct Value *NewValue = VariableAlloc(pc, Parser,
|
struct Value *NewValue = VariableAlloc(pc, Parser,
|
||||||
MEM_ALIGN(sizeof(struct Value)) + DataSize, OnHeap);
|
MEM_ALIGN(sizeof(struct Value)) + DataSize, OnHeap);
|
||||||
NewValue->Val = (union AnyValue*)((char*)NewValue +
|
NewValue->Val = (union AnyValue*)((char*)NewValue +
|
||||||
MEM_ALIGN(sizeof(struct Value)));
|
MEM_ALIGN(sizeof(struct Value)));
|
||||||
NewValue->ValOnHeap = OnHeap;
|
NewValue->ValOnHeap = OnHeap;
|
||||||
NewValue->AnyValOnHeap = false;
|
NewValue->AnyValOnHeap = false;
|
||||||
NewValue->ValOnStack = !OnHeap;
|
NewValue->ValOnStack = !OnHeap;
|
||||||
|
@ -137,7 +137,7 @@ struct Value *VariableAllocValueAndCopy(Picoc *pc, struct ParseState *Parser,
|
||||||
assert(CopySize <= MAX_TMP_COPY_BUF);
|
assert(CopySize <= MAX_TMP_COPY_BUF);
|
||||||
memcpy((void*)&TmpBuf[0], (void*)FromValue->Val, CopySize);
|
memcpy((void*)&TmpBuf[0], (void*)FromValue->Val, CopySize);
|
||||||
NewValue = VariableAllocValueAndData(pc, Parser, CopySize,
|
NewValue = VariableAllocValueAndData(pc, Parser, CopySize,
|
||||||
FromValue->IsLValue, FromValue->LValueFrom, OnHeap);
|
FromValue->IsLValue, FromValue->LValueFrom, OnHeap);
|
||||||
NewValue->Typ = DType;
|
NewValue->Typ = DType;
|
||||||
memcpy((void*)NewValue->Val, (void*)&TmpBuf[0], CopySize);
|
memcpy((void*)NewValue->Val, (void*)&TmpBuf[0], CopySize);
|
||||||
|
|
||||||
|
@ -169,11 +169,13 @@ struct Value *VariableAllocValueShared(struct ParseState *Parser,
|
||||||
struct Value *FromValue)
|
struct Value *FromValue)
|
||||||
{
|
{
|
||||||
return VariableAllocValueFromExistingData(Parser, FromValue->Typ,
|
return VariableAllocValueFromExistingData(Parser, FromValue->Typ,
|
||||||
FromValue->Val, FromValue->IsLValue, FromValue->IsLValue ? FromValue : NULL);
|
FromValue->Val, FromValue->IsLValue,
|
||||||
|
FromValue->IsLValue ? FromValue : NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reallocate a variable so its data has a new size */
|
/* reallocate a variable so its data has a new size */
|
||||||
void VariableRealloc(struct ParseState *Parser, struct Value *FromValue, int NewSize)
|
void VariableRealloc(struct ParseState *Parser, struct Value *FromValue,
|
||||||
|
int NewSize)
|
||||||
{
|
{
|
||||||
if (FromValue->AnyValOnHeap)
|
if (FromValue->AnyValOnHeap)
|
||||||
HeapFreeMem(Parser->pc, FromValue->Val);
|
HeapFreeMem(Parser->pc, FromValue->Val);
|
||||||
|
@ -241,8 +243,8 @@ void VariableScopeEnd(struct ParseState *Parser, int ScopeID, int PrevScopeID)
|
||||||
&(Parser->pc->GlobalTable) : &(Parser->pc->TopStackFrame)->LocalTable;
|
&(Parser->pc->GlobalTable) : &(Parser->pc->TopStackFrame)->LocalTable;
|
||||||
|
|
||||||
for (Count = 0; Count < HashTable->Size; Count++) {
|
for (Count = 0; Count < HashTable->Size; Count++) {
|
||||||
for (Entry = HashTable->HashTable[Count];
|
for (Entry = HashTable->HashTable[Count]; Entry != NULL;
|
||||||
Entry != NULL; Entry = NextEntry) {
|
Entry = NextEntry) {
|
||||||
NextEntry = Entry->Next;
|
NextEntry = Entry->Next;
|
||||||
if ((Entry->p.v.Val->ScopeID == ScopeID) &&
|
if ((Entry->p.v.Val->ScopeID == ScopeID) &&
|
||||||
(Entry->p.v.Val->OutOfScope == false)) {
|
(Entry->p.v.Val->OutOfScope == false)) {
|
||||||
|
@ -270,8 +272,8 @@ int VariableDefinedAndOutOfScope(Picoc *pc, const char* Ident)
|
||||||
&(pc->GlobalTable) : &(pc->TopStackFrame)->LocalTable;
|
&(pc->GlobalTable) : &(pc->TopStackFrame)->LocalTable;
|
||||||
|
|
||||||
for (Count = 0; Count < HashTable->Size; Count++) {
|
for (Count = 0; Count < HashTable->Size; Count++) {
|
||||||
for (Entry = HashTable->HashTable[Count];
|
for (Entry = HashTable->HashTable[Count]; Entry != NULL;
|
||||||
Entry != NULL; Entry = Entry->Next) {
|
Entry = Entry->Next) {
|
||||||
if (Entry->p.v.Val->OutOfScope == true &&
|
if (Entry->p.v.Val->OutOfScope == true &&
|
||||||
(char*)((intptr_t)Entry->p.v.Key & ~1) == Ident)
|
(char*)((intptr_t)Entry->p.v.Key & ~1) == Ident)
|
||||||
return true;
|
return true;
|
||||||
|
@ -343,7 +345,8 @@ struct Value *VariableDefineButIgnoreIdentical(struct ParseState *Parser,
|
||||||
|
|
||||||
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);
|
||||||
MNPos += strlen(MNPos);
|
MNPos += strlen(MNPos);
|
||||||
}
|
}
|
||||||
|
@ -354,7 +357,7 @@ struct Value *VariableDefineButIgnoreIdentical(struct ParseState *Parser,
|
||||||
|
|
||||||
/* is this static already defined? */
|
/* is this static already defined? */
|
||||||
if (!TableGet(&pc->GlobalTable, RegisteredMangledName, &ExistingValue,
|
if (!TableGet(&pc->GlobalTable, RegisteredMangledName, &ExistingValue,
|
||||||
&DeclFileName, &DeclLine, &DeclColumn)) {
|
&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,
|
ExistingValue = VariableAllocValueFromType(Parser->pc, Parser, Typ,
|
||||||
true, NULL, true);
|
true, NULL, true);
|
||||||
|
@ -387,7 +390,7 @@ int VariableDefined(Picoc *pc, const char *Ident)
|
||||||
struct Value *FoundValue;
|
struct Value *FoundValue;
|
||||||
|
|
||||||
if (pc->TopStackFrame == NULL || !TableGet(&pc->TopStackFrame->LocalTable,
|
if (pc->TopStackFrame == NULL || !TableGet(&pc->TopStackFrame->LocalTable,
|
||||||
Ident, &FoundValue, NULL, NULL, NULL)) {
|
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;
|
||||||
}
|
}
|
||||||
|
@ -400,7 +403,7 @@ void VariableGet(Picoc *pc, struct ParseState *Parser, const char *Ident,
|
||||||
struct Value **LVal)
|
struct Value **LVal)
|
||||||
{
|
{
|
||||||
if (pc->TopStackFrame == NULL || !TableGet(&pc->TopStackFrame->LocalTable,
|
if (pc->TopStackFrame == NULL || !TableGet(&pc->TopStackFrame->LocalTable,
|
||||||
Ident, LVal, NULL, NULL, NULL)) {
|
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);
|
||||||
|
|
Loading…
Reference in a new issue