Implemented typedef

git-svn-id: http://picoc.googlecode.com/svn/trunk@421 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2010-06-06 17:03:15 +00:00
parent a591133f35
commit a21f1d8a70
6 changed files with 152 additions and 81 deletions

43
parse.c
View file

@ -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 */

View file

@ -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
View 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
View file

@ -0,0 +1,3 @@
1
12,34
12,34

View file

@ -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
View file

@ -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;
} }