Added support for extern variable declarations
Effectively just ignores any declarations as global scope is shared across files in PicoC anyway, so the ultimate definition should be enough.
This commit is contained in:
parent
875a635648
commit
d04337125e
|
@ -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, &IsVolatile);
|
||||
TypeParse(&Parser, &ParsedType, &Identifier, &IsStatic, &IsExtern, &IsVolatile);
|
||||
HeapFree(Tokens);
|
||||
}
|
||||
```
|
||||
|
|
9
c-tests/extern.c
Normal file
9
c-tests/extern.c
Normal file
|
@ -0,0 +1,9 @@
|
|||
#include "extern.h"
|
||||
|
||||
int a;
|
||||
|
||||
int main(void) {
|
||||
a = 1;
|
||||
decrement();
|
||||
return a + b;
|
||||
}
|
4
c-tests/extern.h
Normal file
4
c-tests/extern.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
extern int a;
|
||||
extern long b;
|
||||
|
||||
//void decrement();
|
8
c-tests/extern2.c
Normal file
8
c-tests/extern2.c
Normal file
|
@ -0,0 +1,8 @@
|
|||
#include "extern.h"
|
||||
|
||||
long b = 1;
|
||||
|
||||
void decrement() {
|
||||
a--;
|
||||
b--;
|
||||
}
|
|
@ -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, NULL);
|
||||
TypeParse(&Parser, &ReturnType, &Identifier, NULL, NULL, NULL);
|
||||
NewValue = ParseFunctionDefinition(&Parser, ReturnType, Identifier);
|
||||
NewValue->Val->FuncDef.Intrinsic = FuncList[Count].Func;
|
||||
HeapFreeMem(pc, Tokens);
|
||||
|
|
|
@ -1469,7 +1469,7 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
|
|||
char *CastIdentifier;
|
||||
struct Value *CastTypeValue;
|
||||
|
||||
TypeParse(Parser, &CastType, &CastIdentifier, NULL, NULL);
|
||||
TypeParse(Parser, &CastType, &CastIdentifier, NULL, 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, NULL);
|
||||
TypeParse(Parser, &Typ, &Identifier, NULL, NULL, NULL);
|
||||
TypeValue = VariableAllocValueFromType(Parser->pc, Parser,
|
||||
&Parser->pc->TypeType, false, NULL, false);
|
||||
TypeValue->Val->Typ = Typ;
|
||||
|
|
|
@ -575,11 +575,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 *IsVolatile);
|
||||
int *IsStatic, int *IsExtern, 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, int *IsVolatile);
|
||||
char **Identifier, int *IsStatic, int *IsExtern, 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,
|
||||
|
|
10
parse.c
10
parse.c
|
@ -122,7 +122,7 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser,
|
|||
break;
|
||||
} else {
|
||||
/* add a parameter */
|
||||
TypeParse(&ParamParser, &ParamType, &ParamIdentifier, NULL, NULL);
|
||||
TypeParse(&ParamParser, &ParamType, &ParamIdentifier, NULL, NULL, NULL);
|
||||
if (ParamType->Base == TypeVoid) {
|
||||
/* this isn't a real parameter at all - delete it */
|
||||
//ParamCount--;
|
||||
|
@ -339,6 +339,7 @@ void ParseDeclarationAssignment(struct ParseState *Parser,
|
|||
int ParseDeclaration(struct ParseState *Parser, enum LexToken Token)
|
||||
{
|
||||
int IsStatic = false;
|
||||
int IsExtern = false;
|
||||
int IsVolatile = false;
|
||||
int FirstVisit = false;
|
||||
char *Identifier;
|
||||
|
@ -347,7 +348,7 @@ int ParseDeclaration(struct ParseState *Parser, enum LexToken Token)
|
|||
struct Value *NewVariable = NULL;
|
||||
Picoc *pc = Parser->pc;
|
||||
|
||||
TypeParseFront(Parser, &BasicType, &IsStatic, &IsVolatile);
|
||||
TypeParseFront(Parser, &BasicType, &IsStatic, &IsExtern, &IsVolatile);
|
||||
do {
|
||||
TypeParseIdentPart(Parser, BasicType, &Typ, &Identifier);
|
||||
if ((Token != TokenVoidType && Token != TokenStructType &&
|
||||
|
@ -361,7 +362,8 @@ int ParseDeclaration(struct ParseState *Parser, enum LexToken Token)
|
|||
{
|
||||
ParseFunctionDefinition(Parser, Typ, Identifier);
|
||||
return false;
|
||||
} else {
|
||||
} else if (!IsExtern) {
|
||||
/* extern means declaration rather than definition, so ignore */
|
||||
if (Typ == &pc->VoidType && Identifier != pc->StrEmpty)
|
||||
ProgramFail(Parser, "can't define a void variable");
|
||||
|
||||
|
@ -586,7 +588,7 @@ void ParseTypedef(struct ParseState *Parser)
|
|||
struct ValueType **TypPtr;
|
||||
struct Value InitValue;
|
||||
|
||||
TypeParse(Parser, &Typ, &TypeName, NULL, NULL);
|
||||
TypeParse(Parser, &Typ, &TypeName, NULL, NULL, NULL);
|
||||
|
||||
if (Parser->Mode == RunModeRun) {
|
||||
TypPtr = &Typ;
|
||||
|
|
17
type.c
17
type.c
|
@ -265,7 +265,7 @@ void TypeParseStruct(struct ParseState *Parser, struct ValueType **Typ,
|
|||
STRUCT_TABLE_SIZE, true);
|
||||
|
||||
do {
|
||||
TypeParse(Parser, &MemberType, &MemberIdentifier, NULL, NULL);
|
||||
TypeParse(Parser, &MemberType, &MemberIdentifier, NULL, 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 *IsVolatile)
|
||||
int *IsStatic, int *IsExtern, int *IsVolatile)
|
||||
{
|
||||
int Unsigned = false;
|
||||
int StaticQualifier = false;
|
||||
int ExternQualifier = false;
|
||||
int VolatileQualifier = false;
|
||||
enum LexToken Token;
|
||||
struct ParseState Before;
|
||||
|
@ -414,6 +415,8 @@ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ,
|
|||
Token == TokenVolatileType || Token == TokenConstType) {
|
||||
if (Token == TokenStaticType)
|
||||
StaticQualifier = true;
|
||||
else if (Token == TokenExternType)
|
||||
ExternQualifier = true;
|
||||
else if (Token == TokenVolatileType)
|
||||
VolatileQualifier = true;
|
||||
|
||||
|
@ -427,6 +430,8 @@ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ,
|
|||
FollowToken == TokenVolatileType || FollowToken == TokenConstType) {
|
||||
if (FollowToken == TokenStaticType)
|
||||
StaticQualifier = true;
|
||||
else if (FollowToken == TokenExternType)
|
||||
ExternQualifier = true;
|
||||
else if (FollowToken == TokenVolatileType)
|
||||
VolatileQualifier = true;
|
||||
|
||||
|
@ -436,6 +441,8 @@ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ,
|
|||
|
||||
if (IsStatic != NULL)
|
||||
*IsStatic = StaticQualifier;
|
||||
if (IsExtern != NULL)
|
||||
*IsExtern = ExternQualifier;
|
||||
if (IsVolatile != NULL)
|
||||
*IsVolatile = VolatileQualifier;
|
||||
|
||||
|
@ -570,7 +577,7 @@ void TypeParseIdentPart(struct ParseState *Parser, struct ValueType *BasicTyp,
|
|||
if (*Typ != NULL)
|
||||
ProgramFail(Parser, "bad type declaration");
|
||||
|
||||
TypeParse(Parser, Typ, Identifier, NULL, NULL);
|
||||
TypeParse(Parser, Typ, Identifier, NULL, NULL, NULL);
|
||||
if (LexGetToken(Parser, NULL, true) != TokenCloseBracket)
|
||||
ProgramFail(Parser, "')' expected");
|
||||
break;
|
||||
|
@ -606,11 +613,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, int *IsVolatile)
|
||||
char **Identifier, int *IsStatic, int *IsExtern, int *IsVolatile)
|
||||
{
|
||||
struct ValueType *BasicType;
|
||||
|
||||
TypeParseFront(Parser, &BasicType, IsStatic, IsVolatile);
|
||||
TypeParseFront(Parser, &BasicType, IsStatic, IsExtern, IsVolatile);
|
||||
TypeParseIdentPart(Parser, BasicType, Typ, Identifier);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue