Stage 3 complete, (+ - * / binary operators implemented)
This commit is contained in:
@@ -357,12 +357,53 @@ func generateOutput(_ node: SyntaxTreeNode) -> String {
|
|||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|
||||||
case .TermSequence:
|
case .ParenthesizedExpression:
|
||||||
for child in node.children {
|
for child in node.children {
|
||||||
text += generateOutput(child)
|
text += generateOutput(child)
|
||||||
}
|
}
|
||||||
break
|
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:
|
case .FactorSequence:
|
||||||
var operation: ConstructVariant = .Error
|
var operation: ConstructVariant = .Error
|
||||||
let count = node.children.count
|
let count = node.children.count
|
||||||
@@ -383,8 +424,15 @@ func generateOutput(_ node: SyntaxTreeNode) -> String {
|
|||||||
|
|
||||||
switch operation {
|
switch operation {
|
||||||
case .Multiplication:
|
case .Multiplication:
|
||||||
text += " pop %ecx\n"
|
text += " pop \t%ecx\n"
|
||||||
text += " imul %ecx, %eax\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:
|
default:
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
@@ -394,7 +442,7 @@ func generateOutput(_ node: SyntaxTreeNode) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if i != node.children.count - 1 {
|
if i != node.children.count - 1 {
|
||||||
text += " push %eax\n"
|
text += " push\t%eax\n"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
@@ -437,19 +485,21 @@ func generateOutput(_ node: SyntaxTreeNode) -> String {
|
|||||||
break
|
break
|
||||||
|
|
||||||
case .BitwiseCompliment:
|
case .BitwiseCompliment:
|
||||||
text += " not %eax\n"
|
text += " not \t%eax\n"
|
||||||
break
|
break
|
||||||
|
|
||||||
case .Negation:
|
case .Negation:
|
||||||
text += " neg %eax\n"
|
text += " neg \t%eax\n"
|
||||||
break
|
break
|
||||||
|
|
||||||
case .LogicalNegation:
|
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
|
break
|
||||||
|
|
||||||
case .LiteralInteger:
|
case .LiteralInteger:
|
||||||
text += " movl $\(node.value), %eax\n"
|
text += " movl\t$\(node.value), %eax\n"
|
||||||
break
|
break
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -485,6 +535,7 @@ func parse(lexed: [Substring]) -> String {
|
|||||||
enum Validity {
|
enum Validity {
|
||||||
case Valid
|
case Valid
|
||||||
case Invalid
|
case Invalid
|
||||||
|
case Panic
|
||||||
case Break
|
case Break
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -518,8 +569,11 @@ func validateConstruct(_ construct: Construct, tokens: inout [Token], node: Synt
|
|||||||
|
|
||||||
print("\(indent)Testing variant \(variant) (Loop = \(loop)) (Loopable = \(loopable))")
|
print("\(indent)Testing variant \(variant) (Loop = \(loop)) (Loopable = \(loopable))")
|
||||||
valid = validateConstruct(constructDefinitions[type]![variant]!, tokens: &tokens, node: childNode, loopingEnabled: loopable)
|
valid = validateConstruct(constructDefinitions[type]![variant]!, tokens: &tokens, node: childNode, loopingEnabled: loopable)
|
||||||
if valid == .Invalid {
|
if valid == .Panic {
|
||||||
print("\(indent)Fail (no valid variants)\n")
|
print("\(indent)Fail: panic (variant \"\(variant)\"))\n")
|
||||||
|
return .Invalid
|
||||||
|
} else if valid == .Invalid {
|
||||||
|
print("\(indent)Fail: no valid variants (variant \"\(variant)\")\n")
|
||||||
tokens = tokenBackup
|
tokens = tokenBackup
|
||||||
_ = node.popLastChild()
|
_ = node.popLastChild()
|
||||||
continue
|
continue
|
||||||
@@ -541,9 +595,14 @@ func validateConstruct(_ construct: Construct, tokens: inout [Token], node: Synt
|
|||||||
print("\(indent)Looping due to factor")
|
print("\(indent)Looping due to factor")
|
||||||
loop = true
|
loop = true
|
||||||
} else {
|
} else {
|
||||||
print("\(indent)Breaking out of factor loop")
|
if node.children.count != 0 {
|
||||||
loop = false
|
print("\(indent)Breaking out of factor loop")
|
||||||
return .Break
|
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
|
return .Invalid
|
||||||
} else if valid == .Break {
|
} else if valid == .Break {
|
||||||
print("\(indent)End validate subconstruct (variant \"\(validVariant) by breaking\")")
|
print("\(indent)End validate subconstruct (variant \"\(validVariant) by breaking\")")
|
||||||
print(type)
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
10
test
10
test
@@ -1,9 +1,11 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
gcc $1.c
|
nvim test.c
|
||||||
gcc $1.s -o my.out
|
gcc -m32 test.c -o gcc.out
|
||||||
|
./.build/debug/rxcc test.c
|
||||||
|
gcc -m32 test.s -o rxcc.out
|
||||||
echo "GCC:"
|
echo "GCC:"
|
||||||
./a.out
|
./gcc.out
|
||||||
echo $?
|
echo $?
|
||||||
echo "RXCC"
|
echo "RXCC"
|
||||||
./my.out
|
./rxcc.out
|
||||||
echo $?
|
echo $?
|
||||||
|
|||||||
3
test.c
3
test.c
@@ -1,3 +1,4 @@
|
|||||||
int main() {
|
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
|
.globl main
|
||||||
main:
|
main:
|
||||||
movl $1, %eax
|
movl $4, %eax
|
||||||
push %eax
|
push %eax
|
||||||
movl $2, %eax
|
movl $4, %eax
|
||||||
pop %ecx
|
neg %eax
|
||||||
imul %ecx, %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
|
ret
|
||||||
|
|||||||
3
test2.c
3
test2.c
@@ -1,3 +1,4 @@
|
|||||||
int main() {
|
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