Commit 4b4c3970 authored by Kenton Varda's avatar Kenton Varda

More misc stuff.

parent f0877237
...@@ -289,24 +289,31 @@ requireNoDuplicateNames decls = Active () (loop (List.sort locatedNames)) where ...@@ -289,24 +289,31 @@ requireNoDuplicateNames decls = Active () (loop (List.sort locatedNames)) where
------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------
data CompiledDecl = CompiledMember String (Status Desc) data CompiledStatementStatus = CompiledMemberStatus String (Status Desc)
| CompiledOption (Status OptionAssignmentDesc) | CompiledOptionStatus (Status OptionAssignmentDesc)
compiledErrors (CompiledMember _ status) = statusErrors status toCompiledStatement :: CompiledStatementStatus -> Maybe CompiledStatement
compiledErrors (CompiledOption status) = statusErrors status toCompiledStatement (CompiledMemberStatus name (Active desc _)) = Just (CompiledMember desc)
toCompiledStatement (CompiledOptionStatus (Active desc _)) = Just (CompiledOption desc)
toCompiledStatement _ = Nothing
compileChildDecls :: Desc -> [Declaration] -> Status ([Desc], MemberMap, OptionMap) compiledErrors (CompiledMemberStatus _ status) = statusErrors status
compileChildDecls desc decls = Active (members, memberMap, options) errors where compiledErrors (CompiledOptionStatus status) = statusErrors status
compileChildDecls :: Desc -> [Declaration]
-> Status ([Desc], MemberMap, OptionMap, [CompiledStatement])
compileChildDecls desc decls = Active (members, memberMap, options, statements) errors where
compiledDecls = map (compileDecl desc) decls compiledDecls = map (compileDecl desc) decls
memberMap = Map.fromList memberPairs memberMap = Map.fromList memberPairs
members = [member | (_, Just member) <- memberPairs] members = [member | (_, Just member) <- memberPairs]
memberPairs = [(name, statusToMaybe status) | CompiledMember name status <- compiledDecls] memberPairs = [(name, statusToMaybe status) | CompiledMemberStatus name status <- compiledDecls]
options = Map.fromList [(optionName (optionAssignmentOption o), o) options = Map.fromList [(optionName (optionAssignmentOption o), o)
| CompiledOption (Active o _) <- compiledDecls] | CompiledOptionStatus (Active o _) <- compiledDecls]
errors = concatMap compiledErrors compiledDecls errors = concatMap compiledErrors compiledDecls
statements = mapMaybe toCompiledStatement compiledDecls
compileDecl scope (AliasDecl (Located _ name) target) = compileDecl scope (AliasDecl (Located _ name) target) =
CompiledMember name (do CompiledMemberStatus name (do
targetDesc <- lookupDesc scope target targetDesc <- lookupDesc scope target
return (DescAlias AliasDesc return (DescAlias AliasDesc
{ aliasName = name { aliasName = name
...@@ -315,7 +322,7 @@ compileDecl scope (AliasDecl (Located _ name) target) = ...@@ -315,7 +322,7 @@ compileDecl scope (AliasDecl (Located _ name) target) =
})) }))
compileDecl scope (ConstantDecl (Located _ name) t (Located valuePos value)) = compileDecl scope (ConstantDecl (Located _ name) t (Located valuePos value)) =
CompiledMember name (do CompiledMemberStatus name (do
typeDesc <- compileType scope t typeDesc <- compileType scope t
valueDesc <- compileValue valuePos typeDesc value valueDesc <- compileValue valuePos typeDesc value
return (DescConstant ConstantDesc return (DescConstant ConstantDesc
...@@ -326,8 +333,8 @@ compileDecl scope (ConstantDecl (Located _ name) t (Located valuePos value)) = ...@@ -326,8 +333,8 @@ compileDecl scope (ConstantDecl (Located _ name) t (Located valuePos value)) =
})) }))
compileDecl scope (EnumDecl (Located _ name) decls) = compileDecl scope (EnumDecl (Located _ name) decls) =
CompiledMember name (feedback (\desc -> do CompiledMemberStatus name (feedback (\desc -> do
(members, memberMap, options) <- compileChildDecls desc decls (members, memberMap, options, statements) <- compileChildDecls desc decls
requireNoDuplicateNames decls requireNoDuplicateNames decls
requireSequentialNumbering "Enum values" [ num | EnumValueDecl _ num _ <- decls ] requireSequentialNumbering "Enum values" [ num | EnumValueDecl _ num _ <- decls ]
return (DescEnum EnumDesc return (DescEnum EnumDesc
...@@ -335,23 +342,24 @@ compileDecl scope (EnumDecl (Located _ name) decls) = ...@@ -335,23 +342,24 @@ compileDecl scope (EnumDecl (Located _ name) decls) =
, enumParent = scope , enumParent = scope
, enumValues = [d | DescEnumValue d <- members] , enumValues = [d | DescEnumValue d <- members]
, enumOptions = options , enumOptions = options
, enumMembers = members
, enumMemberMap = memberMap , enumMemberMap = memberMap
, enumStatements = statements
}))) })))
compileDecl scope (EnumValueDecl (Located _ name) (Located _ number) decls) = compileDecl scope (EnumValueDecl (Located _ name) (Located _ number) decls) =
CompiledMember name (feedback (\desc -> do CompiledMemberStatus name (feedback (\desc -> do
(_, _, options) <- compileChildDecls desc decls (_, _, options, statements) <- compileChildDecls desc decls
return (DescEnumValue EnumValueDesc return (DescEnumValue EnumValueDesc
{ enumValueName = name { enumValueName = name
, enumValueParent = scope , enumValueParent = scope
, enumValueNumber = number , enumValueNumber = number
, enumValueOptions = options , enumValueOptions = options
, enumValueStatements = statements
}))) })))
compileDecl scope (StructDecl (Located _ name) decls) = compileDecl scope (StructDecl (Located _ name) decls) =
CompiledMember name (feedback (\desc -> do CompiledMemberStatus name (feedback (\desc -> do
(members, memberMap, options) <- 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 ]
requireSequentialNumbering "Fields" fieldNums requireSequentialNumbering "Fields" fieldNums
...@@ -366,17 +374,17 @@ compileDecl scope (StructDecl (Located _ name) decls) = ...@@ -366,17 +374,17 @@ compileDecl scope (StructDecl (Located _ name) decls) =
, structNestedStructs = [d | DescStruct d <- members] , structNestedStructs = [d | DescStruct d <- members]
, structNestedInterfaces = [d | DescInterface d <- members] , structNestedInterfaces = [d | DescInterface d <- members]
, structOptions = options , structOptions = options
, structMembers = members
, structMemberMap = memberMap , structMemberMap = memberMap
, structStatements = statements
}))) })))
compileDecl scope (FieldDecl (Located _ name) (Located _ number) typeExp defaultValue decls) = compileDecl scope (FieldDecl (Located _ name) (Located _ number) typeExp defaultValue decls) =
CompiledMember name (feedback (\desc -> do CompiledMemberStatus name (feedback (\desc -> do
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)
Nothing -> return Nothing Nothing -> return Nothing
(_, _, options) <- compileChildDecls desc decls (_, _, options, statements) <- compileChildDecls desc decls
return (DescField FieldDesc return (DescField FieldDesc
{ fieldName = name { fieldName = name
, fieldParent = scope , fieldParent = scope
...@@ -384,11 +392,12 @@ compileDecl scope (FieldDecl (Located _ name) (Located _ number) typeExp default ...@@ -384,11 +392,12 @@ compileDecl scope (FieldDecl (Located _ name) (Located _ number) typeExp default
, fieldType = typeDesc , fieldType = typeDesc
, fieldDefaultValue = defaultDesc , fieldDefaultValue = defaultDesc
, fieldOptions = options , fieldOptions = options
, fieldStatements = statements
}))) })))
compileDecl scope (InterfaceDecl (Located _ name) decls) = compileDecl scope (InterfaceDecl (Located _ name) decls) =
CompiledMember name (feedback (\desc -> do CompiledMemberStatus name (feedback (\desc -> do
(members, memberMap, options) <- compileChildDecls desc decls (members, memberMap, options, statements) <- compileChildDecls desc decls
requireNoDuplicateNames decls requireNoDuplicateNames decls
requireSequentialNumbering "Methods" [ num | MethodDecl _ num _ _ _ <- decls ] requireSequentialNumbering "Methods" [ num | MethodDecl _ num _ _ _ <- decls ]
return (DescInterface InterfaceDesc return (DescInterface InterfaceDesc
...@@ -401,15 +410,15 @@ compileDecl scope (InterfaceDecl (Located _ name) decls) = ...@@ -401,15 +410,15 @@ compileDecl scope (InterfaceDecl (Located _ name) decls) =
, interfaceNestedStructs = [d | DescStruct d <- members] , interfaceNestedStructs = [d | DescStruct d <- members]
, interfaceNestedInterfaces = [d | DescInterface d <- members] , interfaceNestedInterfaces = [d | DescInterface d <- members]
, interfaceOptions = options , interfaceOptions = options
, interfaceMembers = members
, interfaceMemberMap = memberMap , interfaceMemberMap = memberMap
, interfaceStatements = statements
}))) })))
compileDecl scope (MethodDecl (Located _ name) (Located _ number) params returnType decls) = compileDecl scope (MethodDecl (Located _ name) (Located _ number) params returnType decls) =
CompiledMember 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) <- compileChildDecls desc decls (_, _, options, statements) <- compileChildDecls desc decls
return (DescMethod MethodDesc return (DescMethod MethodDesc
{ methodName = name { methodName = name
, methodParent = scope , methodParent = scope
...@@ -417,17 +426,19 @@ compileDecl scope (MethodDecl (Located _ name) (Located _ number) params returnT ...@@ -417,17 +426,19 @@ compileDecl scope (MethodDecl (Located _ name) (Located _ number) params returnT
, methodParams = paramDescs , methodParams = paramDescs
, methodReturnType = returnTypeDesc , methodReturnType = returnTypeDesc
, methodOptions = options , methodOptions = options
, methodStatements = statements
}))) })))
compileDecl scope (OptionDecl name (Located valuePos value)) = compileDecl scope (OptionDecl name (Located valuePos value)) =
CompiledOption (do CompiledOptionStatus (do
uncheckedOptionDesc <- lookupDesc scope name uncheckedOptionDesc <- lookupDesc scope name
optionDesc <- case uncheckedOptionDesc of optionDesc <- case uncheckedOptionDesc of
(DescOption d) -> return d (DescOption d) -> return d
_ -> makeError (declNamePos name) (printf "'%s' is not an option." (declNameString name)) _ -> makeError (declNamePos name) (printf "'%s' is not an option." (declNameString name))
valueDesc <- compileValue valuePos (optionType optionDesc) value valueDesc <- compileValue valuePos (optionType optionDesc) value
return OptionAssignmentDesc return OptionAssignmentDesc
{ optionAssignmentOption = optionDesc { optionAssignmentParent = scope
, optionAssignmentOption = optionDesc
, optionAssignmentValue = valueDesc , optionAssignmentValue = valueDesc
}) })
...@@ -440,7 +451,7 @@ compileParam scope (name, typeExp, defaultValue) = do ...@@ -440,7 +451,7 @@ compileParam scope (name, typeExp, defaultValue) = do
compileFile name decls = compileFile name decls =
feedback (\desc -> do feedback (\desc -> do
(members, memberMap, options) <- compileChildDecls (DescFile desc) decls (members, memberMap, options, statements) <- compileChildDecls (DescFile desc) decls
requireNoDuplicateNames decls requireNoDuplicateNames decls
return FileDesc return FileDesc
{ fileName = name { fileName = name
...@@ -451,11 +462,17 @@ compileFile name decls = ...@@ -451,11 +462,17 @@ compileFile name decls =
, fileStructs = [d | DescStruct d <- members] , fileStructs = [d | DescStruct d <- members]
, fileInterfaces = [d | DescInterface d <- members] , fileInterfaces = [d | DescInterface d <- members]
, fileOptions = options , fileOptions = options
, fileMembers = members
, fileMemberMap = memberMap , fileMemberMap = memberMap
, fileImportMap = undefined , fileImportMap = undefined
, fileStatements = statements
}) })
parseAndCompileFile filename text = result where parseAndCompileFile filename text = result where
(decls, parseErrors) = parseFile filename text (decls, parseErrors) = parseFile filename text
-- Here we're doing the copmile step even if there were errors in parsing, and just combining
-- all the errors together. This may allow the user to fix more errors per compiler iteration,
-- but it might also be confusing if a parse error causes a subsequent compile error, especially
-- if the compile error ends up being on a line before the parse error (e.g. there's a parse
-- error in a type definition, causing a not-defined error on a field trying to use that type).
-- TODO: Re-evaluate after getting some experience on whether this is annoing.
result = statusAddErrors parseErrors (compileFile filename decls) result = statusAddErrors parseErrors (compileFile filename decls)
...@@ -29,6 +29,7 @@ import Util(delimit) ...@@ -29,6 +29,7 @@ import Util(delimit)
import Text.Parsec.Pos import Text.Parsec.Pos
import Text.Parsec.Error import Text.Parsec.Error
import Text.Printf(printf) import Text.Printf(printf)
import qualified Data.List as List
main::IO() main::IO()
main = do main = do
...@@ -39,17 +40,13 @@ handleFile filename = do ...@@ -39,17 +40,13 @@ handleFile filename = do
text <- readFile filename text <- readFile filename
case parseAndCompileFile filename text of case parseAndCompileFile filename text of
Active desc [] -> print desc Active desc [] -> print desc
Active _ e -> mapM_ printError e Active _ e -> mapM_ printError (List.sortBy compareErrors e)
Failed e -> mapM_ printError e Failed e -> mapM_ printError (List.sortBy compareErrors e)
--printError e = mapM_ printMessage (errorMessages e) where compareErrors a b = compare (errorPos a) (errorPos b)
-- pos = errorPos e
-- f = sourceName pos
-- l = sourceLine pos
-- c = sourceColumn pos
-- printMessage :: Message -> IO ()
-- printMessage m = printf "%s:%d:%d: %s\n" f l c (messageString m)
-- TODO: This is a fairly hacky way to make showErrorMessages' output not suck. We could do better
-- by interpreting the error structure ourselves.
printError e = printf "%s:%d:%d: %s\n" f l c m' where printError e = printf "%s:%d:%d: %s\n" f l c m' where
pos = errorPos e pos = errorPos e
f = sourceName pos f = sourceName pos
...@@ -57,4 +54,4 @@ printError e = printf "%s:%d:%d: %s\n" f l c m' where ...@@ -57,4 +54,4 @@ printError e = printf "%s:%d:%d: %s\n" f l c m' where
c = sourceColumn pos c = sourceColumn pos
m = showErrorMessages "or" "Unknown parse error" "Expected" "Unexpected" "end of expression" m = showErrorMessages "or" "Unknown parse error" "Expected" "Unexpected" "end of expression"
(errorMessages e) (errorMessages e)
m' = delimit "; " (lines m) m' = delimit "; " (List.filter (not . null) (lines m))
...@@ -25,6 +25,7 @@ module Semantics where ...@@ -25,6 +25,7 @@ module Semantics where
import qualified Data.Map as Map import qualified Data.Map as Map
import qualified Data.List as List import qualified Data.List as List
import qualified Data.Maybe as Maybe
import Data.Int (Int8, Int16, Int32, Int64) import Data.Int (Int8, Int16, Int32, Int64)
import Data.Word (Word8, Word16, Word32, Word64) import Data.Word (Word8, Word16, Word32, Word64)
import Data.Char (chr) import Data.Char (chr)
...@@ -89,7 +90,7 @@ builtinTypes = [minBound::BuiltinType .. maxBound::BuiltinType] ...@@ -89,7 +90,7 @@ builtinTypes = [minBound::BuiltinType .. maxBound::BuiltinType]
-- Get in-language name of type. -- Get in-language name of type.
builtinTypeName :: BuiltinType -> String builtinTypeName :: BuiltinType -> String
builtinTypeName = List.drop 7 . show -- drop "Builtin" prefix builtinTypeName = Maybe.fromJust . List.stripPrefix "Builtin" . show
data ValueDesc = VoidDesc data ValueDesc = VoidDesc
| BoolDesc Bool | BoolDesc Bool
...@@ -170,9 +171,9 @@ data FileDesc = FileDesc ...@@ -170,9 +171,9 @@ data FileDesc = FileDesc
, fileStructs :: [StructDesc] , fileStructs :: [StructDesc]
, fileInterfaces :: [InterfaceDesc] , fileInterfaces :: [InterfaceDesc]
, fileOptions :: OptionMap , fileOptions :: OptionMap
, fileMembers :: [Desc]
, fileMemberMap :: MemberMap , fileMemberMap :: MemberMap
, fileImportMap :: Map.Map String FileDesc , fileImportMap :: Map.Map String FileDesc
, fileStatements :: [CompiledStatement]
} }
data AliasDesc = AliasDesc data AliasDesc = AliasDesc
...@@ -193,8 +194,8 @@ data EnumDesc = EnumDesc ...@@ -193,8 +194,8 @@ data EnumDesc = EnumDesc
, enumParent :: Desc , enumParent :: Desc
, enumValues :: [EnumValueDesc] , enumValues :: [EnumValueDesc]
, enumOptions :: OptionMap , enumOptions :: OptionMap
, enumMembers :: [Desc]
, enumMemberMap :: MemberMap , enumMemberMap :: MemberMap
, enumStatements :: [CompiledStatement]
} }
data EnumValueDesc = EnumValueDesc data EnumValueDesc = EnumValueDesc
...@@ -202,6 +203,7 @@ data EnumValueDesc = EnumValueDesc ...@@ -202,6 +203,7 @@ data EnumValueDesc = EnumValueDesc
, enumValueParent :: Desc , enumValueParent :: Desc
, enumValueNumber :: Integer , enumValueNumber :: Integer
, enumValueOptions :: OptionMap , enumValueOptions :: OptionMap
, enumValueStatements :: [CompiledStatement]
} }
data StructDesc = StructDesc data StructDesc = StructDesc
...@@ -214,8 +216,8 @@ data StructDesc = StructDesc ...@@ -214,8 +216,8 @@ data StructDesc = StructDesc
, structNestedStructs :: [StructDesc] , structNestedStructs :: [StructDesc]
, structNestedInterfaces :: [InterfaceDesc] , structNestedInterfaces :: [InterfaceDesc]
, structOptions :: OptionMap , structOptions :: OptionMap
, structMembers :: [Desc]
, structMemberMap :: MemberMap , structMemberMap :: MemberMap
, structStatements :: [CompiledStatement]
} }
data FieldDesc = FieldDesc data FieldDesc = FieldDesc
...@@ -225,6 +227,7 @@ data FieldDesc = FieldDesc ...@@ -225,6 +227,7 @@ data FieldDesc = FieldDesc
, fieldType :: TypeDesc , fieldType :: TypeDesc
, fieldDefaultValue :: Maybe ValueDesc , fieldDefaultValue :: Maybe ValueDesc
, fieldOptions :: OptionMap , fieldOptions :: OptionMap
, fieldStatements :: [CompiledStatement]
} }
data InterfaceDesc = InterfaceDesc data InterfaceDesc = InterfaceDesc
...@@ -237,8 +240,8 @@ data InterfaceDesc = InterfaceDesc ...@@ -237,8 +240,8 @@ data InterfaceDesc = InterfaceDesc
, interfaceNestedStructs :: [StructDesc] , interfaceNestedStructs :: [StructDesc]
, interfaceNestedInterfaces :: [InterfaceDesc] , interfaceNestedInterfaces :: [InterfaceDesc]
, interfaceOptions :: OptionMap , interfaceOptions :: OptionMap
, interfaceMembers :: [Desc]
, interfaceMemberMap :: MemberMap , interfaceMemberMap :: MemberMap
, interfaceStatements :: [CompiledStatement]
} }
data MethodDesc = MethodDesc data MethodDesc = MethodDesc
...@@ -248,12 +251,14 @@ data MethodDesc = MethodDesc ...@@ -248,12 +251,14 @@ data MethodDesc = MethodDesc
, methodParams :: [(String, TypeDesc, Maybe ValueDesc)] , methodParams :: [(String, TypeDesc, Maybe ValueDesc)]
, methodReturnType :: TypeDesc , methodReturnType :: TypeDesc
, methodOptions :: OptionMap , methodOptions :: OptionMap
, methodStatements :: [CompiledStatement]
} }
type OptionMap = Map.Map String OptionAssignmentDesc type OptionMap = Map.Map String OptionAssignmentDesc
data OptionAssignmentDesc = OptionAssignmentDesc data OptionAssignmentDesc = OptionAssignmentDesc
{ optionAssignmentOption :: OptionDesc { optionAssignmentParent :: Desc
, optionAssignmentOption :: OptionDesc
, optionAssignmentValue :: ValueDesc , optionAssignmentValue :: ValueDesc
} }
...@@ -265,9 +270,12 @@ data OptionDesc = OptionDesc ...@@ -265,9 +270,12 @@ data OptionDesc = OptionDesc
, optionDefaultValue :: Maybe ValueDesc , optionDefaultValue :: Maybe ValueDesc
} }
data CompiledStatement = CompiledMember Desc
| CompiledOption OptionAssignmentDesc
-- TODO: Print options as well as members. Will be ugly-ish. -- TODO: Print options as well as members. Will be ugly-ish.
descToCode :: String -> Desc -> String descToCode :: String -> Desc -> String
descToCode indent (DescFile desc) = concatMap (descToCode indent) (fileMembers desc) descToCode indent (DescFile desc) = concatMap (statementToCode indent) (fileStatements desc)
descToCode indent (DescAlias desc) = printf "%susing %s = %s;\n" indent descToCode indent (DescAlias desc) = printf "%susing %s = %s;\n" indent
(aliasName desc) (aliasName desc)
(descQualifiedName (aliasParent desc) (aliasTarget desc)) (descQualifiedName (aliasParent desc) (aliasTarget desc))
...@@ -275,30 +283,27 @@ descToCode indent (DescConstant desc) = printf "%sconst %s: %s = %s;\n" indent ...@@ -275,30 +283,27 @@ descToCode indent (DescConstant desc) = printf "%sconst %s: %s = %s;\n" indent
(constantName desc) (constantName desc)
(typeName (constantParent desc) (constantType desc)) (typeName (constantParent desc) (constantType desc))
(valueString (constantValue desc)) (valueString (constantValue desc))
descToCode indent (DescEnum desc) = printf "%senum %s {\n%s%s}\n" indent descToCode indent (DescEnum desc) = printf "%senum %s%s" indent
(enumName desc) (enumName desc)
(concatMap (descToCode (" " ++ indent)) (enumMembers desc)) (blockCode indent (enumStatements desc))
indent descToCode indent (DescEnumValue desc) = printf "%s%s = %d%s" indent
descToCode indent (DescEnumValue desc) = printf "%s%s = %d;\n" indent (enumValueName desc) (enumValueNumber desc) (maybeBlockCode indent $ enumValueStatements desc)
(enumValueName desc) (enumValueNumber desc) descToCode indent (DescStruct desc) = printf "%sstruct %s%s" indent
descToCode indent (DescStruct desc) = printf "%sstruct %s {\n%s%s}\n" indent
(structName desc) (structName desc)
(concatMap (descToCode (" " ++ indent)) (structMembers desc)) (blockCode indent (structStatements desc))
indent descToCode indent (DescField desc) = printf "%s%s@%d: %s%s%s" indent
descToCode indent (DescField desc) = printf "%s%s@%d: %s%s;\n" indent
(fieldName desc) (fieldNumber desc) (fieldName desc) (fieldNumber desc)
(typeName (fieldParent desc) (fieldType desc)) (typeName (fieldParent desc) (fieldType desc))
(case fieldDefaultValue desc of { Nothing -> ""; Just v -> " = " ++ valueString v; }) (case fieldDefaultValue desc of { Nothing -> ""; Just v -> " = " ++ valueString v; })
descToCode indent (DescInterface desc) = printf "%sinterface %s {\n%s%s}\n" indent (maybeBlockCode indent $ fieldStatements desc)
descToCode indent (DescInterface desc) = printf "%sinterface %s%s" indent
(interfaceName desc) (interfaceName desc)
(concatMap (descToCode (" " ++ indent)) (interfaceMembers desc)) (blockCode indent (interfaceStatements desc))
indent descToCode indent (DescMethod desc) = printf "%s%s@%d(%s): %s%s" indent
descToCode indent (DescMethod desc) = printf "%s%s@%d(%s): %s;\n" indent
(methodName desc) (methodNumber desc) (methodName desc) (methodNumber desc)
(delimit (map paramToCode (methodParams desc))) (delimit ", " (map paramToCode (methodParams desc)))
(typeName (methodParent desc) (methodReturnType desc)) where (typeName (methodParent desc) (methodReturnType desc))
delimit [] = "" (maybeBlockCode indent $ methodStatements desc) where
delimit (h:t) = h ++ concatMap (", " ++) t
paramToCode (name, t, Nothing) = printf "%s: %s" name (typeName (methodParent desc) t) paramToCode (name, t, Nothing) = printf "%s: %s" name (typeName (methodParent desc) 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 (methodParent desc) t) (valueString v)
...@@ -306,6 +311,22 @@ descToCode _ (DescOption _) = error "options not implemented" ...@@ -306,6 +311,22 @@ 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."
statementToCode :: String -> CompiledStatement -> String
statementToCode indent (CompiledMember desc) = descToCode indent desc
statementToCode indent (CompiledOption desc) = printf "%s%s.%s = %s;\n" indent
(descQualifiedName (optionAssignmentParent desc) $ optionParent $ optionAssignmentOption desc)
(optionName $ optionAssignmentOption desc)
(valueString (optionAssignmentValue desc))
maybeBlockCode :: String -> [CompiledStatement] -> String
maybeBlockCode _ [] = ";\n"
maybeBlockCode indent statements = blockCode indent statements
blockCode :: String -> [CompiledStatement] -> String
blockCode indent statements = printf " {\n%s%s}\n"
(concatMap (statementToCode (" " ++ indent)) statements)
indent
instance Show FileDesc where { show desc = descToCode "" (DescFile desc) } instance Show FileDesc where { show desc = descToCode "" (DescFile desc) }
instance Show AliasDesc where { show desc = descToCode "" (DescAlias desc) } instance Show AliasDesc where { show desc = descToCode "" (DescAlias desc) }
instance Show ConstantDesc where { show desc = descToCode "" (DescConstant desc) } instance Show ConstantDesc where { show desc = descToCode "" (DescConstant desc) }
......
...@@ -23,8 +23,11 @@ ...@@ -23,8 +23,11 @@
module Util where module Util where
delimit delimiter list = concat $ loop list where delimit _ [] = ""
loop ("":t) = loop t delimit delimiter (h:t) = h ++ concatMap (delimiter ++) t
loop (a:"":t) = loop (a:t)
loop (a:b:t) = a:delimiter:loop (b:t) --delimit delimiter list = concat $ loop list where
loop a = a -- loop ("":t) = loop t
-- loop (a:"":t) = loop (a:t)
-- loop (a:b:t) = a:delimiter:loop (b:t)
-- loop a = a
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