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:
parent
b9e1086cbb
commit
4524270e50
4
lex.c
4
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;
|
||||
|
|
16
parse.c
16
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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
13
picoc.h
13
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 */
|
||||
|
|
15
str.c
15
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
58
type.c
58
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;
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in a new issue