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 BITWISE_SHIFT_RIGHT
case ASSIGNMENT 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 case UNDEFINED
} }
@@ -166,8 +176,18 @@ struct rxcc {
enum ConstructVariant { enum ConstructVariant {
case Variable case Variable
case StandaloneVariable 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 Addition
case Subtraction case Subtraction
@@ -256,6 +276,8 @@ struct rxcc {
case LogicalAndPriorityOperator case LogicalAndPriorityOperator
case LogicalOrPriorityOperator case LogicalOrPriorityOperator
case AssignmentOperator
case Program case Program
case Function case Function
case StatementList case StatementList
@@ -296,10 +318,44 @@ struct rxcc {
.VariableAssignment: [ .VariableAssignment: [
.Variable: [ .Variable: [
.Token(type: .IDENTIFIER), .Token(type: .IDENTIFIER),
.Token(type: .ASSIGNMENT), .Construct(type: .AssignmentOperator),
.Construct(type: .Expression), .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: [ .UnaryOperator: [
.Negation: [ .Negation: [
.Token(type: .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: " |= ")
line = line.replacing(/\^ *=/, with: " ^= ")
line = line.replacing(/< *< *=/, with: " <<= ")
line = line.replacing(/> *> *=/, with: " >>= ")
do { do {
let tokens: [Substring] = line.split(separator: try Regex(" +")) let tokens: [Substring] = line.split(separator: try Regex(" +"))
@@ -715,8 +781,8 @@ struct rxcc {
case .Variable: case .Variable:
let count = node.children.count let count = node.children.count
if count > 1 { if count > 2 {
print("ERROR: \(node.variant) with more than 1 child") print("ERROR: \(node.variant) with more than 2 children")
break break
} }
let variable: String = node.value let variable: String = node.value
@@ -726,11 +792,38 @@ struct rxcc {
break break
} }
if count != 0 { if count == 1 {
text += generateOutput(node.children[0]) 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 break
@@ -1525,6 +1618,16 @@ struct rxcc {
else if token.firstMatch(of: /^\^$/) != nil { return .BITWISE_XOR } 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_LEFT }
else if token.firstMatch(of: /^>>$/) != nil { return .BITWISE_SHIFT_RIGHT } 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 return .UNDEFINED
} }

6
test.c
View File

@@ -1,4 +1,8 @@
int main() { int main() {
return 4 ^ 2 | 34 & 20 | (3 & 4) & ~1; int tomas = 1;
int jefferson = 3;
tomas *= jefferson;
jefferson *= tomas;
return tomas * jefferson;
} }