diff --git a/Sources/rxcc/rxcc.swift b/Sources/rxcc/rxcc.swift index d20a5ab..3220caa 100644 --- a/Sources/rxcc/rxcc.swift +++ b/Sources/rxcc/rxcc.swift @@ -144,6 +144,16 @@ struct rxcc { case BITWISE_SHIFT_RIGHT case ASSIGNMENT + case COMPOUND_ASSIGNMENT_ADDITION + case COMPOUND_ASSIGNMENT_SUBTRACTION + case COMPOUND_ASSIGNMENT_MULTIPLICATION + case COMPOUND_ASSIGNMENT_DIVISION + case COMPOUND_ASSIGNMENT_MODULO + case COMPOUND_ASSIGNMENT_BITWISE_SHIFT_LEFT + case COMPOUND_ASSIGNMENT_BITWISE_SHIFT_RIGHT + case COMPOUND_ASSIGNMENT_BITWISE_AND + case COMPOUND_ASSIGNMENT_BITWISE_OR + case COMPOUND_ASSIGNMENT_BITWISE_XOR case UNDEFINED } @@ -166,8 +176,18 @@ struct rxcc { enum ConstructVariant { case Variable case StandaloneVariable - case IntegerVariableDeclaration - case VariableAssignment + + case StandardAssignment + case CompoundAssignmentAddition + case CompoundAssignmentSubtraction + case CompoundAssignmentMultiplication + case CompoundAssignmentDivision + case CompoundAssignmentModulo + case CompoundAssignmentBitwiseShiftLeft + case CompoundAssignmentBitwiseShiftRight + case CompoundAssignmentBitwiseAnd + case CompoundAssignmentBitwiseOr + case CompoundAssignmentBitwiseXOR case Addition case Subtraction @@ -256,6 +276,8 @@ struct rxcc { case LogicalAndPriorityOperator case LogicalOrPriorityOperator + case AssignmentOperator + case Program case Function case StatementList @@ -296,10 +318,44 @@ struct rxcc { .VariableAssignment: [ .Variable: [ .Token(type: .IDENTIFIER), - .Token(type: .ASSIGNMENT), + .Construct(type: .AssignmentOperator), .Construct(type: .Expression), ], ], + + .AssignmentOperator: [ + .StandardAssignment: [ + .Token(type: .ASSIGNMENT), + ], + .CompoundAssignmentAddition: [ + .Token(type: .COMPOUND_ASSIGNMENT_ADDITION), + ], + .CompoundAssignmentSubtraction: [ + .Token(type: .COMPOUND_ASSIGNMENT_SUBTRACTION), + ], + .CompoundAssignmentMultiplication: [ + .Token(type: .COMPOUND_ASSIGNMENT_MULTIPLICATION), + ], + .CompoundAssignmentModulo: [ + .Token(type: .COMPOUND_ASSIGNMENT_MODULO), + ], + .CompoundAssignmentBitwiseShiftLeft: [ + .Token(type: .COMPOUND_ASSIGNMENT_BITWISE_SHIFT_LEFT), + ], + .CompoundAssignmentBitwiseShiftRight: [ + .Token(type: .COMPOUND_ASSIGNMENT_BITWISE_SHIFT_RIGHT), + ], + .CompoundAssignmentBitwiseAnd: [ + .Token(type: .COMPOUND_ASSIGNMENT_BITWISE_AND), + ], + .CompoundAssignmentBitwiseOr: [ + .Token(type: .COMPOUND_ASSIGNMENT_BITWISE_OR), + ], + .CompoundAssignmentBitwiseXOR: [ + .Token(type: .COMPOUND_ASSIGNMENT_BITWISE_XOR), + ], + ], + .UnaryOperator: [ .Negation: [ .Token(type: .NEGATION), @@ -624,6 +680,16 @@ struct rxcc { line = line.replacing(/> *=/, with: " >= ") line = line.replacing(/< * *>/, with: " >> ") + line = line.replacing(/\+ *=/, with: " += ") + line = line.replacing(/- *=/, with: " -= ") + line = line.replacing(/\* *=/, with: " *= ") + line = line.replacing(/\/ *=/, with: " /= ") + line = line.replacing(/% *=/, with: " %= ") + line = line.replacing(/& *=/, with: " &= ") + line = line.replacing(/\| *=/, with: " |= ") + line = line.replacing(/\^ *=/, with: " ^= ") + line = line.replacing(/< *< *=/, with: " <<= ") + line = line.replacing(/> *> *=/, with: " >>= ") do { let tokens: [Substring] = line.split(separator: try Regex(" +")) @@ -715,8 +781,8 @@ struct rxcc { case .Variable: let count = node.children.count - if count > 1 { - print("ERROR: \(node.variant) with more than 1 child") + if count > 2 { + print("ERROR: \(node.variant) with more than 2 children") break } let variable: String = node.value @@ -726,11 +792,38 @@ struct rxcc { break } - if count != 0 { - text += generateOutput(node.children[0]) + if count == 1 { + text += generateOutput(node.children[0]) // Get the value of the assignment + text += " movl\t%eax, \(variables[variable]!)(%ebp)\n" + break } - text += " movl\t%eax, \(variables[variable]!)(%ebp)\n" + if count != 0 { + text += generateOutput(node.children[1]) // Get the value of the assignment + } + + switch node.children[0].variant { + case .StandardAssignment: + text += " movl\t%eax, \(variables[variable]!)(%ebp)\n" + break + + case .CompoundAssignmentAddition: + text += " addl\t%eax, \(variables[variable]!)(%ebp)\n" + break + + case .CompoundAssignmentSubtraction: + text += " subl\t%eax, \(variables[variable]!)(%ebp)\n" + break + + case .CompoundAssignmentMultiplication: + text += " imul\t\(variables[variable]!)(%ebp), %eax\n" + text += " movl\t%eax, \(variables[variable]!)(%ebp)\n" + break + + default: + print("ERROR: Unknown assignment type \"\(node.children[0].variant)\"") + break + } break @@ -1525,6 +1618,16 @@ struct rxcc { else if token.firstMatch(of: /^\^$/) != nil { return .BITWISE_XOR } else if token.firstMatch(of: /^<<$/) != nil { return .BITWISE_SHIFT_LEFT } else if token.firstMatch(of: /^>>$/) != nil { return .BITWISE_SHIFT_RIGHT } + else if token.firstMatch(of: /^\+=$/) != nil { return .COMPOUND_ASSIGNMENT_ADDITION } + else if token.firstMatch(of: /^-=$/) != nil { return .COMPOUND_ASSIGNMENT_SUBTRACTION } + else if token.firstMatch(of: /^\*=$/) != nil { return .COMPOUND_ASSIGNMENT_MULTIPLICATION } + else if token.firstMatch(of: /^\/=$/) != nil { return .COMPOUND_ASSIGNMENT_DIVISION } + else if token.firstMatch(of: /^%=$/) != nil { return .COMPOUND_ASSIGNMENT_MODULO } + else if token.firstMatch(of: /^<<=$/) != nil { return .COMPOUND_ASSIGNMENT_BITWISE_SHIFT_LEFT } + else if token.firstMatch(of: /^>>=$/) != nil { return .COMPOUND_ASSIGNMENT_BITWISE_SHIFT_RIGHT } + else if token.firstMatch(of: /^&=$/) != nil { return .COMPOUND_ASSIGNMENT_BITWISE_AND } + else if token.firstMatch(of: /^\|=$/) != nil { return .COMPOUND_ASSIGNMENT_BITWISE_OR } + else if token.firstMatch(of: /^\^=$/) != nil { return .COMPOUND_ASSIGNMENT_BITWISE_XOR } return .UNDEFINED } diff --git a/test.c b/test.c index af90d6e..95233d8 100644 --- a/test.c +++ b/test.c @@ -1,4 +1,8 @@ int main() { - return 4 ^ 2 | 34 & 20 | (3 & 4) & ~1; + int tomas = 1; + int jefferson = 3; + tomas *= jefferson; + jefferson *= tomas; + return tomas * jefferson; }