/* parse a type - the part which is repeated with each identifier in a declaration list */ void TypeParseIdentPart(struct ParseState *Parser, struct ValueType *BasicTyp, struct ValueType **Typ, char **Identifier) { struct ParseState Before; enum LexToken Token; struct Value *LexValue; int Done = FALSE; *Typ = BasicTyp; *Identifier = StrEmpty; while (!Done) { ParserCopy(&Before, Parser); Token = LexGetToken(Parser, &LexValue, TRUE); switch (Token) { case TokenOpenBracket: if (*Typ != NULL) ProgramFail(Parser, "bad type declaration"); TypeParse(Parser, Typ, Identifier, NULL); if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) ProgramFail(Parser, "')' expected"); break; case TokenAsterisk: if (*Typ == NULL) ProgramFail(Parser, "bad type declaration"); *Typ = TypeGetMatching(Parser, *Typ, TypePointer, 0, StrEmpty, TRUE); break; case TokenIdentifier: if (*Typ == NULL || *Identifier != StrEmpty) ProgramFail(Parser, "bad type declaration"); *Identifier = LexValue->Val->Identifier; Done = TRUE; break; default: ParserCopy(Parser, &Before); Done = TRUE; break; } } if (*Typ == NULL) ProgramFail(Parser, "bad type declaration"); if (*Identifier != StrEmpty) { /* parse stuff after the identifier */ *Typ = TypeParseBack(Parser, *Typ); } }
/* parse a type - the part at the end after the identifier. eg. array specifications etc. */ struct ValueType *TypeParseBack(struct ParseState *Parser, struct ValueType *FromType) { enum LexToken Token; struct ParseState Before; ParserCopy(&Before, Parser); Token = LexGetToken(Parser, NULL, TRUE); if (Token == TokenLeftSquareBracket) { /* add another array bound */ if (LexGetToken(Parser, NULL, FALSE) == TokenRightSquareBracket) { /* an unsized array */ LexGetToken(Parser, NULL, TRUE); return TypeGetMatching(Parser, TypeParseBack(Parser, FromType), TypeArray, 0, StrEmpty, TRUE); } else { /* get a numeric array size */ enum RunMode OldMode = Parser->Mode; int ArraySize; Parser->Mode = RunModeRun; ArraySize = ExpressionParseInt(Parser); Parser->Mode = OldMode; if (LexGetToken(Parser, NULL, TRUE) != TokenRightSquareBracket) ProgramFail(Parser, "']' expected"); return TypeGetMatching(Parser, TypeParseBack(Parser, FromType), TypeArray, ArraySize, StrEmpty, TRUE); } } else { /* the type specification has finished */ ParserCopy(Parser, &Before); return FromType; } }