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 '{': 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;

16
parse.c
View file

@ -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]);
}
}

13
picoc.h
View file

@ -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 */

15
str.c
View file

@ -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);
}
}

58
type.c
View file

@ -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;

View file

@ -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))