Skip to content

Commit 0ab6b11

Browse files
committed
Assembler: split Processor and Assembler modules.
1 parent 1be5ddd commit 0ab6b11

File tree

6 files changed

+103
-97
lines changed

6 files changed

+103
-97
lines changed

Naggum.Assembler/Assembler.fs

Lines changed: 2 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,100 +1,9 @@
11
module Naggum.Assembler.Assembler
22

3-
open System
4-
open System.Reflection
53
open System.Reflection.Emit
64

75
open Naggum.Assembler.Representation
8-
open Naggum.Compiler
9-
open Naggum.Compiler.Reader
106

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 =
1009
Seq.empty

Naggum.Assembler/Naggum.Assembler.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
<None Include="App.config" />
5252
<Compile Include="AssemblyInfo.fs" />
5353
<Compile Include="Representation.fs" />
54+
<Compile Include="Processor.fs" />
5455
<Compile Include="Assembler.fs" />
5556
<Compile Include="Program.fs" />
5657
</ItemGroup>

Naggum.Assembler/Processor.fs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
module Naggum.Assembler.Processor
2+
3+
open System
4+
open System.Reflection
5+
open System.Reflection.Emit
6+
7+
open Naggum.Assembler.Representation
8+
open Naggum.Compiler
9+
open Naggum.Compiler.Reader
10+
11+
let private processMetadataItem = function
12+
| Atom (Symbol ".entrypoint") -> EntryPoint
13+
| other -> failwithf "Unrecognized metadata item definition: %A" other
14+
15+
let private resolveAssembly _ =
16+
Assembly.GetAssembly(typeof<Int32>) // TODO: Assembly resolver
17+
18+
let private 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 private resolveTypes =
26+
List.map (function
27+
| Atom (Symbol name) -> resolveType name
28+
| other -> failwithf "Unrecognized type: %A" other)
29+
30+
let private 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 private 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 private 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 private 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 private 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 private 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

Naggum.Assembler/Program.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ let save (assembly : AssemblyBuilder) =
2525

2626
let assemble fileName =
2727
use stream = File.OpenRead fileName
28-
let repr = Assembler.prepare fileName stream
28+
let repr = Processor.prepare fileName stream
2929
let assemblies = Assembler.assemble repr
3030
assemblies |> Seq.iter save
3131

Naggum.Test/Naggum.Test.fsproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
5353
</Content>
5454
<Content Include="packages.config" />
55-
<Compile Include="AssemblerTests.fs" />
55+
<Compile Include="ProcessorTests.fs" />
5656
<Compile Include="CompilerTest.fs" />
5757
</ItemGroup>
5858
<ItemGroup>

Naggum.Test/AssemblerTests.fs renamed to Naggum.Test/ProcessorTests.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module Naggum.Test.AssemblerTest
1+
module Naggum.Test.ProcessorTests
22

33
open System
44
open System.IO
@@ -29,7 +29,7 @@ let consoleWriteLine =
2929

3030
let checkPreparationResult (source : string) (expected : Assembly list) =
3131
use stream = new MemoryStream(Encoding.UTF8.GetBytes source)
32-
let actual = Assembler.prepare "file.ngi" stream |> Seq.toList
32+
let actual = Processor.prepare "file.ngi" stream |> Seq.toList
3333

3434
Assert.Equal (expected.ToString (), actual.ToString ()) // for diagnostic
3535
Assert.Equal<Assembly list> (expected, actual)

0 commit comments

Comments
 (0)