diff --git a/clibrary.c b/clibrary.c index 7e63454..7ec1cb1 100644 --- a/clibrary.c +++ b/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) { diff --git a/expression.c b/expression.c index 5319ff9..78cb586 100644 --- a/expression.c +++ b/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); diff --git a/picoc.h b/picoc.h index 667ac5c..15a07b4 100644 --- a/picoc.h +++ b/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(); diff --git a/platform.c b/platform.c index 8925b20..ad11581 100644 --- a/platform.c +++ b/platform.c @@ -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 diff --git a/type.c b/type.c index a2e7f68..945ae69 100644 --- a/type.c +++ b/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));