Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- namespace codegenfs
- type mlist<'a> =
- System.Collections.Generic.List<'a>
- type File (indentToken : string) =
- let sb = new System.Text.StringBuilder(1024)
- let mutable indent = 0
- member x.Emit (s:string) =
- sb.Append(s) |> ignore
- member x.EmitLineStart () =
- for i in 1 .. indent do
- sb.Append(indentToken) |> ignore
- member x.EmitLineStart (s:string) =
- x.EmitLineStart()
- x.Emit(s)
- member x.EmitLineEnd () =
- sb.Append(System.Environment.NewLine) |> ignore
- member x.EmitLineEnd (s:string) =
- x.Emit(s)
- x.EmitLineEnd()
- member x.EmitLine (s:string) =
- x.EmitLineStart()
- x.Emit(s)
- x.EmitLineEnd()
- member x.Indent (f) =
- indent <- indent + 1
- f()
- indent <- indent - 1
- member x.EmitBlock (f) =
- x.EmitLine("{")
- x.Indent(f)
- x.EmitLine("}")
- override x.ToString () =
- sb.ToString()
- type BinaryOp =
- | Add
- | AddAssign
- | Sub
- | SubAssign
- | Mul
- | MulAssign
- | Div
- | DivAssign
- | Assign
- | Equals
- | NotEquals
- | LessThan
- | LessThanEqual
- | GreaterThan
- | GreaterThanEqual
- type Modifiers =
- | Public = 1
- | Protected = 2
- | Private = 4
- | Internal = 8
- | Abstract = 16
- | Virtual = 32
- | Override = 64
- | Sealed = 128
- | Static = 256
- | Partial = 512
- type CType = {
- Name : string
- } with
- static member Object = {CType.Name = "System.Object"}
- static member op_Implicit(t:System.Type) =
- let rec getName (t:System.Type) =
- let name = t.FullName.Replace('+', '.')
- let args = t.GetGenericArguments()
- if args.Length = 0 then name else
- System.Text.RegularExpressions.Regex.Match(name, "[^`]+").Value
- + "<"
- + (args |> Seq.map getName |> String.concat ", ")
- + ">"
- {CType.Name = getName t}
- type Field = {
- Type : CType
- Name : string
- Modifiers : Modifiers
- Initialize : Source option
- }
- and Property = {
- Type : CType
- Name : string
- Modifiers : Modifiers
- Get : Source option
- Set : Source option
- }
- and Class = {
- Name : string
- BaseType : CType
- Interfaces : CType mlist
- Modifiers : Modifiers
- Fields : Field mlist
- Properties : Property mlist
- } with
- member x.AllBaseTypes =
- seq {
- yield x.BaseType.Name;
- yield! [for i in x.Interfaces -> i.Name]
- } |> String.concat ","
- member x.AsCType =
- {CType.Name = x.Name}
- static member New (mods, name, baseType, interfaces) =
- {
- Class.Name = name
- Class.Modifiers = mods
- Class.BaseType = baseType
- Class.Interfaces = if interfaces = null then new mlist<_>() else interfaces
- Class.Fields = new mlist<_>()
- Class.Properties = new mlist<_>()
- }
- and Source =
- | Raw of string
- | Stmt of Source
- | Class of Class
- | Block of Source array
- | While of Source * Source
- | For of Source * Source * Source * Source
- | IfElse of Source * Source * Source option
- | Binary of Source * BinaryOp * Source
- | Namespace of string * Source mlist
- static member op_Implicit (s:string) = Raw(s)
- static member op_Implicit (l:Source mlist) = Block(l.ToArray())
- static member op_Implicit (a:Source array) = Block(a)
- static member op_Implicit (s:Source seq) = Block(Seq.toArray s)
- static member op_Implicit (s:Source) = Some(s)
- static member op_Implicit (c:Class) = Class(c)
- static member Null = Raw("null")
- static member This = Raw("this")
- static member Base = Raw("base")
- static member True = Raw("true")
- static member False = Raw("false")
- static member NewRawStmt (s:string) =
- Stmt(Raw s)
- static member NewBlockSimple ([<System.ParamArray>] s:Source array) =
- Block s
- static member NewForSimple (var:string, condition:Source, body:Source) =
- For(
- Binary(Raw ("int " + var), BinaryOp.Assign, Raw "0"),
- Binary(Raw var, BinaryOp.LessThan, condition),
- Binary(Raw var, BinaryOp.AddAssign, Raw "1"),
- body
- )
- static member private ToString (op:BinaryOp) =
- match op with
- | Add -> "+"
- | AddAssign -> "+="
- | Sub -> "-"
- | SubAssign -> "-="
- | Mul -> "*"
- | MulAssign -> "*="
- | Div -> "/"
- | DivAssign -> "/="
- | Equals -> "=="
- | NotEquals -> "!="
- | Assign -> "="
- | LessThan -> "<"
- | LessThanEqual -> "<="
- | GreaterThan -> ">"
- | GreaterThanEqual -> ">="
- static member private ToString (mods:Modifiers) =
- "public"
- static member private Emit (f:Field, file:File) =
- let mods = Source.ToString(f.Modifiers)
- file.EmitLineStart()
- file.Emit(sprintf "%s %s %s" mods f.Type.Name f.Name)
- f.Initialize |> Option.iter (fun s -> file.Emit(" = "); Source.Emit(s, file))
- file.Emit(";")
- file.EmitLineEnd()
- static member private Emit (p:Property, file:File) =
- let mods = Source.ToString(p.Modifiers)
- file.EmitLine(sprintf "%s %s %s" mods p.Type.Name p.Name)
- file.EmitBlock(fun () ->
- p.Get |> Option.iter (fun g -> file.EmitLine("get"); Source.Emit (Block [|g|], file))
- p.Set |> Option.iter (fun s -> file.EmitLine("set"); Source.Emit (Block [|s|], file))
- )
- static member private EmitBlock (src:Source, file:File) =
- match src with
- | Block _ -> Source.Emit(src, file)
- | s -> Source.Emit(Block [|s|], file)
- static member Emit (src:Source, file:File) =
- match src with
- | Raw s ->
- file.Emit(s)
- | Stmt s ->
- file.EmitLineStart()
- Source.Emit(s, file)
- file.Emit(";")
- file.EmitLineEnd()
- | Block b ->
- file.EmitBlock(fun () -> for s in b do Source.Emit(s, file))
- | For (init, cond, incr, body) ->
- file.EmitLineStart("for (")
- Source.Emit(init, file)
- file.Emit("; ")
- Source.Emit(cond, file)
- file.Emit("; ")
- Source.Emit(incr, file)
- file.EmitLineEnd(")")
- Source.EmitBlock(body, file)
- | Binary (left, op, right) ->
- file.Emit("(")
- Source.Emit(left, file)
- file.Emit(Source.ToString(op))
- Source.Emit(right, file)
- file.Emit(")")
- | IfElse (expr, if', else') ->
- // test
- file.EmitLineStart("if (")
- Source.Emit(expr, file)
- file.EmitLineEnd(")")
- // if-body
- Source.EmitBlock(if', file)
- // else-body
- else' |> Option.iter (fun s ->
- file.EmitLine("else")
- Source.EmitBlock(s, file)
- )
- | Class c ->
- let mods = Source.ToString(c.Modifiers)
- file.EmitLine(sprintf "%s class %s : %s" mods c.Name c.AllBaseTypes)
- file.EmitBlock(fun () ->
- for f in c.Fields do Source.Emit(f, file)
- for p in c.Properties do Source.Emit(p, file)
- )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement