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
}