diff --git a/Sources/rxcc/rxcc.swift b/Sources/rxcc/rxcc.swift index c63810c..6366923 100644 --- a/Sources/rxcc/rxcc.swift +++ b/Sources/rxcc/rxcc.swift @@ -136,6 +136,13 @@ struct rxcc { case GREATER_THAN case GREATER_THAN_OR_EQUAL_TO + case MODULO + case BITWISE_AND + case BITWISE_OR + case BITWISE_XOR + case BITWISE_SHIFT_LEFT + case BITWISE_SHIFT_RIGHT + case ASSIGNMENT case UNDEFINED @@ -164,8 +171,13 @@ struct rxcc { case Addition case Subtraction + case Multiplication case Division + case Modulo + + case BitwiseShiftLeft + case BitwiseShiftRight case LessThan case LessThanOrEqualTo @@ -186,6 +198,7 @@ struct rxcc { // Expression variants case TermSequence case AdditiveExpressionSequence + case BitwiseShiftExpressionSequence case RelationalExpressionSequence case EqualityExpressionSequence case LogicalAndExpressionSequence @@ -227,6 +240,7 @@ struct rxcc { case MultiplicationPriorityOperator case AdditionPriorityOperator + case BitwiseShiftPriorityOperator case InequalityPriorityOperator case EqualityPriorityOperator case LogicalAndPriorityOperator @@ -239,6 +253,7 @@ struct rxcc { case Expression case LogicalOrExpression case LogicalAndExpression + case BitwiseShiftExpression case EqualityExpression case RelationalExpression case AdditiveExpression @@ -300,6 +315,18 @@ struct rxcc { .Division: [ .Token(type: .DIVISION), ], + .Modulo: [ + .Token(type: .MODULO), + ], + ], + + .BitwiseShiftPriorityOperator: [ + .BitwiseShiftLeft: [ + .Token(type: .BITWISE_SHIFT_LEFT), + ], + .BitwiseShiftRight: [ + .Token(type: .BITWISE_SHIFT_RIGHT), + ], ], .InequalityPriorityOperator: [ @@ -370,9 +397,16 @@ struct rxcc { ], .RelationalExpression: [ + .BitwiseShiftExpressionSequence: [ + .Construct(type: .BitwiseShiftExpression), + .OperatorLoop(type: .InequalityPriorityOperator), + ] + ], + + .BitwiseShiftExpression: [ .AdditiveExpressionSequence: [ .Construct(type: .AdditiveExpression), - .OperatorLoop(type: .InequalityPriorityOperator), + .OperatorLoop(type: .BitwiseShiftPriorityOperator), ] ], @@ -520,6 +554,9 @@ 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: " == ") @@ -527,6 +564,8 @@ struct rxcc { 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(" +")) @@ -610,7 +649,6 @@ struct rxcc { print("ERROR: \(node.variant) with more or less than 1 child") break } - let variable: String = node.children[0].value text += generateOutput(node.children[0]) text += " push\t%eax\n" @@ -789,7 +827,7 @@ struct rxcc { } break - case .AdditiveExpressionSequence: + case .BitwiseShiftExpressionSequence: var operation: ConstructVariant = .Error let count = node.children.count if count == 0 { @@ -845,6 +883,48 @@ struct rxcc { } break + case .AdditiveExpressionSequence: + var operation: ConstructVariant = .Error + let count = node.children.count + if count == 0 { + print("ERROR: \(node.variant) with no children") + break + } + for i in 0...count - 1 { + let child: SyntaxTreeNode = node.children[i] + + // Operation + if i % 2 == 1 { + operation = child.variant + continue + } + + text += generateOutput(child) + + switch operation { + case .BitwiseShiftLeft: + text += " movl\t%eax, %ecx\n" // Move e2 to ecx + text += " pop \t%eax\n" // Move e1 to eax + text += " sal \t%cl, %eax\n" // Perform e1 << e2; result in e1 + + case .BitwiseShiftRight: + text += " movl\t%eax, %ecx\n" // Move e2 to ecx + text += " pop \t%eax\n" // Move e1 to eax + text += " sar \t%cl, %eax\n" // Perform e1 >> e2; result in e1 + + default: + if i != 0 { + print("Unknown operation \"\(operation)\" in \(node.variant)") + } + break + } + + if i != node.children.count - 1 { + text += " push\t%eax\n" + } + } + break + case .TermSequence: var operation: ConstructVariant = .Error let count = node.children.count @@ -908,6 +988,7 @@ struct rxcc { case .Multiplication: text += " pop \t%ecx\n" text += " imul\t%ecx, %eax\n" + break case .Division: text += " movl\t%eax, %ecx\n" // Move e2 to ecx @@ -915,6 +996,16 @@ struct rxcc { text += " cdq\n" // Extend eax into edx text += " idivl\t%ecx\n" // Perform edx:eax / ecx // eax = quotient; edx rem. + break + + case .Modulo: + text += " movl\t%eax, %ecx\n" // Move e2 to ecx + text += " pop \t%eax\n" // Fetch e1 off stack into eax + text += " cdq\n" // Extend eax into edx + text += " idivl\t%ecx\n" // Perform edx:eax / ecx + // eax = quotient; edx rem. + text += " movl\t%edx, %eax\n" // Move remainder to eax + break default: if i != 0 { @@ -1212,7 +1303,7 @@ struct rxcc { } else if type != token.type { print("\(indent)Failed to validate token \"\(token.content)\". Expected \"\(type)\"") - //print("\(indent)AKA, \(type) not equal to \(token.type)") + print("\(indent)AKA, \(type) not equal to \(token.type)") return .Invalid } print("\(indent)Validated token \"\(token.content)\"") @@ -1262,6 +1353,12 @@ struct rxcc { else if token.firstMatch(of: /^>$/) != nil { return .GREATER_THAN } else if token.firstMatch(of: /^>=$/) != nil { return .GREATER_THAN_OR_EQUAL_TO } else if token.firstMatch(of: /^=$/) != nil { return .ASSIGNMENT } + else if token.firstMatch(of: /^%$/) != nil { return .MODULO } + else if token.firstMatch(of: /^&$/) != nil { return .BITWISE_AND } + else if token.firstMatch(of: /^\|$/) != nil { return .BITWISE_OR } + 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 } return .UNDEFINED } diff --git a/test.c b/test.c index 337f3aa..2a5963e 100644 --- a/test.c +++ b/test.c @@ -1,4 +1,4 @@ int main() { - + return 3 % 2 / 29 % 23 + 9 % 2 % 3 % 4 % 5; }