diff --git a/parse.c b/parse.c index 17027d4..f1c653a 100644 --- a/parse.c +++ b/parse.c @@ -8,8 +8,8 @@ int ParameterUsed = 0; struct Value ReturnValue; /* local prototypes */ -int ParseExpression(struct LexState *Lexer, struct Value *Result, int RunIt); -void ParseIntExpression(struct LexState *Lexer, struct Value *Result, int RunIt); +int ParseExpression(struct LexState *Lexer, struct Value **Result, int RunIt); +void ParseIntExpression(struct LexState *Lexer, struct Value **Result, int RunIt); int ParseStatement(struct LexState *Lexer, int RunIt); int ParseArguments(struct LexState *Lexer, int RunIt); @@ -26,32 +26,32 @@ void ParseInit() void ParseParameterList(struct LexState *CallLexer, struct LexState *FuncLexer, int RunIt) { struct ValueType *Typ; - union AnyValue Identifier; + Str Identifier; enum LexToken Token = LexGetPlainToken(FuncLexer); /* open bracket */ int ParamCount; for (ParamCount = 0; ParamCount < ParameterUsed; ParamCount++) { - TypeParse(FuncLexer, &Typ); - Token = LexGetToken(FuncLexer, &Identifier); - if (Token != TokenComma && Token != TokenCloseBracket) + TypeParse(FuncLexer, &Typ, &Identifier); + if (Identifier->Len != 0) { /* there's an identifier */ - if (Token != TokenIdentifier) - ProgramFail(FuncLexer, "invalid parameter"); - if (RunIt) { if (Parameter[ParamCount].Typ != Typ) ProgramFail(CallLexer, "parameter %d has the wrong type", ParamCount+1); - VariableDefine(FuncLexer, &Identifier.String, &Parameter[ParamCount]); + VariableDefine(FuncLexer, &Identifier, &Parameter[ParamCount]); } - - Token = LexGetPlainToken(FuncLexer); - if (Token != TokenComma && Token != TokenCloseBracket) - ProgramFail(FuncLexer, "comma expected"); } - } + + Token = LexGetPlainToken(FuncLexer); + if (ParamCount < ParameterUsed-1 && Token != TokenComma) + ProgramFail(FuncLexer, "comma expected"); + } + + if (Token != TokenCloseBracket) + ProgramFail(FuncLexer, "')' expected"); + if (ParameterUsed == 0) Token = LexGetPlainToken(FuncLexer); @@ -60,7 +60,7 @@ void ParseParameterList(struct LexState *CallLexer, struct LexState *FuncLexer, } /* do a function call */ -void ParseFunctionCall(struct LexState *Lexer, struct Value *Result, Str *FuncName, int RunIt) +void ParseFunctionCall(struct LexState *Lexer, struct Value **Result, Str *FuncName, int RunIt) { enum LexToken Token = LexGetPlainToken(Lexer); /* open bracket */ @@ -119,7 +119,7 @@ void ParseFunctionCall(struct LexState *Lexer, struct Value *Result, Str *FuncNa } /* parse a single value */ -int ParseValue(struct LexState *Lexer, struct Value *Result, struct Value **LValue, int RunIt) +int ParseValue(struct LexState *Lexer, struct Value **Result, struct Value **LValue, int RunIt) { struct LexState PreState = *Lexer; enum LexToken Token = LexGetToken(Lexer, Result->Val); @@ -188,7 +188,7 @@ int ParseValue(struct LexState *Lexer, struct Value *Result, struct Value **LVal } /* parse an expression. operator precedence is not supported */ -int ParseExpression(struct LexState *Lexer, struct Value *Result, int RunIt) +int ParseExpression(struct LexState *Lexer, struct Value **Result, int RunIt) { struct Value CurrentValue; struct Value *CurrentLValue; @@ -304,7 +304,7 @@ int ParseExpression(struct LexState *Lexer, struct Value *Result, int RunIt) } /* parse an expression. operator precedence is not supported */ -void ParseIntExpression(struct LexState *Lexer, struct Value *Result, int RunIt) +void ParseIntExpression(struct LexState *Lexer, struct Value **Result, int RunIt) { if (!ParseExpression(Lexer, Result, RunIt)) ProgramFail(Lexer, "expression expected"); @@ -363,7 +363,7 @@ void ParseMacroDefinition(struct LexState *Lexer) ProgramFail(Lexer, "'%S' is already defined", &MacroName.String); } -void ParseFor(struct LexState *Lexer, struct Value *Result, int RunIt) +void ParseFor(struct LexState *Lexer, int RunIt) { struct Value Conditional; struct LexState PreConditional; @@ -485,6 +485,7 @@ int ParseStatement(struct LexState *Lexer, int RunIt) break; case TokenFor: + ParseFor(Lexer, RunIt); break; case TokenSemicolon: break; diff --git a/picoc.h b/picoc.h index aecae5c..8e9c956 100644 --- a/picoc.h +++ b/picoc.h @@ -43,71 +43,22 @@ struct Table; /* lexical tokens */ enum LexToken { - TokenNone, - TokenEOF, - TokenIdentifier, - TokenIntegerConstant, - TokenFPConstant, - TokenStringConstant, - TokenCharacterConstant, - TokenType, - TokenOpenBracket, - TokenCloseBracket, - TokenAssign, - TokenPlus, - TokenMinus, - TokenAsterisk, - TokenSlash, - TokenEquality, - TokenLessThan, - TokenGreaterThan, - TokenLessEqual, - TokenGreaterEqual, - TokenSemicolon, - TokenArrow, - TokenAmpersand, - TokenLeftBrace, - TokenRightBrace, - TokenLeftAngleBracket, - TokenRightAngleBracket, - TokenLogicalAnd, - TokenLogicalOr, - TokenArithmeticOr, - TokenArithmeticExor, - TokenUnaryExor, - TokenUnaryNot, - TokenComma, - TokenDot, - TokenAddAssign, - TokenSubtractAssign, - TokenIncrement, - TokenDecrement, - TokenIntType, - TokenCharType, - TokenFloatType, - TokenDoubleType, - TokenVoidType, - TokenEnumType, - TokenLongType, - TokenSignedType, - TokenShortType, - TokenStructType, - TokenUnionType, - TokenUnsignedType, - TokenTypedef, - TokenDo, - TokenElse, - TokenFor, - TokenIf, - TokenWhile, - TokenBreak, - TokenSwitch, - TokenCase, - TokenDefault, - TokenReturn, - TokenHashDefine, - TokenHashInclude, - TokenEndOfLine + TokenNone, TokenEOF, TokenEndOfLine, + TokenIdentifier, TokenIntegerConstant, TokenFPConstant, TokenStringConstant, TokenCharacterConstant, + TokenOpenBracket, TokenCloseBracket, + TokenAssign, TokenPlus, TokenMinus, TokenAsterisk, TokenSlash, + TokenEquality, TokenLessThan, TokenGreaterThan, TokenLessEqual, TokenGreaterEqual, + TokenSemicolon, TokenComma, TokenDot, + TokenArrow, TokenAmpersand, + TokenLeftBrace, TokenRightBrace, + TokenLeftAngleBracket, TokenRightAngleBracket, + TokenLogicalAnd, TokenLogicalOr, TokenArithmeticOr, TokenArithmeticExor, TokenUnaryExor, TokenUnaryNot, + TokenAddAssign, TokenSubtractAssign, + TokenIncrement, TokenDecrement, + TokenIntType, TokenCharType, TokenFloatType, TokenDoubleType, TokenVoidType, TokenEnumType, + TokenLongType, TokenSignedType, TokenShortType, TokenStructType, TokenUnionType, TokenUnsignedType, TokenTypedef, + TokenDo, TokenElse, TokenFor, TokenIf, TokenWhile, TokenBreak, TokenSwitch, TokenCase, TokenDefault, TokenReturn, + TokenHashDefine, TokenHashInclude }; /* string type so we can use source file strings */ @@ -157,6 +108,7 @@ struct ValueType enum BaseType Base; /* what kind of type this is */ int ArraySize; /* the size of an array type */ int Sizeof; /* the storage required */ + Str Identifier; /* the name of a struct or union */ struct ValueType *FromType; /* the type we're derived from (or NULL) */ struct ValueType *DerivedTypeList; /* first in a list of types derived from this one */ struct ValueType *Next; /* next item in the derived type list */ @@ -235,6 +187,7 @@ extern struct ValueType FunctionType; extern struct ValueType MacroType; /* 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); @@ -267,7 +220,7 @@ void Parse(const Str *FileName, const Str *Source, int RunIt); /* type.c */ void TypeInit(); int TypeSizeof(struct ValueType *Typ); -int TypeParse(struct LexState *Lexer, struct ValueType **Typ, Str *Identifier); +void TypeParse(struct LexState *Lexer, struct ValueType **Typ, Str *Identifier); /* intrinsic.c */ void IntrinsicInit(struct Table *GlobalTable); diff --git a/str.c b/str.c index 4154b96..408f499 100644 --- a/str.c +++ b/str.c @@ -7,6 +7,12 @@ #include "picoc.h" +void StrCopy(Str *Dest, const Str *Source) +{ + Dest->Str = Source->Str; + Dest->Len = Source->Len; +} + void StrToC(char *Dest, int DestSize, const Str *Source) { int CopyLen = min(DestSize-1, Source->Len); diff --git a/type.c b/type.c index 32448e1..6bb7425 100644 --- a/type.c +++ b/type.c @@ -16,11 +16,11 @@ struct ValueType Type_Type; /* add a new type to the set of types we know about */ struct ValueType *TypeAdd(struct LexState *Lexer, struct ValueType *ParentType, enum BaseType Base, int ArraySize, Str *Identifier, int Sizeof) { - struct ValueType *NewType = VariableAlloc(sizeof(struct ValueType)); + struct ValueType *NewType = VariableAlloc(Lexer, sizeof(struct ValueType)); NewType->Base = Base; NewType->ArraySize = ArraySize; NewType->Sizeof = Sizeof; - NewType->Identifier = Identifier; + StrCopy(&NewType->Identifier, Identifier); NewType->Members = NULL; NewType->FromType = ParentType; NewType->DerivedTypeList = NULL; @@ -35,7 +35,7 @@ struct ValueType *TypeGetMatching(struct LexState *Lexer, struct ValueType *Pare { int Sizeof; struct ValueType *ThisType = ParentType->DerivedTypeList; - while (ThisType != NULL && (ThisType->Base != Base || ThisType->ArraySize != ArraySize || !StrEqual(ThisType->Identifier, Identifier)) + while (ThisType != NULL && (ThisType->Base != Base || ThisType->ArraySize != ArraySize || !StrEqual(&ThisType->Identifier, Identifier))) ThisType = ThisType->Next; if (ThisType != NULL) @@ -58,12 +58,12 @@ void TypeAddBaseType(struct ValueType *TypeNode, enum BaseType Base, int Sizeof) TypeNode->Base = Base; TypeNode->ArraySize = 0; TypeNode->Sizeof = Sizeof; - TypeNode->Identifier = Identifier; + StrFromC(&TypeNode->Identifier, ""); TypeNode->Members = NULL; TypeNode->FromType = NULL; TypeNode->DerivedTypeList = NULL; - TypeNode->Next = UberType->DerivedTypeList; - UberType->DerivedTypeList = NewType; + TypeNode->Next = UberType.DerivedTypeList; + UberType.DerivedTypeList = TypeNode; } /* initialise the type system */ @@ -92,7 +92,7 @@ void TypeParseStruct(struct LexState *Lexer, struct ValueType **Typ, int IsStruc if (LexGetToken(Lexer, &LexValue) != TokenIdentifier) ProgramFail(Lexer, "struct/union name required"); - if (LexGetTokenOnly(Lexer) != TokenOpenBrace) + if (LexGetPlainToken(Lexer) != TokenOpenBrace) ProgramFail(Lexer, "'{' expected"); if (StackLevel != 0) @@ -123,9 +123,9 @@ void TypeParseStruct(struct LexState *Lexer, struct ValueType **Typ, int IsStruc if (!TableSet((*Typ)->Members, &MemberIdentifier, MemberValue)) ProgramFail(Lexer, "member '%S' already defined", &MemberIdentifier); - } while (LexPeekTokenOnly(Lexer) != TokenCloseBrace); + } while (LexPeekPlainToken(Lexer) != TokenCloseBrace); - LexGetTokenOnly(Lexer); + LexGetPlainToken(Lexer); } /* parse a type */ @@ -134,6 +134,7 @@ void TypeParse(struct LexState *Lexer, struct ValueType **Typ, Str *Identifier) struct LexState Before; struct LexToken Token; union AnyValue LexValue; + struct Value ArraySize; int Done = FALSE; *Typ = NULL; @@ -195,9 +196,18 @@ void TypeParse(struct LexState *Lexer, struct ValueType **Typ, Str *Identifier) switch (LexGetTokenOnly(Lexer)) { case TokenOpenSquareBracket: - if (ParseExpression(xxx) - XXX - get a closing square bracket - *Typ = TypeGetMatching(Lexer, *Typ, TypeArray, xxx); + { + struct Value ArraySize; + union AnyValue ArraySizeAnyValue; + ArraySize->Val = &ArraySizeAnyValue; + if (!ParseExpression(Lexer, &ArraySize, TRUE)) + ArraySize->Val->Integer = 0; + + if (LexGetTokenOnly(Lexer) != TokenCloseSquareBracket) + ProgramFail(Lexer, "']' expected"); + + *Typ = TypeGetMatching(Lexer, *Typ, TypeArray, ArraySize->Val->Integer); + } break; case TokenOpenBracket: