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
|
#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)
|
||||||
{
|
{
|
||||||
|
|
16
expression.c
16
expression.c
|
@ -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);
|
||||||
|
|
6
picoc.h
6
picoc.h
|
@ -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();
|
||||||
|
|
|
@ -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
2
type.c
|
@ -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));
|
||||||
|
|
Loading…
Reference in a new issue