1
1
mirror of https://github.com/github/semantic.git synced 2025-01-05 22:28:10 +03:00
semantic/prototype/Doubt/Syntax.swift

133 lines
3.4 KiB
Swift
Raw Normal View History

2015-09-18 17:12:34 +03:00
public enum Term: CustomDebugStringConvertible, CustomDocConvertible, CustomStringConvertible, Equatable {
public init(_ out: Syntax<Term>) {
2015-09-15 20:49:23 +03:00
self = .Roll(out)
2015-07-18 22:43:49 +03:00
}
2015-09-15 21:07:35 +03:00
case Empty
2015-09-18 17:12:34 +03:00
indirect case Roll(Syntax<Term>)
2015-07-18 22:43:49 +03:00
2015-09-15 21:07:35 +03:00
public var debugDescription: String {
2015-09-15 20:49:23 +03:00
switch self {
2015-09-15 21:07:35 +03:00
case .Empty:
return ".Empty"
2015-09-15 20:49:23 +03:00
case let .Roll(s):
2015-09-15 21:07:35 +03:00
return s.debugDescription
2015-09-15 20:49:23 +03:00
}
2015-07-18 22:43:49 +03:00
}
public var doc: Doc {
2015-09-15 21:07:35 +03:00
switch self {
case .Empty:
return .Empty
case let .Roll(s):
return s.doc
}
2015-07-18 22:43:49 +03:00
}
2015-09-23 00:26:45 +03:00
2015-09-23 19:31:28 +03:00
public static let Apply = Syntax.Apply >>> Roll
public static let Abstract = Syntax.Abstract >>> Roll
public static let Assign = Syntax.Assign >>> Roll
public static let Variable = Syntax.Variable >>> Roll
public static let Literal = Syntax.Literal >>> Roll
public static let Group = Syntax.Group >>> Roll
2015-07-18 22:43:49 +03:00
}
2015-09-15 20:46:45 +03:00
public enum Syntax<Payload>: CustomDebugStringConvertible, CustomDocConvertible {
2015-07-18 22:43:49 +03:00
case Apply(Payload, [Payload])
case Abstract([Payload], [Payload])
2015-07-18 22:43:49 +03:00
case Assign(String, Payload)
case Variable(String)
case Literal(String)
case Group(Payload, [Payload])
public func map<T>(@noescape transform: Payload -> T) -> Syntax<T> {
2015-07-18 22:43:49 +03:00
switch self {
case let .Apply(f, args):
return .Apply(transform(f), args.map(transform))
case let .Abstract(parameters, body):
return .Abstract(parameters.map(transform), body.map(transform))
2015-07-18 22:43:49 +03:00
case let .Assign(n, v):
return .Assign(n, transform(v))
case let .Variable(n):
return .Variable(n)
case let .Literal(v):
return .Literal(v)
case let .Group(n, v):
return .Group(transform(n), v.map(transform))
}
}
2015-09-16 19:22:53 +03:00
public func reduce<T>(var initial: T, @noescape combine: (T, Payload) throws -> T) rethrows -> T {
switch self {
case let .Apply(x, xs):
initial = try combine(initial, x)
return try xs.reduce(initial, combine: combine)
case let .Abstract(xs, x):
initial = try xs.reduce(initial, combine: combine)
return try x.reduce(initial, combine: combine)
2015-09-16 19:22:53 +03:00
case let .Assign(_, x):
return try combine(initial, x)
case let .Group(x, xs):
initial = try combine(initial, x)
return try xs.reduce(initial, combine: combine)
default:
return initial
}
}
public typealias Recur = Payload
2015-07-18 22:43:49 +03:00
public var debugDescription: String {
2015-07-18 22:43:49 +03:00
switch self {
case let .Apply(f, vs):
2015-09-15 21:07:35 +03:00
let s = vs.map { String(reflecting: $0) }.joinWithSeparator(", ")
2015-07-18 22:43:49 +03:00
return ".Apply(\(f), [ \(s) ])"
case let .Abstract(parameters, body):
2015-09-15 21:07:35 +03:00
let s = parameters.map { String(reflecting: $0) }.joinWithSeparator(", ")
2015-07-18 22:43:49 +03:00
return ".Abstract([ \(s) ], \(body))"
case let .Assign(n, v):
return ".Assign(\(n), \(v))"
case let .Variable(n):
return ".Variable(\(n))"
case let .Literal(s):
return ".Literal(\(s))"
case let .Group(n, vs):
2015-09-15 21:07:35 +03:00
let s = vs.map { String(reflecting: $0) }.joinWithSeparator(", ")
return ".Group(\(String(reflecting: n)), [ \(s) ])"
2015-07-18 22:43:49 +03:00
}
}
public var doc: Doc {
2015-07-18 22:43:49 +03:00
switch self {
case let .Apply(f, vs):
return .Horizontal([
Doc(f),
2015-09-15 21:33:09 +03:00
.Wrap(.Text("("), .Join(.Text(", "), vs.map(Doc.init)), .Text(")"))
2015-07-18 22:43:49 +03:00
])
case let .Abstract(parameters, body):
return .Horizontal([
2015-09-15 21:33:09 +03:00
.Text("λ"),
.Join(.Text(", "), parameters.map(Doc.init)),
.Text("."),
2015-09-23 00:35:41 +03:00
.Vertical(body.map(Doc.init))
2015-07-18 22:43:49 +03:00
])
case let .Assign(n, v):
return .Horizontal([ .Text(n), .Text("="), Doc(v) ])
2015-07-18 22:43:49 +03:00
case let .Variable(n):
return .Text(n)
case let .Literal(s):
return .Text(s)
case let .Group(n, vs):
return .Horizontal([
Doc(n),
2015-09-15 21:33:09 +03:00
.Wrap(.Text("{"), .Vertical(vs.map(Doc.init)), .Text("}"))
2015-07-18 22:43:49 +03:00
])
}
}
}