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 '|': 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
16
parse.c
|
@ -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
13
picoc.h
|
@ -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
15
str.c
|
@ -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
58
type.c
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
|
|
Loading…
Reference in a new issue