XCTLInitStatement.swift 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. //
  2. // XCTLInitStatement.swift
  3. // notebook
  4. //
  5. // Created by 邢铖 on 2023/5/18.
  6. //
  7. import Foundation
  8. internal class XCTLInitStatement: XCTLStatement, XCTLExpressionPart {
  9. var type: XCTLStatementType { .typeInit }
  10. var holdingObject: XCTLRuntimeVariable = .void
  11. var expressionValue: XCTLExpressionValue { .product }
  12. var typeName: String = ""
  13. var defineName: String = ""
  14. var initArgumentStatements = [XCTLStatement]()
  15. var lazyInitStatements = [XCTLStatement]()
  16. var generatedObject: XCTLRuntimeVariable?
  17. weak var parent: XCTLStatement?
  18. func matchSelfStatement(lex: XCTLLexer) throws -> XCTLStatement? {
  19. let pos = lex.position
  20. if try lex.next().type == .typeIdentifier,
  21. try lex.next().type == .typeIdentifier,
  22. try lex.next().type == .typeOpenBrace {
  23. return XCTLInitStatement()
  24. }
  25. lex.position = pos
  26. if try lex.next().type == .typeIdentifier,
  27. try lex.next().type == .typeOpenBrace {
  28. return XCTLInitStatement()
  29. }
  30. return nil
  31. }
  32. func parseStatement(fromLexerToSelf lex: XCTLLexer, fromParent: XCTLStatement?) throws {
  33. self.parent = fromParent
  34. let typeName = try lex.next()
  35. self.typeName = typeName.rawValue
  36. let nextType = try lex.peek().type
  37. var continueDefine = false
  38. switch nextType {
  39. case .typeIdentifier:
  40. continueDefine = true
  41. break
  42. case .typeOpenBrace:
  43. continueDefine = false
  44. break
  45. default:
  46. throw XCTLCompileTimeError.unexpectTokenInStatement(expect: "typeIdentifier or typeOpenBrace", butGot: nextType.rawValue)
  47. }
  48. if continueDefine {
  49. let nameToken = try lex.next()
  50. defineName = nameToken.rawValue
  51. } else {
  52. defineName = "unnamedObject_" + UUID().uuidString
  53. }
  54. let openBrace1 = try lex.next()
  55. if openBrace1.type != .typeOpenBrace {
  56. throw XCTLCompileTimeError.unexpectTokenInStatement(expect: XCTLTokenType.typeOpenBrace.rawValue, butGot: openBrace1.type.rawValue)
  57. }
  58. while let closeBrace = try? lex.peek(),
  59. closeBrace.type != .typeCloseBrace {
  60. let innerStatement = try self.parseNextExpression(forLexer: lex, terminator: .typeCloseBrace)
  61. self.initArgumentStatements.append(innerStatement)
  62. }
  63. try lex.next()
  64. if try lex.peek().type == .typeOpenBrace {
  65. try lex.next()
  66. while let closeBrace = try? lex.peek(),
  67. closeBrace.type != .typeCloseBrace {
  68. let innerStatement = try self.parseNextStatement(forLexer: lex)
  69. self.lazyInitStatements.append(innerStatement)
  70. }
  71. try lex.next()
  72. }
  73. lex.lastStatement = self
  74. }
  75. func evaluate(inContext context: XCTLRuntimeAbstractContext) throws -> XCTLRuntimeVariable {
  76. var variables = [XCTLRuntimeVariable]()
  77. for statement in initArgumentStatements {
  78. let value = try statement.evaluate(inContext: context)
  79. if value.type != .typeVoid {
  80. variables.append(value)
  81. }
  82. }
  83. let realTypeName = XCTLTypeMapper.mapName(typeName)
  84. let object = try context.allocateObject(name: realTypeName, args: variables)
  85. self.generatedObject = object
  86. context.setValue(object, forName: self.defineName)
  87. self.holdingObject = object
  88. for it in self.lazyInitStatements {
  89. let referencedStmt = XCTLReferencedVariableStatement(objectReferenced: object, statement: it)
  90. context.addLazyStatement(referencedStmt)
  91. }
  92. context.variableStack.pushVariable(object)
  93. return object
  94. }
  95. }