d6d5cc8df7
Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
153 lines
4.4 KiB
Swift
153 lines
4.4 KiB
Swift
public struct LocalElements {
|
|
|
|
}
|
|
|
|
public struct LocalElement {
|
|
|
|
}
|
|
|
|
public class ParserExecution: ProgramExecution {
|
|
public var state: ParserState
|
|
|
|
public init(_ state: ParserState) {
|
|
self.state = state
|
|
}
|
|
|
|
public func transition(toNextState state: ParserState) -> ParserExecution {
|
|
let next = self
|
|
next.state = state
|
|
return next
|
|
}
|
|
|
|
public override var description: String {
|
|
return "Execution: \(super.description)\nCurrent State: \(state)"
|
|
}
|
|
}
|
|
|
|
public protocol Expression {
|
|
/// Evaluate an expression for a given execution
|
|
/// - Parameters
|
|
/// - execution: The execution context in which to evaluate the expression
|
|
/// - Returns: The value of expression
|
|
func evaluate(execution: ParserExecution) -> Value
|
|
}
|
|
|
|
public protocol ParserStatement {
|
|
/// Evaluate a statement for a given execution
|
|
/// - Parameters
|
|
/// - execution: The execution context in which to evaluate the parser statement
|
|
/// - Returns: An updated execution after evaluating the parser statement
|
|
func evaluate(execution: ParserExecution) -> ParserExecution
|
|
}
|
|
|
|
public struct ParserTransitionStatement: ParserStatement {
|
|
public init() {}
|
|
public func evaluate(execution: ParserExecution) -> ParserExecution {
|
|
return execution
|
|
}
|
|
}
|
|
|
|
public struct VariableDeclarationStatement: ParserStatement {
|
|
public var id: Identifier
|
|
public init(withIdentifier id: Identifier) {
|
|
self.id = id
|
|
}
|
|
|
|
public func evaluate(execution: ParserExecution) -> ParserExecution {
|
|
print("Evaluating!")
|
|
execution.scopes.scopes[0].variables.append(Variable(name: id.name, withValue: id.value, isConstant: false))
|
|
print("Execution: \(execution)")
|
|
return execution
|
|
}
|
|
}
|
|
|
|
public struct ExpressionStatement: ParserStatement {
|
|
public init() {}
|
|
public func evaluate(execution: ParserExecution) -> ParserExecution {
|
|
return execution
|
|
}
|
|
}
|
|
|
|
public struct ParserState: Equatable, CustomStringConvertible {
|
|
|
|
public private(set) var state_name: String
|
|
public private(set) var local_elements: [ParserStatement]
|
|
public private(set) var statements: [ParserStatement]
|
|
public private(set) var transition: ParserTransitionStatement?
|
|
|
|
public var description: String {
|
|
return "Name: \(state_name)"
|
|
}
|
|
|
|
public static func == (lhs: ParserState, rhs: ParserState) -> Bool {
|
|
return lhs.state_name == rhs.state_name
|
|
}
|
|
|
|
/// Construct a ParserState
|
|
public init(name: String, withLocalElements localElements: [ParserStatement]?, withStatements statements: [ParserStatement]?, withTransition transitionStatement: ParserTransitionStatement) {
|
|
state_name = name
|
|
transition = transitionStatement
|
|
local_elements = localElements ?? Array()
|
|
self.statements = statements ?? Array()
|
|
}
|
|
|
|
func evaluate(execution: ParserExecution) -> ParserExecution {
|
|
var currentExecution = execution
|
|
|
|
// First, evaluate the local elements.
|
|
for local_element in local_elements {
|
|
currentExecution = local_element.evaluate(execution: currentExecution)
|
|
}
|
|
|
|
// Then, evaluate the statements.
|
|
for statement in statements {
|
|
currentExecution = statement.evaluate(execution: currentExecution)
|
|
}
|
|
|
|
return if let transition = transition {
|
|
currentExecution.transition(toNextState: accept)
|
|
} else {
|
|
currentExecution.transition(toNextState: reject)
|
|
}
|
|
}
|
|
|
|
/// (private) constructor (no transition)
|
|
///
|
|
/// accept and reject are the only final states and they are constructed internally.
|
|
init(name: String) {
|
|
state_name = name
|
|
transition = .none
|
|
local_elements = Array()
|
|
statements = Array()
|
|
}
|
|
}
|
|
|
|
public struct ParserStates {
|
|
public var states: [ParserState] = Array()
|
|
}
|
|
|
|
nonisolated(unsafe) public let accept: ParserState = ParserState(name: "accept")
|
|
nonisolated(unsafe) public let reject: ParserState = ParserState(name: "reject")
|
|
|
|
public struct Parser: CustomStringConvertible {
|
|
public var states: [ParserState] = Array()
|
|
public var count: Int {
|
|
states.count
|
|
}
|
|
|
|
public init() {}
|
|
|
|
public func findStartState() -> Optional<ParserState> {
|
|
for state in states {
|
|
if state.state_name == "start" {
|
|
return state
|
|
}
|
|
}
|
|
return .none
|
|
}
|
|
|
|
public var description: String {
|
|
return "Parser"
|
|
}
|
|
}
|