|
1 | 1 | module Naggum.Assembler.Assembler |
2 | 2 |
|
3 | | -open System |
4 | | -open System.Reflection |
5 | 3 | open System.Reflection.Emit |
6 | 4 |
|
7 | 5 | open Naggum.Assembler.Representation |
8 | | -open Naggum.Compiler |
9 | | -open Naggum.Compiler.Reader |
10 | 6 |
|
11 | | -let processMetadataItem = function |
12 | | - | Atom (Symbol ".entrypoint") -> EntryPoint |
13 | | - | other -> failwithf "Unrecognized metadata item definition: %A" other |
14 | | - |
15 | | -let resolveAssembly _ = |
16 | | - Assembly.GetAssembly(typeof<Int32>) // TODO: Assembly resolver |
17 | | - |
18 | | -let resolveType name = |
19 | | - let result = Type.GetType name // TODO: Resolve types from the assembler context |
20 | | - if isNull result then |
21 | | - failwithf "Type %s could not be found" name |
22 | | - |
23 | | - result |
24 | | - |
25 | | -let resolveTypes = |
26 | | - List.map (function |
27 | | - | Atom (Symbol name) -> resolveType name |
28 | | - | other -> failwithf "Unrecognized type: %A" other) |
29 | | - |
30 | | -let processMethodSignature = function |
31 | | - | [Atom (Symbol assembly) |
32 | | - Atom (Symbol typeName) |
33 | | - Atom (Symbol methodName) |
34 | | - List argumentTypes |
35 | | - Atom (Symbol returnType)] -> |
36 | | - { Assembly = Some (resolveAssembly assembly) // TODO: Resolve types from current assembly |
37 | | - ContainingType = Some (resolveType typeName) // TODO: Resolve methods without a type (e.g. assembly methods) |
38 | | - Name = methodName |
39 | | - ArgumentTypes = resolveTypes argumentTypes |
40 | | - ReturnType = resolveType returnType } |
41 | | - | other -> failwithf "Unrecognized method signature: %A" other |
42 | | - |
43 | | -let processInstruction = function |
44 | | - | List ([Atom (Symbol "ldstr"); Atom (Object (:? string as s))]) -> |
45 | | - Ldstr s |
46 | | - | List ([Atom (Symbol "call"); List (calleeSignature)]) -> |
47 | | - let signature = processMethodSignature calleeSignature |
48 | | - Call signature |
49 | | - | List ([Atom (Symbol "ret")]) -> Ret |
50 | | - | other -> failwithf "Unrecognized instruction: %A" other |
51 | | - |
52 | | -let addMetadata metadata method' = |
53 | | - List.fold (fun ``method`` metadataExpr -> |
54 | | - let metadataItem = processMetadataItem metadataExpr |
55 | | - { ``method`` with Metadata = Set.add metadataItem ``method``.Metadata }) |
56 | | - method' |
57 | | - metadata |
58 | | - |
59 | | -let addBody body method' = |
60 | | - List.fold (fun ``method`` bodyClause -> |
61 | | - let instruction = processInstruction bodyClause |
62 | | - { ``method`` with Body = List.append ``method``.Body [instruction] }) |
63 | | - method' |
64 | | - body |
65 | | - |
66 | | -let processAssemblyUnit = function |
67 | | - | List (Atom (Symbol ".method") |
68 | | - :: Atom (Symbol name) |
69 | | - :: List argumentTypes |
70 | | - :: Atom (Symbol returnType) |
71 | | - :: List metadata |
72 | | - :: body) -> |
73 | | - let definition = |
74 | | - { Metadata = Set.empty |
75 | | - Visibility = Public // TODO: Determine method visibility |
76 | | - Name = name |
77 | | - ArgumentTypes = resolveTypes argumentTypes |
78 | | - ReturnType = resolveType returnType |
79 | | - Body = List.empty } |
80 | | - definition |
81 | | - |> addMetadata metadata |
82 | | - |> addBody body |
83 | | - |> Method |
84 | | - | other -> failwithf "Unrecognized assembly unit definition: %A" other |
85 | | - |
86 | | -let prepareTopLevel = function |
87 | | - | List (Atom (Symbol ".assembly") :: Atom (Symbol name) :: units) -> |
88 | | - { Name = name |
89 | | - Units = List.map processAssemblyUnit units } |
90 | | - | other -> failwithf "Unknown top-level construct: %A" other |
91 | | - |
92 | | -/// Prepares the source file for assembling. Returns the intermediate |
93 | | -/// representation of the source code. |
94 | | -let prepare fileName stream : Assembly seq = |
95 | | - let forms = Reader.parse fileName stream |
96 | | - forms |> Seq.map prepareTopLevel |
97 | | - |
98 | | -/// Assembles the source code. Returns a list of assemblies ready for saving. |
99 | | -let assemble repr : AssemblyBuilder seq = |
| 7 | +/// Assembles the intermediate program representation. Returns a list of assemblies ready for saving. |
| 8 | +let assemble (assemblies : Assembly seq) : AssemblyBuilder seq = |
100 | 9 | Seq.empty |
0 commit comments