From 4524270e50ebe3337cadfbea4c33b611c2e852ba Mon Sep 17 00:00:00 2001 From: "zik.saleeba" Date: Sun, 25 Jan 2009 02:09:44 +0000 Subject: [PATCH] Changing everything to handled heap-allocated values git-svn-id: http://picoc.googlecode.com/svn/trunk@37 21eae674-98b7-11dd-bd71-f92a316d2d60 --- lex.c | 4 ++-- parse.c | 16 +++++++++------ picoc.h | 13 +++++++----- str.c | 15 +++++++------- type.c | 58 +++++++++++++++++++++++++++++------------------------- variable.c | 1 + 6 files changed, 60 insertions(+), 47 deletions(-) diff --git a/lex.c b/lex.c index cc930c2..ecf678c 100644 --- a/lex.c +++ b/lex.c @@ -210,8 +210,8 @@ enum LexToken LexGetTokenUncached(struct LexState *Lexer, union AnyValue *Value) case '|': NEXTIS('|', TokenLogicalOr, TokenArithmeticOr); case '{': return TokenLeftBrace; case '}': return TokenRightBrace; - case '[': return TokenLeftAngleBracket; - case ']': return TokenRightAngleBracket; + case '[': return TokenLeftSquareBracket; + case ']': return TokenRightSquareBracket; case '!': return TokenUnaryNot; case '^': return TokenArithmeticExor; case '~': return TokenUnaryExor; diff --git a/parse.c b/parse.c index f1c653a..b7d29de 100644 --- a/parse.c +++ b/parse.c @@ -3,9 +3,9 @@ #include "picoc.h" /* parameter passing area */ -struct Value Parameter[PARAMETER_MAX]; +struct Value *Parameter[PARAMETER_MAX]; int ParameterUsed = 0; -struct Value ReturnValue; +struct Value *ReturnValue; /* local prototypes */ int ParseExpression(struct LexState *Lexer, struct Value **Result, int RunIt); @@ -33,14 +33,14 @@ void ParseParameterList(struct LexState *CallLexer, struct LexState *FuncLexer, for (ParamCount = 0; ParamCount < ParameterUsed; ParamCount++) { TypeParse(FuncLexer, &Typ, &Identifier); - if (Identifier->Len != 0) + if (Identifier.Len != 0) { /* there's an identifier */ if (RunIt) { - if (Parameter[ParamCount].Typ != Typ) + if (Parameter[ParamCount]->Typ != Typ) ProgramFail(CallLexer, "parameter %d has the wrong type", ParamCount+1); - VariableDefine(FuncLexer, &Identifier, &Parameter[ParamCount]); + VariableDefine(FuncLexer, &Identifier, Parameter[ParamCount]); } } @@ -90,8 +90,9 @@ void ParseFunctionCall(struct LexState *Lexer, struct Value **Result, Str *FuncN struct LexState FuncLexer; struct ValueType *ReturnType; struct Value *LValue; + int Count; - VariableGet(Lexer, FuncName, Result, &LValue); + VariableGet(Lexer, FuncName, *Result, &LValue); if (Result->Typ->Base != TypeFunction) ProgramFail(Lexer, "not a function - can't call"); @@ -115,6 +116,9 @@ void ParseFunctionCall(struct LexState *Lexer, struct Value **Result, Str *FuncN } else IntrinsicCall(Lexer, Result, ReturnType, Result->Val->Integer); + + for (Count = 0; Count < ParameterUsed; Count++) + HeapFree(Parameter[ParameterUsed]); } } diff --git a/picoc.h b/picoc.h index 8e9c956..da1782b 100644 --- a/picoc.h +++ b/picoc.h @@ -51,7 +51,7 @@ enum LexToken TokenSemicolon, TokenComma, TokenDot, TokenArrow, TokenAmpersand, TokenLeftBrace, TokenRightBrace, - TokenLeftAngleBracket, TokenRightAngleBracket, + TokenLeftSquareBracket, TokenRightSquareBracket, TokenLogicalAnd, TokenLogicalOr, TokenArithmeticOr, TokenArithmeticExor, TokenUnaryExor, TokenUnaryNot, TokenAddAssign, TokenSubtractAssign, TokenIncrement, TokenDecrement, @@ -175,9 +175,11 @@ struct StackFrame extern struct Table GlobalTable; extern struct LexState FunctionStore[FUNCTION_STORE_MAX]; extern int FunctionStoreUsed; -extern struct Value Parameter[PARAMETER_MAX]; +extern struct Value *Parameter[PARAMETER_MAX]; extern int ParameterUsed; -extern struct Value ReturnValue; +extern struct StackFrame Stack[STACK_MAX]; +extern int StackUsed; +extern struct Value *ReturnValue; extern struct ValueType IntType; extern struct ValueType CharType; extern struct ValueType StringType; @@ -185,9 +187,9 @@ extern struct ValueType FPType; extern struct ValueType VoidType; extern struct ValueType FunctionType; extern struct ValueType MacroType; +extern Str StrEmpty; /* str.c */ -void StrCopy(Str *Dest, const Str *Source); void StrToC(char *Dest, int DestSize, const Str *Source); void StrFromC(Str *Dest, const char *Source); int StrEqual(const Str *Str1, const Str *Str2); @@ -215,6 +217,7 @@ void LexToEndOfLine(struct LexState *Lexer); /* parse.c */ void ParseInit(void); +int ParseExpression(struct LexState *Lexer, struct Value **Result, int RunIt); void Parse(const Str *FileName, const Str *Source, int RunIt); /* type.c */ @@ -243,7 +246,7 @@ struct Value *VariableAllocValueAndCopy(struct LexState *Lexer, struct Value *Fr struct Value *VariableAllocValueFromType(struct LexState *Lexer, struct ValueType *Typ); void VariableDefine(struct LexState *Lexer, const Str *Ident, struct Value *InitValue); int VariableDefined(Str *Ident); -void VariableGet(struct LexState *Lexer, Str *Ident, struct Value *Val, struct Value **LVal); +XXX void VariableGet(struct LexState *Lexer, Str *Ident, struct Value *Val, struct Value **LVal); void VariableStackFrameAdd(struct LexState *Lexer); #endif /* PICOC_H */ diff --git a/str.c b/str.c index 408f499..ecfdea6 100644 --- a/str.c +++ b/str.c @@ -6,13 +6,9 @@ #include "picoc.h" +Str StrEmpty = { "", 0 }; -void StrCopy(Str *Dest, const Str *Source) -{ - Dest->Str = Source->Str; - Dest->Len = Source->Len; -} - +/* convert a Str to a C string */ void StrToC(char *Dest, int DestSize, const Str *Source) { int CopyLen = min(DestSize-1, Source->Len); @@ -20,12 +16,14 @@ void StrToC(char *Dest, int DestSize, const Str *Source) Dest[CopyLen] = '\0'; } +/* convert a C string to a Str */ void StrFromC(Str *Dest, const char *Source) { Dest->Str = Source; Dest->Len = strlen(Source); } +/* compare two Strs for equality */ int StrEqual(const Str *Str1, const Str *Str2) { if (Str1->Len != Str2->Len) @@ -34,11 +32,13 @@ int StrEqual(const Str *Str1, const Str *Str2) return memcmp(Str1->Str, Str2->Str, Str1->Len) == 0; } +/* compare a Str to a C string */ int StrEqualC(const Str *Str1, const char *Str2) { return strncmp(Str1->Str, Str2, Str1->Len) == 0 && Str2[Str1->Len] == '\0'; } +/* print an integer to a stream without using printf/sprintf */ void StrPrintInt(int Num, FILE *Stream) { int Div; @@ -70,6 +70,7 @@ void StrPrintInt(int Num, FILE *Stream) } } +/* print a double to a stream without using printf/sprintf */ void StrPrintFP(double Num, FILE *Stream) { int Exponent = 0; @@ -92,6 +93,7 @@ void StrPrintFP(double Num, FILE *Stream) } } +/* Str version of printf */ void StrPrintf(const char *Format, ...) { va_list Args; @@ -126,4 +128,3 @@ void vStrPrintf(const char *Format, va_list Args) putchar(*FPos); } } - diff --git a/type.c b/type.c index 6bb7425..fb342a0 100644 --- a/type.c +++ b/type.c @@ -20,7 +20,7 @@ struct ValueType *TypeAdd(struct LexState *Lexer, struct ValueType *ParentType, NewType->Base = Base; NewType->ArraySize = ArraySize; NewType->Sizeof = Sizeof; - StrCopy(&NewType->Identifier, Identifier); + NewType->Identifier = *Identifier; NewType->Members = NULL; NewType->FromType = ParentType; NewType->DerivedTypeList = NULL; @@ -58,7 +58,7 @@ void TypeAddBaseType(struct ValueType *TypeNode, enum BaseType Base, int Sizeof) TypeNode->Base = Base; TypeNode->ArraySize = 0; TypeNode->Sizeof = Sizeof; - StrFromC(&TypeNode->Identifier, ""); + TypeNode->Identifier = StrEmpty; TypeNode->Members = NULL; TypeNode->FromType = NULL; TypeNode->DerivedTypeList = NULL; @@ -84,7 +84,6 @@ void TypeInit() void TypeParseStruct(struct LexState *Lexer, struct ValueType **Typ, int IsStruct) { union AnyValue LexValue; - int TotalSize = 0; struct ValueType *MemberType; Str MemberIdentifier; struct Value *MemberValue; @@ -92,30 +91,30 @@ void TypeParseStruct(struct LexState *Lexer, struct ValueType **Typ, int IsStruc if (LexGetToken(Lexer, &LexValue) != TokenIdentifier) ProgramFail(Lexer, "struct/union name required"); - if (LexGetPlainToken(Lexer) != TokenOpenBrace) + if (LexGetPlainToken(Lexer) != TokenLeftBrace) ProgramFail(Lexer, "'{' expected"); - if (StackLevel != 0) + if (StackUsed != 0) ProgramFail(Lexer, "struct/union definitions can only be globals"); *Typ = TypeGetMatching(Lexer, &UberType, IsStruct ? TypeStruct : TypeUnion, 0, &LexValue.String); - (*Typ)->Members = VariableAlloc(sizeof(struct Table) + STRUCT_TABLE_SIZE * sizeof(struct TableEntry)); - (*Typ)->Members->HashTable = (struct Table *)((void *)(*Typ)->Members + sizeof(struct Table)); + (*Typ)->Members = VariableAlloc(Lexer, sizeof(struct Table) + STRUCT_TABLE_SIZE * sizeof(struct TableEntry)); + (*Typ)->Members->HashTable = (void *)(*Typ)->Members + sizeof(struct Table); do { TypeParse(Lexer, &MemberType, &MemberIdentifier); MemberValue = VariableAllocValueAndData(Lexer, sizeof(int)); MemberValue->MustFree = TRUE; - MemberValue->Typ = &MemberType; + MemberValue->Typ = MemberType; if (IsStruct) { /* allocate this member's location in the struct */ - MemberValue->Value->Integer = (*Typ)->Sizeof; + MemberValue->Val->Integer = (*Typ)->Sizeof; (*Typ)->Sizeof += MemberValue->Typ->Sizeof; } else { /* union members always start at 0, make sure it's big enough to hold the largest member */ - MemberValue->Value->Integer = 0; + MemberValue->Val->Integer = 0; if (MemberValue->Typ->Sizeof > (*Typ)->Sizeof) (*Typ)->Sizeof = MemberValue->Typ->Sizeof; } @@ -123,7 +122,7 @@ void TypeParseStruct(struct LexState *Lexer, struct ValueType **Typ, int IsStruc if (!TableSet((*Typ)->Members, &MemberIdentifier, MemberValue)) ProgramFail(Lexer, "member '%S' already defined", &MemberIdentifier); - } while (LexPeekPlainToken(Lexer) != TokenCloseBrace); + } while (LexPeekPlainToken(Lexer) != TokenRightBrace); LexGetPlainToken(Lexer); } @@ -132,9 +131,8 @@ void TypeParseStruct(struct LexState *Lexer, struct ValueType **Typ, int IsStruc void TypeParse(struct LexState *Lexer, struct ValueType **Typ, Str *Identifier) { struct LexState Before; - struct LexToken Token; + enum LexToken Token; union AnyValue LexValue; - struct Value ArraySize; int Done = FALSE; *Typ = NULL; @@ -160,8 +158,8 @@ void TypeParse(struct LexState *Lexer, struct ValueType **Typ, Str *Identifier) if (*Typ != NULL) ProgramFail(Lexer, "bad type declaration"); - TypeParseDeclarator(Lexer, Typ, Identifier); - if (LexGetTokenOnly(Lexer) != TokenCloseBracket) + TypeParse(Lexer, Typ, Identifier); + if (LexGetPlainToken(Lexer) != TokenCloseBracket) ProgramFail(Lexer, "')' expected"); break; @@ -169,11 +167,11 @@ void TypeParse(struct LexState *Lexer, struct ValueType **Typ, Str *Identifier) if (*Typ == NULL) ProgramFail(Lexer, "bad type declaration"); - *Typ = TypeGetMatching(Lexer, *Typ, TypePointer, 0); + *Typ = TypeGetMatching(Lexer, *Typ, TypePointer, 0, &StrEmpty); break; case TokenIdentifier: - if (*Typ == NULL || Identifier->Length != 0) + if (*Typ == NULL || Identifier->Len != 0) ProgramFail(Lexer, "bad type declaration"); *Identifier = LexValue.String; @@ -187,26 +185,32 @@ void TypeParse(struct LexState *Lexer, struct ValueType **Typ, Str *Identifier) if (*Typ == NULL) ProgramFail(Lexer, "bad type declaration"); - if (Identifier->Length != 0) + if (Identifier->Len != 0) { /* parse stuff after the identifier */ Done = FALSE; while (!Done) { Before = *Lexer; - switch (LexGetTokenOnly(Lexer)) + switch (LexGetPlainToken(Lexer)) { - case TokenOpenSquareBracket: + case TokenLeftSquareBracket: { - struct Value ArraySize; - union AnyValue ArraySizeAnyValue; - ArraySize->Val = &ArraySizeAnyValue; - if (!ParseExpression(Lexer, &ArraySize, TRUE)) - ArraySize->Val->Integer = 0; + struct Value *ArraySizeValue; + int ArraySize = 0; - if (LexGetTokenOnly(Lexer) != TokenCloseSquareBracket) + if (ParseExpression(Lexer, &ArraySizeValue, TRUE)) + { + if (ArraySizeValue->Typ->Base != TypeInt) + ProgramFail(Lexer, "array size must be an integer"); + + ArraySize = ArraySizeValue->Val->Integer; + HeapFree(ArraySizeValue); + } + + if (LexGetPlainToken(Lexer) != TokenRightSquareBracket) ProgramFail(Lexer, "']' expected"); - *Typ = TypeGetMatching(Lexer, *Typ, TypeArray, ArraySize->Val->Integer); + *Typ = TypeGetMatching(Lexer, *Typ, TypeArray, ArraySize, &StrEmpty); } break; diff --git a/variable.c b/variable.c index 6fce420..e1ec11c 100644 --- a/variable.c +++ b/variable.c @@ -86,6 +86,7 @@ int VariableDefined(Str *Ident) } /* get the value of a variable. must be defined */ +XXX void VariableGet(struct LexState *Lexer, Str *Ident, struct Value *Val, struct Value **LVal) { if (StackUsed == 0 || !TableGet(&Stack[StackUsed-1].LocalTable, Ident, LVal))