Skip to content

Commit e8e9497

Browse files
committed
Assembler: callee method signatures.
1 parent 79960aa commit e8e9497

File tree

3 files changed

+81
-17
lines changed

3 files changed

+81
-17
lines changed

Naggum.Assembler/Assembler.fs

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module Naggum.Assembler.Assembler
22

33
open System
4+
open System.Reflection
45
open System.Reflection.Emit
56

67
open Naggum.Assembler.Representation
@@ -11,9 +12,40 @@ let processMetadataItem = function
1112
| Atom (Symbol ".entrypoint") -> EntryPoint
1213
| other -> failwithf "Unrecognized metadata item definition: %A" other
1314

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 typeName }
41+
| other -> failwithf "Unrecognized method signature: %A" other
42+
1443
let processInstruction = function
15-
| List ([Atom (Symbol "ldstr"); Atom (Symbol string)]) -> Ldstr string
16-
| List ([Atom (Symbol "call"); Atom (Symbol methodName)]) -> failwithf "Method calls are not supported now"
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
1749
| List ([Atom (Symbol "ret")]) -> Ret
1850
| other -> failwithf "Unrecognized instruction: %A" other
1951

@@ -32,12 +64,18 @@ let addBody body method' =
3264
body
3365

3466
let processAssemblyUnit = function
35-
| List (Atom (Symbol ".method") :: Atom (Symbol name) :: List arguments :: List metadata :: body) ->
67+
| List (Atom (Symbol ".method")
68+
:: Atom (Symbol name)
69+
:: List argumentTypes
70+
:: Atom (Symbol returnType)
71+
:: List metadata
72+
:: body) ->
3673
let definition =
3774
{ Metadata = Set.empty
3875
Visibility = Public // TODO: Determine method visibility
3976
Name = name
40-
ReturnType = typeof<Void> // TODO: Determine method return type
77+
ArgumentTypes = resolveTypes argumentTypes
78+
ReturnType = resolveType returnType
4179
Body = List.empty }
4280
definition
4381
|> addMetadata metadata

Naggum.Assembler/Representation.fs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,26 @@ type MetadataItem =
88
type Visibility =
99
| Public
1010

11+
type Type = System.Type
12+
13+
type MethodSignature =
14+
{ Assembly : Assembly option
15+
ContainingType : Type option
16+
Name : string
17+
ArgumentTypes : Type list
18+
ReturnType : Type }
19+
1120
type Instruction =
1221
| Ldstr of string
13-
| Call of MethodInfo
22+
| Call of MethodSignature
1423
| Ret
1524

1625
type MethodDefinition =
1726
{ Metadata : Set<MetadataItem>
1827
Visibility : Visibility
1928
Name : string
20-
ReturnType : System.Type
29+
ArgumentTypes : Type list
30+
ReturnType : Type
2131
Body : Instruction list }
2232

2333
type AssemblyUnit =

Naggum.Test/AssemblerTests.fs

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,35 @@
22

33
open System
44
open System.IO
5+
open System.Reflection
56
open System.Text
67

78
open Xunit
89

910
open Naggum.Assembler
1011
open Naggum.Assembler.Representation
1112

13+
let mscorlib = Assembly.GetAssembly(typeof<Int32>)
14+
15+
let mainMethodDefinition =
16+
{ Metadata = Set.singleton EntryPoint
17+
Visibility = Public
18+
Name = "Main"
19+
ArgumentTypes = List.empty
20+
ReturnType = typeof<Void>
21+
Body = List.empty }
22+
23+
let consoleWriteLine =
24+
{ Assembly = Some mscorlib
25+
ContainingType = Some typeof<Console>
26+
Name = "WriteLine"
27+
ArgumentTypes = [typeof<string>]
28+
ReturnType = typeof<Void> }
29+
1230
let checkPreparationResult (source : string) (expected : Assembly list) =
1331
use stream = new MemoryStream(Encoding.UTF8.GetBytes source)
1432
let actual = Assembler.prepare "file.ngi" stream |> Seq.toList
15-
33+
1634
Assert.Equal<Assembly list> (expected, actual)
1735

1836
[<Fact>]
@@ -24,33 +42,31 @@ let ``Empty assembly should be processed`` () =
2442
[<Fact>]
2543
let ``Simplest method should be processed`` () =
2644
let source = "(.assembly Stub
27-
(.method Main () (.entrypoint)
45+
(.method Main () System.Void (.entrypoint)
2846
(ret)))
2947
"
3048
let result =
3149
{ Name = "Stub"
32-
Units = [Method { Metadata = Set.singleton EntryPoint
33-
Visibility = Public
34-
Name = "Main"
35-
ReturnType = typeof<Void>
36-
Body = [ Ret ] } ] }
50+
Units = [Method { mainMethodDefinition with
51+
Body = [ Ret ] } ] }
3752
checkPreparationResult source [result]
3853

3954
[<Fact>]
4055
let ``Hello world assembly should be processed`` () =
4156
let source = "(.assembly Hello
42-
(.method Main () (.entrypoint)
57+
(.method Main () System.Void (.entrypoint)
4358
(ldstr \"Hello, world!\")
44-
(call `void System.Console::WriteLine(string)`)
59+
(call (mscorlib System.Console WriteLine (System.String) System.Void))
4560
(ret)))
4661
"
4762
let result =
48-
{ Name = "Empty"
63+
{ Name = "Hello"
4964
Units = [Method { Metadata = Set.singleton EntryPoint
5065
Visibility = Public
5166
Name = "Main"
67+
ArgumentTypes = List.empty
5268
ReturnType = typeof<Void>
5369
Body = [ Ldstr "Hello, world!"
54-
Call (typeof<Console>.GetMethod("WriteLine", [| typeof<String> |]))
70+
Call consoleWriteLine
5571
Ret ] } ] }
5672
checkPreparationResult source [result]

0 commit comments

Comments
 (0)