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:
parent
f2f44b1bf7
commit
c805b3fdec
21
clibrary.c
21
clibrary.c
|
@ -98,6 +98,27 @@ void PrintFP(double Num, CharWriter *PutCh)
|
|||
}
|
||||
#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 */
|
||||
void LibPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
|
||||
{
|
||||
|
|
16
expression.c
16
expression.c
|
@ -350,7 +350,7 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
|
|||
struct Value *Result;
|
||||
|
||||
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))
|
||||
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");
|
||||
|
||||
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
|
||||
ExpressionStackPushValue(Parser, StackTop, TopValue);
|
||||
|
@ -652,7 +652,7 @@ void ExpressionGetStructElement(struct ParseState *Parser, struct ExpressionStac
|
|||
}
|
||||
|
||||
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))
|
||||
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 */
|
||||
VariableGet(Parser, FuncName, &FuncValue);
|
||||
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);
|
||||
ReturnValue = (*StackTop)->p.Val;
|
||||
|
@ -902,7 +902,9 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
|
|||
Param->Val->Character = COERCE_INTEGER(Param); /* cast to char */
|
||||
|
||||
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");
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -969,7 +971,7 @@ int ExpressionParseInt(struct ParseState *Parser)
|
|||
if (Parser->Mode == RunModeRun)
|
||||
{
|
||||
if (!IS_INTEGER_COERCIBLE(Val))
|
||||
ProgramFail(Parser, "integer value expected");
|
||||
ProgramFail(Parser, "integer value expected instead of %t", Val->Typ);
|
||||
|
||||
Result = COERCE_INTEGER(Val);
|
||||
VariableStackPop(Parser, Val);
|
||||
|
|
6
picoc.h
6
picoc.h
|
@ -113,7 +113,6 @@ enum BaseType
|
|||
TypeStruct, /* aggregate type */
|
||||
TypeUnion, /* merged type */
|
||||
TypeEnum, /* enumated integer type */
|
||||
TypeType /* a type (eg. typedef) */
|
||||
};
|
||||
|
||||
/* data type */
|
||||
|
@ -333,14 +332,15 @@ struct Value *VariableStringLiteralGet(char *Ident);
|
|||
void VariableStringLiteralDefine(char *Ident, struct Value *Val);
|
||||
void VariableCheckPointer(struct ParseState *Parser, struct Value *PointerValue);
|
||||
|
||||
/* library.c */
|
||||
/* clibrary.c */
|
||||
void LibraryInit(struct Table *GlobalTable, const char *LibraryName, struct LibraryFunction (*FuncList)[]);
|
||||
void CLibraryInit();
|
||||
void PrintInt(int Num, CharWriter *PutCh);
|
||||
void PrintStr(const char *Str, 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 LexFail(struct LexState *Lexer, const char *Message, ...);
|
||||
void PlatformCleanup();
|
||||
|
|
|
@ -53,6 +53,7 @@ void PlatformVPrintf(const char *Format, va_list Args)
|
|||
case 's': PrintStr(va_arg(Args, char *), PlatformPutc); break;
|
||||
case 'd': PrintInt(va_arg(Args, int), PlatformPutc); break;
|
||||
case 'c': PlatformPutc(va_arg(Args, int)); break;
|
||||
case 't': PrintType(va_arg(Args, struct ValueType *), PlatformPutc); break;
|
||||
#ifndef NO_FP
|
||||
case 'f': PrintFP(va_arg(Args, double), PlatformPutc); break;
|
||||
#endif
|
||||
|
|
2
type.c
2
type.c
|
@ -12,7 +12,6 @@ struct ValueType VoidType;
|
|||
struct ValueType FunctionType;
|
||||
struct ValueType MacroType;
|
||||
struct ValueType EnumType;
|
||||
struct ValueType Type_Type;
|
||||
struct ValueType *CharPtrType;
|
||||
struct ValueType *CharArrayType;
|
||||
|
||||
|
@ -123,7 +122,6 @@ void TypeInit()
|
|||
TypeAddBaseType(&VoidType, TypeVoid, 0);
|
||||
TypeAddBaseType(&FunctionType, TypeFunction, sizeof(int));
|
||||
TypeAddBaseType(&MacroType, TypeMacro, sizeof(int));
|
||||
TypeAddBaseType(&Type_Type, TypeType, sizeof(struct ValueType *));
|
||||
TypeAddBaseType(&CharType, TypeChar, sizeof(char));
|
||||
CharPtrType = TypeAdd(NULL, &CharType, TypePointer, 0, StrEmpty, sizeof(struct PointerValue));
|
||||
CharArrayType = TypeAdd(NULL, &CharType, TypeArray, 0, StrEmpty, sizeof(char));
|
||||
|
|
Loading…
Reference in a new issue