Changing everything to handled heap-allocated values

git-svn-id: http://picoc.googlecode.com/svn/trunk@37 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-01-25 02:09:44 +00:00
parent b9e1086cbb
commit 4524270e50
6 changed files with 60 additions and 47 deletions

4
lex.c
View file

@ -210,8 +210,8 @@ enum LexToken LexGetTokenUncached(struct LexState *Lexer, union AnyValue *Value)
case '|': NEXTIS('|', TokenLogicalOr, TokenArithmeticOr); case '|': NEXTIS('|', TokenLogicalOr, TokenArithmeticOr);
case '{': return TokenLeftBrace; case '{': return TokenLeftBrace;
case '}': return TokenRightBrace; case '}': return TokenRightBrace;
case '[': return TokenLeftAngleBracket; case '[': return TokenLeftSquareBracket;
case ']': return TokenRightAngleBracket; case ']': return TokenRightSquareBracket;
case '!': return TokenUnaryNot; case '!': return TokenUnaryNot;
case '^': return TokenArithmeticExor; case '^': return TokenArithmeticExor;
case '~': return TokenUnaryExor; case '~': return TokenUnaryExor;

16
parse.c
View file

@ -3,9 +3,9 @@
#include "picoc.h" #include "picoc.h"
/* parameter passing area */ /* parameter passing area */
struct Value Parameter[PARAMETER_MAX]; struct Value *Parameter[PARAMETER_MAX];
int ParameterUsed = 0; int ParameterUsed = 0;
struct Value ReturnValue; struct Value *ReturnValue;
/* local prototypes */ /* local prototypes */
int ParseExpression(struct LexState *Lexer, struct Value **Result, int RunIt); 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++) for (ParamCount = 0; ParamCount < ParameterUsed; ParamCount++)
{ {
TypeParse(FuncLexer, &Typ, &Identifier); TypeParse(FuncLexer, &Typ, &Identifier);
if (Identifier->Len != 0) if (Identifier.Len != 0)
{ /* there's an identifier */ { /* there's an identifier */
if (RunIt) if (RunIt)
{ {
if (Parameter[ParamCount].Typ != Typ) if (Parameter[ParamCount]->Typ != Typ)
ProgramFail(CallLexer, "parameter %d has the wrong type", ParamCount+1); 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 LexState FuncLexer;
struct ValueType *ReturnType; struct ValueType *ReturnType;
struct Value *LValue; struct Value *LValue;
int Count;
VariableGet(Lexer, FuncName, Result, &LValue); VariableGet(Lexer, FuncName, *Result, &LValue);
if (Result->Typ->Base != TypeFunction) if (Result->Typ->Base != TypeFunction)
ProgramFail(Lexer, "not a function - can't call"); ProgramFail(Lexer, "not a function - can't call");
@ -115,6 +116,9 @@ void ParseFunctionCall(struct LexState *Lexer, struct Value **Result, Str *FuncN
} }
else else
IntrinsicCall(Lexer, Result, ReturnType, Result->Val->Integer); IntrinsicCall(Lexer, Result, ReturnType, Result->Val->Integer);
for (Count = 0; Count < ParameterUsed; Count++)
HeapFree(Parameter[ParameterUsed]);
} }
} }

13
picoc.h
View file

@ -51,7 +51,7 @@ enum LexToken
TokenSemicolon, TokenComma, TokenDot, TokenSemicolon, TokenComma, TokenDot,
TokenArrow, TokenAmpersand, TokenArrow, TokenAmpersand,
TokenLeftBrace, TokenRightBrace, TokenLeftBrace, TokenRightBrace,
TokenLeftAngleBracket, TokenRightAngleBracket, TokenLeftSquareBracket, TokenRightSquareBracket,
TokenLogicalAnd, TokenLogicalOr, TokenArithmeticOr, TokenArithmeticExor, TokenUnaryExor, TokenUnaryNot, TokenLogicalAnd, TokenLogicalOr, TokenArithmeticOr, TokenArithmeticExor, TokenUnaryExor, TokenUnaryNot,
TokenAddAssign, TokenSubtractAssign, TokenAddAssign, TokenSubtractAssign,
TokenIncrement, TokenDecrement, TokenIncrement, TokenDecrement,
@ -175,9 +175,11 @@ struct StackFrame
extern struct Table GlobalTable; extern struct Table GlobalTable;
extern struct LexState FunctionStore[FUNCTION_STORE_MAX]; extern struct LexState FunctionStore[FUNCTION_STORE_MAX];
extern int FunctionStoreUsed; extern int FunctionStoreUsed;
extern struct Value Parameter[PARAMETER_MAX]; extern struct Value *Parameter[PARAMETER_MAX];
extern int ParameterUsed; 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 IntType;
extern struct ValueType CharType; extern struct ValueType CharType;
extern struct ValueType StringType; extern struct ValueType StringType;
@ -185,9 +187,9 @@ extern struct ValueType FPType;
extern struct ValueType VoidType; extern struct ValueType VoidType;
extern struct ValueType FunctionType; extern struct ValueType FunctionType;
extern struct ValueType MacroType; extern struct ValueType MacroType;
extern Str StrEmpty;
/* str.c */ /* str.c */
void StrCopy(Str *Dest, const Str *Source);
void StrToC(char *Dest, int DestSize, const Str *Source); void StrToC(char *Dest, int DestSize, const Str *Source);
void StrFromC(Str *Dest, const char *Source); void StrFromC(Str *Dest, const char *Source);
int StrEqual(const Str *Str1, const Str *Str2); int StrEqual(const Str *Str1, const Str *Str2);
@ -215,6 +217,7 @@ void LexToEndOfLine(struct LexState *Lexer);
/* parse.c */ /* parse.c */
void ParseInit(void); void ParseInit(void);
int ParseExpression(struct LexState *Lexer, struct Value **Result, int RunIt);
void Parse(const Str *FileName, const Str *Source, int RunIt); void Parse(const Str *FileName, const Str *Source, int RunIt);
/* type.c */ /* type.c */
@ -243,7 +246,7 @@ struct Value *VariableAllocValueAndCopy(struct LexState *Lexer, struct Value *Fr
struct Value *VariableAllocValueFromType(struct LexState *Lexer, struct ValueType *Typ); struct Value *VariableAllocValueFromType(struct LexState *Lexer, struct ValueType *Typ);
void VariableDefine(struct LexState *Lexer, const Str *Ident, struct Value *InitValue); void VariableDefine(struct LexState *Lexer, const Str *Ident, struct Value *InitValue);
int VariableDefined(Str *Ident); 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); void VariableStackFrameAdd(struct LexState *Lexer);
#endif /* PICOC_H */ #endif /* PICOC_H */

15
str.c
View file

@ -6,13 +6,9 @@
#include "picoc.h" #include "picoc.h"
Str StrEmpty = { "", 0 };
void StrCopy(Str *Dest, const Str *Source) /* convert a Str to a C string */
{
Dest->Str = Source->Str;
Dest->Len = Source->Len;
}
void StrToC(char *Dest, int DestSize, const Str *Source) void StrToC(char *Dest, int DestSize, const Str *Source)
{ {
int CopyLen = min(DestSize-1, Source->Len); int CopyLen = min(DestSize-1, Source->Len);
@ -20,12 +16,14 @@ void StrToC(char *Dest, int DestSize, const Str *Source)
Dest[CopyLen] = '\0'; Dest[CopyLen] = '\0';
} }
/* convert a C string to a Str */
void StrFromC(Str *Dest, const char *Source) void StrFromC(Str *Dest, const char *Source)
{ {
Dest->Str = Source; Dest->Str = Source;
Dest->Len = strlen(Source); Dest->Len = strlen(Source);
} }
/* compare two Strs for equality */
int StrEqual(const Str *Str1, const Str *Str2) int StrEqual(const Str *Str1, const Str *Str2)
{ {
if (Str1->Len != Str2->Len) 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; return memcmp(Str1->Str, Str2->Str, Str1->Len) == 0;
} }
/* compare a Str to a C string */
int StrEqualC(const Str *Str1, const char *Str2) int StrEqualC(const Str *Str1, const char *Str2)
{ {
return strncmp(Str1->Str, Str2, Str1->Len) == 0 && Str2[Str1->Len] == '\0'; 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) void StrPrintInt(int Num, FILE *Stream)
{ {
int Div; 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) void StrPrintFP(double Num, FILE *Stream)
{ {
int Exponent = 0; int Exponent = 0;
@ -92,6 +93,7 @@ void StrPrintFP(double Num, FILE *Stream)
} }
} }
/* Str version of printf */
void StrPrintf(const char *Format, ...) void StrPrintf(const char *Format, ...)
{ {
va_list Args; va_list Args;
@ -126,4 +128,3 @@ void vStrPrintf(const char *Format, va_list Args)
putchar(*FPos); putchar(*FPos);
} }
} }

