Implemented typedef
git-svn-id: http://picoc.googlecode.com/svn/trunk@421 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
parent
a591133f35
commit
a21f1d8a70
43
parse.c
43
parse.c
|
@ -344,21 +344,54 @@ enum RunMode ParseBlock(struct ParseState *Parser, int AbsorbOpenBrace, int Cond
|
||||||
return Parser->Mode;
|
return Parser->Mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* parse a typedef declaration */
|
||||||
|
void ParseTypedef(struct ParseState *Parser)
|
||||||
|
{
|
||||||
|
struct ValueType *Typ;
|
||||||
|
struct ValueType **TypPtr;
|
||||||
|
char *TypeName;
|
||||||
|
struct Value InitValue;
|
||||||
|
|
||||||
|
TypeParse(Parser, &Typ, &TypeName);
|
||||||
|
|
||||||
|
if (Parser->Mode == RunModeRun)
|
||||||
|
{
|
||||||
|
TypPtr = &Typ;
|
||||||
|
InitValue.Typ = &TypeType;
|
||||||
|
InitValue.Val = (union AnyValue *)TypPtr;
|
||||||
|
VariableDefine(Parser, TypeName, &InitValue, NULL, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* parse a statement */
|
/* parse a statement */
|
||||||
enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemicolon)
|
enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemicolon)
|
||||||
{
|
{
|
||||||
struct Value *CValue;
|
struct Value *CValue;
|
||||||
struct Value *LexerValue;
|
struct Value *LexerValue;
|
||||||
|
struct Value *VarValue;
|
||||||
int Condition;
|
int Condition;
|
||||||
struct ParseState PreState = *Parser;
|
struct ParseState PreState = *Parser;
|
||||||
enum LexToken Token = LexGetToken(Parser, NULL, TRUE);
|
enum LexToken Token = LexGetToken(Parser, &LexerValue, TRUE);
|
||||||
|
|
||||||
switch (Token)
|
switch (Token)
|
||||||
{
|
{
|
||||||
case TokenEOF:
|
case TokenEOF:
|
||||||
return ParseResultEOF;
|
return ParseResultEOF;
|
||||||
|
|
||||||
case TokenIdentifier:
|
case TokenIdentifier:
|
||||||
|
/* might be a typedef-typed variable declaration or it might be an expression */
|
||||||
|
if (VariableDefined(LexerValue->Val->Identifier))
|
||||||
|
{
|
||||||
|
VariableGet(Parser, LexerValue->Val->Identifier, &VarValue);
|
||||||
|
if (VarValue->Typ->Base == Type_Type)
|
||||||
|
{
|
||||||
|
*Parser = PreState;
|
||||||
|
ParseDeclaration(Parser, Token);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* else fallthrough to expression */
|
||||||
|
|
||||||
case TokenAsterisk:
|
case TokenAsterisk:
|
||||||
case TokenAmpersand:
|
case TokenAmpersand:
|
||||||
case TokenIncrement:
|
case TokenIncrement:
|
||||||
|
@ -582,7 +615,11 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi
|
||||||
else
|
else
|
||||||
ExpressionParse(Parser, &CValue);
|
ExpressionParse(Parser, &CValue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TokenTypedef:
|
||||||
|
ParseTypedef(Parser);
|
||||||
|
break;
|
||||||
|
|
||||||
case TokenDelete:
|
case TokenDelete:
|
||||||
{
|
{
|
||||||
/* try it as a function or variable name to delete */
|
/* try it as a function or variable name to delete */
|
||||||
|
|
|
@ -1,79 +1,79 @@
|
||||||
int array[16];
|
int array[16];
|
||||||
|
|
||||||
//Swap integer values by array indexes
|
//Swap integer values by array indexes
|
||||||
void swap(int a, int b)
|
void swap(int a, int b)
|
||||||
{
|
{
|
||||||
int tmp = array[a];
|
int tmp = array[a];
|
||||||
array[a] = array[b];
|
array[a] = array[b];
|
||||||
array[b] = tmp;
|
array[b] = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Partition the array into two halves and return the
|
//Partition the array into two halves and return the
|
||||||
//index about which the array is partitioned
|
//index about which the array is partitioned
|
||||||
int partition(int left, int right)
|
int partition(int left, int right)
|
||||||
{
|
{
|
||||||
int pivotIndex = left;
|
int pivotIndex = left;
|
||||||
int pivotValue = array[pivotIndex];
|
int pivotValue = array[pivotIndex];
|
||||||
int index = left;
|
int index = left;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
swap(pivotIndex, right);
|
swap(pivotIndex, right);
|
||||||
for(i = left; i < right; i++)
|
for(i = left; i < right; i++)
|
||||||
{
|
{
|
||||||
if(array[i] < pivotValue)
|
if(array[i] < pivotValue)
|
||||||
{
|
{
|
||||||
swap(i, index);
|
swap(i, index);
|
||||||
index += 1;
|
index += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
swap(right, index);
|
swap(right, index);
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Quicksort the array
|
//Quicksort the array
|
||||||
void quicksort(int left, int right)
|
void quicksort(int left, int right)
|
||||||
{
|
{
|
||||||
if(left >= right)
|
if(left >= right)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int index = partition(left, right);
|
int index = partition(left, right);
|
||||||
quicksort(left, index - 1);
|
quicksort(left, index - 1);
|
||||||
quicksort(index + 1, right);
|
quicksort(index + 1, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
array[0] = 62;
|
|
||||||
array[1] = 83;
|
|
||||||
array[2] = 4;
|
|
||||||
array[3] = 89;
|
|
||||||
array[4] = 36;
|
|
||||||
array[5] = 21;
|
|
||||||
array[6] = 74;
|
|
||||||
array[7] = 37;
|
|
||||||
array[8] = 65;
|
|
||||||
array[9] = 33;
|
|
||||||
array[10] = 96;
|
|
||||||
array[11] = 38;
|
|
||||||
array[12] = 53;
|
|
||||||
array[13] = 16;
|
|
||||||
array[14] = 74;
|
|
||||||
array[15] = 55;
|
|
||||||
|
|
||||||
for (i = 0; i < 16; i++)
|
array[0] = 62;
|
||||||
printf("%d ", array[i]);
|
array[1] = 83;
|
||||||
|
array[2] = 4;
|
||||||
printf("\n");
|
array[3] = 89;
|
||||||
|
array[4] = 36;
|
||||||
quicksort(0, 15);
|
array[5] = 21;
|
||||||
|
array[6] = 74;
|
||||||
for (i = 0; i < 16; i++)
|
array[7] = 37;
|
||||||
printf("%d ", array[i]);
|
array[8] = 65;
|
||||||
|
array[9] = 33;
|
||||||
printf("\n");
|
array[10] = 96;
|
||||||
}
|
array[11] = 38;
|
||||||
|
array[12] = 53;
|
||||||
|
array[13] = 16;
|
||||||
|
array[14] = 74;
|
||||||
|
array[15] = 55;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
printf("%d ", array[i]);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
quicksort(0, 15);
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
printf("%d ", array[i]);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
main();
|
main();
|
||||||
|
|
||||||
|
|
22
tests/39_typedef.c
Normal file
22
tests/39_typedef.c
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
typedef int MyInt;
|
||||||
|
|
||||||
|
MyInt a = 1;
|
||||||
|
printf("%d\n", a);
|
||||||
|
|
||||||
|
struct FunStruct
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct FunStruct MyFunStruct;
|
||||||
|
|
||||||
|
MyFunStruct b;
|
||||||
|
b.i = 12;
|
||||||
|
b.j = 34;
|
||||||
|
printf("%d,%d\n", b.i, b.j);
|
||||||
|
|
||||||
|
typedef MyFunStruct *MoreFunThanEver;
|
||||||
|
|
||||||
|
MoreFunThanEver c = &b;
|
||||||
|
printf("%d,%d\n", c->i, c->j);
|
3
tests/39_typedef.expect
Normal file
3
tests/39_typedef.expect
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
1
|
||||||
|
12,34
|
||||||
|
12,34
|
|
@ -31,7 +31,8 @@ TESTS= 00_assignment.test \
|
||||||
35_sizeof.test \
|
35_sizeof.test \
|
||||||
36_array_initialisers.test \
|
36_array_initialisers.test \
|
||||||
37_sprintf.test \
|
37_sprintf.test \
|
||||||
38_multiple_array_index.test
|
38_multiple_array_index.test \
|
||||||
|
39_typedef.test
|
||||||
|
|
||||||
%.test: %.expect %.c
|
%.test: %.expect %.c
|
||||||
@echo Test: $*...
|
@echo Test: $*...
|
||||||
|
|
14
type.c
14
type.c
|
@ -315,14 +315,16 @@ void TypeParseEnum(struct ParseState *Parser, struct ValueType **Typ)
|
||||||
int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ)
|
int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ)
|
||||||
{
|
{
|
||||||
struct ParseState Before = *Parser;
|
struct ParseState Before = *Parser;
|
||||||
enum LexToken Token = LexGetToken(Parser, NULL, TRUE);
|
struct Value *LexerValue;
|
||||||
|
enum LexToken Token = LexGetToken(Parser, &LexerValue, TRUE);
|
||||||
int Unsigned = FALSE;
|
int Unsigned = FALSE;
|
||||||
|
struct Value *VarValue;
|
||||||
*Typ = NULL;
|
*Typ = NULL;
|
||||||
|
|
||||||
/* handle signed/unsigned with no trailing type */
|
/* handle signed/unsigned with no trailing type */
|
||||||
if (Token == TokenSignedType || Token == TokenUnsignedType)
|
if (Token == TokenSignedType || Token == TokenUnsignedType)
|
||||||
{
|
{
|
||||||
enum LexToken FollowToken = LexGetToken(Parser, NULL, FALSE);
|
enum LexToken FollowToken = LexGetToken(Parser, &LexerValue, FALSE);
|
||||||
Unsigned = (Token == TokenUnsignedType);
|
Unsigned = (Token == TokenUnsignedType);
|
||||||
|
|
||||||
if (FollowToken != TokenIntType && FollowToken != TokenLongType && FollowToken != TokenShortType && FollowToken != TokenCharType)
|
if (FollowToken != TokenIntType && FollowToken != TokenLongType && FollowToken != TokenShortType && FollowToken != TokenCharType)
|
||||||
|
@ -335,7 +337,7 @@ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token = LexGetToken(Parser, NULL, TRUE);
|
Token = LexGetToken(Parser, &LexerValue, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (Token)
|
switch (Token)
|
||||||
|
@ -362,6 +364,12 @@ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ)
|
||||||
|
|
||||||
TypeParseEnum(Parser, Typ);
|
TypeParseEnum(Parser, Typ);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TokenIdentifier:
|
||||||
|
/* we already know it's a typedef-defined type because we got here */
|
||||||
|
VariableGet(Parser, LexerValue->Val->Identifier, &VarValue);
|
||||||
|
*Typ = VarValue->Val->Typ;
|
||||||
|
break;
|
||||||
|
|
||||||
default: *Parser = Before; return FALSE;
|
default: *Parser = Before; return FALSE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue