XCTLLessthanStatement.swift 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  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.parseNextExpression(forLexer: lex, terminator: .typeOpenBrace)
  33. try self.childrenStmt.parseStatement(fromLexerToSelf: lex, fromParent: self)
  34. lex.lastStatement = self
  35. }
  36. func evaluate(inContext context: XCTLRuntimeAbstractContext) throws -> XCTLRuntimeVariable {
  37. guard let condFrame = context.findConditionFrame() else {
  38. throw XCTLRuntimeError.invalidConditionFrame
  39. }
  40. guard let originalValue = self.parent?.holdingObject,
  41. originalValue.type != .typeVoid else {
  42. throw XCTLRuntimeError.parentNoHoldingObject
  43. }
  44. if condFrame.doNext {
  45. condFrame.doNext = false
  46. condFrame.doElse = false
  47. return try self.childrenStmt.evaluate(inContext: context)
  48. }
  49. let compareValue = try self.compareValueStmt.evaluate(inContext: context)
  50. if compareValue.type == .typeVoid {
  51. throw XCTLRuntimeError.unexpectedVariableType(expect: "any", butGot: "void")
  52. }
  53. if compareValue.type != .typeNumber || originalValue.type != .typeNumber {
  54. throw XCTLRuntimeError.unexpectedVariableType(expect: "number", butGot: compareValue.type.rawValue)
  55. }
  56. if compareValue.doubleValue > originalValue.doubleValue {
  57. condFrame.doElse = false
  58. return try self.childrenStmt.evaluate(inContext: context)
  59. }
  60. return .void
  61. }
  62. }