XCTLLessthanStatement.swift 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. //
  2. // XCTLLessthanStatement.swift
  3. // notebook
  4. //
  5. // Created by 邢铖 on 2023/5/25.
  6. //
  7. import Foundation
  8. internal class XCTLLessthanStatement : XCTLStatement {
  9. var type: XCTLStatementType { .typeLessthan }
  10. var holdingObject: XCTLRuntimeVariable { .void }
  11. var compareValueStmt: XCTLStatement!
  12. var childrenStmt: XCTLStatement = XCTLListStatement()
  13. weak var condStmt: XCTLConditionParentStatement?
  14. weak var parent: XCTLStatement?
  15. func matchSelfStatement(lex: XCTLLexer) throws -> XCTLStatement? {
  16. if try lex.next().type == .typeLessthan {
  17. return XCTLLessthanStatement()
  18. }
  19. return nil
  20. }
  21. func parseStatement(fromLexerToSelf lex: XCTLLexer, fromParent: XCTLStatement?) throws {
  22. if fromParent == nil {
  23. throw XCTLCompileTimeError.unexpectParentStatementType(expect: "any", butGot: "none")
  24. }
  25. guard let parent = fromParent as? XCTLListStatementProtocol,
  26. let condStmt = parent.conditionParent else {
  27. throw XCTLCompileTimeError.unexpectParentStatementType(expect: "any-cond-stmt", butGot: "\(fromParent?.type.rawValue ?? "void")")
  28. }
  29. self.parent = fromParent
  30. self.condStmt = condStmt
  31. try lex.next()
  32. self.compareValueStmt = try self.parseNextStatement(forLexer: lex)
  33. try self.childrenStmt.parseStatement(fromLexerToSelf: lex, fromParent: self)
  34. }
  35. func evaluate(inContext context: XCTLRuntimeAbstractContext) throws -> XCTLRuntimeVariable {
  36. guard let condFrame = context.findConditionFrame() else {
  37. throw XCTLRuntimeError.invalidConditionFrame
  38. }
  39. guard let originalValue = self.parent?.holdingObject,
  40. originalValue.type != .typeVoid else {
  41. throw XCTLRuntimeError.parentNoHoldingObject
  42. }
  43. if condFrame.doNext {
  44. condFrame.doNext = false
  45. condFrame.doElse = false
  46. return try self.childrenStmt.evaluate(inContext: context)
  47. }
  48. let compareValue = try self.compareValueStmt.evaluate(inContext: context)
  49. if compareValue.type == .typeVoid {
  50. throw XCTLRuntimeError.unexpectedVariableType(expect: "any", butGot: "void")
  51. }
  52. if compareValue.type != .typeNumber || originalValue.type != .typeNumber {
  53. throw XCTLRuntimeError.unexpectedVariableType(expect: "number", butGot: compareValue.type.rawValue)
  54. }
  55. if compareValue.doubleValue > originalValue.doubleValue {
  56. condFrame.doElse = false
  57. return try self.childrenStmt.evaluate(inContext: context)
  58. }
  59. return .void
  60. }
  61. }