Added ability to print types in error messages

git-svn-id: http://picoc.googlecode.com/svn/trunk@268 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-04-24 01:02:25 +00:00
parent f2f44b1bf7
commit c805b3fdec
5 changed files with 34 additions and 12 deletions

View file

@ -98,6 +98,27 @@ void PrintFP(double Num, CharWriter *PutCh)
} }
#endif #endif
/* print a type to a stream without using printf/sprintf */
void PrintType(struct ValueType *Typ, CharWriter *PutCh)
{
switch (Typ->Base)
{
case TypeVoid: PrintStr("void", PutCh); break;
case TypeInt: PrintStr("int", PutCh); break;
#ifndef NO_FP
case TypeFP: PrintStr("double", PutCh); break;
#endif
case TypeChar: PrintStr("char", PutCh); break;
case TypeFunction: PrintStr("function", PutCh); break;
case TypeMacro: PrintStr("macro", PutCh); break;
case TypePointer: if (Typ->FromType) PrintType(Typ->FromType, PutCh); PutCh('*'); break;
case TypeArray: PrintType(Typ->FromType, PutCh); PutCh('['); if (Typ->ArraySize != 0) PrintInt(Typ->ArraySize, PutCh); PutCh(']'); break;
case TypeStruct: PrintStr("struct ", PutCh); PrintStr(Typ->Identifier, PutCh); break;
case TypeUnion: PrintStr("union ", PutCh); PrintStr(Typ->Identifier, PutCh); break;
case TypeEnum: PrintStr("enum ", PutCh); PrintStr(Typ->Identifier, PutCh); break;
}
}
/* intrinsic functions made available to the language */ /* intrinsic functions made available to the language */
void LibPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) void LibPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{ {

View file

@ -350,7 +350,7 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
struct Value *Result; struct Value *Result;
if (BottomValue->Typ->Base != TypeArray) if (BottomValue->Typ->Base != TypeArray)
ProgramFail(Parser, "not an array"); ProgramFail(Parser, "this %t is not an array", BottomValue->Typ);
if (!IS_INTEGER_COERCIBLE(TopValue)) if (!IS_INTEGER_COERCIBLE(TopValue))
ProgramFail(Parser, "array index must be an integer"); ProgramFail(Parser, "array index must be an integer");
@ -517,7 +517,7 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
ProgramFail(Parser, "can't assign to this"); ProgramFail(Parser, "can't assign to this");
if (BottomValue->Typ != TopValue->Typ) if (BottomValue->Typ != TopValue->Typ)
ProgramFail(Parser, "can't assign to a different type of variable"); ProgramFail(Parser, "can't assign from a %t to a %t", TopValue->Typ, BottomValue->Typ);
memcpy((void *)BottomValue->Val, (void *)TopValue->Val, TypeSizeValue(TopValue)); // XXX - need to handle arrays memcpy((void *)BottomValue->Val, (void *)TopValue->Val, TypeSizeValue(TopValue)); // XXX - need to handle arrays
ExpressionStackPushValue(Parser, StackTop, TopValue); ExpressionStackPushValue(Parser, StackTop, TopValue);
@ -652,7 +652,7 @@ void ExpressionGetStructElement(struct ParseState *Parser, struct ExpressionStac
} }
if (StructVal->Typ->Base != TypeStruct && StructVal->Typ->Base != TypeUnion) if (StructVal->Typ->Base != TypeStruct && StructVal->Typ->Base != TypeUnion)
ProgramFail(Parser, "can't use '%s' on something that's not a struct or union %s", (Token == TokenDot) ? "." : "->", (Token == TokenArrow) ? "pointer" : ""); ProgramFail(Parser, "can't use '%s' on something that's not a struct or union %s : it's a %t", (Token == TokenDot) ? "." : "->", (Token == TokenArrow) ? "pointer" : "", ParamVal->Typ);
if (!TableGet(StructVal->Typ->Members, Ident->Val->Identifier, &MemberValue)) if (!TableGet(StructVal->Typ->Members, Ident->Val->Identifier, &MemberValue))
ProgramFail(Parser, "doesn't have a member called '%s'", Ident->Val->Identifier); ProgramFail(Parser, "doesn't have a member called '%s'", Ident->Val->Identifier);
@ -866,7 +866,7 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
/* get the function definition */ /* get the function definition */
VariableGet(Parser, FuncName, &FuncValue); VariableGet(Parser, FuncName, &FuncValue);
if (FuncValue->Typ->Base != TypeFunction) if (FuncValue->Typ->Base != TypeFunction)
ProgramFail(Parser, "not a function - can't call"); ProgramFail(Parser, "%t is not a function - can't call", FuncValue->Typ);
ExpressionStackPushValueByType(Parser, StackTop, FuncValue->Val->FuncDef.ReturnType); ExpressionStackPushValueByType(Parser, StackTop, FuncValue->Val->FuncDef.ReturnType);
ReturnValue = (*StackTop)->p.Val; ReturnValue = (*StackTop)->p.Val;
@ -902,7 +902,9 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
Param->Val->Character = COERCE_INTEGER(Param); /* cast to char */ Param->Val->Character = COERCE_INTEGER(Param); /* cast to char */
else else
ProgramFail(Parser, "parameter %d to %s() is the wrong type", ArgCount+1, FuncName); ProgramFail(Parser, "parameter %d to %s() is %t instead of %t", ArgCount+1, FuncName, Param->Typ, FuncValue->Val->FuncDef.ParamType[ArgCount]);
Param->Typ = FuncValue->Val->FuncDef.ParamType[ArgCount];
} }
} }
@ -946,7 +948,7 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
ProgramFail(&FuncParser, "function body expected"); ProgramFail(&FuncParser, "function body expected");
if (FuncValue->Val->FuncDef.ReturnType != ReturnValue->Typ) if (FuncValue->Val->FuncDef.ReturnType != ReturnValue->Typ)
ProgramFail(&FuncParser, "bad type of return value"); ProgramFail(&FuncParser, "return value is %t instead of %t", ReturnValue->Typ, FuncValue->Val->FuncDef.ReturnType);
VariableStackFramePop(Parser); VariableStackFramePop(Parser);
} }
@ -969,7 +971,7 @@ int ExpressionParseInt(struct ParseState *Parser)
if (Parser->Mode == RunModeRun) if (Parser->Mode == RunModeRun)
{ {
if (!IS_INTEGER_COERCIBLE(Val)) if (!IS_INTEGER_COERCIBLE(Val))
ProgramFail(Parser, "integer value expected"); ProgramFail(Parser, "integer value expected instead of %t", Val->Typ);
Result = COERCE_INTEGER(Val); Result = COERCE_INTEGER(Val);
VariableStackPop(Parser, Val); VariableStackPop(Parser, Val);

View file

@ -113,7 +113,6 @@ enum BaseType
TypeStruct, /* aggregate type */ TypeStruct, /* aggregate type */
TypeUnion, /* merged type */ TypeUnion, /* merged type */
TypeEnum, /* enumated integer type */ TypeEnum, /* enumated integer type */
TypeType /* a type (eg. typedef) */
}; };
/* data type */ /* data type */
@ -333,14 +332,15 @@ struct Value *VariableStringLiteralGet(char *Ident);
void VariableStringLiteralDefine(char *Ident, struct Value *Val); void VariableStringLiteralDefine(char *Ident, struct Value *Val);
void VariableCheckPointer(struct ParseState *Parser, struct Value *PointerValue); void VariableCheckPointer(struct ParseState *Parser, struct Value *PointerValue);
/* library.c */ /* clibrary.c */
void LibraryInit(struct Table *GlobalTable, const char *LibraryName, struct LibraryFunction (*FuncList)[]); void LibraryInit(struct Table *GlobalTable, const char *LibraryName, struct LibraryFunction (*FuncList)[]);
void CLibraryInit(); void CLibraryInit();
void PrintInt(int Num, CharWriter *PutCh); void PrintInt(int Num, CharWriter *PutCh);
void PrintStr(const char *Str, CharWriter *PutCh); void PrintStr(const char *Str, CharWriter *PutCh);
void PrintFP(double Num, CharWriter *PutCh); void PrintFP(double Num, CharWriter *PutCh);
void PrintType(struct ValueType *Typ, CharWriter *PutCh);
/* platform_support.c */ /* platform.c */
void ProgramFail(struct ParseState *Parser, const char *Message, ...); void ProgramFail(struct ParseState *Parser, const char *Message, ...);
void LexFail(struct LexState *Lexer, const char *Message, ...); void LexFail(struct LexState *Lexer, const char *Message, ...);
void PlatformCleanup(); void PlatformCleanup();

