Before Expression Fixing
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,3 +7,4 @@ DerivedData/
|
||||
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
|
||||
.netrc
|
||||
run
|
||||
bin/
|
||||
|
||||
@@ -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)
|
||||
|
||||
break
|
||||
|
||||
switch operation.variant {
|
||||
case .BitwiseCompliment:
|
||||
text += String(~Int(generateOutput(expression))!)
|
||||
text += " not %eax\n"
|
||||
break
|
||||
|
||||
case .Negation:
|
||||
text += String(-Int(generateOutput(expression))!)
|
||||
text += " neg %eax\n"
|
||||
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
|
||||
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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user