Stage 3 complete, (+ - * / binary operators implemented)
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
|
||||
10
test
10
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 $?
|
||||
|
||||
3
test.c
3
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));
|
||||
}
|
||||
|
||||
|
||||
113
test.s
113
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
|
||||
|
||||
3
test2.c
3
test2.c
@@ -1,3 +1,4 @@
|
||||
int main() {
|
||||
return ~1 * 2;
|
||||
return -(2 * 3) * 5 * (2 * 5) * (3 * -4 * -(-2 * 5) * 4) * -7 * 7;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user