Commit 2c8595bc authored by Kenton Varda's avatar Kenton Varda

Redo IDs. They now look like ordinals, except that they are 64-bit unique integers.

parent 567c2de2
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
$id("v3JF2GP4Supe9JSSJ3pnSdUqhJI"); @0xbdf87d7bb8304e81;
$namespace("capnproto::annotations"); $namespace("capnproto::annotations");
annotation namespace(file): Text; annotation namespace(file): Text;
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@0xf36d7b330303c66e;
using Test = import "test.capnp"; using Test = import "test.capnp";
struct TestImport { struct TestImport {
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@0xd508eebdc2dc42b8;
using Cxx = import "c++.capnp"; using Cxx = import "c++.capnp";
# Use a namespace likely to cause trouble if the generated code doesn't use fully-qualified # Use a namespace likely to cause trouble if the generated code doesn't use fully-qualified
......
...@@ -29,7 +29,8 @@ executable capnpc ...@@ -29,7 +29,8 @@ executable capnpc
filepath, filepath,
directory, directory,
syb, syb,
transformers transformers,
entropy
ghc-options: -Wall -fno-warn-missing-signatures ghc-options: -Wall -fno-warn-missing-signatures
other-modules: other-modules:
Lexer, Lexer,
......
...@@ -25,18 +25,21 @@ module Compiler (Status(..), parseAndCompileFile) where ...@@ -25,18 +25,21 @@ module Compiler (Status(..), parseAndCompileFile) where
import Grammar import Grammar
import Semantics import Semantics
import Token(Located(Located), locatedPos, locatedValue) import Token(Located(Located), locatedValue)
import Parser(parseFile) import Parser(parseFile)
import Control.Monad(when, unless) import Control.Monad(when, unless, liftM)
import qualified Data.Map as Map import qualified Data.Map as Map
import Data.Map((!)) import Data.Map((!))
import qualified Data.Set as Set import qualified Data.Set as Set
import qualified Data.List as List import qualified Data.List as List
import Data.Maybe(mapMaybe, fromMaybe, listToMaybe, catMaybes, isJust) import Data.Maybe(mapMaybe, fromMaybe, isJust, isNothing)
import Data.Word(Word64, Word8)
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) import qualified Data.Digest.MD5 as MD5
import qualified Codec.Binary.UTF8.String as UTF8
import Util(delimit, intToBytes)
------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------
-- Error helpers -- Error helpers
...@@ -164,8 +167,7 @@ builtinTypeMap = Map.fromList ...@@ -164,8 +167,7 @@ builtinTypeMap = Map.fromList
[("List", DescBuiltinList), [("List", DescBuiltinList),
("Inline", DescBuiltinInline), ("Inline", DescBuiltinInline),
("InlineList", DescBuiltinInlineList), ("InlineList", DescBuiltinInlineList),
("InlineData", DescBuiltinInlineData), ("InlineData", DescBuiltinInlineData)])
("id", DescBuiltinId)])
------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------
...@@ -364,43 +366,30 @@ compileType scope (TypeExpression n params) = do ...@@ -364,43 +366,30 @@ compileType scope (TypeExpression n params) = do
printf "'%s' doesn't take parameters." (declNameString n) printf "'%s' doesn't take parameters." (declNameString n)
compileAnnotation :: Desc -> AnnotationTarget -> Annotation compileAnnotation :: Desc -> AnnotationTarget -> Annotation
-> Status (Maybe AnnotationDesc, ValueDesc) -> Status (AnnotationDesc, ValueDesc)
compileAnnotation scope kind (Annotation name (Located pos value)) = do compileAnnotation scope kind (Annotation name (Located pos value)) = do
nameDesc <- lookupDesc scope name nameDesc <- lookupDesc scope name
case nameDesc of case nameDesc of
DescBuiltinId -> do
compiledValue <- compileValue pos (BuiltinType BuiltinText) value
return (Nothing, compiledValue)
DescAnnotation annDesc -> do DescAnnotation annDesc -> do
unless (Set.member kind (annotationTargets annDesc)) unless (Set.member kind (annotationTargets annDesc))
(makeError (declNamePos name) (makeError (declNamePos name)
$ printf "'%s' cannot be used on %s." (declNameString name) (show kind)) $ printf "'%s' cannot be used on %s." (declNameString name) (show kind))
compiledValue <- compileValue pos (annotationType annDesc) value compiledValue <- compileValue pos (annotationType annDesc) value
return (Just annDesc, compiledValue) return (annDesc, compiledValue)
_ -> makeError (declNamePos name) _ -> makeError (declNamePos name)
$ printf "'%s' is not an annotation." (declNameString name) $ printf "'%s' is not an annotation." (declNameString name)
compileAnnotations :: Desc -> AnnotationTarget -> [Annotation] compileAnnotations :: Desc -> AnnotationTarget -> [Annotation]
-> Status (Maybe String, AnnotationMap) -- (id, other annotations) -> Status AnnotationMap
compileAnnotations scope kind annotations = do compileAnnotations scope kind annotations = do
let compileLocated ann@(Annotation name _) = let compileLocated ann@(Annotation name _) =
fmap (Located $ declNamePos name) $ compileAnnotation scope kind ann fmap (Located $ declNamePos name) $ compileAnnotation scope kind ann
compiled <- doAll $ map compileLocated annotations compiled <- doAll $ map compileLocated annotations
-- Makes a map entry for the annotation keyed by ID. Throws out annotations with no ID. -- Makes a map entry for the annotation keyed by ID.
let ids = [ Located pos i | Located pos (Nothing, TextDesc i) <- compiled ] let locatedEntries = [ Located pos (annotationId desc, (desc, v))
theId = fmap locatedValue $ listToMaybe ids | Located pos (desc, v) <- compiled ]
dupIds = map (flip makeError "Duplicate annotation 'id'." . locatedPos) $ List.drop 1 ids
-- For the annotations other than "id", we want to build a map keyed by annotation ID.
-- We drop any annotation that doesn't have an ID.
locatedEntries = catMaybes
[ annotationById pos (desc, v) | Located pos (Just desc, v) <- compiled ]
annotationById pos ann@(desc, _) =
case descAutoId (DescAnnotation desc) of
Just globalId -> Just (Located pos (globalId, ann))
Nothing -> Nothing
-- TODO(cleanup): Generalize duplicate detection. -- TODO(cleanup): Generalize duplicate detection.
sortedLocatedEntries = detectDup $ List.sortBy compareIds locatedEntries sortedLocatedEntries = detectDup $ List.sortBy compareIds locatedEntries
...@@ -411,9 +400,16 @@ compileAnnotations scope kind annotations = do ...@@ -411,9 +400,16 @@ compileAnnotations scope kind annotations = do
detectDup [] = [] detectDup [] = []
finalEntries <- doAll sortedLocatedEntries finalEntries <- doAll sortedLocatedEntries
_ <- doAll dupIds
return (theId, Map.fromList finalEntries) return $ Map.fromList finalEntries
childId :: String -> Maybe (Located Word64) -> Desc -> Word64
childId _ (Just (Located _ myId)) _ = myId
childId name Nothing parent = let
hash = MD5.hash (intToBytes (descId parent) 8 ++ UTF8.encode name)
addByte :: Word64 -> Word8 -> Word64
addByte b v = b * 256 + fromIntegral v
in foldl addByte 0 (take 8 hash)
------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------
...@@ -801,27 +797,26 @@ compileDecl scope (ConstantDecl (Located _ name) t annotations (Located valuePos ...@@ -801,27 +797,26 @@ compileDecl scope (ConstantDecl (Located _ name) t annotations (Located valuePos
CompiledStatementStatus name (do CompiledStatementStatus name (do
typeDesc <- compileType scope t typeDesc <- compileType scope t
valueDesc <- compileValue valuePos typeDesc value valueDesc <- compileValue valuePos typeDesc value
(theId, compiledAnnotations) <- compileAnnotations scope ConstantAnnotation annotations compiledAnnotations <- compileAnnotations scope ConstantAnnotation annotations
return (DescConstant ConstantDesc return (DescConstant ConstantDesc
{ constantName = name { constantName = name
, constantId = theId
, constantParent = scope , constantParent = scope
, constantType = typeDesc , constantType = typeDesc
, constantValue = valueDesc , constantValue = valueDesc
, constantAnnotations = compiledAnnotations , constantAnnotations = compiledAnnotations
})) }))
compileDecl scope (EnumDecl (Located _ name) annotations decls) = compileDecl scope (EnumDecl (Located _ name) maybeTypeId annotations decls) =
CompiledStatementStatus name (feedback (\desc -> do CompiledStatementStatus name (feedback (\desc -> do
(members, memberMap) <- compileChildDecls desc decls (members, memberMap) <- compileChildDecls desc decls
requireNoDuplicateNames decls requireNoDuplicateNames decls
let numbers = [ num | EnumerantDecl _ num _ <- decls ] let numbers = [ num | EnumerantDecl _ num _ <- decls ]
requireSequentialNumbering "Enumerants" numbers requireSequentialNumbering "Enumerants" numbers
requireOrdinalsInRange numbers requireOrdinalsInRange numbers
(theId, compiledAnnotations) <- compileAnnotations scope EnumAnnotation annotations compiledAnnotations <- compileAnnotations scope EnumAnnotation annotations
return (DescEnum EnumDesc return (DescEnum EnumDesc
{ enumName = name { enumName = name
, enumId = theId , enumId = childId name maybeTypeId scope
, enumParent = scope , enumParent = scope
, enumerants = [d | DescEnumerant d <- members] , enumerants = [d | DescEnumerant d <- members]
, enumAnnotations = compiledAnnotations , enumAnnotations = compiledAnnotations
...@@ -832,10 +827,9 @@ compileDecl scope (EnumDecl (Located _ name) annotations decls) = ...@@ -832,10 +827,9 @@ compileDecl scope (EnumDecl (Located _ name) annotations decls) =
compileDecl scope@(DescEnum parent) compileDecl scope@(DescEnum parent)
(EnumerantDecl (Located _ name) (Located _ number) annotations) = (EnumerantDecl (Located _ name) (Located _ number) annotations) =
CompiledStatementStatus name (do CompiledStatementStatus name (do
(theId, compiledAnnotations) <- compileAnnotations scope EnumerantAnnotation annotations compiledAnnotations <- compileAnnotations scope EnumerantAnnotation annotations
return (DescEnumerant EnumerantDesc return (DescEnumerant EnumerantDesc
{ enumerantName = name { enumerantName = name
, enumerantId = theId
, enumerantParent = parent , enumerantParent = parent
, enumerantNumber = number , enumerantNumber = number
, enumerantAnnotations = compiledAnnotations , enumerantAnnotations = compiledAnnotations
...@@ -843,14 +837,14 @@ compileDecl scope@(DescEnum parent) ...@@ -843,14 +837,14 @@ compileDecl scope@(DescEnum parent)
compileDecl _ (EnumerantDecl (Located pos name) _ _) = compileDecl _ (EnumerantDecl (Located pos name) _ _) =
CompiledStatementStatus name (makeError pos "Enumerants can only appear inside enums.") CompiledStatementStatus name (makeError pos "Enumerants can only appear inside enums.")
compileDecl scope (StructDecl (Located _ name) isFixed annotations decls) = compileDecl scope (StructDecl (Located _ name) maybeTypeId isFixed annotations decls) =
CompiledStatementStatus name (feedback (\desc -> do CompiledStatementStatus name (feedback (\desc -> do
(members, memberMap) <- compileChildDecls desc decls (members, memberMap) <- compileChildDecls desc decls
requireNoDuplicateNames decls requireNoDuplicateNames decls
let fieldNums = extractFieldNumbers decls let fieldNums = extractFieldNumbers decls
requireSequentialNumbering "Fields" fieldNums requireSequentialNumbering "Fields" fieldNums
requireOrdinalsInRange fieldNums requireOrdinalsInRange fieldNums
(theId, compiledAnnotations) <- compileAnnotations scope StructAnnotation annotations compiledAnnotations <- compileAnnotations scope StructAnnotation annotations
let (dataSize, pointerCount, fieldPackingMap) = packFields fields unions let (dataSize, pointerCount, fieldPackingMap) = packFields fields unions
fields = [d | DescField d <- members] fields = [d | DescField d <- members]
unions = [d | DescUnion d <- members] unions = [d | DescUnion d <- members]
...@@ -859,7 +853,7 @@ compileDecl scope (StructDecl (Located _ name) isFixed annotations decls) = ...@@ -859,7 +853,7 @@ compileDecl scope (StructDecl (Located _ name) isFixed annotations decls) =
return (let return (let
in DescStruct StructDesc in DescStruct StructDesc
{ structName = name { structName = name
, structId = theId , structId = childId name maybeTypeId scope
, structParent = scope , structParent = scope
, structDataSize = finalDataSize , structDataSize = finalDataSize
, structPointerCount = finalPointerCount , structPointerCount = finalPointerCount
...@@ -880,12 +874,11 @@ compileDecl scope@(DescStruct parent) ...@@ -880,12 +874,11 @@ compileDecl scope@(DescStruct parent)
orderedFieldNumbers = List.sort $ map fieldNumber fields orderedFieldNumbers = List.sort $ map fieldNumber fields
discriminantMap = Map.fromList $ zip orderedFieldNumbers [0..] discriminantMap = Map.fromList $ zip orderedFieldNumbers [0..]
requireNoMoreThanOneFieldNumberLessThan name numPos number fields requireNoMoreThanOneFieldNumberLessThan name numPos number fields
(theId, compiledAnnotations) <- compileAnnotations scope UnionAnnotation annotations compiledAnnotations <- compileAnnotations scope UnionAnnotation annotations
return (let return (let
DataOffset Size16 tagOffset = structFieldPackingMap parent ! number DataOffset Size16 tagOffset = structFieldPackingMap parent ! number
in DescUnion UnionDesc in DescUnion UnionDesc
{ unionName = name { unionName = name
, unionId = theId
, unionParent = parent , unionParent = parent
, unionNumber = number , unionNumber = number
, unionTagOffset = tagOffset , unionTagOffset = tagOffset
...@@ -925,11 +918,10 @@ compileDecl scope ...@@ -925,11 +918,10 @@ compileDecl scope
_ -> return ()) _ -> return ())
return result return result
Nothing -> return Nothing Nothing -> return Nothing
(theId, compiledAnnotations) <- compileAnnotations scope FieldAnnotation annotations compiledAnnotations <- compileAnnotations scope FieldAnnotation annotations
return (let return (let
in DescField FieldDesc in DescField FieldDesc
{ fieldName = name { fieldName = name
, fieldId = theId
, fieldParent = parent , fieldParent = parent
, fieldNumber = number , fieldNumber = number
, fieldOffset = structFieldPackingMap parent ! number , fieldOffset = structFieldPackingMap parent ! number
...@@ -939,17 +931,17 @@ compileDecl scope ...@@ -939,17 +931,17 @@ compileDecl scope
, fieldAnnotations = compiledAnnotations , fieldAnnotations = compiledAnnotations
})) }))
compileDecl scope (InterfaceDecl (Located _ name) annotations decls) = compileDecl scope (InterfaceDecl (Located _ name) maybeTypeId annotations decls) =
CompiledStatementStatus name (feedback (\desc -> do CompiledStatementStatus name (feedback (\desc -> do
(members, memberMap) <- compileChildDecls desc decls (members, memberMap) <- compileChildDecls desc decls
requireNoDuplicateNames decls requireNoDuplicateNames decls
let numbers = [ num | MethodDecl _ num _ _ _ <- decls ] let numbers = [ num | MethodDecl _ num _ _ _ <- decls ]
requireSequentialNumbering "Methods" numbers requireSequentialNumbering "Methods" numbers
requireOrdinalsInRange numbers requireOrdinalsInRange numbers
(theId, compiledAnnotations) <- compileAnnotations scope InterfaceAnnotation annotations compiledAnnotations <- compileAnnotations scope InterfaceAnnotation annotations
return (DescInterface InterfaceDesc return (DescInterface InterfaceDesc
{ interfaceName = name { interfaceName = name
, interfaceId = theId , interfaceId = childId name maybeTypeId scope
, interfaceParent = scope , interfaceParent = scope
, interfaceMethods = [d | DescMethod d <- members] , interfaceMethods = [d | DescMethod d <- members]
, interfaceAnnotations = compiledAnnotations , interfaceAnnotations = compiledAnnotations
...@@ -962,10 +954,9 @@ compileDecl scope@(DescInterface parent) ...@@ -962,10 +954,9 @@ compileDecl scope@(DescInterface parent)
CompiledStatementStatus name (feedback (\desc -> do CompiledStatementStatus name (feedback (\desc -> do
paramDescs <- doAll (map (compileParam desc) (zip [0..] params)) paramDescs <- doAll (map (compileParam desc) (zip [0..] params))
returnTypeDesc <- compileType scope returnType returnTypeDesc <- compileType scope returnType
(theId, compiledAnnotations) <- compileAnnotations scope MethodAnnotation annotations compiledAnnotations <- compileAnnotations scope MethodAnnotation annotations
return (DescMethod MethodDesc return (DescMethod MethodDesc
{ methodName = name { methodName = name
, methodId = theId
, methodParent = parent , methodParent = parent
, methodNumber = number , methodNumber = number
, methodParams = paramDescs , methodParams = paramDescs
...@@ -975,13 +966,13 @@ compileDecl scope@(DescInterface parent) ...@@ -975,13 +966,13 @@ compileDecl scope@(DescInterface parent)
compileDecl _ (MethodDecl (Located pos name) _ _ _ _) = compileDecl _ (MethodDecl (Located pos name) _ _ _ _) =
CompiledStatementStatus name (makeError pos "Methods can only appear inside interfaces.") CompiledStatementStatus name (makeError pos "Methods can only appear inside interfaces.")
compileDecl scope (AnnotationDecl (Located _ name) typeExp annotations targets) = compileDecl scope (AnnotationDecl (Located _ name) maybeTypeId typeExp annotations targets) =
CompiledStatementStatus name (do CompiledStatementStatus name (do
typeDesc <- compileType scope typeExp typeDesc <- compileType scope typeExp
(theId, compiledAnnotations) <- compileAnnotations scope AnnotationAnnotation annotations compiledAnnotations <- compileAnnotations scope AnnotationAnnotation annotations
return (DescAnnotation AnnotationDesc return (DescAnnotation AnnotationDesc
{ annotationName = name { annotationName = name
, annotationId = theId , annotationId = childId name maybeTypeId scope
, annotationParent = scope , annotationParent = scope
, annotationType = typeDesc , annotationType = typeDesc
, annotationAnnotations = compiledAnnotations , annotationAnnotations = compiledAnnotations
...@@ -994,10 +985,9 @@ compileParam scope@(DescMethod parent) ...@@ -994,10 +985,9 @@ compileParam scope@(DescMethod parent)
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
(theId, compiledAnnotations) <- compileAnnotations scope ParamAnnotation annotations compiledAnnotations <- compileAnnotations scope ParamAnnotation annotations
return ParamDesc return ParamDesc
{ paramName = name { paramName = name
, paramId = theId
, paramParent = parent , paramParent = parent
, paramNumber = ordinal , paramNumber = ordinal
, paramType = typeDesc , paramType = typeDesc
...@@ -1006,15 +996,14 @@ compileParam scope@(DescMethod parent) ...@@ -1006,15 +996,14 @@ compileParam scope@(DescMethod parent)
} }
compileParam _ _ = error "scope of parameter was not a method" compileParam _ _ = error "scope of parameter was not a method"
compileFile name decls annotations importMap = compileFile name theId decls annotations importMap =
feedback (\desc -> do feedback (\desc -> do
(members, memberMap) <- compileChildDecls (DescFile desc) decls (members, memberMap) <- compileChildDecls (DescFile desc) decls
requireNoDuplicateNames decls requireNoDuplicateNames decls
(theId, compiledAnnotations) compiledAnnotations <- compileAnnotations (DescFile desc) FileAnnotation annotations
<- compileAnnotations (DescFile desc) FileAnnotation annotations
return FileDesc return FileDesc
{ fileName = name { fileName = name
, fileId = theId , fileId = locatedValue theId
, fileImports = Map.elems importMap , fileImports = Map.elems importMap
, fileRuntimeImports = , fileRuntimeImports =
Set.fromList $ map fileName $ concatMap descRuntimeImports members Set.fromList $ map fileName $ concatMap descRuntimeImports members
...@@ -1029,7 +1018,7 @@ dedup = Set.toList . Set.fromList ...@@ -1029,7 +1018,7 @@ dedup = Set.toList . Set.fromList
emptyFileDesc filename = FileDesc emptyFileDesc filename = FileDesc
{ fileName = filename { fileName = filename
, fileId = Nothing , fileId = 0x0
, fileImports = [] , fileImports = []
, fileRuntimeImports = Set.empty , fileRuntimeImports = Set.empty
, fileAnnotations = Map.empty , fileAnnotations = Map.empty
...@@ -1042,9 +1031,10 @@ parseAndCompileFile :: Monad m ...@@ -1042,9 +1031,10 @@ parseAndCompileFile :: Monad m
=> FilePath -- Name of this file. => FilePath -- Name of this file.
-> String -- Content of this file. -> String -- Content of this file.
-> (String -> m (Either FileDesc String)) -- Callback to import other files. -> (String -> m (Either FileDesc String)) -- Callback to import other files.
-> m Word64 -- Callback to generate a random id.
-> m (Status FileDesc) -- Compiled file and/or errors. -> m (Status FileDesc) -- Compiled file and/or errors.
parseAndCompileFile filename text importCallback = do parseAndCompileFile filename text importCallback randomCallback = do
let (decls, annotations, parseErrors) = parseFile filename text let (maybeFileId, decls, annotations, parseErrors) = parseFile filename text
importNames = dedup $ concatMap declImports decls importNames = dedup $ concatMap declImports decls
doImport (Located pos name) = do doImport (Located pos name) = do
result <- importCallback name result <- importCallback name
...@@ -1055,6 +1045,11 @@ parseAndCompileFile filename text importCallback = do ...@@ -1055,6 +1045,11 @@ parseAndCompileFile filename text importCallback = do
importStatuses <- mapM doImport importNames importStatuses <- mapM doImport importNames
let dummyPos = newPos filename 1 1
theFileId <- case maybeFileId of
Nothing -> liftM (Located dummyPos) randomCallback
Just i -> return i
return (do return (do
-- We are now in the Status monad. -- We are now in the Status monad.
...@@ -1075,5 +1070,11 @@ parseAndCompileFile filename text importCallback = do ...@@ -1075,5 +1070,11 @@ parseAndCompileFile filename text importCallback = do
-- of one bad import. -- of one bad import.
imports <- doAll importStatuses imports <- doAll importStatuses
-- Report lack of an id.
when (isNothing maybeFileId) $
makeError dummyPos $
printf "File does not declare an ID. I've generated one for you. Add this line \
\to your file: @0x%016x;" (locatedValue theFileId)
-- Compile the file! -- Compile the file!
compileFile filename decls annotations $ Map.fromList imports) compileFile filename theFileId decls annotations $ Map.fromList imports)
...@@ -31,7 +31,7 @@ import Data.Word(Word8) ...@@ -31,7 +31,7 @@ import Data.Word(Word8)
import qualified Data.Digest.MD5 as MD5 import qualified Data.Digest.MD5 as MD5
import qualified Data.Map as Map import qualified Data.Map as Map
import qualified Data.Set as Set import qualified Data.Set as Set
import Data.Maybe(catMaybes, fromMaybe) import Data.Maybe(catMaybes)
import Data.Binary.IEEE754(floatToWord, doubleToWord) import Data.Binary.IEEE754(floatToWord, doubleToWord)
import Text.Printf(printf) import Text.Printf(printf)
import Text.Hastache import Text.Hastache
...@@ -51,7 +51,7 @@ muNull = MuBool False; ...@@ -51,7 +51,7 @@ muNull = MuBool False;
-- Using a single-element list has the same effect, though. -- Using a single-element list has the same effect, though.
muJust c = MuList [c] muJust c = MuList [c]
namespaceAnnotationId = "v3JF2GP4Supe9JSSJ3pnSdUqhJI.namespace" namespaceAnnotationId = 0xb9c6f99ebf805f2c
fileNamespace desc = fmap testAnnotation $ Map.lookup namespaceAnnotationId $ fileAnnotations desc fileNamespace desc = fmap testAnnotation $ Map.lookup namespaceAnnotationId $ fileAnnotations desc
...@@ -422,7 +422,7 @@ fileContext desc = mkStrContext context where ...@@ -422,7 +422,7 @@ fileContext desc = mkStrContext context where
context "fileName" = MuVariable $ fileName desc context "fileName" = MuVariable $ fileName desc
context "fileBasename" = MuVariable $ takeBaseName $ fileName desc context "fileBasename" = MuVariable $ takeBaseName $ fileName desc
context "fileIncludeGuard" = MuVariable $ context "fileIncludeGuard" = MuVariable $
"CAPNPROTO_INCLUDED_" ++ hashString (fileName desc ++ ':':fromMaybe "" (fileId desc)) "CAPNPROTO_INCLUDED_" ++ hashString (fileName desc ++ ':':show (fileId desc))
context "fileNamespaces" = MuList $ map (namespaceContext context) namespace context "fileNamespaces" = MuList $ map (namespaceContext context) namespace
context "fileEnums" = MuList $ map (enumContext context) [e | DescEnum e <- fileMembers desc] context "fileEnums" = MuList $ map (enumContext context) [e | DescEnum e <- fileMembers desc]
context "fileTypes" = MuList $ map (typeContext context) flattenedMembers context "fileTypes" = MuList $ map (typeContext context) flattenedMembers
......
...@@ -25,6 +25,7 @@ module Grammar where ...@@ -25,6 +25,7 @@ module Grammar where
import Token (Located) import Token (Located)
import Data.Maybe (maybeToList) import Data.Maybe (maybeToList)
import Data.Word (Word64)
data DeclName = AbsoluteName (Located String) data DeclName = AbsoluteName (Located String)
| RelativeName (Located String) | RelativeName (Located String)
...@@ -100,43 +101,45 @@ instance Show AnnotationTarget where ...@@ -100,43 +101,45 @@ instance Show AnnotationTarget where
data Declaration = UsingDecl (Located String) DeclName data Declaration = UsingDecl (Located String) DeclName
| ConstantDecl (Located String) TypeExpression [Annotation] (Located FieldValue) | ConstantDecl (Located String) TypeExpression [Annotation] (Located FieldValue)
| EnumDecl (Located String) [Annotation] [Declaration] | EnumDecl (Located String) (Maybe (Located Word64)) [Annotation] [Declaration]
| EnumerantDecl (Located String) (Located Integer) [Annotation] | EnumerantDecl (Located String) (Located Integer) [Annotation]
| StructDecl (Located String) (Maybe (Located (Integer, Integer))) | StructDecl (Located String) (Maybe (Located Word64))
[Annotation] [Declaration] (Maybe (Located (Integer, Integer))) [Annotation] [Declaration]
| FieldDecl (Located String) (Located Integer) | FieldDecl (Located String) (Located Integer)
TypeExpression [Annotation] (Maybe (Located FieldValue)) TypeExpression [Annotation] (Maybe (Located FieldValue))
| UnionDecl (Located String) (Located Integer) [Annotation] [Declaration] | UnionDecl (Located String) (Located Integer) [Annotation] [Declaration]
| InterfaceDecl (Located String) [Annotation] [Declaration] | InterfaceDecl (Located String) (Maybe (Located Word64))
[Annotation] [Declaration]
| MethodDecl (Located String) (Located Integer) [ParamDecl] | MethodDecl (Located String) (Located Integer) [ParamDecl]
TypeExpression [Annotation] TypeExpression [Annotation]
| AnnotationDecl (Located String) TypeExpression [Annotation] [AnnotationTarget] | AnnotationDecl (Located String) (Maybe (Located Word64)) TypeExpression
[Annotation] [AnnotationTarget]
deriving (Show) deriving (Show)
declarationName :: Declaration -> Maybe (Located String) declarationName :: Declaration -> Maybe (Located String)
declarationName (UsingDecl n _) = Just n declarationName (UsingDecl n _) = Just n
declarationName (ConstantDecl n _ _ _) = Just n declarationName (ConstantDecl n _ _ _) = Just n
declarationName (EnumDecl n _ _) = Just n declarationName (EnumDecl n _ _ _) = Just n
declarationName (EnumerantDecl n _ _) = Just n declarationName (EnumerantDecl 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 (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 (AnnotationDecl n _ _ _) = Just n declarationName (AnnotationDecl n _ _ _ _) = Just n
declImports :: Declaration -> [Located String] declImports :: Declaration -> [Located String]
declImports (UsingDecl _ name) = maybeToList (declNameImport name) declImports (UsingDecl _ name) = maybeToList (declNameImport name)
declImports (ConstantDecl _ t ann _) = typeImports t ++ concatMap annotationImports ann declImports (ConstantDecl _ t ann _) = typeImports t ++ concatMap annotationImports ann
declImports (EnumDecl _ ann decls) = concatMap annotationImports ann ++ concatMap declImports decls declImports (EnumDecl _ _ ann decls) = concatMap annotationImports ann ++ concatMap declImports decls
declImports (EnumerantDecl _ _ ann) = concatMap annotationImports ann declImports (EnumerantDecl _ _ ann) = concatMap annotationImports ann
declImports (StructDecl _ _ ann decls) = concatMap annotationImports ann ++ declImports (StructDecl _ _ _ ann decls) = concatMap annotationImports ann ++
concatMap declImports decls concatMap declImports decls
declImports (FieldDecl _ _ t ann _) = typeImports t ++ concatMap annotationImports ann declImports (FieldDecl _ _ t ann _) = typeImports t ++ concatMap annotationImports ann
declImports (UnionDecl _ _ ann decls) = concatMap annotationImports ann ++ declImports (UnionDecl _ _ ann decls) = concatMap annotationImports ann ++
concatMap declImports decls concatMap declImports decls
declImports (InterfaceDecl _ ann decls) = concatMap annotationImports ann ++ declImports (InterfaceDecl _ _ ann decls) = concatMap annotationImports ann ++
concatMap declImports decls concatMap declImports decls
declImports (MethodDecl _ _ params t ann) = declImports (MethodDecl _ _ params t ann) =
concat [concatMap paramImports params, typeImports t, concatMap annotationImports ann] concat [concatMap paramImports params, typeImports t, concatMap annotationImports ann]
declImports (AnnotationDecl _ t ann _) = typeImports t ++ concatMap annotationImports ann declImports (AnnotationDecl _ _ t ann _) = typeImports t ++ concatMap annotationImports ann
...@@ -29,8 +29,9 @@ import System.Exit(exitFailure, exitSuccess) ...@@ -29,8 +29,9 @@ import System.Exit(exitFailure, exitSuccess)
import System.IO(hPutStr, stderr) import System.IO(hPutStr, stderr)
import System.FilePath(takeDirectory) import System.FilePath(takeDirectory)
import System.Directory(createDirectoryIfMissing, doesDirectoryExist, doesFileExist) import System.Directory(createDirectoryIfMissing, doesDirectoryExist, doesFileExist)
import System.Entropy(getEntropy)
import Control.Monad import Control.Monad
import Control.Monad.IO.Class(liftIO) import Control.Monad.IO.Class(MonadIO, liftIO)
import Control.Exception(IOException, catch) import Control.Exception(IOException, catch)
import Control.Monad.Trans.State(StateT, state, modify, execStateT) import Control.Monad.Trans.State(StateT, state, modify, execStateT)
import Prelude hiding (catch) import Prelude hiding (catch)
...@@ -42,6 +43,8 @@ import Text.Printf(printf) ...@@ -42,6 +43,8 @@ import Text.Printf(printf)
import qualified Data.List as List import qualified Data.List as List
import qualified Data.Map as Map import qualified Data.Map as Map
import qualified Data.ByteString.Lazy.Char8 as LZ import qualified Data.ByteString.Lazy.Char8 as LZ
import Data.ByteString(unpack)
import Data.Word(Word64, Word8)
import Semantics import Semantics
import CxxGenerator(generateCxx) import CxxGenerator(generateCxx)
...@@ -54,6 +57,7 @@ data Opt = SearchPathOpt FilePath ...@@ -54,6 +57,7 @@ data Opt = SearchPathOpt FilePath
| OutputOpt String (Maybe GeneratorFn) FilePath | OutputOpt String (Maybe GeneratorFn) FilePath
| VerboseOpt | VerboseOpt
| HelpOpt | HelpOpt
| GenIdOpt
main :: IO () main :: IO ()
main = do main = do
...@@ -66,6 +70,7 @@ main = do ...@@ -66,6 +70,7 @@ main = do
\directory). LANG may be any of:\n\ \directory). LANG may be any of:\n\
\ " ++ unwords (Map.keys generatorFns)) \ " ++ unwords (Map.keys generatorFns))
, Option "v" ["verbose"] (NoArg VerboseOpt) "Write information about parsed files." , Option "v" ["verbose"] (NoArg VerboseOpt) "Write information about parsed files."
, Option "i" ["generate-id"] (NoArg GenIdOpt) "Generate a new unique ID."
, Option "h" ["help"] (NoArg HelpOpt) "Print usage info and exit." , Option "h" ["help"] (NoArg HelpOpt) "Print usage info and exit."
] ]
let usage = usageInfo let usage = usageInfo
...@@ -88,11 +93,16 @@ main = do ...@@ -88,11 +93,16 @@ main = do
exitFailure) exitFailure)
let isHelp = not $ null [opt | opt@HelpOpt <- options] let isHelp = not $ null [opt | opt@HelpOpt <- options]
when isHelp (do when isHelp (do
putStr usage putStr usage
exitSuccess) exitSuccess)
let isGenId = not $ null [opt | opt@GenIdOpt <- options]
when isGenId (do
i <- generateId
_ <- printf "@0x%016x\n" i
exitSuccess)
let isVerbose = not $ null [opt | opt@VerboseOpt <- options] let isVerbose = not $ null [opt | opt@VerboseOpt <- options]
let outputs = [(fn, dir) | OutputOpt _ (Just fn) dir <- options] let outputs = [(fn, dir) | OutputOpt _ (Just fn) dir <- options]
let searchPath = [dir | SearchPathOpt dir <- options] let searchPath = [dir | SearchPathOpt dir <- options]
...@@ -187,6 +197,16 @@ readAndParseFile isVerbose searchPath filename = do ...@@ -187,6 +197,16 @@ readAndParseFile isVerbose searchPath filename = do
Right err -> return $ Right err Right err -> return $ Right err
Left text -> parseFile isVerbose searchPath filename text Left text -> parseFile isVerbose searchPath filename text
generateId :: MonadIO m => m Word64
generateId = do
byteString <- liftIO $ getEntropy 8
let i | ix < 2^(63::Integer) = ix + 2^(63::Integer)
| otherwise = ix
ix = foldl addByte 0 (unpack byteString)
addByte :: Word64 -> Word8 -> Word64
addByte b v = b * 256 + fromIntegral v
return i
parseFile isVerbose searchPath filename text = do parseFile isVerbose searchPath filename text = do
let importCallback name = do let importCallback name = do
let candidates = relativePath filename searchPath name let candidates = relativePath filename searchPath name
...@@ -195,7 +215,7 @@ parseFile isVerbose searchPath filename text = do ...@@ -195,7 +215,7 @@ parseFile isVerbose searchPath filename text = do
Nothing -> return $ Right "File not found." Nothing -> return $ Right "File not found."
Just path -> importFile isVerbose searchPath path Just path -> importFile isVerbose searchPath path
status <- parseAndCompileFile filename text importCallback status <- parseAndCompileFile filename text importCallback generateId
case status of case status of
Active desc [] -> do Active desc [] -> do
when isVerbose (liftIO $ print desc) when isVerbose (liftIO $ print desc)
......
...@@ -24,8 +24,10 @@ ...@@ -24,8 +24,10 @@
module Parser (parseFile) where module Parser (parseFile) where
import Data.Generics import Data.Generics
import Data.Maybe(fromMaybe) import Data.Maybe(fromMaybe, listToMaybe)
import Data.Word(Word64)
import Text.Parsec hiding (tokens) import Text.Parsec hiding (tokens)
import Text.Parsec.Error(newErrorMessage, Message(Message))
import Token import Token
import Grammar import Grammar
import Lexer (lexer) import Lexer (lexer)
...@@ -40,7 +42,7 @@ tokenErrorString (ParenthesizedList _) = "parenthesized list" ...@@ -40,7 +42,7 @@ tokenErrorString (ParenthesizedList _) = "parenthesized list"
tokenErrorString (BracketedList _) = "bracketed list" tokenErrorString (BracketedList _) = "bracketed list"
tokenErrorString (LiteralInt i) = "integer literal " ++ show i tokenErrorString (LiteralInt i) = "integer literal " ++ show i
tokenErrorString (LiteralFloat f) = "float literal " ++ show f tokenErrorString (LiteralFloat f) = "float literal " ++ show f
tokenErrorString (LiteralString s) = "string literal " ++ show s tokenErrorString (LiteralString s) = "string literal " ++ show s
tokenErrorString AtSign = "\"@\"" tokenErrorString AtSign = "\"@\""
tokenErrorString Colon = "\":\"" tokenErrorString Colon = "\":\""
tokenErrorString DollarSign = "\"$\"" tokenErrorString DollarSign = "\"$\""
...@@ -89,6 +91,13 @@ matchLiteralBool t = case locatedValue t of ...@@ -89,6 +91,13 @@ matchLiteralBool t = case locatedValue t of
_ -> Nothing _ -> Nothing
matchSimpleToken expected t = if locatedValue t == expected then Just () else Nothing matchSimpleToken expected t = if locatedValue t == expected then Just () else Nothing
matchLiteralId :: Located Token -> Maybe Word64
matchLiteralId (Located _ (LiteralInt i))
| i >= (2^(63 :: Integer)) &&
i < (2^(64 :: Integer))
= Just (fromIntegral i)
matchLiteralId _ = Nothing
varIdentifier = tokenParser matchIdentifier varIdentifier = tokenParser matchIdentifier
<|> (tokenParser matchTypeIdentifier >>= <|> (tokenParser matchTypeIdentifier >>=
fail "Non-type identifiers must start with lower-case letter.") fail "Non-type identifiers must start with lower-case letter.")
...@@ -104,6 +113,7 @@ anyIdentifier = tokenParser matchIdentifier ...@@ -104,6 +113,7 @@ anyIdentifier = tokenParser matchIdentifier
literalInt = tokenParser (matchUnary LiteralInt) <?> "integer" literalInt = tokenParser (matchUnary LiteralInt) <?> "integer"
literalFloat = tokenParser (matchUnary LiteralFloat) <?> "floating-point number" literalFloat = tokenParser (matchUnary LiteralFloat) <?> "floating-point number"
literalString = tokenParser (matchUnary LiteralString) <?> "string" literalString = tokenParser (matchUnary LiteralString) <?> "string"
literalId = tokenParser matchLiteralId <?> "id (generate using capnpc -i)"
literalBool = tokenParser matchLiteralBool <?> "boolean" literalBool = tokenParser matchLiteralBool <?> "boolean"
literalVoid = tokenParser (matchSimpleToken VoidKeyword) <?> "\"void\"" literalVoid = tokenParser (matchSimpleToken VoidKeyword) <?> "\"void\""
...@@ -166,6 +176,8 @@ nameWithOrdinal = do ...@@ -166,6 +176,8 @@ nameWithOrdinal = do
ordinal <- located literalInt ordinal <- located literalInt
return (name, ordinal) return (name, ordinal)
declId = atSign >> literalId
annotation :: TokenParser Annotation annotation :: TokenParser Annotation
annotation = do annotation = do
dollarSign dollarSign
...@@ -175,10 +187,15 @@ annotation = do ...@@ -175,10 +187,15 @@ annotation = do
<|> return VoidFieldValue) <|> return VoidFieldValue)
return (Annotation name value) return (Annotation name value)
topLine :: Maybe [Located Statement] -> TokenParser (Either Declaration Annotation) data TopLevelDecl = TopLevelDecl Declaration
topLine Nothing = liftM Left (usingDecl <|> constantDecl <|> annotationDecl) | TopLevelAnnotation Annotation
<|> liftM Right annotation | TopLevelId (Located Word64)
topLine (Just statements) = liftM Left $ typeDecl statements
topLine :: Maybe [Located Statement] -> TokenParser TopLevelDecl
topLine Nothing = liftM TopLevelId (located declId)
<|> liftM TopLevelDecl (usingDecl <|> constantDecl <|> annotationDecl)
<|> liftM TopLevelAnnotation annotation
topLine (Just statements) = liftM TopLevelDecl $ typeDecl statements
usingDecl = do usingDecl = do
usingKeyword usingKeyword
...@@ -214,9 +231,10 @@ typeDecl statements = enumDecl statements ...@@ -214,9 +231,10 @@ typeDecl statements = enumDecl statements
enumDecl statements = do enumDecl statements = do
enumKeyword enumKeyword
name <- located typeIdentifier name <- located typeIdentifier
typeId <- optionMaybe $ located declId
annotations <- many annotation annotations <- many annotation
children <- parseBlock enumLine statements children <- parseBlock enumLine statements
return (EnumDecl name annotations children) return (EnumDecl name typeId annotations children)
enumLine :: Maybe [Located Statement] -> TokenParser Declaration enumLine :: Maybe [Located Statement] -> TokenParser Declaration
enumLine Nothing = enumerantDecl enumLine Nothing = enumerantDecl
...@@ -230,10 +248,11 @@ enumerantDecl = do ...@@ -230,10 +248,11 @@ enumerantDecl = do
structDecl statements = do structDecl statements = do
structKeyword structKeyword
name <- located typeIdentifier name <- located typeIdentifier
typeId <- optionMaybe $ located declId
fixed <- optionMaybe fixedSpec fixed <- optionMaybe fixedSpec
annotations <- many annotation annotations <- many annotation
children <- parseBlock structLine statements children <- parseBlock structLine statements
return (StructDecl name fixed annotations children) return (StructDecl name typeId fixed annotations children)
fixedSpec = do fixedSpec = do
fixedKeyword fixedKeyword
...@@ -312,9 +331,10 @@ fieldAssignment = do ...@@ -312,9 +331,10 @@ fieldAssignment = do
interfaceDecl statements = do interfaceDecl statements = do
interfaceKeyword interfaceKeyword
name <- located typeIdentifier name <- located typeIdentifier
typeId <- optionMaybe $ located declId
annotations <- many annotation annotations <- many annotation
children <- parseBlock interfaceLine statements children <- parseBlock interfaceLine statements
return (InterfaceDecl name annotations children) return (InterfaceDecl name typeId annotations children)
interfaceLine :: Maybe [Located Statement] -> TokenParser Declaration interfaceLine :: Maybe [Located Statement] -> TokenParser Declaration
interfaceLine Nothing = usingDecl <|> constantDecl <|> methodDecl <|> annotationDecl interfaceLine Nothing = usingDecl <|> constantDecl <|> methodDecl <|> annotationDecl
...@@ -339,12 +359,13 @@ paramDecl = do ...@@ -339,12 +359,13 @@ paramDecl = do
annotationDecl = do annotationDecl = do
annotationKeyword annotationKeyword
name <- located varIdentifier name <- located varIdentifier
annId <- optionMaybe $ located declId
targets <- try (parenthesized asterisk >> return allAnnotationTargets) targets <- try (parenthesized asterisk >> return allAnnotationTargets)
<|> parenthesizedList annotationTarget <|> parenthesizedList annotationTarget
colon colon
t <- typeExpression t <- typeExpression
annotations <- many annotation annotations <- many annotation
return (AnnotationDecl name t annotations targets) return (AnnotationDecl name annId t annotations targets)
allAnnotationTargets = [minBound::AnnotationTarget .. maxBound::AnnotationTarget] allAnnotationTargets = [minBound::AnnotationTarget .. maxBound::AnnotationTarget]
annotationTarget = (exactIdentifier "file" >> return FileAnnotation) annotationTarget = (exactIdentifier "file" >> return FileAnnotation)
...@@ -404,15 +425,23 @@ parseStatement parser (Located _ (Line tokens)) = ...@@ -404,15 +425,23 @@ parseStatement parser (Located _ (Line tokens)) =
parseStatement parser (Located _ (Block tokens statements)) = parseStatement parser (Located _ (Block tokens statements)) =
parseCollectingErrors (parser (Just statements)) tokens parseCollectingErrors (parser (Just statements)) tokens
parseFileTokens :: [Located Statement] -> ([Declaration], [Annotation], [ParseError]) parseFileTokens :: [Located Statement]
parseFileTokens statements = (decls, annotations, errors) where -> (Maybe (Located Word64), [Declaration], [Annotation], [ParseError])
results :: [Either ParseError (Either Declaration Annotation, [ParseError])] parseFileTokens statements = (fileId, decls, annotations, errors) where
results :: [Either ParseError (TopLevelDecl, [ParseError])]
results = map (parseStatement topLine) statements results = map (parseStatement topLine) statements
errors = concatMap extractErrors results errors = concatMap extractErrors results ++ idErrors
decls = [ decl | Right (Left decl, _) <- results ] decls = [ decl | Right (TopLevelDecl decl, _) <- results ]
annotations = [ ann | Right (Right ann, _) <- results ] annotations = [ ann | Right (TopLevelAnnotation ann, _) <- results ]
ids = [ i | Right (TopLevelId i, _) <- results ]
parseFile :: String -> String -> ([Declaration], [Annotation], [ParseError]) fileId = listToMaybe ids
idErrors | length ids <= 1 = []
| otherwise = map makeDupeIdError ids
makeDupeIdError (Located pos _) =
newErrorMessage (Message "File declares multiple ids.") pos
parseFile :: String -> String
-> (Maybe (Located Word64), [Declaration], [Annotation], [ParseError])
parseFile filename text = case parse lexer filename text of parseFile filename text = case parse lexer filename text of
Left e -> ([], [], [e]) Left e -> (Nothing, [], [], [e])
Right statements -> parseFileTokens statements Right statements -> parseFileTokens statements
...@@ -66,7 +66,6 @@ data Desc = DescFile FileDesc ...@@ -66,7 +66,6 @@ data Desc = DescFile FileDesc
| DescBuiltinInline | DescBuiltinInline
| DescBuiltinInlineList | DescBuiltinInlineList
| DescBuiltinInlineData | DescBuiltinInlineData
| DescBuiltinId
descName (DescFile _) = "(top-level)" descName (DescFile _) = "(top-level)"
descName (DescUsing d) = usingName d descName (DescUsing d) = usingName d
...@@ -85,34 +84,13 @@ descName DescBuiltinList = "List" ...@@ -85,34 +84,13 @@ descName DescBuiltinList = "List"
descName DescBuiltinInline = "Inline" descName DescBuiltinInline = "Inline"
descName DescBuiltinInlineList = "InlineList" descName DescBuiltinInlineList = "InlineList"
descName DescBuiltinInlineData = "InlineData" descName DescBuiltinInlineData = "InlineData"
descName DescBuiltinId = "id"
descId (DescFile d) = fileId d descId (DescFile d) = fileId d
descId (DescUsing _) = Nothing
descId (DescConstant d) = constantId d
descId (DescEnum d) = enumId d descId (DescEnum d) = enumId d
descId (DescEnumerant d) = enumerantId d
descId (DescStruct d) = structId d descId (DescStruct d) = structId d
descId (DescUnion d) = unionId d
descId (DescField d) = fieldId d
descId (DescInterface d) = interfaceId d descId (DescInterface d) = interfaceId d
descId (DescMethod d) = methodId d
descId (DescParam d) = paramId d
descId (DescAnnotation d) = annotationId d descId (DescAnnotation d) = annotationId d
descId (DescBuiltinType _) = Nothing descId _ = error "This construct does not have an ID."
descId DescBuiltinList = Nothing
descId DescBuiltinInline = Nothing
descId DescBuiltinInlineList = Nothing
descId DescBuiltinInlineData = Nothing
descId DescBuiltinId = Just "0U0T3e_SnatEfk6UcH2tcjTt1E0"
-- Gets the ID if explicitly defined, or generates it by appending ".name" to the parent's ID.
-- If no ancestor has an ID, still returns Nothing.
descAutoId d = case descId d of
Just i -> Just i
Nothing -> case d of
DescFile _ -> Nothing
_ -> fmap (++ '.':descName d) $ descAutoId $ descParent d
descParent (DescFile _) = error "File descriptor has no parent." descParent (DescFile _) = error "File descriptor has no parent."
descParent (DescUsing d) = usingParent d descParent (DescUsing d) = usingParent d
...@@ -131,7 +109,6 @@ descParent DescBuiltinList = error "Builtin type has no parent." ...@@ -131,7 +109,6 @@ descParent DescBuiltinList = error "Builtin type has no parent."
descParent DescBuiltinInline = error "Builtin type has no parent." descParent DescBuiltinInline = error "Builtin type has no parent."
descParent DescBuiltinInlineList = error "Builtin type has no parent." descParent DescBuiltinInlineList = error "Builtin type has no parent."
descParent DescBuiltinInlineData = error "Builtin type has no parent." descParent DescBuiltinInlineData = error "Builtin type has no parent."
descParent DescBuiltinId = error "Builtin annotation has no parent."
descFile (DescFile d) = d descFile (DescFile d) = d
descFile desc = descFile $ descParent desc descFile desc = descFile $ descParent desc
...@@ -153,7 +130,6 @@ descAnnotations DescBuiltinList = Map.empty ...@@ -153,7 +130,6 @@ descAnnotations DescBuiltinList = Map.empty
descAnnotations DescBuiltinInline = Map.empty descAnnotations DescBuiltinInline = Map.empty
descAnnotations DescBuiltinInlineList = Map.empty descAnnotations DescBuiltinInlineList = Map.empty
descAnnotations DescBuiltinInlineData = Map.empty descAnnotations DescBuiltinInlineData = Map.empty
descAnnotations DescBuiltinId = Map.empty
descRuntimeImports (DescFile _) = error "Not to be called on files." descRuntimeImports (DescFile _) = error "Not to be called on files."
descRuntimeImports (DescUsing d) = usingRuntimeImports d descRuntimeImports (DescUsing d) = usingRuntimeImports d
...@@ -172,7 +148,6 @@ descRuntimeImports DescBuiltinList = [] ...@@ -172,7 +148,6 @@ descRuntimeImports DescBuiltinList = []
descRuntimeImports DescBuiltinInline = [] descRuntimeImports DescBuiltinInline = []
descRuntimeImports DescBuiltinInlineList = [] descRuntimeImports DescBuiltinInlineList = []
descRuntimeImports DescBuiltinInlineData = [] descRuntimeImports DescBuiltinInlineData = []
descRuntimeImports DescBuiltinId = []
type MemberMap = Map.Map String (Maybe Desc) type MemberMap = Map.Map String (Maybe Desc)
...@@ -398,7 +373,7 @@ descQualifiedName scope desc = descQualifiedName (descParent scope) desc ...@@ -398,7 +373,7 @@ descQualifiedName scope desc = descQualifiedName (descParent scope) desc
data FileDesc = FileDesc data FileDesc = FileDesc
{ fileName :: String { fileName :: String
, fileId :: Maybe String , fileId :: Word64
, fileImports :: [FileDesc] , fileImports :: [FileDesc]
-- Set of imports which are used at runtime, i.e. not just for annotations. -- Set of imports which are used at runtime, i.e. not just for annotations.
-- The set contains file names matching files in fileImports. -- The set contains file names matching files in fileImports.
...@@ -419,7 +394,6 @@ usingRuntimeImports _ = [] ...@@ -419,7 +394,6 @@ usingRuntimeImports _ = []
data ConstantDesc = ConstantDesc data ConstantDesc = ConstantDesc
{ constantName :: String { constantName :: String
, constantId :: Maybe String
, constantParent :: Desc , constantParent :: Desc
, constantType :: TypeDesc , constantType :: TypeDesc
, constantAnnotations :: AnnotationMap , constantAnnotations :: AnnotationMap
...@@ -430,7 +404,7 @@ constantRuntimeImports desc = typeRuntimeImports $ constantType desc ...@@ -430,7 +404,7 @@ constantRuntimeImports desc = typeRuntimeImports $ constantType desc
data EnumDesc = EnumDesc data EnumDesc = EnumDesc
{ enumName :: String { enumName :: String
, enumId :: Maybe String , enumId :: Word64
, enumParent :: Desc , enumParent :: Desc
, enumerants :: [EnumerantDesc] , enumerants :: [EnumerantDesc]
, enumAnnotations :: AnnotationMap , enumAnnotations :: AnnotationMap
...@@ -442,7 +416,6 @@ enumRuntimeImports desc = concatMap descRuntimeImports $ enumMembers desc ...@@ -442,7 +416,6 @@ enumRuntimeImports desc = concatMap descRuntimeImports $ enumMembers desc
data EnumerantDesc = EnumerantDesc data EnumerantDesc = EnumerantDesc
{ enumerantName :: String { enumerantName :: String
, enumerantId :: Maybe String
, enumerantParent :: EnumDesc , enumerantParent :: EnumDesc
, enumerantNumber :: Integer , enumerantNumber :: Integer
, enumerantAnnotations :: AnnotationMap , enumerantAnnotations :: AnnotationMap
...@@ -452,7 +425,7 @@ enumerantRuntimeImports _ = [] ...@@ -452,7 +425,7 @@ enumerantRuntimeImports _ = []
data StructDesc = StructDesc data StructDesc = StructDesc
{ structName :: String { structName :: String
, structId :: Maybe String , structId :: Word64
, structParent :: Desc , structParent :: Desc
, structDataSize :: DataSectionSize , structDataSize :: DataSectionSize
, structPointerCount :: Integer , structPointerCount :: Integer
...@@ -473,7 +446,6 @@ structRuntimeImports desc = concatMap descRuntimeImports $ structMembers desc ...@@ -473,7 +446,6 @@ structRuntimeImports desc = concatMap descRuntimeImports $ structMembers desc
data UnionDesc = UnionDesc data UnionDesc = UnionDesc
{ unionName :: String { unionName :: String
, unionId :: Maybe String
, unionParent :: StructDesc , unionParent :: StructDesc
, unionNumber :: Integer , unionNumber :: Integer
, unionTagOffset :: Integer , unionTagOffset :: Integer
...@@ -490,7 +462,6 @@ unionRuntimeImports desc = concatMap descRuntimeImports $ unionMembers desc ...@@ -490,7 +462,6 @@ unionRuntimeImports desc = concatMap descRuntimeImports $ unionMembers desc
data FieldDesc = FieldDesc data FieldDesc = FieldDesc
{ fieldName :: String { fieldName :: String
, fieldId :: Maybe String
, fieldParent :: StructDesc , fieldParent :: StructDesc
, fieldNumber :: Integer , fieldNumber :: Integer
, fieldOffset :: FieldOffset , fieldOffset :: FieldOffset
...@@ -504,7 +475,7 @@ fieldRuntimeImports desc = typeRuntimeImports $ fieldType desc ...@@ -504,7 +475,7 @@ fieldRuntimeImports desc = typeRuntimeImports $ fieldType desc
data InterfaceDesc = InterfaceDesc data InterfaceDesc = InterfaceDesc
{ interfaceName :: String { interfaceName :: String
, interfaceId :: Maybe String , interfaceId :: Word64
, interfaceParent :: Desc , interfaceParent :: Desc
, interfaceMethods :: [MethodDesc] , interfaceMethods :: [MethodDesc]
, interfaceAnnotations :: AnnotationMap , interfaceAnnotations :: AnnotationMap
...@@ -516,7 +487,6 @@ interfaceRuntimeImports desc = concatMap descRuntimeImports $ interfaceMembers d ...@@ -516,7 +487,6 @@ interfaceRuntimeImports desc = concatMap descRuntimeImports $ interfaceMembers d
data MethodDesc = MethodDesc data MethodDesc = MethodDesc
{ methodName :: String { methodName :: String
, methodId :: Maybe String
, methodParent :: InterfaceDesc , methodParent :: InterfaceDesc
, methodNumber :: Integer , methodNumber :: Integer
, methodParams :: [ParamDesc] , methodParams :: [ParamDesc]
...@@ -529,7 +499,6 @@ methodRuntimeImports desc = typeRuntimeImports (methodReturnType desc) ++ ...@@ -529,7 +499,6 @@ methodRuntimeImports desc = typeRuntimeImports (methodReturnType desc) ++
data ParamDesc = ParamDesc data ParamDesc = ParamDesc
{ paramName :: String { paramName :: String
, paramId :: Maybe String
, paramParent :: MethodDesc , paramParent :: MethodDesc
, paramNumber :: Integer , paramNumber :: Integer
, paramType :: TypeDesc , paramType :: TypeDesc
...@@ -544,20 +513,18 @@ data AnnotationDesc = AnnotationDesc ...@@ -544,20 +513,18 @@ data AnnotationDesc = AnnotationDesc
, annotationParent :: Desc , annotationParent :: Desc
, annotationType :: TypeDesc , annotationType :: TypeDesc
, annotationAnnotations :: AnnotationMap , annotationAnnotations :: AnnotationMap
, annotationId :: Maybe String , annotationId :: Word64
, annotationTargets :: Set.Set AnnotationTarget , annotationTargets :: Set.Set AnnotationTarget
} }
annotationRuntimeImports desc = typeRuntimeImports $ annotationType desc annotationRuntimeImports desc = typeRuntimeImports $ annotationType desc
type AnnotationMap = Map.Map String (AnnotationDesc, ValueDesc) type AnnotationMap = Map.Map Word64 (AnnotationDesc, ValueDesc)
descToCode :: String -> Desc -> String descToCode :: String -> Desc -> String
descToCode indent self@(DescFile desc) = printf "# %s\n%s%s%s" descToCode indent self@(DescFile desc) = printf "# %s\n@0x%016x;\n%s%s"
(fileName desc) (fileName desc)
(case fileId desc of (fileId desc)
Just i -> printf "$id(%s);\n" $ show i
Nothing -> "")
(concatMap ((++ ";\n") . annotationCode self) $ Map.toList $ fileAnnotations desc) (concatMap ((++ ";\n") . annotationCode self) $ Map.toList $ fileAnnotations desc)
(concatMap (descToCode indent) (fileMembers desc)) (concatMap (descToCode indent) (fileMembers desc))
descToCode indent (DescUsing desc) = printf "%susing %s = %s;\n" indent descToCode indent (DescUsing desc) = printf "%susing %s = %s;\n" indent
...@@ -568,16 +535,18 @@ descToCode indent self@(DescConstant desc) = printf "%sconst %s: %s = %s%s;\n" i ...@@ -568,16 +535,18 @@ descToCode indent self@(DescConstant desc) = printf "%sconst %s: %s = %s%s;\n" i
(typeName (descParent self) (constantType desc)) (typeName (descParent self) (constantType desc))
(valueString (constantValue desc)) (valueString (constantValue desc))
(annotationsCode self) (annotationsCode self)
descToCode indent self@(DescEnum desc) = printf "%senum %s%s {\n%s%s}\n" indent descToCode indent self@(DescEnum desc) = printf "%senum %s @0x%016x%s {\n%s%s}\n" indent
(enumName desc) (enumName desc)
(enumId desc)
(annotationsCode self) (annotationsCode self)
(blockCode indent (enumMembers desc)) (blockCode indent (enumMembers desc))
indent indent
descToCode indent self@(DescEnumerant desc) = printf "%s%s @%d%s;\n" indent descToCode indent self@(DescEnumerant desc) = printf "%s%s @%d%s;\n" indent
(enumerantName desc) (enumerantNumber desc) (enumerantName desc) (enumerantNumber desc)
(annotationsCode self) (annotationsCode self)
descToCode indent self@(DescStruct desc) = printf "%sstruct %s%s%s {\n%s%s}\n" indent descToCode indent self@(DescStruct desc) = printf "%sstruct %s @0x%016x%s%s {\n%s%s}\n" indent
(structName desc) (structName desc)
(structId desc)
(if structIsFixedWidth desc (if structIsFixedWidth desc
then printf " fixed(%s, %d pointers) " then printf " fixed(%s, %d pointers) "
(dataSectionSizeString $ structDataSize desc) (dataSectionSizeString $ structDataSize desc)
...@@ -609,8 +578,9 @@ descToCode indent self@(DescUnion desc) = printf "%sunion %s@%d%s { # [%d, %d)\ ...@@ -609,8 +578,9 @@ descToCode indent self@(DescUnion desc) = printf "%sunion %s@%d%s { # [%d, %d)\
(unionTagOffset desc * 16) (unionTagOffset desc * 16 + 16) (unionTagOffset desc * 16) (unionTagOffset desc * 16 + 16)
(blockCode indent $ unionMembers desc) (blockCode indent $ unionMembers desc)
indent indent
descToCode indent self@(DescInterface desc) = printf "%sinterface %s%s {\n%s%s}\n" indent descToCode indent self@(DescInterface desc) = printf "%sinterface %s @0x%016x%s {\n%s%s}\n" indent
(interfaceName desc) (interfaceName desc)
(interfaceId desc)
(annotationsCode self) (annotationsCode self)
(blockCode indent (interfaceMembers desc)) (blockCode indent (interfaceMembers desc))
indent indent
...@@ -626,8 +596,9 @@ descToCode _ self@(DescParam desc) = printf "%s: %s%s%s" ...@@ -626,8 +596,9 @@ descToCode _ self@(DescParam desc) = printf "%s: %s%s%s"
Just v -> printf " = %s" $ valueString v Just v -> printf " = %s" $ valueString v
Nothing -> "") Nothing -> "")
(annotationsCode self) (annotationsCode self)
descToCode indent self@(DescAnnotation desc) = printf "%sannotation %s: %s on(%s)%s;\n" indent descToCode indent self@(DescAnnotation desc) = printf "%sannotation %s @0x%016x: %s on(%s)%s;\n" indent
(annotationName desc) (annotationName desc)
(annotationId desc)
(typeName (descParent self) (annotationType desc)) (typeName (descParent self) (annotationType desc))
(delimit ", " $ map show $ Set.toList $ annotationTargets desc) (delimit ", " $ map show $ Set.toList $ annotationTargets desc)
(annotationsCode self) (annotationsCode self)
...@@ -636,7 +607,6 @@ descToCode _ DescBuiltinList = error "Can't print code for builtin type." ...@@ -636,7 +607,6 @@ descToCode _ DescBuiltinList = error "Can't print code for builtin type."
descToCode _ DescBuiltinInline = error "Can't print code for builtin type." descToCode _ DescBuiltinInline = error "Can't print code for builtin type."
descToCode _ DescBuiltinInlineList = error "Can't print code for builtin type." descToCode _ DescBuiltinInlineList = error "Can't print code for builtin type."
descToCode _ DescBuiltinInlineData = error "Can't print code for builtin type." descToCode _ DescBuiltinInlineData = error "Can't print code for builtin type."
descToCode _ DescBuiltinId = error "Can't print code for builtin annotation."
maybeBlockCode :: String -> [Desc] -> String maybeBlockCode :: String -> [Desc] -> String
maybeBlockCode _ [] = ";\n" maybeBlockCode _ [] = ";\n"
...@@ -645,18 +615,14 @@ maybeBlockCode indent statements = printf " {\n%s%s}\n" (blockCode indent statem ...@@ -645,18 +615,14 @@ maybeBlockCode indent statements = printf " {\n%s%s}\n" (blockCode indent statem
blockCode :: String -> [Desc] -> String blockCode :: String -> [Desc] -> String
blockCode indent = concatMap (descToCode (" " ++ indent)) blockCode indent = concatMap (descToCode (" " ++ indent))
annotationCode :: Desc -> (String, (AnnotationDesc, ValueDesc)) -> String annotationCode :: Desc -> (Word64, (AnnotationDesc, ValueDesc)) -> String
annotationCode scope (_, (desc, VoidDesc)) = annotationCode scope (_, (desc, VoidDesc)) =
printf "$%s" (descQualifiedName scope (DescAnnotation desc)) printf "$%s" (descQualifiedName scope (DescAnnotation desc))
annotationCode scope (_, (desc, val)) = annotationCode scope (_, (desc, val)) =
printf "$%s(%s)" (descQualifiedName scope (DescAnnotation desc)) (valueString val) printf "$%s(%s)" (descQualifiedName scope (DescAnnotation desc)) (valueString val)
annotationsCode desc = let annotationsCode desc = concatMap ((' ':) . annotationCode (descParent desc)) $ Map.toList
nonIds = concatMap ((' ':) . annotationCode (descParent desc)) $ Map.toList $ descAnnotations desc
$ descAnnotations desc
in case descId desc of
Just i -> printf " $id(%s)%s" (show i) nonIds
Nothing -> nonIds
instance Show FileDesc where { show desc = descToCode "" (DescFile desc) } instance Show FileDesc where { show desc = descToCode "" (DescFile desc) }
instance Show UsingDesc where { show desc = descToCode "" (DescUsing desc) } instance Show UsingDesc where { show desc = descToCode "" (DescUsing desc) }
......
...@@ -25,6 +25,8 @@ module Util where ...@@ -25,6 +25,8 @@ module Util where
import Data.Char (isUpper, toUpper) import Data.Char (isUpper, toUpper)
import Data.List (intercalate, isPrefixOf) import Data.List (intercalate, isPrefixOf)
import Data.Bits(shiftR, Bits)
import Data.Word(Word8)
--delimit _ [] = "" --delimit _ [] = ""
--delimit delimiter (h:t) = h ++ concatMap (delimiter ++) t --delimit delimiter (h:t) = h ++ concatMap (delimiter ++) t
...@@ -50,3 +52,8 @@ toTitleCase [] = [] ...@@ -50,3 +52,8 @@ toTitleCase [] = []
toUpperCaseWithUnderscores :: String -> String toUpperCaseWithUnderscores :: String -> String
toUpperCaseWithUnderscores name = delimit "_" $ map (map toUpper) $ splitName name toUpperCaseWithUnderscores name = delimit "_" $ map (map toUpper) $ splitName name
intToBytes :: (Integral a, Bits a) => a -> Int -> [Word8]
intToBytes i count = map (byte i) [0..(count - 1)] where
byte :: (Integral a, Bits a) => a -> Int -> Word8
byte i2 amount = fromIntegral (shiftR i2 (amount * 8))
...@@ -25,18 +25,13 @@ module WireFormat(encodeMessage) where ...@@ -25,18 +25,13 @@ module WireFormat(encodeMessage) where
import Data.List(sortBy, genericLength, genericReplicate) import Data.List(sortBy, genericLength, genericReplicate)
import Data.Word import Data.Word
import Data.Bits(shiftL, shiftR, Bits, setBit, xor) import Data.Bits(shiftL, Bits, setBit, xor)
import Data.Function(on) import Data.Function(on)
import Semantics import Semantics
import Data.Binary.IEEE754(floatToWord, doubleToWord) import Data.Binary.IEEE754(floatToWord, doubleToWord)
import Text.Printf(printf) import Text.Printf(printf)
import qualified Codec.Binary.UTF8.String as UTF8 import qualified Codec.Binary.UTF8.String as UTF8
import Util(intToBytes)
byte :: (Integral a, Bits a) => a -> Int -> Word8
byte i amount = fromIntegral (shiftR i (amount * 8))
bytes :: (Integral a, Bits a) => a -> Int -> [Word8]
bytes i count = map (byte i) [0..(count - 1)]
padToWord b = let padToWord b = let
trailing = mod (length b) 8 trailing = mod (length b) 8
...@@ -55,19 +50,19 @@ xorData _ _ = error "Value type mismatch when xor'ing." ...@@ -55,19 +50,19 @@ xorData _ _ = error "Value type mismatch when xor'ing."
encodeDataValue :: TypeDesc -> ValueDesc -> EncodedData encodeDataValue :: TypeDesc -> ValueDesc -> EncodedData
encodeDataValue _ VoidDesc = EncodedBytes [] encodeDataValue _ VoidDesc = EncodedBytes []
encodeDataValue _ (BoolDesc v) = EncodedBit v encodeDataValue _ (BoolDesc v) = EncodedBit v
encodeDataValue _ (Int8Desc v) = EncodedBytes $ bytes v 1 encodeDataValue _ (Int8Desc v) = EncodedBytes $ intToBytes v 1
encodeDataValue _ (Int16Desc v) = EncodedBytes $ bytes v 2 encodeDataValue _ (Int16Desc v) = EncodedBytes $ intToBytes v 2
encodeDataValue _ (Int32Desc v) = EncodedBytes $ bytes v 4 encodeDataValue _ (Int32Desc v) = EncodedBytes $ intToBytes v 4
encodeDataValue _ (Int64Desc v) = EncodedBytes $ bytes v 8 encodeDataValue _ (Int64Desc v) = EncodedBytes $ intToBytes v 8
encodeDataValue _ (UInt8Desc v) = EncodedBytes $ bytes v 1 encodeDataValue _ (UInt8Desc v) = EncodedBytes $ intToBytes v 1
encodeDataValue _ (UInt16Desc v) = EncodedBytes $ bytes v 2 encodeDataValue _ (UInt16Desc v) = EncodedBytes $ intToBytes v 2
encodeDataValue _ (UInt32Desc v) = EncodedBytes $ bytes v 4 encodeDataValue _ (UInt32Desc v) = EncodedBytes $ intToBytes v 4
encodeDataValue _ (UInt64Desc v) = EncodedBytes $ bytes v 8 encodeDataValue _ (UInt64Desc v) = EncodedBytes $ intToBytes v 8
encodeDataValue _ (Float32Desc v) = EncodedBytes $ bytes (floatToWord v) 4 encodeDataValue _ (Float32Desc v) = EncodedBytes $ intToBytes (floatToWord v) 4
encodeDataValue _ (Float64Desc v) = EncodedBytes $ bytes (doubleToWord v) 8 encodeDataValue _ (Float64Desc v) = EncodedBytes $ intToBytes (doubleToWord v) 8
encodeDataValue _ (TextDesc _) = error "Not fixed-width data." encodeDataValue _ (TextDesc _) = error "Not fixed-width data."
encodeDataValue _ (DataDesc _) = error "Not fixed-width data." encodeDataValue _ (DataDesc _) = error "Not fixed-width data."
encodeDataValue _ (EnumerantValueDesc v) = EncodedBytes $ bytes (enumerantNumber v) 2 encodeDataValue _ (EnumerantValueDesc v) = EncodedBytes $ intToBytes (enumerantNumber v) 2
encodeDataValue _ (StructValueDesc _) = error "Not fixed-width data." encodeDataValue _ (StructValueDesc _) = error "Not fixed-width data."
encodeDataValue _ (ListDesc _) = error "Not fixed-width data." encodeDataValue _ (ListDesc _) = error "Not fixed-width data."
...@@ -132,23 +127,23 @@ packPointers size items o = loop 0 items (o + size - 1) where ...@@ -132,23 +127,23 @@ packPointers size items o = loop 0 items (o + size - 1) where
loop idx [] _ = (genericReplicate ((size - idx) * 8) 0, []) loop idx [] _ = (genericReplicate ((size - idx) * 8) 0, [])
encodeStructReference desc offset = encodeStructReference desc offset =
bytes (offset * 4 + structTag) 4 ++ intToBytes (offset * 4 + structTag) 4 ++
bytes (dataSectionWordSize $ structDataSize desc) 2 ++ intToBytes (dataSectionWordSize $ structDataSize desc) 2 ++
bytes (structPointerCount desc) 2 intToBytes (structPointerCount desc) 2
encodeInlineStructListReference elementDataSize elementPointerCount elementCount offset = let encodeInlineStructListReference elementDataSize elementPointerCount elementCount offset = let
dataBits = dataSectionBits elementDataSize * elementCount dataBits = dataSectionBits elementDataSize * elementCount
dataWords = div (dataBits + 63) 64 dataWords = div (dataBits + 63) 64
in bytes (offset * 4 + structTag) 4 ++ in intToBytes (offset * 4 + structTag) 4 ++
bytes dataWords 2 ++ intToBytes dataWords 2 ++
bytes (elementPointerCount * elementCount) 2 intToBytes (elementPointerCount * elementCount) 2
encodeListReference elemSize@(SizeInlineComposite ds rc) elementCount offset = encodeListReference elemSize@(SizeInlineComposite ds rc) elementCount offset =
bytes (offset * 4 + listTag) 4 ++ intToBytes (offset * 4 + listTag) 4 ++
bytes (fieldSizeEnum elemSize + shiftL (elementCount * (dataSectionWordSize ds + rc)) 3) 4 intToBytes (fieldSizeEnum elemSize + shiftL (elementCount * (dataSectionWordSize ds + rc)) 3) 4
encodeListReference elemSize elementCount offset = encodeListReference elemSize elementCount offset =
bytes (offset * 4 + listTag) 4 ++ intToBytes (offset * 4 + listTag) 4 ++
bytes (fieldSizeEnum elemSize + shiftL elementCount 3) 4 intToBytes (fieldSizeEnum elemSize + shiftL elementCount 3) 4
fieldSizeEnum SizeVoid = 0 fieldSizeEnum SizeVoid = 0
fieldSizeEnum (SizeData Size1) = 1 fieldSizeEnum (SizeData Size1) = 1
......
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