From a21f1d8a702935a5a9522dae85dce7b9ee3b72be Mon Sep 17 00:00:00 2001 From: "zik.saleeba" Date: Sun, 6 Jun 2010 17:03:15 +0000 Subject: [PATCH] Implemented typedef git-svn-id: http://picoc.googlecode.com/svn/trunk@421 21eae674-98b7-11dd-bd71-f92a316d2d60 --- parse.c | 43 +++++++++++- tests/25_quicksort.c | 148 ++++++++++++++++++++-------------------- tests/39_typedef.c | 22 ++++++ tests/39_typedef.expect | 3 + tests/Makefile | 3 +- type.c | 14 +++- 6 files changed, 152 insertions(+), 81 deletions(-) create mode 100644 tests/39_typedef.c create mode 100644 tests/39_typedef.expect diff --git a/parse.c b/parse.c index 4ca6d44..79f5e16 100644 --- a/parse.c +++ b/parse.c @@ -344,21 +344,54 @@ enum RunMode ParseBlock(struct ParseState *Parser, int AbsorbOpenBrace, int Cond 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 */ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemicolon) { struct Value *CValue; struct Value *LexerValue; + struct Value *VarValue; int Condition; struct ParseState PreState = *Parser; - enum LexToken Token = LexGetToken(Parser, NULL, TRUE); + enum LexToken Token = LexGetToken(Parser, &LexerValue, TRUE); switch (Token) { case TokenEOF: 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 TokenAmpersand: case TokenIncrement: @@ -582,7 +615,11 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi else ExpressionParse(Parser, &CValue); break; - + + case TokenTypedef: + ParseTypedef(Parser); + break; + case TokenDelete: { /* try it as a function or variable name to delete */ diff --git a/tests/25_quicksort.c b/tests/25_quicksort.c index f54881b..ada436d 100644 --- a/tests/25_quicksort.c +++ b/tests/25_quicksort.c @@ -1,79 +1,79 @@ -int array[16]; - -//Swap integer values by array indexes -void swap(int a, int b) -{ - int tmp = array[a]; - array[a] = array[b]; - array[b] = tmp; -} - -//Partition the array into two halves and return the -//index about which the array is partitioned -int partition(int left, int right) -{ - int pivotIndex = left; - int pivotValue = array[pivotIndex]; - int index = left; - int i; - - swap(pivotIndex, right); - for(i = left; i < right; i++) - { - if(array[i] < pivotValue) - { - swap(i, index); - index += 1; - } - } - swap(right, index); - - return index; -} - -//Quicksort the array -void quicksort(int left, int right) -{ - if(left >= right) - return; - - int index = partition(left, right); - quicksort(left, index - 1); - quicksort(index + 1, right); -} - +int array[16]; + +//Swap integer values by array indexes +void swap(int a, int b) +{ + int tmp = array[a]; + array[a] = array[b]; + array[b] = tmp; +} + +//Partition the array into two halves and return the +//index about which the array is partitioned +int partition(int left, int right) +{ + int pivotIndex = left; + int pivotValue = array[pivotIndex]; + int index = left; + int i; + + swap(pivotIndex, right); + for(i = left; i < right; i++) + { + if(array[i] < pivotValue) + { + swap(i, index); + index += 1; + } + } + swap(right, index); + + return index; +} + +//Quicksort the array +void quicksort(int left, int right) +{ + if(left >= right) + return; + + int index = partition(left, right); + quicksort(left, index - 1); + quicksort(index + 1, right); +} + void main() { - 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; + int i; - 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"); -} + 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++) + printf("%d ", array[i]); + + printf("\n"); + + quicksort(0, 15); + + for (i = 0; i < 16; i++) + printf("%d ", array[i]); + + printf("\n"); +} main(); diff --git a/tests/39_typedef.c b/tests/39_typedef.c new file mode 100644 index 0000000..541a493 --- /dev/null +++ b/tests/39_typedef.c @@ -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); diff --git a/tests/39_typedef.expect b/tests/39_typedef.expect new file mode 100644 index 0000000..b9050a9 --- /dev/null +++ b/tests/39_typedef.expect @@ -0,0 +1,3 @@ +1 +12,34 +12,34 diff --git a/tests/Makefile b/tests/Makefile index 2ebcafd..e28faa8 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -31,7 +31,8 @@ TESTS= 00_assignment.test \ 35_sizeof.test \ 36_array_initialisers.test \ 37_sprintf.test \ - 38_multiple_array_index.test + 38_multiple_array_index.test \ + 39_typedef.test %.test: %.expect %.c @echo Test: $*... diff --git a/type.c b/type.c index fe79ee9..a63f765 100644 --- a/type.c +++ b/type.c @@ -315,14 +315,16 @@ void TypeParseEnum(struct ParseState *Parser, struct ValueType **Typ) int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ) { struct ParseState Before = *Parser; - enum LexToken Token = LexGetToken(Parser, NULL, TRUE); + struct Value *LexerValue; + enum LexToken Token = LexGetToken(Parser, &LexerValue, TRUE); int Unsigned = FALSE; + struct Value *VarValue; *Typ = NULL; /* handle signed/unsigned with no trailing type */ if (Token == TokenSignedType || Token == TokenUnsignedType) { - enum LexToken FollowToken = LexGetToken(Parser, NULL, FALSE); + enum LexToken FollowToken = LexGetToken(Parser, &LexerValue, FALSE); Unsigned = (Token == TokenUnsignedType); if (FollowToken != TokenIntType && FollowToken != TokenLongType && FollowToken != TokenShortType && FollowToken != TokenCharType) @@ -335,7 +337,7 @@ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ) return TRUE; } - Token = LexGetToken(Parser, NULL, TRUE); + Token = LexGetToken(Parser, &LexerValue, TRUE); } switch (Token) @@ -362,6 +364,12 @@ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ) TypeParseEnum(Parser, Typ); 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; }