View file

@ -53,6 +53,7 @@ void PlatformVPrintf(const char *Format, va_list Args)
case 's': PrintStr(va_arg(Args, char *), PlatformPutc); break; case 's': PrintStr(va_arg(Args, char *), PlatformPutc); break;
case 'd': PrintInt(va_arg(Args, int), PlatformPutc); break; case 'd': PrintInt(va_arg(Args, int), PlatformPutc); break;
case 'c': PlatformPutc(va_arg(Args, int)); break; case 'c': PlatformPutc(va_arg(Args, int)); break;
case 't': PrintType(va_arg(Args, struct ValueType *), PlatformPutc); break;
#ifndef NO_FP #ifndef NO_FP
case 'f': PrintFP(va_arg(Args, double), PlatformPutc); break; case 'f': PrintFP(va_arg(Args, double), PlatformPutc); break;
#endif #endif

2
type.c
View file

@ -12,7 +12,6 @@ struct ValueType VoidType;
struct ValueType FunctionType; struct ValueType FunctionType;
struct ValueType MacroType; struct ValueType MacroType;
struct ValueType EnumType; struct ValueType EnumType;
struct ValueType Type_Type;
struct ValueType *CharPtrType; struct ValueType *CharPtrType;
struct ValueType *CharArrayType; struct ValueType *CharArrayType;
@ -123,7 +122,6 @@ void TypeInit()
TypeAddBaseType(&VoidType, TypeVoid, 0); TypeAddBaseType(&VoidType, TypeVoid, 0);
TypeAddBaseType(&FunctionType, TypeFunction, sizeof(int)); TypeAddBaseType(&FunctionType, TypeFunction, sizeof(int));
TypeAddBaseType(&MacroType, TypeMacro, sizeof(int)); TypeAddBaseType(&MacroType, TypeMacro, sizeof(int));
TypeAddBaseType(&Type_Type, TypeType, sizeof(struct ValueType *));
TypeAddBaseType(&CharType, TypeChar, sizeof(char)); TypeAddBaseType(&CharType, TypeChar, sizeof(char));
CharPtrType = TypeAdd(NULL, &CharType, TypePointer, 0, StrEmpty, sizeof(struct PointerValue)); CharPtrType = TypeAdd(NULL, &CharType, TypePointer, 0, StrEmpty, sizeof(struct PointerValue));
CharArrayType = TypeAdd(NULL, &CharType, TypeArray, 0, StrEmpty, sizeof(char)); CharArrayType = TypeAdd(NULL, &CharType, TypeArray, 0, StrEmpty, sizeof(char));