Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Support For Alignment Specifier In C Struct Declarations #94

Merged
merged 4 commits into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ See http://visq.github.io/language-c/
Currently unsupported C11 constructs:
- static assertion 6.7.10 (`_Static_assert`)
- generic selection 6.5.1.1 (`_Generic`)
- `_Atomic`, `_Alignas`, `_Thread_local`
- `_Atomic`, `_Thread_local`
- Universal character names

Currently unsupported GNU C extensions:
Expand Down
42 changes: 39 additions & 3 deletions src/Language/C/Parser/Parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -1127,10 +1127,8 @@ struct_or_union_specifier :: { CStructUnion }
struct_or_union_specifier
: struct_or_union attrs_opt identifier '{' struct_declaration_list '}'
{% withNodeInfo $1 $ CStruct (unL $1) (Just $3) (Just$ RList.reverse $5) $2 }

| struct_or_union attrs_opt '{' struct_declaration_list '}'
{% withNodeInfo $1 $ CStruct (unL $1) Nothing (Just$ RList.reverse $4) $2 }

| struct_or_union attrs_opt identifier
{% withNodeInfo $1 $ CStruct (unL $1) (Just $3) Nothing $2 }

Expand All @@ -1145,7 +1143,8 @@ struct_declaration_list :: { Reversed [CDecl] }
struct_declaration_list
: {- empty -} { RList.empty }
| struct_declaration_list ';' { $1 }
| struct_declaration_list struct_declaration { $1 `RList.snoc` $2 }
| struct_declaration_list struct_declaration { $1 `RList.snoc` ( if ( containsAlign $1 ) then ( addAlign $2 ( getAlign $1 ) ) else $2 ) }
| struct_declaration_list alignment_specifier struct_declaration { $1 `RList.snoc` ( addAlign $3 $2 )}


-- parse C structure declaration (C99 6.7.2.1)
Expand Down Expand Up @@ -2179,6 +2178,43 @@ attribute_params

{

containsAlign :: Reversed [CDecl] -> Bool
containsAlign (Reversed input) = checkDecls input where
checkDecls :: [CDecl] -> Bool
checkDecls list = foldr (\x -> \y -> ( checkDecl x ) || y ) False list

checkDecl :: CDecl -> Bool
checkDecl ( CDecl list _ _ ) = checkList list

checkList :: [CDeclarationSpecifier NodeInfo] -> Bool
checkList [] = False
checkList ( ( CAlignSpec _ ) : tail ) = True
checkList ( _ : tail ) = checkList tail


getAlign :: Reversed [CDecl] -> CAlignmentSpecifier NodeInfo
getAlign ( Reversed input ) = getDecls input where
getDecls :: [CDecl] -> CAlignmentSpecifier NodeInfo
getDecls ( ( CDecl list _ _ ) : _ ) | listHasAlign list = getFromList list
getDecls ( _ : rest ) = getDecls rest

listHasAlign :: [CDeclarationSpecifier a] -> Bool
listHasAlign list = foldr ( \x -> \y -> ( declSpecHasAlign x ) || y ) False list

declSpecHasAlign :: CDeclarationSpecifier a -> Bool
declSpecHasAlign ( CAlignSpec _ ) = True
declSpecHasAlign _ = False

getFromList :: [CDeclarationSpecifier a ] -> CAlignmentSpecifier a
getFromList [] = error "Internal error: getAlign called on c declaration list with no alignment"
getFromList ( ( CAlignSpec x ) : _ ) = x
getFromList ( _ : rest ) = getFromList rest



addAlign :: CDecl -> CAlignmentSpecifier NodeInfo -> CDecl
addAlign ( CDecl list list2 a ) align = CDecl ( (CAlignSpec align) : list ) list2 a

-- sometimes it is neccessary to reverse an unreversed list
reverseList :: [a] -> Reversed [a]
reverseList = Reversed . List.reverse
Expand Down
Loading