From 45d85111f09b02c028b4e80fba6a644cceb085c8 Mon Sep 17 00:00:00 2001 From: Russell Joyce Date: Tue, 9 Jun 2020 12:30:47 +0100 Subject: [PATCH] Added parsing of volatile qualifier This doesn't affect code execution, but is exposed through TypeParse(). --- README.md | 2 +- clibrary.c | 2 +- expression.c | 4 ++-- interpreter.h | 7 ++++--- lex.c | 5 +++-- parse.c | 8 +++++--- stats.c | 3 ++- stats.h | 2 +- type.c | 18 ++++++++++++------ 9 files changed, 31 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 8948c3f..ca84ad7 100644 --- a/README.md +++ b/README.md @@ -327,7 +327,7 @@ void PlatformLibraryInit() /* define an example structure */ Tokens = LexAnalyse(IntrinsicName, StructDefinition, strlen(StructDefinition), NULL); LexInitParser(&Parser, StructDefinition, Tokens, IntrinsicName, true, false); - TypeParse(&Parser, &ParsedType, &Identifier, &IsStatic); + TypeParse(&Parser, &ParsedType, &Identifier, &IsStatic, &IsVolatile); HeapFree(Tokens); } ``` diff --git a/clibrary.c b/clibrary.c index cb60cd0..73df0b1 100644 --- a/clibrary.c +++ b/clibrary.c @@ -46,7 +46,7 @@ void LibraryAdd(Picoc *pc, struct LibraryFunction *FuncList) strlen((char*)FuncList[Count].Prototype), NULL); LexInitParser(&Parser, pc, FuncList[Count].Prototype, Tokens, IntrinsicName, true, false); - TypeParse(&Parser, &ReturnType, &Identifier, NULL); + TypeParse(&Parser, &ReturnType, &Identifier, NULL, NULL); NewValue = ParseFunctionDefinition(&Parser, ReturnType, Identifier); NewValue->Val->FuncDef.Intrinsic = FuncList[Count].Func; HeapFreeMem(pc, Tokens); diff --git a/expression.c b/expression.c index cce6348..41be219 100644 --- a/expression.c +++ b/expression.c @@ -1469,7 +1469,7 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) char *CastIdentifier; struct Value *CastTypeValue; - TypeParse(Parser, &CastType, &CastIdentifier, NULL); + TypeParse(Parser, &CastType, &CastIdentifier, NULL, NULL); if (LexGetToken(Parser, &LexValue, true) != TokenCloseBracket) ProgramFail(Parser, "brackets not closed"); @@ -1668,7 +1668,7 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) PrefixState = false; ParserCopy(Parser, &PreState); - TypeParse(Parser, &Typ, &Identifier, NULL); + TypeParse(Parser, &Typ, &Identifier, NULL, NULL); TypeValue = VariableAllocValueFromType(Parser->pc, Parser, &Parser->pc->TypeType, false, NULL, false); TypeValue->Val->Typ = Typ; diff --git a/interpreter.h b/interpreter.h index 02b90ae..3f99510 100644 --- a/interpreter.h +++ b/interpreter.h @@ -174,7 +174,8 @@ enum LexToken { /* 0x5c */ TokenEOF, TokenEndOfLine, TokenEndOfFunction, - TokenBackSlash + TokenBackSlash, + TokenVolatileType }; /* used in dynamic memory allocation */ @@ -571,11 +572,11 @@ extern int TypeSizeValue(struct Value *Val, int Compact); extern int TypeStackSizeValue(struct Value *Val); extern int TypeLastAccessibleOffset(Picoc *pc, struct Value *Val); extern int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ, - int *IsStatic); + int *IsStatic, int *IsVolatile); extern void TypeParseIdentPart(struct ParseState *Parser, struct ValueType *BasicTyp, struct ValueType **Typ, char **Identifier); extern void TypeParse(struct ParseState *Parser, struct ValueType **Typ, - char **Identifier, int *IsStatic); + char **Identifier, int *IsStatic, int *IsVolatile); extern struct ValueType *TypeGetMatching(Picoc *pc, struct ParseState *Parser, struct ValueType *ParentType, enum BaseType Base, int ArraySize, const char *Identifier, int AllowDuplicates); extern struct ValueType *TypeCreateOpaqueStruct(Picoc *pc, struct ParseState *Parser, diff --git a/lex.c b/lex.c index 6bce2cb..5c4ef4d 100644 --- a/lex.c +++ b/lex.c @@ -93,7 +93,8 @@ static struct ReservedWord ReservedWords[] = { {"union", TokenUnionType}, {"unsigned", TokenUnsignedType}, {"void", TokenVoidType}, - {"while", TokenWhile} + {"while", TokenWhile}, + {"volatile", TokenVolatileType} }; @@ -848,7 +849,7 @@ enum LexToken LexGetRawToken(struct ParseState *Parser, struct Value **Value, #ifdef DEBUG_LEXER printf("Got token=%02x inc=%d pos=%d\n", Token, IncPos, Parser->CharacterPos); #endif - assert(Token >= TokenNone && Token <= TokenEndOfFunction); + assert(Token >= TokenNone && Token <= TokenVolatileType); return Token; } diff --git a/parse.c b/parse.c index 3f6ce58..08ada95 100644 --- a/parse.c +++ b/parse.c @@ -121,7 +121,7 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, break; } else { /* add a parameter */ - TypeParse(&ParamParser, &ParamType, &ParamIdentifier, NULL); + TypeParse(&ParamParser, &ParamType, &ParamIdentifier, NULL, NULL); if (ParamType->Base == TypeVoid) { /* this isn't a real parameter at all - delete it */ //ParamCount--; @@ -338,6 +338,7 @@ void ParseDeclarationAssignment(struct ParseState *Parser, int ParseDeclaration(struct ParseState *Parser, enum LexToken Token) { int IsStatic = false; + int IsVolatile = false; int FirstVisit = false; char *Identifier; struct ValueType *BasicType; @@ -345,7 +346,7 @@ int ParseDeclaration(struct ParseState *Parser, enum LexToken Token) struct Value *NewVariable = NULL; Picoc *pc = Parser->pc; - TypeParseFront(Parser, &BasicType, &IsStatic); + TypeParseFront(Parser, &BasicType, &IsStatic, &IsVolatile); do { TypeParseIdentPart(Parser, BasicType, &Typ, &Identifier); if ((Token != TokenVoidType && Token != TokenStructType && @@ -576,7 +577,7 @@ void ParseTypedef(struct ParseState *Parser) struct ValueType **TypPtr; struct Value InitValue; - TypeParse(Parser, &Typ, &TypeName, NULL); + TypeParse(Parser, &Typ, &TypeName, NULL, NULL); if (Parser->Mode == RunModeRun) { TypPtr = &Typ; @@ -737,6 +738,7 @@ enum ParseResult ParseStatement(struct ParseState *Parser, case TokenAutoType: case TokenRegisterType: case TokenExternType: + case TokenVolatileType: *Parser = PreState; CheckTrailingSemicolon = ParseDeclaration(Parser, Token); break; diff --git a/stats.c b/stats.c index 6736788..51f1067 100644 --- a/stats.c +++ b/stats.c @@ -111,7 +111,8 @@ struct LexTokenStat LexTokenStats[NO_TOKENS] = { {"TokenEOF", {0, 0, 0, 0, 0, 0, 0}}, {"TokenEndOfLine", {0, 0, 0, 0, 0, 0, 0}}, {"TokenEndOfFunction", {0, 0, 0, 0, 0, 0, 0}}, - {"TokenBackSlash", {0, 0, 0, 0, 0, 0, 0}} + {"TokenBackSlash", {0, 0, 0, 0, 0, 0, 0}}, + {"TokenVolatileType", {0, 0, 0, 0, 0, 0, 0}} }; diff --git a/stats.h b/stats.h index a017c1e..ee70675 100644 --- a/stats.h +++ b/stats.h @@ -8,7 +8,7 @@ #include "interpreter.h" #define NO_RUN_MODES 7 -#define NO_TOKENS 97 +#define NO_TOKENS 98 extern const char *RunModeNames[NO_RUN_MODES]; diff --git a/type.c b/type.c index f998861..7a61a06 100644 --- a/type.c +++ b/type.c @@ -265,7 +265,7 @@ void TypeParseStruct(struct ParseState *Parser, struct ValueType **Typ, STRUCT_TABLE_SIZE, true); do { - TypeParse(Parser, &MemberType, &MemberIdentifier, NULL); + TypeParse(Parser, &MemberType, &MemberIdentifier, NULL, NULL); if (MemberType == NULL || MemberIdentifier == NULL) ProgramFail(Parser, "invalid type in struct"); @@ -393,10 +393,11 @@ void TypeParseEnum(struct ParseState *Parser, struct ValueType **Typ) /* parse a type - just the basic type */ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ, - int *IsStatic) + int *IsStatic, int *IsVolatile) { int Unsigned = false; int StaticQualifier = false; + int VolatileQualifier = false; enum LexToken Token; struct ParseState Before; struct Value *LexerValue; @@ -408,15 +409,20 @@ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ, ParserCopy(&Before, Parser); Token = LexGetToken(Parser, &LexerValue, true); while (Token == TokenStaticType || Token == TokenAutoType || - Token == TokenRegisterType || Token == TokenExternType) { + Token == TokenRegisterType || Token == TokenExternType || + Token == TokenVolatileType) { if (Token == TokenStaticType) StaticQualifier = true; + else if (Token == TokenVolatileType) + VolatileQualifier = true; Token = LexGetToken(Parser, &LexerValue, true); } if (IsStatic != NULL) *IsStatic = StaticQualifier; + if (IsVolatile != NULL) + *IsVolatile = VolatileQualifier; /* handle signed/unsigned with no trailing type */ if (Token == TokenSignedType || Token == TokenUnsignedType) { @@ -541,7 +547,7 @@ void TypeParseIdentPart(struct ParseState *Parser, struct ValueType *BasicTyp, if (*Typ != NULL) ProgramFail(Parser, "bad type declaration"); - TypeParse(Parser, Typ, Identifier, NULL); + TypeParse(Parser, Typ, Identifier, NULL, NULL); if (LexGetToken(Parser, NULL, true) != TokenCloseBracket) ProgramFail(Parser, "')' expected"); break; @@ -577,11 +583,11 @@ void TypeParseIdentPart(struct ParseState *Parser, struct ValueType *BasicTyp, /* parse a type - a complete declaration including identifier */ void TypeParse(struct ParseState *Parser, struct ValueType **Typ, - char **Identifier, int *IsStatic) + char **Identifier, int *IsStatic, int *IsVolatile) { struct ValueType *BasicType; - TypeParseFront(Parser, &BasicType, IsStatic); + TypeParseFront(Parser, &BasicType, IsStatic, IsVolatile); TypeParseIdentPart(Parser, BasicType, Typ, Identifier); }