@@ -33,148 +33,10 @@ open Naggum.Runtime
3333
3434open Context
3535
36- //TODO: Shoot that putrid shit and throw it out.
37- let rec private generate ( context : Context ) ( typeBuilder : TypeBuilder ) ( ilGen : ILGenerator ) ( form : SExp ) =
38- match form with
39- | List list ->
40- match list with
41- | ( Atom ( Symbol " defun" ) :: Atom ( Symbol name) :: List args :: body) ->
42- let argsDef = Array.create ( List.length args) typeof< obj>
43- let methodGen = typeBuilder.DefineMethod( name, MethodAttributes.Public ||| MethodAttributes.Static, typeof< obj>, argsDef)
44- let methodILGen = ( methodGen.GetILGenerator())
45- generateBody context typeBuilder methodILGen body
46- methodILGen.Emit( OpCodes.Ret)
47- // Add function to context:
48- context.functions.[ name] <- methodGen
49- | Atom ( Symbol " if" ) :: condition :: if_ true :: if_ false :: [] -> //full if form
50- generate context typeBuilder ilGen condition
51- let if_true_lbl = ilGen.DefineLabel()
52- let end_form = ilGen.DefineLabel()
53- ilGen.Emit ( OpCodes.Brtrue, if_ true_ lbl)
54- generate context typeBuilder ilGen if_ false
55- ilGen.Emit ( OpCodes.Br, end_ form)
56- ilGen.MarkLabel if_ true_ lbl
57- generate context typeBuilder ilGen if_ true
58- ilGen.MarkLabel end_ form
59- | Atom ( Symbol " if" ) :: condition :: if_ true :: [] -> //reduced if form
60- generate context typeBuilder ilGen condition
61- let if_true_lbl = ilGen.DefineLabel()
62- let end_form = ilGen.DefineLabel()
63- ilGen.Emit ( OpCodes.Brtrue, if_ true_ lbl)
64- ilGen.Emit OpCodes.Ldnull
65- ilGen.Emit ( OpCodes.Br, end_ form)
66- ilGen.MarkLabel if_ true_ lbl
67- generate context typeBuilder ilGen if_ true
68- ilGen.MarkLabel end_ form
69- | Atom ( Symbol " let" ) :: bindings :: body -> //let form
70- ilGen.BeginScope()
71- let scope_subctx = new Context ( context)
72- match bindings with
73- | List list ->
74- for binding in list do
75- match binding with
76- | List [( Atom ( Symbol name)); form] ->
77- let local = ilGen.DeclareLocal( typeof< obj>)
78- generate context typeBuilder ilGen form
79- ilGen.Emit ( OpCodes.Stloc, local)
80- scope_ subctx.locals.[ name] <- Local ( local, typeof< obj>)
81- | other -> failwithf " In let bindings: Expected: (name (form))\n Got: %A \n " other
82- | other -> failwithf " In let form: expected: list of bindings\n Got: %A " other
83- generateBody scope_ subctx typeBuilder ilGen body
84- ilGen.EndScope()
85- | Atom ( Symbol fname) :: args -> //generic funcall pattern
86- genApply fname context typeBuilder ilGen args
87- | _ -> failwithf " %A not supported yet." list
88- | Atom a ->
89- let genf = new GeneratorFactory( typeBuilder) :> IGeneratorFactory
90- let gen = genf.MakeGenerator context ( Atom a)
91- ignore ( gen.Generate ilGen)
92- | other -> failwithf " %A form not supported yet." other
93- and private generateBody context ( typeBuilder : TypeBuilder ) ( ilGen : ILGenerator ) ( body : SExp list ) =
94- match body with
95- | [] ->
96- ilGen.Emit( OpCodes.Ldnull)
97- | [ last] ->
98- generate context typeBuilder ilGen last
99- | sexp :: rest ->
100- generate context typeBuilder ilGen sexp
101- ilGen.Emit( OpCodes.Pop)
102- generateBody context typeBuilder ilGen rest
103- and private generateSeq context ( typeBuilder : TypeBuilder ) ( ilGen : ILGenerator ) ( seq : SExp list ) =
104- match seq with
105- | [] ->
106- ilGen.Emit( OpCodes.Ldnull)
107- | [ last] ->
108- generate context typeBuilder ilGen last
109- | sexp :: rest ->
110- generate context typeBuilder ilGen sexp
111- generateBody context typeBuilder ilGen rest
112- and private genApply ( funcName : string ) ( context : Context ) ( typeBuilder : TypeBuilder ) ( ilGen : ILGenerator ) ( argList : SExp list ) : unit =
113- try
114- let func = context.functions.[ funcName]
115- generateSeq context typeBuilder ilGen argList
116- ilGen.Emit( OpCodes.Call, func)
117- with
118- | :? KeyNotFoundException -> failwithf " Function %A not found." funcName
119-
12036let private prologue ( ilGen : ILGenerator ) =
12137 ilGen.BeginScope()
12238
12339let private epilogue context typeBuilder ( ilGen : ILGenerator ) =
124- (* let argGetter = typeof<Value>.GetMethod "get_EmptyList"
125- let isAtomGetter = typeof<SExp>.GetMethod "get_IsAtom"
126- let atomItemGetter = typeof<SExp>.GetNestedType("Atom").GetMethod "get_Item"
127- let isNumberGetter = typeof<Value>.GetMethod "get_IsNumber"
128- let numberItemGetter = typeof<Value>.GetNestedType("Number").GetMethod "get_Item" *)
129-
130- //ilGen.Emit(OpCodes.Call, argGetter)
131- genApply " main" context typeBuilder ilGen ([])
132- (*
133- // Analyze value returned from main:
134- let sexp = ilGen.DeclareLocal(typeof<SExp>)
135- let value = ilGen.DeclareLocal(typeof<Value>)
136-
137- let returnZero = ilGen.DefineLabel()
138- let ``return`` = ilGen.DefineLabel()
139-
140- // Get SExp:
141- ilGen.Emit(OpCodes.Castclass, typeof<SExp>)
142- ilGen.Emit(OpCodes.Stloc, sexp.LocalIndex)
143-
144- // Check whether SExp is SExp.Atom:
145- ilGen.Emit(OpCodes.Ldloc, sexp.LocalIndex)
146- ilGen.Emit(OpCodes.Call, isAtomGetter)
147- ilGen.Emit(OpCodes.Brfalse, returnZero)
148-
149- // Cast SExp to SExp.Atom:
150- ilGen.Emit(OpCodes.Ldloc, sexp.LocalIndex)
151- ilGen.Emit(OpCodes.Castclass, typeof<SExp>.GetNestedType("Atom"))
152-
153- // Get Value:
154- ilGen.Emit(OpCodes.Call, atomItemGetter)
155- ilGen.Emit(OpCodes.Stloc, value.LocalIndex)
156-
157- // Check whether Value is Number:
158- ilGen.Emit(OpCodes.Ldloc, value.LocalIndex)
159- ilGen.Emit(OpCodes.Call, isNumberGetter)
160- ilGen.Emit(OpCodes.Brfalse, returnZero)
161-
162- // Cast Value to Number:
163- ilGen.Emit(OpCodes.Ldloc, value.LocalIndex)
164- ilGen.Emit(OpCodes.Castclass, typeof<Value>.GetNestedType("Number"))
165-
166- // Get float64 value:
167- ilGen.Emit(OpCodes.Call, numberItemGetter)
168-
169- // Convert to int32:
170- ilGen.Emit(OpCodes.Conv_I4)
171- ilGen.Emit(OpCodes.Br, ``return``)
172-
173- ilGen.MarkLabel returnZero
174- ilGen.Emit(OpCodes.Ldc_I4, 0)
175-
176- ilGen.MarkLabel ``return``
177- *)
17840 ilGen.Emit OpCodes.Ret
17941 ilGen.EndScope()
18042
@@ -200,10 +62,12 @@ let compile (source : StreamReader) (assemblyName : string) (fileName : string)
20062
20163 prologue ilGenerator
20264 while not source.EndOfStream do
203- let sexp = Reader.parse source
204- let gen = gf.MakeGenerator context sexp
205- ignore( gen.Generate ilGenerator)
206- //generate context typeBuilder ilGenerator sexp
65+ try
66+ let sexp = Reader.parse source
67+ let gen = gf.MakeGenerator context sexp
68+ gen.Generate ilGenerator
69+ with
70+ | ex -> printfn " File: %A \n Form: %A \n Error: %A " fileName sexp ex.Source
20771
20872 epilogue context typeBuilder ilGenerator
20973
0 commit comments