Stage 3 complete, (+ - * / binary operators implemented)

This commit is contained in:
2026-01-31 21:32:53 -05:00
parent 1d9ad824a6
commit 409c5938f9
11 changed files with 190 additions and 31 deletions

View File

@@ -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
}

BIN
a.out

Binary file not shown.

BIN
gcc.out Executable file

Binary file not shown.

BIN
my.out Executable file

Binary file not shown.

BIN
rxcc.out Executable file

Binary file not shown.

10
test
View File

@@ -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
View File

@@ -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
View File

@@ -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

View File

@@ -1,3 +1,4 @@
int main() {
return ~1 * 2;
return -(2 * 3) * 5 * (2 * 5) * (3 * -4 * -(-2 * 5) * 4) * -7 * 7;
}

View File

@@ -1,6 +0,0 @@
.globl main
main:
movl $1, %eax
not %eax
movl $2, %eax
ret

0
test2s
View File