Created
October 12, 2018 15:19
-
-
Save BenziAhamed/16b4b4d2bf8aa7a309983e56c384831e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Cocoa | |
// what is a 'type'? | |
// it has a domain, a name | |
// it can have 'properties' | |
protocol TypeBuilder : class { | |
func setType(type: String) | |
func setTypeName(name: String) | |
func addProperty(type: String, label: String) | |
var codeRepresentation: String { get } | |
} | |
class DebuggingTypeBuilder : TypeBuilder { | |
func setType(type: String) { | |
print("type is \(type)") | |
} | |
func setTypeName(name: String) { | |
print("type name is \(name)") | |
} | |
func addProperty(type: String, label: String) { | |
print("property '\(label)' of \(type)") | |
} | |
var codeRepresentation: String { | |
return "code representation unsupported" | |
} | |
} | |
class BaseTypeBuilder : TypeBuilder { | |
var typeName: String = "" | |
var type: String = "" | |
var properties = [(type: String, label: String)]() | |
func setTypeName(name: String) { | |
typeName = name | |
} | |
func setType(type: String) { | |
self.type = type | |
} | |
func addProperty(type: String, label: String) { | |
properties.append((type, label)) | |
} | |
open var codeRepresentation: String { | |
fatalError("This must be overriden with a concrete implementation") | |
} | |
} | |
class CobolTypeBuilder : BaseTypeBuilder { | |
static let typeMap = [ | |
"Int" : "INTEGER", | |
"String" : "STRING", | |
] | |
override var codeRepresentation: String { | |
let properties = self.properties.map { | |
let type = CobolTypeBuilder.typeMap[$0.type, default: "UNKNOWN"] | |
return " VARIABLE \($0.label.uppercased()) OF \(type)" | |
}.joined(separator: "\n") | |
return """ | |
BEGIN RECORD \(typeName.uppercased()) | |
\(properties) | |
END TYPE | |
""" | |
} | |
} | |
class PythonTypeBuilder : BaseTypeBuilder { | |
override var codeRepresentation: String { | |
let initList = properties.map { | |
"\($0.label)" | |
}.joined(separator: ", ") | |
let assignList = properties.map { | |
" self.\($0.label) = \($0.label)" | |
}.joined(separator: "\n ") | |
return """ | |
class \(typeName): | |
def __init(\(initList)): | |
\(assignList) | |
""" | |
} | |
} | |
class KotlinTypeBuilder : BaseTypeBuilder { | |
override var codeRepresentation: String { | |
let properties = self.properties.map { | |
"val \($0.label): \($0.type)" | |
}.joined(separator: ", ") | |
return "data class \(typeName)(\(properties))" | |
} | |
} | |
class JavaTypeBuilder : BaseTypeBuilder { | |
override var codeRepresentation: String { | |
let properties = self.properties.map { | |
" public \($0.type) \($0.label);" | |
}.joined(separator: "\n") | |
return """ | |
class \(typeName) { | |
\(properties) | |
} | |
""" | |
} | |
} | |
struct TypeEncoder { | |
func encode<T>(value: T, using builder: TypeBuilder) { | |
let mirror = Mirror(reflecting: value) | |
var typeInfo = "<untyped>" | |
mirror.displayStyle.flatMap { typeInfo = "\($0)" } | |
builder.setType(type: typeInfo) | |
let typeName = type(of: value) | |
builder.setTypeName(name: "\(typeName)") | |
mirror.children.forEach { | |
let childType = type(of: $0.value) | |
builder.addProperty(type: "\(childType)", label: $0.label ?? "<unlabeled>") | |
} | |
} | |
} | |
struct Point { | |
let x: Int | |
let y: Int | |
} | |
extension Point { | |
static let zero = Point.init(x: 0, y: 0) | |
} | |
let builders: [TypeBuilder] = [ | |
DebuggingTypeBuilder(), | |
CobolTypeBuilder(), | |
KotlinTypeBuilder(), | |
JavaTypeBuilder(), | |
PythonTypeBuilder(), | |
] | |
builders.forEach { | |
print("\(type(of: $0))") | |
TypeEncoder().encode(value: Point.zero, using: $0) | |
print("\($0.codeRepresentation)") | |
print() | |
} | |
Author
BenziAhamed
commented
Oct 12, 2018
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment