Skip to content

Commit b09355d

Browse files
committed
Assembler: initial assembly preparation code.
1 parent fb9cbe2 commit b09355d

File tree

3 files changed

+78
-2
lines changed

3 files changed

+78
-2
lines changed

Naggum.Assembler/Assembler.fs

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,61 @@
11
module Naggum.Assembler.Assembler
22

3+
open System
34
open System.Reflection.Emit
45

6+
open Naggum.Assembler.Representation
57
open Naggum.Compiler
8+
open Naggum.Compiler.Reader
9+
10+
let processMetadataItem = function
11+
| Atom (Symbol ".entrypoint") -> EntryPoint
12+
| other -> failwithf "Unrecognized metadata item definition: %A" other
13+
14+
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"
17+
| List ([Atom (Symbol "ret")]) -> Ret
18+
| other -> failwithf "Unrecognized instruction: %A" other
19+
20+
let addMetadata metadata method' =
21+
List.fold (fun ``method`` metadataExpr ->
22+
let metadataItem = processMetadataItem metadataExpr
23+
{ ``method`` with Metadata = Set.add metadataItem ``method``.Metadata })
24+
method'
25+
metadata
26+
27+
let addBody body method' =
28+
List.fold (fun ``method`` bodyClause ->
29+
let instruction = processInstruction bodyClause
30+
{ ``method`` with Body = List.append ``method``.Body [instruction] })
31+
method'
32+
body
33+
34+
let processAssemblyUnit = function
35+
| List (Atom (Symbol ".method") :: Atom (Symbol name) :: List arguments :: List metadata :: body) ->
36+
let definition =
37+
{ Metadata = Set.empty
38+
Visibility = Public // TODO: Determine method visibility
39+
Name = name
40+
ReturnType = typeof<Void> // TODO: Determine method return type
41+
Body = List.empty }
42+
definition
43+
|> addMetadata metadata
44+
|> addBody body
45+
|> Method
46+
| other -> failwithf "Unrecognized assembly unit definition: %A" other
47+
48+
let prepareTopLevel = function
49+
| List (Atom (Symbol ".assembly") :: Atom (Symbol name) :: units) ->
50+
{ Name = name
51+
Units = List.map processAssemblyUnit units }
52+
| other -> failwithf "Unknown top-level construct: %A" other
653

754
/// Prepares the source file for assembling. Returns the intermediate
855
/// representation of the source code.
9-
let prepare fileName stream =
56+
let prepare fileName stream : Assembly seq =
1057
let forms = Reader.parse fileName stream
11-
()
58+
forms |> Seq.map prepareTopLevel
1259

1360
/// Assembles the source code. Returns a list of assemblies ready for saving.
1461
let assemble repr : AssemblyBuilder seq =

Naggum.Assembler/Naggum.Assembler.fsproj

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

Naggum.Assembler/Representation.fs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
namespace Naggum.Assembler.Representation
2+
3+
open System.Reflection
4+
5+
type MetadataItem =
6+
| EntryPoint
7+
8+
type Visibility =
9+
| Public
10+
11+
type Instruction =
12+
| Ldstr of string
13+
| Call of MethodInfo
14+
| Ret
15+
16+
type MethodDefinition =
17+
{ Metadata : Set<MetadataItem>
18+
Visibility : Visibility
19+
Name : string
20+
ReturnType : System.Type
21+
Body : Instruction list }
22+
23+
type AssemblyUnit =
24+
| Method of MethodDefinition
25+
26+
type Assembly =
27+
{ Name : string
28+
Units : AssemblyUnit list }

0 commit comments

Comments
 (0)