Skip to content

Commit d6c421e

Browse files
committed
Some work on types
1 parent 6afefb8 commit d6c421e

6 files changed

Lines changed: 72 additions & 3 deletions

File tree

ngc/FormGenerator.fs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ open System.Collections.Generic
2424
open System.Reflection
2525
open System.Reflection.Emit
2626
open Naggum.Runtime
27+
open Naggum.Compiler.Globals
2728
open Naggum.Compiler.Reader
2829
open Naggum.Compiler.Context
2930
open Naggum.Compiler.IGenerator
@@ -259,4 +260,43 @@ type NewObjGenerator(context : Context, typeBuilder : TypeBuilder, typeName : st
259260
if typeName.StartsWith "System" then
260261
[Type.GetType typeName]
261262
else
262-
[context.types.[typeName]]
263+
[context.types.[typeName]]
264+
265+
type TypeGenerator(context : Context, typeBuilder : TypeBuilder, typeName : string, parentTypeName: string, members : SExp list, gf : IGeneratorFactory) =
266+
let newTypeBuilder =
267+
if parentTypeName = "" then
268+
Globals.ModuleBuilder.DefineType(typeName, TypeAttributes.Class ||| TypeAttributes.Public, typeof<obj>)
269+
else
270+
Globals.ModuleBuilder.DefineType(typeName, TypeAttributes.Class ||| TypeAttributes.Public, context.types.[parentTypeName])
271+
let newGeneratorFactory = gf.MakeGeneratorFactory newTypeBuilder
272+
let mutable fields : string list = []
273+
274+
let generate_field field_name =
275+
let fieldBuilder = newTypeBuilder.DefineField(field_name,typeof<obj>,FieldAttributes.Public)
276+
fields <- List.append fields [field_name]
277+
let generate_method method_name method_parms method_body =
278+
let method_gen = newTypeBuilder.DefineMethod(method_name,MethodAttributes.Public,
279+
typeof<obj>,
280+
Array.create (List.length method_parms) typeof<obj>)
281+
let method_ctx = new Context(context)
282+
for parm in method_parms do
283+
match parm with
284+
| Atom(Symbol parm_name) ->
285+
let parm_idx = (List.findIndex (fun (p) -> p = parm) method_parms)
286+
method_ctx.locals.[parm_name] <- Arg (parm_idx,typeof<obj>)
287+
| other -> failwithf "In method %A%A parameter definition:\nExpected: Atom(Symbol)\nGot: %A" typeName method_name parm
288+
let body_gen = newGeneratorFactory.MakeBody method_ctx method_body
289+
body_gen.Generate (method_gen.GetILGenerator())
290+
(method_gen.GetILGenerator()).Emit(OpCodes.Ret)
291+
292+
interface IGenerator with
293+
member this.Generate ilGen =
294+
for m in members do
295+
match m with
296+
| List (Atom (Symbol "field") :: Atom (Symbol name) :: []) -> generate_field name
297+
| List (Atom (Symbol "field") :: Atom (Symbol access) :: Atom (Symbol name) :: []) -> generate_field name
298+
| List (Atom (Symbol "method") :: Atom (Symbol name) :: List parms :: body) -> generate_method name parms body
299+
| List (Atom (Symbol "method") :: Atom (Symbol name) :: Atom (Symbol access) :: List parms :: body) -> generate_method name parms body
300+
| other -> failwithf "In definition of type %A: \nUnknown member definition: %A" typeName other
301+
member this.ReturnTypes () =
302+
[typeof<System.Void>]

ngc/Generator.fs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ open System.Collections.Generic
2626
open System.Reflection
2727
open System.Reflection.Emit
2828

29+
open Naggum.Compiler.Globals
2930
open Naggum.Compiler.IGenerator
3031
open Naggum.Compiler.GeneratorFactory
3132
open Naggum.Compiler.Reader
@@ -43,8 +44,8 @@ let private epilogue context typeBuilder (ilGen : ILGenerator) =
4344
let compile (source : Stream) (assemblyName : string) (fileName : string) (asmRefs:string list): unit =
4445
let assemblyName = new AssemblyName(assemblyName)
4546
let assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save)
46-
let moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyBuilder.GetName().Name, fileName)
47-
let typeBuilder = moduleBuilder.DefineType("Program", TypeAttributes.Public ||| TypeAttributes.Class ||| TypeAttributes.BeforeFieldInit)
47+
Globals.ModuleBuilder <- assemblyBuilder.DefineDynamicModule(assemblyBuilder.GetName().Name, fileName)
48+
let typeBuilder = Globals.ModuleBuilder.DefineType("Program", TypeAttributes.Public ||| TypeAttributes.Class ||| TypeAttributes.BeforeFieldInit)
4849
let methodBuilder = typeBuilder.DefineMethod("Main", MethodAttributes.Public ||| MethodAttributes.Static, typeof<int>, [| |])
4950

5051
let gf = new GeneratorFactory(typeBuilder) :> IGeneratorFactory

ngc/GeneratorFactory.fs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,5 @@ type GeneratorFactory(typeBldr:TypeBuilder) =
124124
member this.MakeSequence context seq = this.makeSequenceGenerator (context,seq) :> IGenerator
125125

126126
member this.MakeBody context body = this.makeBodyGenerator (context,body) :> IGenerator
127+
128+
member this.MakeGeneratorFactory newTypeBuilder = (new GeneratorFactory (newTypeBuilder)) :> IGeneratorFactory

ngc/Globals.fs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
(* Copyright (C) 2011-2012 by ForNeVeR,Hagane
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is
8+
furnished to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in
11+
all copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
THE SOFTWARE. *)
20+
module Naggum.Compiler.Globals
21+
22+
open System.Reflection.Emit
23+
24+
let mutable ModuleBuilder:ModuleBuilder = null

ngc/IGenerator.fs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,5 @@ type IGeneratorFactory =
3838
abstract MakeGenerator : Context -> SExp -> IGenerator
3939
abstract MakeSequence : Context -> SExp list -> IGenerator
4040
abstract MakeBody : Context -> SExp list -> IGenerator
41+
abstract MakeGeneratorFactory : TypeBuilder -> IGeneratorFactory
4142
end

ngc/ngc.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
<Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="!Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
3939
<Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition=" Exists('$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll')" />
4040
<ItemGroup>
41+
<Compile Include="Globals.fs" />
4142
<Compile Include="Reader.fs" />
4243
<Compile Include="Context.fs" />
4344
<Compile Include="IGenerator.fs" />

0 commit comments

Comments
 (0)