From 6926feead1a7fadb7f5f974996bef8c30b3bfdbe Mon Sep 17 00:00:00 2001 From: Ruben Beltran del Rio Date: Wed, 9 Jul 2025 01:55:50 +0200 Subject: Use AST based text editor --- Map/Business/WmapParser/Entity.swift | 389 +++++++++++++++++++++++++++++++++++ 1 file changed, 389 insertions(+) create mode 100644 Map/Business/WmapParser/Entity.swift (limited to 'Map/Business/WmapParser/Entity.swift') diff --git a/Map/Business/WmapParser/Entity.swift b/Map/Business/WmapParser/Entity.swift new file mode 100644 index 0000000..40dd7ca --- /dev/null +++ b/Map/Business/WmapParser/Entity.swift @@ -0,0 +1,389 @@ +struct Wmap { + protocol Entity { + var position: SourcePosition { get } + var range: SourceRange { get } + var syntaxElements: [SyntaxElement] { get } + } + + struct Vertex: Entity { + let label: String + let position: SourcePosition + let coordinates: (Double, Double) + let shape: String? + let range: SourceRange + + // Syntax element ranges (populated during parsing) + let labelRange: SourceRange + let leftParenRange: SourceRange + let xCoordRange: SourceRange + let commaRange: SourceRange + let yCoordRange: SourceRange + let rightParenRange: SourceRange + let shapeRange: SourceRange? + + var syntaxElements: [SyntaxElement] { + var elements: [SyntaxElement] = [] + + // Vertex label + elements.append( + SyntaxElement( + type: .vertexLabel, + range: labelRange, + value: label + )) + + // Left parenthesis + elements.append( + SyntaxElement( + type: .punctuation, + range: leftParenRange, + value: "(" + )) + + // X coordinate + elements.append( + SyntaxElement( + type: .number, + range: xCoordRange, + value: String(coordinates.0) + )) + + // Comma + elements.append( + SyntaxElement( + type: .punctuation, + range: commaRange, + value: "," + )) + + // Y coordinate + elements.append( + SyntaxElement( + type: .number, + range: yCoordRange, + value: String(coordinates.1) + )) + + // Right parenthesis + elements.append( + SyntaxElement( + type: .punctuation, + range: rightParenRange, + value: ")" + )) + + // Shape if present + if let shape = shape, let shapeRange = shapeRange { + elements.append( + SyntaxElement( + type: .shape, + range: shapeRange, + value: "[\(shape)]" + )) + } + + return elements + } + } + + struct Edge: Entity { + let from: String + let to: String + let isDirected: Bool + let position: SourcePosition + let range: SourceRange + + // Syntax element ranges + let fromLabelRange: SourceRange + let edgeTypeRange: SourceRange + let toLabelRange: SourceRange + + var syntaxElements: [SyntaxElement] { + var elements: [SyntaxElement] = [] + + // From vertex label + elements.append( + SyntaxElement( + type: .vertexLabel, + range: fromLabelRange, + value: from + )) + + // Edge symbol + elements.append( + SyntaxElement( + type: .symbol, + range: edgeTypeRange, + value: isDirected ? "->" : "--" + )) + + // To vertex label + elements.append( + SyntaxElement( + type: .vertexLabel, + range: toLabelRange, + value: to + )) + + return elements + } + } + + struct Note: Entity { + let coordinates: (Double, Double) + let text: String + let position: SourcePosition + let range: SourceRange + + // Syntax element ranges + let keywordRange: SourceRange + let leftParenRange: SourceRange + let xCoordRange: SourceRange + let commaRange: SourceRange + let yCoordRange: SourceRange + let rightParenRange: SourceRange + let textRange: SourceRange + + var syntaxElements: [SyntaxElement] { + var elements: [SyntaxElement] = [] + + // [Note] keyword + elements.append( + SyntaxElement( + type: .keyword, + range: keywordRange, + value: "[Note]" + )) + + // Left parenthesis + elements.append( + SyntaxElement( + type: .punctuation, + range: leftParenRange, + value: "(" + )) + + // X coordinate + elements.append( + SyntaxElement( + type: .number, + range: xCoordRange, + value: String(coordinates.0) + )) + + // Comma + elements.append( + SyntaxElement( + type: .punctuation, + range: commaRange, + value: "," + )) + + // Y coordinate + elements.append( + SyntaxElement( + type: .number, + range: yCoordRange, + value: String(coordinates.1) + )) + + // Right parenthesis + elements.append( + SyntaxElement( + type: .punctuation, + range: rightParenRange, + value: ")" + )) + + // Text content + elements.append( + SyntaxElement( + type: .text, + range: textRange, + value: text + )) + + return elements + } + } + + struct Stage: Entity { + let number: String // i, ii, iii, iv + let value: Double + let position: SourcePosition + let range: SourceRange + + // Syntax element ranges + let leftBracketRange: SourceRange + let stageNumberRange: SourceRange + let rightBracketRange: SourceRange + let valueRange: SourceRange + + var syntaxElements: [SyntaxElement] { + var elements: [SyntaxElement] = [] + + // Left bracket + elements.append( + SyntaxElement( + type: .punctuation, + range: leftBracketRange, + value: "[" + )) + + // Stage number + elements.append( + SyntaxElement( + type: .stageNumber, + range: stageNumberRange, + value: number + )) + + // Right bracket + elements.append( + SyntaxElement( + type: .punctuation, + range: rightBracketRange, + value: "]" + )) + + // Value + elements.append( + SyntaxElement( + type: .number, + range: valueRange, + value: String(value) + )) + + return elements + } + } + + struct Group: Entity { + let vertices: [String] + let position: SourcePosition + let range: SourceRange + + // Syntax element ranges + let keywordRange: SourceRange + let vertexRanges: [SourceRange] + let commaRanges: [SourceRange] + + var syntaxElements: [SyntaxElement] { + var elements: [SyntaxElement] = [] + + // [Group] keyword + elements.append( + SyntaxElement( + type: .keyword, + range: keywordRange, + value: "[Group]" + )) + + // Vertex labels and commas + for (index, vertex) in vertices.enumerated() { + elements.append( + SyntaxElement( + type: .vertexLabel, + range: vertexRanges[index], + value: vertex + )) + + // Add comma if not the last vertex + if index < vertices.count - 1 { + elements.append( + SyntaxElement( + type: .punctuation, + range: commaRanges[index], + value: "," + )) + } + } + + return elements + } + } + + struct Inertia: Entity { + let vertex: String + let position: SourcePosition + let range: SourceRange + + // Syntax element ranges + let keywordRange: SourceRange + let vertexRange: SourceRange + + var syntaxElements: [SyntaxElement] { + var elements: [SyntaxElement] = [] + + // [Inertia] keyword + elements.append( + SyntaxElement( + type: .keyword, + range: keywordRange, + value: "[Inertia]" + )) + + // Vertex label + elements.append( + SyntaxElement( + type: .vertexLabel, + range: vertexRange, + value: vertex + )) + + return elements + } + } + + struct Evolution: Entity { + let vertex: String + let isPositive: Bool + let value: Double + let position: SourcePosition + let range: SourceRange + + // Syntax element ranges + let keywordRange: SourceRange + let vertexRange: SourceRange + let signRange: SourceRange + let valueRange: SourceRange + + var syntaxElements: [SyntaxElement] { + var elements: [SyntaxElement] = [] + + // [Evolution] keyword + elements.append( + SyntaxElement( + type: .keyword, + range: keywordRange, + value: "[Evolution]" + )) + + // Vertex label + elements.append( + SyntaxElement( + type: .vertexLabel, + range: vertexRange, + value: vertex + )) + + // Sign + elements.append( + SyntaxElement( + type: .symbol, + range: signRange, + value: isPositive ? "+" : "-" + )) + + // Value + elements.append( + SyntaxElement( + type: .number, + range: valueRange, + value: String(value) + )) + + return elements + } + } +} -- cgit