diff --git a/Sources/rxcc/rxcc.swift b/Sources/rxcc/rxcc.swift index a941430..38b6290 100644 --- a/Sources/rxcc/rxcc.swift +++ b/Sources/rxcc/rxcc.swift @@ -357,12 +357,53 @@ func generateOutput(_ node: SyntaxTreeNode) -> String { } break - case .TermSequence: + case .ParenthesizedExpression: for child in node.children { text += generateOutput(child) } break + case .TermSequence: + var operation: ConstructVariant = .Error + let count = node.children.count + if count == 0 { + print("ERROR: FactorSequence 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 .Addition: + text += " pop \t%ecx\n" + text += " addl\t%ecx, %eax\n" + + case .Subtraction: + text += " pop \t%ecx\n" + text += " subl\t%eax, %ecx\n" + text += " movl\t%ecx, %eax\n" + + default: + if i != 0 { + print("Unknown operation \"\(operation)\" in FactorSequence") + } + break + } + + if i != node.children.count - 1 { + text += " push\t%eax\n" + } + } + break + case .FactorSequence: var operation: ConstructVariant = .Error let count = node.children.count @@ -383,8 +424,15 @@ func generateOutput(_ node: SyntaxTreeNode) -> String { switch operation { case .Multiplication: - text += " pop %ecx\n" - text += " imul %ecx, %eax\n" + text += " pop \t%ecx\n" + text += " imul\t%ecx, %eax\n" + + case .Division: + 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. default: if i != 0 { @@ -394,7 +442,7 @@ func generateOutput(_ node: SyntaxTreeNode) -> String { } if i != node.children.count - 1 { - text += " push %eax\n" + text += " push\t%eax\n" } } break @@ -437,19 +485,21 @@ func generateOutput(_ node: SyntaxTreeNode) -> String { break case .BitwiseCompliment: - text += " not %eax\n" + text += " not \t%eax\n" break case .Negation: - text += " neg %eax\n" + text += " neg \t%eax\n" break case .LogicalNegation: - text += " cmpl $0, %eax\n movl $0, %eax\n sete %al\n" + text += " cmpl\t$0, %eax\n" + text += " movl\t$0, %eax\n" + text += " sete\t%al\n" break case .LiteralInteger: - text += " movl $\(node.value), %eax\n" + text += " movl\t$\(node.value), %eax\n" break default: @@ -485,6 +535,7 @@ func parse(lexed: [Substring]) -> String { enum Validity { case Valid case Invalid + case Panic case Break } @@ -518,8 +569,11 @@ func validateConstruct(_ construct: Construct, tokens: inout [Token], node: Synt print("\(indent)Testing variant \(variant) (Loop = \(loop)) (Loopable = \(loopable))") valid = validateConstruct(constructDefinitions[type]![variant]!, tokens: &tokens, node: childNode, loopingEnabled: loopable) - if valid == .Invalid { - print("\(indent)Fail (no valid variants)\n") + if valid == .Panic { + print("\(indent)Fail: panic (variant \"\(variant)\"))\n") + return .Invalid + } else if valid == .Invalid { + print("\(indent)Fail: no valid variants (variant \"\(variant)\")\n") tokens = tokenBackup _ = node.popLastChild() continue @@ -541,9 +595,14 @@ func validateConstruct(_ construct: Construct, tokens: inout [Token], node: Synt print("\(indent)Looping due to factor") loop = true } else { - print("\(indent)Breaking out of factor loop") - loop = false - return .Break + if node.children.count != 0 { + print("\(indent)Breaking out of factor loop") + loop = false + return .Break + } else { + print("\(indent)ERROR: FactorSequence has no children") + return .Panic + } } } @@ -569,7 +628,6 @@ func validateConstruct(_ construct: Construct, tokens: inout [Token], node: Synt return .Invalid } else if valid == .Break { print("\(indent)End validate subconstruct (variant \"\(validVariant) by breaking\")") - print(type) break } diff --git a/a.out b/a.out index 6397d0d..6e3808f 100755 Binary files a/a.out and b/a.out differ diff --git a/gcc.out b/gcc.out new file mode 100755 index 0000000..dc8acb7 Binary files /dev/null and b/gcc.out differ diff --git a/my.out b/my.out new file mode 100755 index 0000000..888207b Binary files /dev/null and b/my.out differ diff --git a/rxcc.out b/rxcc.out new file mode 100755 index 0000000..3d3f4f2 Binary files /dev/null and b/rxcc.out differ diff --git a/test b/test index 5a14f46..d58f20b 100755 --- a/test +++ b/test @@ -1,9 +1,11 @@ #!/bin/bash -gcc $1.c -gcc $1.s -o my.out +nvim test.c +gcc -m32 test.c -o gcc.out +./.build/debug/rxcc test.c +gcc -m32 test.s -o rxcc.out echo "GCC:" -./a.out +./gcc.out echo $? echo "RXCC" -./my.out +./rxcc.out echo $? diff --git a/test.c b/test.c index 3f0924b..30a9028 100644 --- a/test.c +++ b/test.c @@ -1,3 +1,4 @@ int main() { - return 1 * 2; + return !(4 + -4) + 6 / (2 + 2) * -4 * ~4 / 9 + -(4 / (5 * (32 / 2) + ~1) - (400 / 90 + 1) - -~((5 / 4) * (2 + 3) / -9)); } + diff --git a/test.s b/test.s index 6f18599..23386b4 100644 --- a/test.s +++ b/test.s @@ -1,8 +1,111 @@ .globl main main: - movl $1, %eax - push %eax - movl $2, %eax - pop %ecx - imul %ecx, %eax + movl $4, %eax + push %eax + movl $4, %eax + neg %eax + pop %ecx + addl %ecx, %eax + cmpl $0, %eax + movl $0, %eax + sete %al + push %eax + movl $6, %eax + push %eax + movl $2, %eax + push %eax + movl $2, %eax + pop %ecx + addl %ecx, %eax + movl %eax, %ecx + pop %eax + cdq + idivl %ecx + push %eax + movl $4, %eax + neg %eax + pop %ecx + imul %ecx, %eax + push %eax + movl $4, %eax + not %eax + pop %ecx + imul %ecx, %eax + push %eax + movl $9, %eax + movl %eax, %ecx + pop %eax + cdq + idivl %ecx + pop %ecx + addl %ecx, %eax + push %eax + movl $4, %eax + push %eax + movl $5, %eax + push %eax + movl $32, %eax + push %eax + movl $2, %eax + movl %eax, %ecx + pop %eax + cdq + idivl %ecx + pop %ecx + imul %ecx, %eax + push %eax + movl $1, %eax + not %eax + pop %ecx + addl %ecx, %eax + movl %eax, %ecx + pop %eax + cdq + idivl %ecx + push %eax + movl $400, %eax + push %eax + movl $90, %eax + movl %eax, %ecx + pop %eax + cdq + idivl %ecx + push %eax + movl $1, %eax + pop %ecx + addl %ecx, %eax + pop %ecx + subl %eax, %ecx + movl %ecx, %eax + push %eax + movl $5, %eax + push %eax + movl $4, %eax + movl %eax, %ecx + pop %eax + cdq + idivl %ecx + push %eax + movl $2, %eax + push %eax + movl $3, %eax + pop %ecx + addl %ecx, %eax + pop %ecx + imul %ecx, %eax + push %eax + movl $9, %eax + neg %eax + movl %eax, %ecx + pop %eax + cdq + idivl %ecx + not %eax + neg %eax + pop %ecx + subl %eax, %ecx + movl %ecx, %eax + neg %eax + pop %ecx + addl %ecx, %eax ret diff --git a/test2.c b/test2.c index 8ec47b5..4296359 100644 --- a/test2.c +++ b/test2.c @@ -1,3 +1,4 @@ int main() { - return ~1 * 2; + return -(2 * 3) * 5 * (2 * 5) * (3 * -4 * -(-2 * 5) * 4) * -7 * 7; } + diff --git a/test2.s b/test2.s deleted file mode 100644 index 3afb065..0000000 --- a/test2.s +++ /dev/null @@ -1,6 +0,0 @@ - .globl main -main: - movl $1, %eax - not %eax - movl $2, %eax - ret diff --git a/test2s b/test2s deleted file mode 100644 index e69de29..0000000