From 9583f9e281b4b15dbc025c6873e585b17cc082a6 Mon Sep 17 00:00:00 2001 From: Trevor Maze Date: Thu, 29 Jan 2026 14:39:27 -0500 Subject: [PATCH] Before Expression Fixing --- .gitignore | 1 + Sources/rxcc/rxcc.swift | 245 +++++++++++++++++++++++----------------- 2 files changed, 145 insertions(+), 101 deletions(-) diff --git a/.gitignore b/.gitignore index 8b2582c..561c1ac 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ DerivedData/ .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata .netrc run +bin/ diff --git a/Sources/rxcc/rxcc.swift b/Sources/rxcc/rxcc.swift index 25b0a68..35e3ed9 100644 --- a/Sources/rxcc/rxcc.swift +++ b/Sources/rxcc/rxcc.swift @@ -1,58 +1,5 @@ import Foundation -enum TokenType { - case BRACE_OPEN - case BRACE_CLOSE - case PARENTHESIS_OPEN - case PARENTHESIS_CLOSE - case SEMICOLON - case INT - case RETURN - case IDENTIFIER - case LITERAL_INTEGER - case NEGATION - case BITWISE_COMPLIMENT - case LOGICAL_NEGATION - - case UNDEFINED -} - -struct Token { - let content: Substring - let type: TokenType -} - -typealias Construct = [Element] - -enum Element { - case Construct(type: ConstructType) - case Token(type: TokenType) -} - -enum ConstructVariant { - // Unary operation variants - case Negation - case BitwiseCompliment - case LogicalNegation - - // Expression variants - case LiteralInteger - case UnaryOperation - - // Statement variants - case ReturnInteger - - // Function Variants - case Integer - - // Program Variants - case SingleFunction - - // Misc. - case Root - case Error -} - class SyntaxTreeNode { var parent: SyntaxTreeNode? var children: [SyntaxTreeNode] @@ -99,9 +46,85 @@ class SyntaxTreeNode { } } -enum ConstructType { +enum TokenType { + case BRACE_OPEN + case BRACE_CLOSE + case PARENTHESIS_OPEN + case PARENTHESIS_CLOSE + case SEMICOLON + case INT + case RETURN + case IDENTIFIER + case LITERAL_INTEGER + + case NEGATION + case BITWISE_COMPLIMENT + case LOGICAL_NEGATION + + case ADDITION + case MULTIPLICATION + case DIVISION + + case UNDEFINED +} + +struct Token { + let content: Substring + let type: TokenType +} + +typealias Construct = [Element] + +enum Element { + case Construct(type: ConstructType) + case Token(type: TokenType) +} + +enum ConstructVariant { + case Addition + case Subtraction + case Multiplication + case Division + + // Unary operation variants + case Negation + case BitwiseCompliment + case LogicalNegation + + // Expression variants + case AdditionPriorityOperation + case SingleTerm + + // Term variants + case MultiplicationPriorityOperation + case SingleFactor + + // Factor variants + case LiteralInteger case UnaryOperation + case ParenthesizedExpression + + // Statement variants + case ReturnInteger + + // Function Variants + case Integer + + // Program Variants + case SingleFunction + + // Misc. + case Root + case Error +} + +enum ConstructType { + case UnaryOperator + case MultiplicationPriorityOperator + case AdditionPriorityOperator case Expression + case Factor + case Term case Statement case Function case Program @@ -113,7 +136,7 @@ struct ConstructDefinitions { } let constructDefinitions: Dictionary> = [ - .UnaryOperation: [ + .UnaryOperator: [ .Negation: [ .Token(type: .NEGATION), ], @@ -125,13 +148,58 @@ let constructDefinitions: Dictionary String { return "" } -/*func generateOutput(tree: SyntaxTreeNode) -> String { - var text: String = "" - switch tree.variant { - case .Integer: - text += " .globl \(tree.value)\n\(tree.value):\n" - break - - case .ReturnInteger: - text += " movl $\(tree.children[0].value), %eax\n ret\n" - break - - default: - break - } - - for child in tree.children { - text += generateOutput(tree: child) - } - - return text -}*/ - func generateOutput(_ node: SyntaxTreeNode) -> String { var text: String = "" switch node.variant { @@ -349,13 +395,13 @@ func generateOutput(_ node: SyntaxTreeNode) -> String { break case .ReturnInteger: - var returnValue: String = "" if node.children.count != 1 { print("\(node.variant) cannot have more than one child node") return "[ERROR]" } - returnValue += generateOutput(node.children[0]) - text += " movl $\(returnValue), %eax\n ret\n" + + text += generateOutput(node.children[0]) + text += " ret\n" break case .UnaryOperation: @@ -365,31 +411,25 @@ func generateOutput(_ node: SyntaxTreeNode) -> String { let operation: SyntaxTreeNode = node.children[0] let expression: SyntaxTreeNode = node.children[1] + text += generateOutput(expression) + text += generateOutput(operation) - switch operation.variant { - case .BitwiseCompliment: - text += String(~Int(generateOutput(expression))!) - break - - case .Negation: - text += String(-Int(generateOutput(expression))!) - break - - case .LogicalNegation: - text += String(Int(generateOutput(expression))! == 0 ? "1" : "0") - break - - default: - print("\(node.variant): Unknown unary operation \"\(operation.variant)\"") - } break - case .Negation, .BitwiseCompliment, .LogicalNegation: - text += node.value + case .BitwiseCompliment: + text += " not %eax\n" + break + + case .Negation: + text += " neg %eax\n" + break + + case .LogicalNegation: + text += " cmpl $0, %eax\n movl $0, %eax\n sete %al\n" break case .LiteralInteger: - text += node.value + text += " movl $\(node.value), %eax\n" break default: @@ -469,6 +509,9 @@ func categorizeToken(token: Substring) -> TokenType { else if token.firstMatch(of: /^-$/) != nil { return .NEGATION } else if token.firstMatch(of: /^~$/) != nil { return .BITWISE_COMPLIMENT } else if token.firstMatch(of: /^!$/) != nil { return .LOGICAL_NEGATION } + else if token.firstMatch(of: /^\+$/) != nil { return .ADDITION } + else if token.firstMatch(of: /^\*$/) != nil { return .MULTIPLICATION } + else if token.firstMatch(of: /^\/$/) != nil { return .DIVISION } return .UNDEFINED }