58
type.c
View file

@ -20,7 +20,7 @@ struct ValueType *TypeAdd(struct LexState *Lexer, struct ValueType *ParentType,
NewType->Base = Base; NewType->Base = Base;
NewType->ArraySize = ArraySize; NewType->ArraySize = ArraySize;
NewType->Sizeof = Sizeof; NewType->Sizeof = Sizeof;
StrCopy(&NewType->Identifier, Identifier); NewType->Identifier = *Identifier;
NewType->Members = NULL; NewType->Members = NULL;
NewType->FromType = ParentType; NewType->FromType = ParentType;
NewType->DerivedTypeList = NULL; NewType->DerivedTypeList = NULL;
@ -58,7 +58,7 @@ void TypeAddBaseType(struct ValueType *TypeNode, enum BaseType Base, int Sizeof)
TypeNode->Base = Base; TypeNode->Base = Base;
TypeNode->ArraySize = 0; TypeNode->ArraySize = 0;
TypeNode->Sizeof = Sizeof; TypeNode->Sizeof = Sizeof;
StrFromC(&TypeNode->Identifier, ""); TypeNode->Identifier = StrEmpty;
TypeNode->Members = NULL; TypeNode->Members = NULL;
TypeNode->FromType = NULL; TypeNode->FromType = NULL;
TypeNode->DerivedTypeList = NULL; TypeNode->DerivedTypeList = NULL;
@ -84,7 +84,6 @@ void TypeInit()
void TypeParseStruct(struct LexState *Lexer, struct ValueType **Typ, int IsStruct) void TypeParseStruct(struct LexState *Lexer, struct ValueType **Typ, int IsStruct)
{ {
union AnyValue LexValue; union AnyValue LexValue;
int TotalSize = 0;
struct ValueType *MemberType; struct ValueType *MemberType;
Str MemberIdentifier; Str MemberIdentifier;
struct Value *MemberValue; struct Value *MemberValue;
@ -92,30 +91,30 @@ void TypeParseStruct(struct LexState *Lexer, struct ValueType **Typ, int IsStruc
if (LexGetToken(Lexer, &LexValue) != TokenIdentifier) if (LexGetToken(Lexer, &LexValue) != TokenIdentifier)
ProgramFail(Lexer, "struct/union name required"); ProgramFail(Lexer, "struct/union name required");
if (LexGetPlainToken(Lexer) != TokenOpenBrace) if (LexGetPlainToken(Lexer) != TokenLeftBrace)
ProgramFail(Lexer, "'{' expected"); ProgramFail(Lexer, "'{' expected");
if (StackLevel != 0) if (StackUsed != 0)
ProgramFail(Lexer, "struct/union definitions can only be globals"); ProgramFail(Lexer, "struct/union definitions can only be globals");
*Typ = TypeGetMatching(Lexer, &UberType, IsStruct ? TypeStruct : TypeUnion, 0, &LexValue.String); *Typ = TypeGetMatching(Lexer, &UberType, IsStruct ? TypeStruct : TypeUnion, 0, &LexValue.String);
(*Typ)->Members = VariableAlloc(sizeof(struct Table) + STRUCT_TABLE_SIZE * sizeof(struct TableEntry)); (*Typ)->Members = VariableAlloc(Lexer, sizeof(struct Table) + STRUCT_TABLE_SIZE * sizeof(struct TableEntry));
(*Typ)->Members->HashTable = (struct Table *)((void *)(*Typ)->Members + sizeof(struct Table)); (*Typ)->Members->HashTable = (void *)(*Typ)->Members + sizeof(struct Table);
do { do {
TypeParse(Lexer, &MemberType, &MemberIdentifier); TypeParse(Lexer, &MemberType, &MemberIdentifier);
MemberValue = VariableAllocValueAndData(Lexer, sizeof(int)); MemberValue = VariableAllocValueAndData(Lexer, sizeof(int));
MemberValue->MustFree = TRUE; MemberValue->MustFree = TRUE;
MemberValue->Typ = &MemberType; MemberValue->Typ = MemberType;
if (IsStruct) if (IsStruct)
{ /* allocate this member's location in the struct */ { /* allocate this member's location in the struct */
MemberValue->Value->Integer = (*Typ)->Sizeof; MemberValue->Val->Integer = (*Typ)->Sizeof;
(*Typ)->Sizeof += MemberValue->Typ->Sizeof; (*Typ)->Sizeof += MemberValue->Typ->Sizeof;
} }
else else
{ /* union members always start at 0, make sure it's big enough to hold the largest member */ { /* 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) if (MemberValue->Typ->Sizeof > (*Typ)->Sizeof)
(*Typ)->Sizeof = MemberValue->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)) if (!TableSet((*Typ)->Members, &MemberIdentifier, MemberValue))
ProgramFail(Lexer, "member '%S' already defined", &MemberIdentifier); ProgramFail(Lexer, "member '%S' already defined", &MemberIdentifier);
} while (LexPeekPlainToken(Lexer) != TokenCloseBrace); } while (LexPeekPlainToken(Lexer) != TokenRightBrace);
LexGetPlainToken(Lexer); 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) void TypeParse(struct LexState *Lexer, struct ValueType **Typ, Str *Identifier)
{ {
struct LexState Before; struct LexState Before;
struct LexToken Token; enum LexToken Token;
union AnyValue LexValue; union AnyValue LexValue;
struct Value ArraySize;
int Done = FALSE; int Done = FALSE;
*Typ = NULL; *Typ = NULL;
@ -160,8 +158,8 @@ void TypeParse(struct LexState *Lexer, struct ValueType **Typ, Str *Identifier)
if (*Typ != NULL) if (*Typ != NULL)
ProgramFail(Lexer, "bad type declaration"); ProgramFail(Lexer, "bad type declaration");
TypeParseDeclarator(Lexer, Typ, Identifier); TypeParse(Lexer, Typ, Identifier);
if (LexGetTokenOnly(Lexer) != TokenCloseBracket) if (LexGetPlainToken(Lexer) != TokenCloseBracket)
ProgramFail(Lexer, "')' expected"); ProgramFail(Lexer, "')' expected");
break; break;
@ -169,11 +167,11 @@ void TypeParse(struct LexState *Lexer, struct ValueType **Typ, Str *Identifier)
if (*Typ == NULL) if (*Typ == NULL)
ProgramFail(Lexer, "bad type declaration"); ProgramFail(Lexer, "bad type declaration");
*Typ = TypeGetMatching(Lexer, *Typ, TypePointer, 0); *Typ = TypeGetMatching(Lexer, *Typ, TypePointer, 0, &StrEmpty);
break; break;
case TokenIdentifier: case TokenIdentifier:
if (*Typ == NULL || Identifier->Length != 0) if (*Typ == NULL || Identifier->Len != 0)
ProgramFail(Lexer, "bad type declaration"); ProgramFail(Lexer, "bad type declaration");
*Identifier = LexValue.String; *Identifier = LexValue.String;
@ -187,26 +185,32 @@ void TypeParse(struct LexState *Lexer, struct ValueType **Typ, Str *Identifier)
if (*Typ == NULL) if (*Typ == NULL)
ProgramFail(Lexer, "bad type declaration"); ProgramFail(Lexer, "bad type declaration");
if (Identifier->Length != 0) if (Identifier->Len != 0)
{ /* parse stuff after the identifier */ { /* parse stuff after the identifier */
Done = FALSE; Done = FALSE;
while (!Done) while (!Done)
{ {
Before = *Lexer; Before = *Lexer;
switch (LexGetTokenOnly(Lexer)) switch (LexGetPlainToken(Lexer))
{ {
case TokenOpenSquareBracket: case TokenLeftSquareBracket:
{ {
struct Value ArraySize; struct Value *ArraySizeValue;
union AnyValue ArraySizeAnyValue; int ArraySize = 0;
ArraySize->Val = &ArraySizeAnyValue;
if (!ParseExpression(Lexer, &ArraySize, TRUE))
ArraySize->Val->Integer = 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"); ProgramFail(Lexer, "']' expected");
*Typ = TypeGetMatching(Lexer, *Typ, TypeArray, ArraySize->Val->Integer); *Typ = TypeGetMatching(Lexer, *Typ, TypeArray, ArraySize, &StrEmpty);
} }
break; break;

View file

@ -86,6 +86,7 @@ int VariableDefined(Str *Ident)
} }
/* get the value of a variable. must be defined */ /* get the value of a variable. must be defined */
XXX
void VariableGet(struct LexState *Lexer, Str *Ident, struct Value *Val, struct Value **LVal) void VariableGet(struct LexState *Lexer, Str *Ident, struct Value *Val, struct Value **LVal)
{ {
if (StackUsed == 0 || !TableGet(&Stack[StackUsed-1].LocalTable, Ident, LVal)) if (StackUsed == 0 || !TableGet(&Stack[StackUsed-1].LocalTable, Ident, LVal))