enums implemented
git-svn-id: http://picoc.googlecode.com/svn/trunk@180 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
parent
2f5a46681e
commit
23bce9d38a
1
parse.c
1
parse.c
|
@ -350,6 +350,7 @@ int ParseStatement(struct ParseState *Parser)
|
|||
case TokenVoidType:
|
||||
case TokenStructType:
|
||||
case TokenUnionType:
|
||||
case TokenEnumType:
|
||||
*Parser = PreState;
|
||||
ParseDeclaration(Parser, Token);
|
||||
break;
|
||||
|
|
3
picoc.h
3
picoc.h
|
@ -115,7 +115,7 @@ struct ValueType
|
|||
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 */
|
||||
struct Table *Members; /* members of a struct, union or enum */
|
||||
struct Table *Members; /* members of a struct or union */
|
||||
};
|
||||
|
||||
/* function definition */
|
||||
|
@ -170,7 +170,6 @@ struct Value
|
|||
char ValOnHeap; /* the AnyValue is on the heap (but this Value is on the stack) */
|
||||
char ValOnStack; /* the AnyValue is on the stack along with this Value */
|
||||
char IsLValue; /* is modifiable and is allocated somewhere we can usefully modify it */
|
||||
char TempToken; /* temporary token used in expression evaluation */
|
||||
};
|
||||
|
||||
/* hash table data structure */
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
/* get a line of interactive input */
|
||||
char *PlatformGetLine(char *Buf, int MaxLen)
|
||||
{
|
||||
fflush(stdout);
|
||||
return fgets(Buf, MaxLen, stdin);
|
||||
}
|
||||
|
||||
|
|
18
tests/17_enum.c
Normal file
18
tests/17_enum.c
Normal file
|
@ -0,0 +1,18 @@
|
|||
enum fred
|
||||
{
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
d,
|
||||
e = 54,
|
||||
f = 73,
|
||||
g,
|
||||
h
|
||||
} frod;
|
||||
|
||||
printf("%d %d %d %d %d %d %d %d\n", a, b, c, d, e, f, g, h);
|
||||
printf("%d\n", frod);
|
||||
frod = 12;
|
||||
printf("%d\n", frod);
|
||||
frod = e;
|
||||
printf("%d\n", frod);
|
4
tests/17_enum.expect
Normal file
4
tests/17_enum.expect
Normal file
|
@ -0,0 +1,4 @@
|
|||
0 1 2 3 54 73 74 75
|
||||
0
|
||||
12
|
||||
54
|
|
@ -12,7 +12,8 @@ TESTS= 00_assignment.test \
|
|||
12_hashdefine.test \
|
||||
13_integer_literals.test \
|
||||
14_if.test \
|
||||
16_nesting.test
|
||||
16_nesting.test \
|
||||
17_enum.test
|
||||
|
||||
%.test: %.expect %.c
|
||||
@echo Test: $*...
|
||||
|
|
61
type.c
61
type.c
|
@ -175,6 +175,60 @@ void TypeParseStruct(struct ParseState *Parser, struct ValueType **Typ, int IsSt
|
|||
LexGetToken(Parser, NULL, TRUE);
|
||||
}
|
||||
|
||||
/* parse an enum declaration */
|
||||
void TypeParseEnum(struct ParseState *Parser, struct ValueType **Typ)
|
||||
{
|
||||
struct Value *LexValue;
|
||||
struct Value InitValue;
|
||||
enum LexToken Token;
|
||||
struct ValueType *EnumType;
|
||||
int EnumValue = 0;
|
||||
char *EnumIdentifier;
|
||||
|
||||
if (TopStackFrame != NULL)
|
||||
ProgramFail(Parser, "enum definitions can only be globals");
|
||||
|
||||
if (LexGetToken(Parser, &LexValue, TRUE) != TokenIdentifier)
|
||||
ProgramFail(Parser, "enum name required");
|
||||
|
||||
*Typ = &IntType;
|
||||
EnumType = TypeGetMatching(Parser, &UberType, TypeEnum, 0, LexValue->Val->Identifier);
|
||||
Token = LexGetToken(Parser, NULL, FALSE);
|
||||
if (Token != TokenLeftBrace)
|
||||
{ /* use the already defined enum */
|
||||
if ((*Typ)->Members == NULL)
|
||||
ProgramFail(Parser, "enum '%s' isn't defined", LexValue->Val->Identifier);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
LexGetToken(Parser, NULL, TRUE);
|
||||
(*Typ)->Members = &GlobalTable;
|
||||
memset(&InitValue, '\0', sizeof(struct Value));
|
||||
InitValue.Typ = &IntType;
|
||||
InitValue.Val = (union AnyValue *)&EnumValue;
|
||||
do {
|
||||
if (LexGetToken(Parser, &LexValue, TRUE) != TokenIdentifier)
|
||||
ProgramFail(Parser, "identifier expected");
|
||||
|
||||
EnumIdentifier = LexValue->Val->Identifier;
|
||||
if (LexGetToken(Parser, NULL, FALSE) == TokenAssign)
|
||||
{
|
||||
LexGetToken(Parser, NULL, TRUE);
|
||||
EnumValue = ExpressionParseInt(Parser);
|
||||
}
|
||||
|
||||
VariableDefine(Parser, EnumIdentifier, &InitValue);
|
||||
|
||||
Token = LexGetToken(Parser, NULL, TRUE);
|
||||
if (Token != TokenComma && Token != TokenRightBrace)
|
||||
ProgramFail(Parser, "comma expected");
|
||||
|
||||
EnumValue++;
|
||||
|
||||
} while (Token == TokenComma);
|
||||
}
|
||||
|
||||
/* parse a type - just the basic type */
|
||||
int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ)
|
||||
{
|
||||
|
@ -198,6 +252,13 @@ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ)
|
|||
TypeParseStruct(Parser, Typ, Token == TokenStructType);
|
||||
break;
|
||||
|
||||
case TokenEnumType:
|
||||
if (*Typ != NULL)
|
||||
ProgramFail(Parser, "bad type declaration");
|
||||
|
||||
TypeParseEnum(Parser, Typ);
|
||||
break;
|
||||
|
||||
default: *Parser = Before; return FALSE;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue