XCTLReturnStatement.swift 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. //
  2. // XCTLReturnStatement.swift
  3. // XCTreeLang
  4. //
  5. // Created by 邢铖 on 2023/6/1.
  6. //
  7. import Foundation
  8. internal class XCTLReturnStatement: XCTLStatement {
  9. var type: XCTLStatementType { .typeReturn }
  10. var holdingObject: XCTLRuntimeVariable { .void }
  11. var returnValueStatement: XCTLStatement!
  12. weak var parent: XCTLStatement?
  13. weak var parentParagraph: XCTLParagraphStatement!
  14. func matchSelfStatement(lex: XCTLLexer) throws -> XCTLStatement? {
  15. return try lex.peek().type == .typeReturn ? XCTLReturnStatement() : nil
  16. }
  17. func parseStatement(fromLexerToSelf lex: XCTLLexer, fromParent: XCTLStatement?) throws {
  18. self.parent = fromParent
  19. var parentStmt: XCTLStatement? = self.parent
  20. while let stmt = parentStmt {
  21. if let listStmt = stmt as? XCTLParagraphStatement {
  22. self.parentParagraph = listStmt
  23. break
  24. }
  25. parentStmt = stmt.parent
  26. }
  27. if parentParagraph == nil {
  28. throw XCTLCompileTimeError.unexpectParentStatementType(expect: XCTLStatementType.typeParagraph.rawValue, butGot: self.parent?.type.rawValue ?? "none")
  29. }
  30. try lex.next()
  31. self.returnValueStatement = try self.parseNextExpression(forLexer: lex)
  32. lex.lastStatement = self
  33. }
  34. func evaluate(inContext context: XCTLRuntimeAbstractContext) throws -> XCTLRuntimeVariable {
  35. guard let listFrame = context.findListFrame() else {
  36. throw XCTLRuntimeError.invalidListFrame
  37. }
  38. let condFrame = context.findConditionFrame()
  39. let value = try self.returnValueStatement.evaluate(inContext: context)
  40. listFrame.breakListEvaluate = true
  41. listFrame.listResultValue = value
  42. condFrame?.doElse = false
  43. return value
  44. }
  45. }