Commit fb31458e authored by Kenton Varda's avatar Kenton Varda

Disallow retroactive unionization.

parent 3c418b99
...@@ -33,6 +33,7 @@ import Data.Maybe(mapMaybe) ...@@ -33,6 +33,7 @@ import Data.Maybe(mapMaybe)
import Text.Parsec.Pos(SourcePos, newPos) import Text.Parsec.Pos(SourcePos, newPos)
import Text.Parsec.Error(ParseError, newErrorMessage, Message(Message, Expect)) import Text.Parsec.Error(ParseError, newErrorMessage, Message(Message, Expect))
import Text.Printf(printf) import Text.Printf(printf)
import Util(delimit)
------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------
-- Error helpers -- Error helpers
...@@ -289,7 +290,17 @@ requireNoDuplicateNames decls = Active () (loop (List.sort locatedNames)) where ...@@ -289,7 +290,17 @@ requireNoDuplicateNames decls = Active () (loop (List.sort locatedNames)) where
fieldInUnion name f = case fieldUnion f of fieldInUnion name f = case fieldUnion f of
Nothing -> False Nothing -> False
Just x -> (unionName x) == name Just x -> unionName x == name
requireNoMoreThanOneFieldNumberLessThan name pos num fields = Active () errors where
retroFields = [fieldName f | f <- fields, fieldNumber f < num]
message = printf "No more than one field in a union may have a number less than the \
\union's number, as it is not possible to retroactively unionize fields that \
\had been separate. The following fields of union '%s' have lower numbers: %s"
name (delimit ", " retroFields)
errors = if length retroFields <= 1
then []
else [newErrorMessage (Message message) pos]
------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------
...@@ -378,6 +389,7 @@ compileDecl scope (StructDecl (Located _ name) decls) = ...@@ -378,6 +389,7 @@ compileDecl scope (StructDecl (Located _ name) decls) =
{ structName = name { structName = name
, structParent = scope , structParent = scope
, structFields = [d | DescField d <- members] , structFields = [d | DescField d <- members]
, structUnions = [d | DescUnion d <- members]
, structNestedAliases = [d | DescAlias d <- members] , structNestedAliases = [d | DescAlias d <- members]
, structNestedConstants = [d | DescConstant d <- members] , structNestedConstants = [d | DescConstant d <- members]
, structNestedEnums = [d | DescEnum d <- members] , structNestedEnums = [d | DescEnum d <- members]
...@@ -388,14 +400,16 @@ compileDecl scope (StructDecl (Located _ name) decls) = ...@@ -388,14 +400,16 @@ compileDecl scope (StructDecl (Located _ name) decls) =
, structStatements = statements , structStatements = statements
}))) })))
compileDecl (DescStruct parent) (UnionDecl (Located _ name) (Located _ number) decls) = compileDecl (DescStruct parent) (UnionDecl (Located _ name) (Located numPos number) decls) =
CompiledMemberStatus name (feedback (\desc -> do CompiledMemberStatus name (feedback (\desc -> do
(_, _, options, statements) <- compileChildDecls desc decls (_, _, options, statements) <- compileChildDecls desc decls
fields <- return [f | f <- structFields parent, fieldInUnion name f]
requireNoMoreThanOneFieldNumberLessThan name numPos number fields
return (DescUnion UnionDesc return (DescUnion UnionDesc
{ unionName = name { unionName = name
, unionParent = parent , unionParent = parent
, unionNumber = number , unionNumber = number
, unionFields = [f | f <- structFields parent, fieldInUnion name f] , unionFields = fields
, unionOptions = options , unionOptions = options
, unionStatements = statements , unionStatements = statements
}))) })))
......
...@@ -216,6 +216,7 @@ data StructDesc = StructDesc ...@@ -216,6 +216,7 @@ data StructDesc = StructDesc
{ structName :: String { structName :: String
, structParent :: Desc , structParent :: Desc
, structFields :: [FieldDesc] , structFields :: [FieldDesc]
, structUnions :: [UnionDesc]
, structNestedAliases :: [AliasDesc] , structNestedAliases :: [AliasDesc]
, structNestedConstants :: [ConstantDesc] , structNestedConstants :: [ConstantDesc]
, structNestedEnums :: [EnumDesc] , structNestedEnums :: [EnumDesc]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment