Commit 897276d9 authored by Kenton Varda's avatar Kenton Varda

Unions

parent 4b4c3970
...@@ -251,19 +251,19 @@ compileType scope (TypeExpression n (param:moreParams)) = do ...@@ -251,19 +251,19 @@ compileType scope (TypeExpression n (param:moreParams)) = do
------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------
requireSequentialNumbering :: String -> [Located Integer] -> Status () requireSequentialNumbering :: String -> [Located Integer] -> Status ()
requireSequentialNumbering kind items = Active () (loop 0 sortedItems) where requireSequentialNumbering kind items = Active () (loop undefined (-1) sortedItems) where
sortedItems = List.sort items sortedItems = List.sort items
loop _ [] = [] loop _ _ [] = []
loop expected (Located pos num:rest) = result where loop _ prev (Located pos num:rest) | num == prev + 1 = loop pos num rest
rest' = loop (num + 1) rest loop prevPos prev (Located pos num:rest) | num == prev = err1:err2:loop pos num rest where
result = if num == expected err1 = newErrorMessage (Message message) prevPos
then rest' err2 = newErrorMessage (Message message) pos
else err:rest' where message = printf "Duplicate number %d. %s must be numbered uniquely within their scope."
num kind
loop _ prev (Located pos num:rest) = err:loop pos num rest where
err = newErrorMessage (Message message) pos err = newErrorMessage (Message message) pos
message = printf "Skipped number %d. %s must be numbered sequentially starting \ message = printf "Skipped number %d. %s must be numbered sequentially starting \
\from zero." expected kind \from zero." (prev + 1) kind
maxFieldNumber = 1023
requireFieldNumbersInRange fieldNums = requireFieldNumbersInRange fieldNums =
Active () [ fieldNumError num pos | Located pos num <- fieldNums, num > maxFieldNumber ] where Active () [ fieldNumError num pos | Located pos num <- fieldNums, num > maxFieldNumber ] where
...@@ -287,13 +287,20 @@ requireNoDuplicateNames decls = Active () (loop (List.sort locatedNames)) where ...@@ -287,13 +287,20 @@ requireNoDuplicateNames decls = Active () (loop (List.sort locatedNames)) where
dupError val = newErrorMessage (Message message) where dupError val = newErrorMessage (Message message) where
message = printf "Duplicate declaration \"%s\"." val message = printf "Duplicate declaration \"%s\"." val
fieldInUnion name f = case fieldUnion f of
Nothing -> False
Just x -> (unionName x) == name
------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------
-- For CompiledMemberStatus, the second parameter contains members that should be inserted into the
-- parent's map, e.g. fields defined in a union which should be considered members of the parent
-- struct as well. Usually (except in the case of unions) this map is empty.
data CompiledStatementStatus = CompiledMemberStatus String (Status Desc) data CompiledStatementStatus = CompiledMemberStatus String (Status Desc)
| CompiledOptionStatus (Status OptionAssignmentDesc) | CompiledOptionStatus (Status OptionAssignmentDesc)
toCompiledStatement :: CompiledStatementStatus -> Maybe CompiledStatement toCompiledStatement :: CompiledStatementStatus -> Maybe CompiledStatement
toCompiledStatement (CompiledMemberStatus name (Active desc _)) = Just (CompiledMember desc) toCompiledStatement (CompiledMemberStatus _ (Active desc _)) = Just (CompiledMember desc)
toCompiledStatement (CompiledOptionStatus (Active desc _)) = Just (CompiledOption desc) toCompiledStatement (CompiledOptionStatus (Active desc _)) = Just (CompiledOption desc)
toCompiledStatement _ = Nothing toCompiledStatement _ = Nothing
...@@ -346,22 +353,25 @@ compileDecl scope (EnumDecl (Located _ name) decls) = ...@@ -346,22 +353,25 @@ compileDecl scope (EnumDecl (Located _ name) decls) =
, enumStatements = statements , enumStatements = statements
}))) })))
compileDecl scope (EnumValueDecl (Located _ name) (Located _ number) decls) = compileDecl (DescEnum parent) (EnumValueDecl (Located _ name) (Located _ number) decls) =
CompiledMemberStatus name (feedback (\desc -> do CompiledMemberStatus name (feedback (\desc -> do
(_, _, options, statements) <- compileChildDecls desc decls (_, _, options, statements) <- compileChildDecls desc decls
return (DescEnumValue EnumValueDesc return (DescEnumValue EnumValueDesc
{ enumValueName = name { enumValueName = name
, enumValueParent = scope , enumValueParent = parent
, enumValueNumber = number , enumValueNumber = number
, enumValueOptions = options , enumValueOptions = options
, enumValueStatements = statements , enumValueStatements = statements
}))) })))
compileDecl _ (EnumValueDecl (Located pos name) _ _) =
CompiledMemberStatus name (makeError pos "Enum values can only appear inside enums.")
compileDecl scope (StructDecl (Located _ name) decls) = compileDecl scope (StructDecl (Located _ name) decls) =
CompiledMemberStatus name (feedback (\desc -> do CompiledMemberStatus name (feedback (\desc -> do
(members, memberMap, options, statements) <- compileChildDecls desc decls (members, memberMap, options, statements) <- compileChildDecls desc decls
requireNoDuplicateNames decls requireNoDuplicateNames decls
fieldNums <- return [ num | FieldDecl _ num _ _ _ <- decls ] fieldNums <- return ([ num | FieldDecl _ num _ _ _ _ <- decls ] ++
[ num | UnionDecl _ num _ <- decls ])
requireSequentialNumbering "Fields" fieldNums requireSequentialNumbering "Fields" fieldNums
requireFieldNumbersInRange fieldNums requireFieldNumbersInRange fieldNums
return (DescStruct StructDesc return (DescStruct StructDesc
...@@ -378,8 +388,31 @@ compileDecl scope (StructDecl (Located _ name) decls) = ...@@ -378,8 +388,31 @@ compileDecl scope (StructDecl (Located _ name) decls) =
, structStatements = statements , structStatements = statements
}))) })))
compileDecl scope (FieldDecl (Located _ name) (Located _ number) typeExp defaultValue decls) = compileDecl (DescStruct parent) (UnionDecl (Located _ name) (Located _ number) decls) =
CompiledMemberStatus name (feedback (\desc -> do CompiledMemberStatus name (feedback (\desc -> do
(_, _, options, statements) <- compileChildDecls desc decls
return (DescUnion UnionDesc
{ unionName = name
, unionParent = parent
, unionNumber = number
, unionFields = [f | f <- structFields parent, fieldInUnion name f]
, unionOptions = options
, unionStatements = statements
})))
compileDecl _ (UnionDecl (Located pos name) _ _) =
CompiledMemberStatus name (makeError pos "Unions can only appear inside structs.")
compileDecl scope@(DescStruct parent)
(FieldDecl (Located _ name) (Located _ number) union typeExp defaultValue decls) =
CompiledMemberStatus name (feedback (\desc -> do
unionDesc <- case union of
Nothing -> return Nothing
Just (Located p n) -> do
udesc <- maybeError (descMember n scope) p
(printf "No union '%s' defined in '%s'." n (structName parent))
case udesc of
DescUnion d -> return (Just d)
_ -> makeError p (printf "'%s' is not a union." n)
typeDesc <- compileType scope typeExp typeDesc <- compileType scope typeExp
defaultDesc <- case defaultValue of defaultDesc <- case defaultValue of
Just (Located pos value) -> fmap Just (compileValue pos typeDesc value) Just (Located pos value) -> fmap Just (compileValue pos typeDesc value)
...@@ -387,13 +420,16 @@ compileDecl scope (FieldDecl (Located _ name) (Located _ number) typeExp default ...@@ -387,13 +420,16 @@ compileDecl scope (FieldDecl (Located _ name) (Located _ number) typeExp default
(_, _, options, statements) <- compileChildDecls desc decls (_, _, options, statements) <- compileChildDecls desc decls
return (DescField FieldDesc return (DescField FieldDesc
{ fieldName = name { fieldName = name
, fieldParent = scope , fieldParent = parent
, fieldNumber = number , fieldNumber = number
, fieldUnion = unionDesc
, fieldType = typeDesc , fieldType = typeDesc
, fieldDefaultValue = defaultDesc , fieldDefaultValue = defaultDesc
, fieldOptions = options , fieldOptions = options
, fieldStatements = statements , fieldStatements = statements
}))) })))
compileDecl _ (FieldDecl (Located pos name) _ _ _ _ _) =
CompiledMemberStatus name (makeError pos "Fields can only appear inside structs.")
compileDecl scope (InterfaceDecl (Located _ name) decls) = compileDecl scope (InterfaceDecl (Located _ name) decls) =
CompiledMemberStatus name (feedback (\desc -> do CompiledMemberStatus name (feedback (\desc -> do
...@@ -414,20 +450,23 @@ compileDecl scope (InterfaceDecl (Located _ name) decls) = ...@@ -414,20 +450,23 @@ compileDecl scope (InterfaceDecl (Located _ name) decls) =
, interfaceStatements = statements , interfaceStatements = statements
}))) })))
compileDecl scope (MethodDecl (Located _ name) (Located _ number) params returnType decls) = compileDecl scope@(DescInterface parent)
(MethodDecl (Located _ name) (Located _ number) params returnType decls) =
CompiledMemberStatus name (feedback (\desc -> do CompiledMemberStatus name (feedback (\desc -> do
paramDescs <- doAll (map (compileParam scope) params) paramDescs <- doAll (map (compileParam scope) params)
returnTypeDesc <- compileType scope returnType returnTypeDesc <- compileType scope returnType
(_, _, options, statements) <- compileChildDecls desc decls (_, _, options, statements) <- compileChildDecls desc decls
return (DescMethod MethodDesc return (DescMethod MethodDesc
{ methodName = name { methodName = name
, methodParent = scope , methodParent = parent
, methodNumber = number , methodNumber = number
, methodParams = paramDescs , methodParams = paramDescs
, methodReturnType = returnTypeDesc , methodReturnType = returnTypeDesc
, methodOptions = options , methodOptions = options
, methodStatements = statements , methodStatements = statements
}))) })))
compileDecl _ (MethodDecl (Located pos name) _ _ _ _) =
CompiledMemberStatus name (makeError pos "Methods can only appear inside interfaces.")
compileDecl scope (OptionDecl name (Located valuePos value)) = compileDecl scope (OptionDecl name (Located valuePos value)) =
CompiledOptionStatus (do CompiledOptionStatus (do
......
...@@ -49,8 +49,9 @@ data Declaration = AliasDecl (Located String) DeclName ...@@ -49,8 +49,9 @@ data Declaration = AliasDecl (Located String) DeclName
| EnumDecl (Located String) [Declaration] | EnumDecl (Located String) [Declaration]
| EnumValueDecl (Located String) (Located Integer) [Declaration] | EnumValueDecl (Located String) (Located Integer) [Declaration]
| StructDecl (Located String) [Declaration] | StructDecl (Located String) [Declaration]
| FieldDecl (Located String) (Located Integer) | FieldDecl (Located String) (Located Integer) (Maybe (Located String))
TypeExpression (Maybe (Located FieldValue)) [Declaration] TypeExpression (Maybe (Located FieldValue)) [Declaration]
| UnionDecl (Located String) (Located Integer) [Declaration]
| InterfaceDecl (Located String) [Declaration] | InterfaceDecl (Located String) [Declaration]
| MethodDecl (Located String) (Located Integer) | MethodDecl (Located String) (Located Integer)
[(String, TypeExpression, Maybe (Located FieldValue))] [(String, TypeExpression, Maybe (Located FieldValue))]
...@@ -64,7 +65,8 @@ declarationName (ConstantDecl n _ _) = Just n ...@@ -64,7 +65,8 @@ declarationName (ConstantDecl n _ _) = Just n
declarationName (EnumDecl n _) = Just n declarationName (EnumDecl n _) = Just n
declarationName (EnumValueDecl n _ _) = Just n declarationName (EnumValueDecl n _ _) = Just n
declarationName (StructDecl n _) = Just n declarationName (StructDecl n _) = Just n
declarationName (FieldDecl n _ _ _ _) = Just n declarationName (FieldDecl n _ _ _ _ _) = Just n
declarationName (UnionDecl n _ _) = Just n
declarationName (InterfaceDecl n _) = Just n declarationName (InterfaceDecl n _) = Just n
declarationName (MethodDecl n _ _ _ _) = Just n declarationName (MethodDecl n _ _ _ _) = Just n
declarationName (OptionDecl _ _) = Nothing declarationName (OptionDecl _ _) = Nothing
...@@ -31,11 +31,17 @@ import Text.Parsec.Language (emptyDef) ...@@ -31,11 +31,17 @@ import Text.Parsec.Language (emptyDef)
import Token import Token
keywords = keywords =
[ (ImportKeyword, "import") [ (InKeyword, "in")
, (OfKeyword, "of")
, (AsKeyword, "as")
, (WithKeyword, "with")
, (FromKeyword, "from")
, (ImportKeyword, "import")
, (UsingKeyword, "using") , (UsingKeyword, "using")
, (ConstKeyword, "const") , (ConstKeyword, "const")
, (EnumKeyword, "enum") , (EnumKeyword, "enum")
, (StructKeyword, "struct") , (StructKeyword, "struct")
, (UnionKeyword, "union")
, (InterfaceKeyword, "interface") , (InterfaceKeyword, "interface")
, (OptionKeyword, "option") , (OptionKeyword, "option")
] ]
......
...@@ -43,13 +43,19 @@ tokenErrorString Colon = "\":\"" ...@@ -43,13 +43,19 @@ tokenErrorString Colon = "\":\""
tokenErrorString Period = "\".\"" tokenErrorString Period = "\".\""
tokenErrorString EqualsSign = "\"=\"" tokenErrorString EqualsSign = "\"=\""
tokenErrorString MinusSign = "\"-\"" tokenErrorString MinusSign = "\"-\""
tokenErrorString ImportKeyword = "\"import\"" tokenErrorString InKeyword = "keyword \"in\""
tokenErrorString UsingKeyword = "\"using\"" tokenErrorString OfKeyword = "keyword \"of\""
tokenErrorString ConstKeyword = "\"const\"" tokenErrorString AsKeyword = "keyword \"as\""
tokenErrorString EnumKeyword = "\"enum\"" tokenErrorString WithKeyword = "keyword \"with\""
tokenErrorString StructKeyword = "\"struct\"" tokenErrorString FromKeyword = "keyword \"from\""
tokenErrorString InterfaceKeyword = "\"interface\"" tokenErrorString ImportKeyword = "keyword \"import\""
tokenErrorString OptionKeyword = "\"option\"" tokenErrorString UsingKeyword = "keyword \"using\""
tokenErrorString ConstKeyword = "keyword \"const\""
tokenErrorString EnumKeyword = "keyword \"enum\""
tokenErrorString StructKeyword = "keyword \"struct\""
tokenErrorString UnionKeyword = "keyword \"union\""
tokenErrorString InterfaceKeyword = "keyword \"interface\""
tokenErrorString OptionKeyword = "keyword \"option\""
type TokenParser = Parsec [Located Token] [ParseError] type TokenParser = Parsec [Located Token] [ParseError]
...@@ -78,11 +84,13 @@ colon = tokenParser (matchSimpleToken Colon) <?> "\":\"" ...@@ -78,11 +84,13 @@ colon = tokenParser (matchSimpleToken Colon) <?> "\":\""
period = tokenParser (matchSimpleToken Period) <?> "\".\"" period = tokenParser (matchSimpleToken Period) <?> "\".\""
equalsSign = tokenParser (matchSimpleToken EqualsSign) <?> "\"=\"" equalsSign = tokenParser (matchSimpleToken EqualsSign) <?> "\"=\""
minusSign = tokenParser (matchSimpleToken MinusSign) <?> "\"=\"" minusSign = tokenParser (matchSimpleToken MinusSign) <?> "\"=\""
inKeyword = tokenParser (matchSimpleToken InKeyword) <?> "\"in\""
importKeyword = tokenParser (matchSimpleToken ImportKeyword) <?> "\"import\"" importKeyword = tokenParser (matchSimpleToken ImportKeyword) <?> "\"import\""
usingKeyword = tokenParser (matchSimpleToken UsingKeyword) <?> "\"using\"" usingKeyword = tokenParser (matchSimpleToken UsingKeyword) <?> "\"using\""
constKeyword = tokenParser (matchSimpleToken ConstKeyword) <?> "\"const\"" constKeyword = tokenParser (matchSimpleToken ConstKeyword) <?> "\"const\""
enumKeyword = tokenParser (matchSimpleToken EnumKeyword) <?> "\"enum\"" enumKeyword = tokenParser (matchSimpleToken EnumKeyword) <?> "\"enum\""
structKeyword = tokenParser (matchSimpleToken StructKeyword) <?> "\"struct\"" structKeyword = tokenParser (matchSimpleToken StructKeyword) <?> "\"struct\""
unionKeyword = tokenParser (matchSimpleToken UnionKeyword) <?> "\"union\""
interfaceKeyword = tokenParser (matchSimpleToken InterfaceKeyword) <?> "\"interface\"" interfaceKeyword = tokenParser (matchSimpleToken InterfaceKeyword) <?> "\"interface\""
optionKeyword = tokenParser (matchSimpleToken OptionKeyword) <?> "\"option\"" optionKeyword = tokenParser (matchSimpleToken OptionKeyword) <?> "\"option\""
...@@ -110,6 +118,13 @@ typeExpression = do ...@@ -110,6 +118,13 @@ typeExpression = do
suffixes <- option [] (parenthesizedList typeExpression) suffixes <- option [] (parenthesizedList typeExpression)
return (TypeExpression name suffixes) return (TypeExpression name suffixes)
nameWithOrdinal :: TokenParser (Located String, Located Integer)
nameWithOrdinal = do
name <- located identifier
atSign
ordinal <- located literalInt
return (name, ordinal)
topLine :: Maybe [Located Statement] -> TokenParser Declaration topLine :: Maybe [Located Statement] -> TokenParser Declaration
topLine Nothing = optionDecl <|> aliasDecl <|> constantDecl topLine Nothing = optionDecl <|> aliasDecl <|> constantDecl
topLine (Just statements) = typeDecl statements topLine (Just statements) = typeDecl statements
...@@ -162,18 +177,27 @@ structDecl statements = do ...@@ -162,18 +177,27 @@ structDecl statements = do
return (StructDecl name children) return (StructDecl name children)
structLine :: Maybe [Located Statement] -> TokenParser Declaration structLine :: Maybe [Located Statement] -> TokenParser Declaration
structLine Nothing = optionDecl <|> constantDecl <|> fieldDecl [] structLine Nothing = optionDecl <|> constantDecl <|> unionDecl [] <|> fieldDecl []
structLine (Just statements) = typeDecl statements <|> fieldDecl statements structLine (Just statements) = typeDecl statements <|> unionDecl statements <|> fieldDecl statements
unionDecl statements = do
unionKeyword
(name, ordinal) <- nameWithOrdinal
children <- parseBlock unionLine statements
return (UnionDecl name ordinal children)
unionLine :: Maybe [Located Statement] -> TokenParser Declaration
unionLine Nothing = optionDecl <|> fieldDecl []
unionLine (Just statements) = fieldDecl statements
fieldDecl statements = do fieldDecl statements = do
name <- located identifier (name, ordinal) <- nameWithOrdinal
atSign union <- optionMaybe (inKeyword >> located identifier)
ordinal <- located literalInt
colon colon
t <- typeExpression t <- typeExpression
value <- optionMaybe (equalsSign >> located fieldValue) value <- optionMaybe (equalsSign >> located fieldValue)
children <- parseBlock fieldLine statements children <- parseBlock fieldLine statements
return (FieldDecl name ordinal t value children) return (FieldDecl name ordinal union t value children)
negativeFieldValue = liftM (IntegerFieldValue . negate) literalInt negativeFieldValue = liftM (IntegerFieldValue . negate) literalInt
<|> liftM (FloatFieldValue . negate) literalFloat <|> liftM (FloatFieldValue . negate) literalFloat
...@@ -208,9 +232,7 @@ interfaceLine Nothing = optionDecl <|> constantDecl <|> methodDecl [] ...@@ -208,9 +232,7 @@ interfaceLine Nothing = optionDecl <|> constantDecl <|> methodDecl []
interfaceLine (Just statements) = typeDecl statements <|> methodDecl statements interfaceLine (Just statements) = typeDecl statements <|> methodDecl statements
methodDecl statements = do methodDecl statements = do
name <- located identifier (name, ordinal) <- nameWithOrdinal
atSign
ordinal <- located literalInt
params <- parenthesizedList paramDecl params <- parenthesizedList paramDecl
colon colon
t <- typeExpression t <- typeExpression
......
...@@ -33,6 +33,8 @@ import Text.Printf(printf) ...@@ -33,6 +33,8 @@ import Text.Printf(printf)
import Control.Monad(join) import Control.Monad(join)
import Util(delimit) import Util(delimit)
maxFieldNumber = 255
type ByteString = [Word8] type ByteString = [Word8]
data Desc = DescFile FileDesc data Desc = DescFile FileDesc
...@@ -41,6 +43,7 @@ data Desc = DescFile FileDesc ...@@ -41,6 +43,7 @@ data Desc = DescFile FileDesc
| DescEnum EnumDesc | DescEnum EnumDesc
| DescEnumValue EnumValueDesc | DescEnumValue EnumValueDesc
| DescStruct StructDesc | DescStruct StructDesc
| DescUnion UnionDesc
| DescField FieldDesc | DescField FieldDesc
| DescInterface InterfaceDesc | DescInterface InterfaceDesc
| DescMethod MethodDesc | DescMethod MethodDesc
...@@ -54,6 +57,7 @@ descName (DescConstant d) = constantName d ...@@ -54,6 +57,7 @@ descName (DescConstant d) = constantName d
descName (DescEnum d) = enumName d descName (DescEnum d) = enumName d
descName (DescEnumValue d) = enumValueName d descName (DescEnumValue d) = enumValueName d
descName (DescStruct d) = structName d descName (DescStruct d) = structName d
descName (DescUnion d) = unionName d
descName (DescField d) = fieldName d descName (DescField d) = fieldName d
descName (DescInterface d) = interfaceName d descName (DescInterface d) = interfaceName d
descName (DescMethod d) = methodName d descName (DescMethod d) = methodName d
...@@ -65,11 +69,12 @@ descParent (DescFile _) = error "File descriptor has no parent." ...@@ -65,11 +69,12 @@ descParent (DescFile _) = error "File descriptor has no parent."
descParent (DescAlias d) = aliasParent d descParent (DescAlias d) = aliasParent d
descParent (DescConstant d) = constantParent d descParent (DescConstant d) = constantParent d
descParent (DescEnum d) = enumParent d descParent (DescEnum d) = enumParent d
descParent (DescEnumValue d) = enumValueParent d descParent (DescEnumValue d) = DescEnum (enumValueParent d)
descParent (DescStruct d) = structParent d descParent (DescStruct d) = structParent d
descParent (DescField d) = fieldParent d descParent (DescUnion d) = DescStruct (unionParent d)
descParent (DescField d) = DescStruct (fieldParent d)
descParent (DescInterface d) = interfaceParent d descParent (DescInterface d) = interfaceParent d
descParent (DescMethod d) = methodParent d descParent (DescMethod d) = DescInterface (methodParent d)
descParent (DescOption d) = optionParent d descParent (DescOption d) = optionParent d
descParent (DescBuiltinType _) = error "Builtin type has no parent." descParent (DescBuiltinType _) = error "Builtin type has no parent."
descParent DescBuiltinList = error "Builtin type has no parent." descParent DescBuiltinList = error "Builtin type has no parent."
...@@ -200,7 +205,7 @@ data EnumDesc = EnumDesc ...@@ -200,7 +205,7 @@ data EnumDesc = EnumDesc
data EnumValueDesc = EnumValueDesc data EnumValueDesc = EnumValueDesc
{ enumValueName :: String { enumValueName :: String
, enumValueParent :: Desc , enumValueParent :: EnumDesc
, enumValueNumber :: Integer , enumValueNumber :: Integer
, enumValueOptions :: OptionMap , enumValueOptions :: OptionMap
, enumValueStatements :: [CompiledStatement] , enumValueStatements :: [CompiledStatement]
...@@ -220,10 +225,20 @@ data StructDesc = StructDesc ...@@ -220,10 +225,20 @@ data StructDesc = StructDesc
, structStatements :: [CompiledStatement] , structStatements :: [CompiledStatement]
} }
data UnionDesc = UnionDesc
{ unionName :: String
, unionParent :: StructDesc
, unionNumber :: Integer
, unionFields :: [FieldDesc]
, unionOptions :: OptionMap
, unionStatements :: [CompiledStatement]
}
data FieldDesc = FieldDesc data FieldDesc = FieldDesc
{ fieldName :: String { fieldName :: String
, fieldParent :: Desc , fieldParent :: StructDesc
, fieldNumber :: Integer , fieldNumber :: Integer
, fieldUnion :: Maybe UnionDesc
, fieldType :: TypeDesc , fieldType :: TypeDesc
, fieldDefaultValue :: Maybe ValueDesc , fieldDefaultValue :: Maybe ValueDesc
, fieldOptions :: OptionMap , fieldOptions :: OptionMap
...@@ -246,7 +261,7 @@ data InterfaceDesc = InterfaceDesc ...@@ -246,7 +261,7 @@ data InterfaceDesc = InterfaceDesc
data MethodDesc = MethodDesc data MethodDesc = MethodDesc
{ methodName :: String { methodName :: String
, methodParent :: Desc , methodParent :: InterfaceDesc
, methodNumber :: Integer , methodNumber :: Integer
, methodParams :: [(String, TypeDesc, Maybe ValueDesc)] , methodParams :: [(String, TypeDesc, Maybe ValueDesc)]
, methodReturnType :: TypeDesc , methodReturnType :: TypeDesc
...@@ -291,22 +306,27 @@ descToCode indent (DescEnumValue desc) = printf "%s%s = %d%s" indent ...@@ -291,22 +306,27 @@ descToCode indent (DescEnumValue desc) = printf "%s%s = %d%s" indent
descToCode indent (DescStruct desc) = printf "%sstruct %s%s" indent descToCode indent (DescStruct desc) = printf "%sstruct %s%s" indent
(structName desc) (structName desc)
(blockCode indent (structStatements desc)) (blockCode indent (structStatements desc))
descToCode indent (DescField desc) = printf "%s%s@%d: %s%s%s" indent descToCode indent (DescField desc) = printf "%s%s@%d%s: %s%s%s" indent
(fieldName desc) (fieldNumber desc) (fieldName desc) (fieldNumber desc)
(typeName (fieldParent desc) (fieldType desc)) (case fieldUnion desc of { Nothing -> ""; Just u -> " in " ++ unionName u})
(typeName (DescStruct (fieldParent desc)) (fieldType desc))
(case fieldDefaultValue desc of { Nothing -> ""; Just v -> " = " ++ valueString v; }) (case fieldDefaultValue desc of { Nothing -> ""; Just v -> " = " ++ valueString v; })
(maybeBlockCode indent $ fieldStatements desc) (maybeBlockCode indent $ fieldStatements desc)
descToCode indent (DescUnion desc) = printf "%sunion %s@%d%s" indent
(unionName desc) (unionNumber desc)
(maybeBlockCode indent $ unionStatements desc)
descToCode indent (DescInterface desc) = printf "%sinterface %s%s" indent descToCode indent (DescInterface desc) = printf "%sinterface %s%s" indent
(interfaceName desc) (interfaceName desc)
(blockCode indent (interfaceStatements desc)) (blockCode indent (interfaceStatements desc))
descToCode indent (DescMethod desc) = printf "%s%s@%d(%s): %s%s" indent descToCode indent (DescMethod desc) = printf "%s%s@%d(%s): %s%s" indent
(methodName desc) (methodNumber desc) (methodName desc) (methodNumber desc)
(delimit ", " (map paramToCode (methodParams desc))) (delimit ", " (map paramToCode (methodParams desc)))
(typeName (methodParent desc) (methodReturnType desc)) (typeName scope (methodReturnType desc))
(maybeBlockCode indent $ methodStatements desc) where (maybeBlockCode indent $ methodStatements desc) where
paramToCode (name, t, Nothing) = printf "%s: %s" name (typeName (methodParent desc) t) scope = DescInterface (methodParent desc)
paramToCode (name, t, Nothing) = printf "%s: %s" name (typeName scope t)
paramToCode (name, t, Just v) = printf "%s: %s = %s" paramToCode (name, t, Just v) = printf "%s: %s = %s"
name (typeName (methodParent desc) t) (valueString v) name (typeName scope t) (valueString v)
descToCode _ (DescOption _) = error "options not implemented" descToCode _ (DescOption _) = error "options not implemented"
descToCode _ (DescBuiltinType _) = error "Can't print code for builtin type." descToCode _ (DescBuiltinType _) = error "Can't print code for builtin type."
descToCode _ DescBuiltinList = error "Can't print code for builtin type." descToCode _ DescBuiltinList = error "Can't print code for builtin type."
......
...@@ -48,11 +48,17 @@ data Token = Identifier String ...@@ -48,11 +48,17 @@ data Token = Identifier String
| Period | Period
| EqualsSign | EqualsSign
| MinusSign | MinusSign
| InKeyword
| OfKeyword
| AsKeyword
| WithKeyword
| FromKeyword
| ImportKeyword | ImportKeyword
| UsingKeyword | UsingKeyword
| ConstKeyword | ConstKeyword
| EnumKeyword | EnumKeyword
| StructKeyword | StructKeyword
| UnionKeyword
| InterfaceKeyword | InterfaceKeyword
| OptionKeyword | OptionKeyword
deriving (Show, Eq) deriving (Show, Eq)
......
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