Before Expression Fixing

This commit is contained in:
2026-01-29 14:39:27 -05:00
parent ebd466119e
commit 9583f9e281
2 changed files with 145 additions and 101 deletions

1
.gitignore vendored
View File

@@ -7,3 +7,4 @@ DerivedData/
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
run
bin/

View File

@@ -1,58 +1,5 @@
import Foundation
enum TokenType {
case BRACE_OPEN
case BRACE_CLOSE
case PARENTHESIS_OPEN
case PARENTHESIS_CLOSE
case SEMICOLON
case INT
case RETURN
case IDENTIFIER
case LITERAL_INTEGER
case NEGATION
case BITWISE_COMPLIMENT
case LOGICAL_NEGATION
case UNDEFINED
}
struct Token {
let content: Substring
let type: TokenType
}
typealias Construct = [Element]
enum Element {
case Construct(type: ConstructType)
case Token(type: TokenType)
}
enum ConstructVariant {
// Unary operation variants
case Negation
case BitwiseCompliment
case LogicalNegation
// Expression variants
case LiteralInteger
case UnaryOperation
// Statement variants
case ReturnInteger
// Function Variants
case Integer
// Program Variants
case SingleFunction
// Misc.
case Root
case Error
}
class SyntaxTreeNode {
var parent: SyntaxTreeNode?
var children: [SyntaxTreeNode]
@@ -99,9 +46,85 @@ class SyntaxTreeNode {
}
}
enum ConstructType {
enum TokenType {
case BRACE_OPEN
case BRACE_CLOSE
case PARENTHESIS_OPEN
case PARENTHESIS_CLOSE
case SEMICOLON
case INT
case RETURN
case IDENTIFIER
case LITERAL_INTEGER
case NEGATION
case BITWISE_COMPLIMENT
case LOGICAL_NEGATION
case ADDITION
case MULTIPLICATION
case DIVISION
case UNDEFINED
}
struct Token {
let content: Substring
let type: TokenType
}
typealias Construct = [Element]
enum Element {
case Construct(type: ConstructType)
case Token(type: TokenType)
}
enum ConstructVariant {
case Addition
case Subtraction
case Multiplication
case Division
// Unary operation variants
case Negation
case BitwiseCompliment
case LogicalNegation
// Expression variants
case AdditionPriorityOperation
case SingleTerm
// Term variants
case MultiplicationPriorityOperation
case SingleFactor
// Factor variants
case LiteralInteger
case UnaryOperation
case ParenthesizedExpression
// Statement variants
case ReturnInteger
// Function Variants
case Integer
// Program Variants
case SingleFunction
// Misc.
case Root
case Error
}
enum ConstructType {
case UnaryOperator
case MultiplicationPriorityOperator
case AdditionPriorityOperator
case Expression
case Factor
case Term
case Statement
case Function
case Program
@@ -113,7 +136,7 @@ struct ConstructDefinitions {
}
let constructDefinitions: Dictionary<ConstructType, Dictionary<ConstructVariant, Construct>> = [
.UnaryOperation: [
.UnaryOperator: [
.Negation: [
.Token(type: .NEGATION),
],
@@ -125,13 +148,58 @@ let constructDefinitions: Dictionary<ConstructType, Dictionary<ConstructVariant,
],
],
.AdditionPriorityOperator: [
.Addition: [
.Token(type: .ADDITION),
],
.Subtraction: [
.Token(type: .NEGATION),
],
],
.MultiplicationPriorityOperator: [
.Multiplication: [
.Token(type: .MULTIPLICATION),
],
.Division: [
.Token(type: .DIVISION),
],
],
.Expression: [
.AdditionPriorityOperation: [
.Construct(type: .Expression),
.Construct(type: .AdditionPriorityOperator),
.Construct(type: .Term)
],
.SingleTerm: [
.Construct(type: .Term)
]
],
.Term: [
.MultiplicationPriorityOperation: [
.Construct(type: .Term),
.Construct(type: .MultiplicationPriorityOperator),
.Construct(type: .Term)
],
.SingleFactor: [
.Construct(type: .Factor)
]
],
.Factor: [
.LiteralInteger: [
.Token(type: .LITERAL_INTEGER)
],
.UnaryOperation: [
.Construct(type: .UnaryOperation),
.Construct(type: .Expression)
.Construct(type: .UnaryOperator),
.Construct(type: .Factor)
],
.ParenthesizedExpression: [
.Token(type: .PARENTHESIS_OPEN),
.Construct(type: .Expression),
.Token(type: .PARENTHESIS_CLOSE)
]
],
@@ -310,28 +378,6 @@ func parse(lexed: [Substring]) -> String {
return ""
}
/*func generateOutput(tree: SyntaxTreeNode) -> String {
var text: String = ""
switch tree.variant {
case .Integer:
text += " .globl \(tree.value)\n\(tree.value):\n"
break
case .ReturnInteger:
text += " movl $\(tree.children[0].value), %eax\n ret\n"
break
default:
break
}
for child in tree.children {
text += generateOutput(tree: child)
}
return text
}*/
func generateOutput(_ node: SyntaxTreeNode) -> String {
var text: String = ""
switch node.variant {
@@ -349,13 +395,13 @@ func generateOutput(_ node: SyntaxTreeNode) -> String {
break
case .ReturnInteger:
var returnValue: String = ""
if node.children.count != 1 {
print("\(node.variant) cannot have more than one child node")
return "[ERROR]"
}
returnValue += generateOutput(node.children[0])
text += " movl $\(returnValue), %eax\n ret\n"
text += generateOutput(node.children[0])
text += " ret\n"
break
case .UnaryOperation:
@@ -365,31 +411,25 @@ func generateOutput(_ node: SyntaxTreeNode) -> String {
let operation: SyntaxTreeNode = node.children[0]
let expression: SyntaxTreeNode = node.children[1]
text += generateOutput(expression)
text += generateOutput(operation)
switch operation.variant {
case .BitwiseCompliment:
text += String(~Int(generateOutput(expression))!)
break
case .Negation:
text += String(-Int(generateOutput(expression))!)
break
case .LogicalNegation:
text += String(Int(generateOutput(expression))! == 0 ? "1" : "0")
break
default:
print("\(node.variant): Unknown unary operation \"\(operation.variant)\"")
}
break
case .Negation, .BitwiseCompliment, .LogicalNegation:
text += node.value
case .BitwiseCompliment:
text += " not %eax\n"
break
case .Negation:
text += " neg %eax\n"
break
case .LogicalNegation:
text += " cmpl $0, %eax\n movl $0, %eax\n sete %al\n"
break
case .LiteralInteger:
text += node.value
text += " movl $\(node.value), %eax\n"
break
default:
@@ -469,6 +509,9 @@ func categorizeToken(token: Substring) -> TokenType {
else if token.firstMatch(of: /^-$/) != nil { return .NEGATION }
else if token.firstMatch(of: /^~$/) != nil { return .BITWISE_COMPLIMENT }
else if token.firstMatch(of: /^!$/) != nil { return .LOGICAL_NEGATION }
else if token.firstMatch(of: /^\+$/) != nil { return .ADDITION }
else if token.firstMatch(of: /^\*$/) != nil { return .MULTIPLICATION }
else if token.firstMatch(of: /^\/$/) != nil { return .DIVISION }
return .UNDEFINED
}