Compound assignment (+=, -=, *=)

This commit is contained in:
2026-02-12 16:53:01 -05:00
parent 10023cae86
commit 1dd755ffcb
2 changed files with 116 additions and 9 deletions

View File

@@ -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: " <<= ")
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
}

6
test.c
View File

@@ -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;
}