From 62c1d980f7575162d58b28105bbedbf328470794 Mon Sep 17 00:00:00 2001 From: Trevor Maze Date: Wed, 11 Feb 2026 11:55:16 -0500 Subject: [PATCH] Stage 5 minus missing return support --- Sources/rxcc/rxcc.swift | 2020 ++++++++++++++++++++++----------------- one | 133 +++ test.c | 2 +- two | 507 ++++++++++ 4 files changed, 1790 insertions(+), 872 deletions(-) create mode 100644 one create mode 100644 two diff --git a/Sources/rxcc/rxcc.swift b/Sources/rxcc/rxcc.swift index 574b317..c63810c 100644 --- a/Sources/rxcc/rxcc.swift +++ b/Sources/rxcc/rxcc.swift @@ -1,351 +1,22 @@ import Foundation -class SyntaxTreeNode { - var parent: SyntaxTreeNode? - var children: [SyntaxTreeNode] - - var variant: ConstructVariant - var value: String - - init(_ variant: ConstructVariant) { - self.parent = nil - self.children = [SyntaxTreeNode]() - self.variant = variant - self.value = "" - } - - init(_ variant: ConstructVariant, parent: SyntaxTreeNode) { - self.parent = parent - self.children = [SyntaxTreeNode]() - self.variant = variant - self.value = "" - } - - func addChild(value: ConstructVariant) -> SyntaxTreeNode { - let child = SyntaxTreeNode(value, parent: self) - children.append(child) - return child - } - - func popLastChild() -> SyntaxTreeNode { - if let last: SyntaxTreeNode = children.popLast() { - return last - } - return SyntaxTreeNode(.Error) - } - - func text(_ level: Int = 0) -> String { - var text: String = "\(variant)" - if variant == .LiteralInteger { - text += "(\(value))" - } - for child in children { - text += "\n\(String(repeating: " ", count: level))└───\(child.text(level + 1))" - } - return text - } -} - -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 LOGICAL_AND - case LOGICAL_OR - case EQUAL - case NOT_EQUAL - case LESS_THAN - case LESS_THAN_OR_EQUAL_TO - case GREATER_THAN - case GREATER_THAN_OR_EQUAL_TO - - case UNDEFINED -} - -struct Token { - let content: Substring - let type: TokenType -} - -typealias Construct = [Element] - -enum Element { - case Loop(type: ConstructType) - case Construct(type: ConstructType) - case Token(type: TokenType) -} - -enum ConstructVariant { - case Addition - case Subtraction - case Multiplication - case Division - - case LessThan - case LessThanOrEqualTo - case GreaterThan - case GreaterThanOrEqualTo - - case EqualTo - case NotEqualTo - - case LogicalAnd - case LogicalOr - - // Unary operation variants - case Negation - case BitwiseCompliment - case LogicalNegation - - // Expression variants - case TermSequence - case AdditiveExpressionSequence - case RelationalExpressionSequence - case EqualityExpressionSequence - case LogicalAndExpressionSequence - - // Term variants - case FactorSequence - - // 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 InequalityPriorityOperator - case EqualityPriorityOperator - case LogicalAndPriorityOperator - case LogicalOrPriorityOperator - - case Program - case Function - case Statement - case Expression - case LogicalAndExpression - case EqualityExpression - case RelationalExpression - case AdditiveExpression - case Term - case Factor -} - -struct ConstructDefinitions { - var type: ConstructType - var variants: Dictionary -} - -let constructDefinitions: Dictionary> = [ - .UnaryOperator: [ - .Negation: [ - .Token(type: .NEGATION), - ], - .BitwiseCompliment: [ - .Token(type: .BITWISE_COMPLIMENT), - ], - .LogicalNegation: [ - .Token(type: .LOGICAL_NEGATION), - ], - ], - - .AdditionPriorityOperator: [ - .Addition: [ - .Token(type: .ADDITION), - ], - .Subtraction: [ - .Token(type: .NEGATION), - ], - ], - - .MultiplicationPriorityOperator: [ - .Multiplication: [ - .Token(type: .MULTIPLICATION), - ], - .Division: [ - .Token(type: .DIVISION), - ], - ], - - .InequalityPriorityOperator: [ - .LessThan: [ - .Token(type: .LESS_THAN), - ], - .LessThanOrEqualTo: [ - .Token(type: .LESS_THAN_OR_EQUAL_TO), - ], - .GreaterThan: [ - .Token(type: .GREATER_THAN), - ], - .GreaterThanOrEqualTo: [ - .Token(type: .GREATER_THAN_OR_EQUAL_TO), - ], - ], - - .EqualityPriorityOperator: [ - .EqualTo: [ - .Token(type: .EQUAL), - ], - .NotEqualTo: [ - .Token(type: .NOT_EQUAL), - ], - ], - - .LogicalAndPriorityOperator: [ - .LogicalAnd: [ - .Token(type: .LOGICAL_AND), - ], - ], - - .LogicalOrPriorityOperator: [ - .LogicalOr: [ - .Token(type: .LOGICAL_OR), - ], - ], - - // Expressions - .Expression: [ - .LogicalAndExpressionSequence: [ - .Construct(type: .LogicalAndExpression), - .Loop(type: .LogicalOrPriorityOperator), - ] - ], - - .LogicalAndExpression: [ - .EqualityExpressionSequence: [ - .Construct(type: .EqualityExpression), - .Loop(type: .LogicalAndPriorityOperator), - ] - ], - - .EqualityExpression: [ - .RelationalExpressionSequence: [ - .Construct(type: .RelationalExpression), - .Loop(type: .EqualityPriorityOperator), - ] - ], - - .RelationalExpression: [ - .AdditiveExpressionSequence: [ - .Construct(type: .AdditiveExpression), - .Loop(type: .InequalityPriorityOperator), - ] - ], - - .AdditiveExpression: [ - .TermSequence: [ - .Construct(type: .Term), - .Loop(type: .AdditionPriorityOperator), - ] - ], - - // Sub-expressions - .Term: [ - .FactorSequence: [ - .Construct(type: .Factor), - .Loop(type: .MultiplicationPriorityOperator), - ] - ], - - .Factor: [ - .LiteralInteger: [ - .Token(type: .LITERAL_INTEGER) - ], - .UnaryOperation: [ - .Construct(type: .UnaryOperator), - .Construct(type: .Factor) - ], - .ParenthesizedExpression: [ - .Token(type: .PARENTHESIS_OPEN), - .Construct(type: .Expression), - .Token(type: .PARENTHESIS_CLOSE) - ] - ], - - // Super-expressions - .Statement: [ - .ReturnInteger: [ - .Token(type: .RETURN), - .Construct(type: .Expression), - .Token(type: .SEMICOLON) - ] - ], - - .Function: [ - .Integer: [ - .Token(type: .INT), - .Token(type: .IDENTIFIER), - .Token(type: .PARENTHESIS_OPEN), - .Token(type: .PARENTHESIS_CLOSE), - .Token(type: .BRACE_OPEN), - .Construct(type: .Statement), - .Token(type: .BRACE_CLOSE) - ] - ], - - .Program: [ - .SingleFunction: [ - .Construct(type: .Function) - ] - ] -] - -let program: ConstructDefinitions = ConstructDefinitions( - type: .Function, - variants: [ - .SingleFunction: [ - .Construct(type: .Function) - ] - ] -) - - -struct TestFile { - var name: String - var path: String - var contents: String - var valid: Bool -} - @main struct rxcc { + var variables: Dictionary = [:] + var stackIndex: Int = 0 + static func main() { + var compiler = rxcc() + compiler.initialize() + } + + mutating func initialize() { if CommandLine.arguments.count < 2 { for testFile in getTestFiles() { print("Testing \(testFile.valid ? "valid" : "invalid") file \(testFile.name):") print(testFile.contents) + variables = [:] + stackIndex = 0 let lexed: [Substring] = lex(string: testFile.contents) let output: String = parse(lexed: lexed) @@ -388,603 +59,1210 @@ struct rxcc { } } } -} -func getTestFiles() -> [TestFile] { - var testFiles: [TestFile] = [TestFile]() + class SyntaxTreeNode { + var parent: SyntaxTreeNode? + var children: [SyntaxTreeNode] - let fileManager = FileManager.default - let path = "c/tests/stage_4" + var variant: ConstructVariant + var value: String - do { - let validItems = try fileManager.contentsOfDirectory(atPath: path + "/valid") - for item in validItems { - if item.last?.lowercased() != "c" { - continue - } - let fileURL = URL(fileURLWithPath: path + "/valid").appendingPathComponent(item) - let text = try String(contentsOf: fileURL, encoding: .utf8) - testFiles.append(TestFile(name: item, path: path + "/valid/", contents: text, valid: true)) + init(_ variant: ConstructVariant) { + self.parent = nil + self.children = [SyntaxTreeNode]() + self.variant = variant + self.value = "" } - let invalidItems = try fileManager.contentsOfDirectory(atPath: path + "/invalid") - - for item in invalidItems { - if item.last?.lowercased() != "c" { - continue - } - let fileURL = URL(fileURLWithPath: path + "/invalid").appendingPathComponent(item) - let text = try String(contentsOf: fileURL, encoding: .utf8) - testFiles.append(TestFile(name: item, path: path + "/invalid/", contents: text, valid: false)) + init(_ variant: ConstructVariant, parent: SyntaxTreeNode) { + self.parent = parent + self.children = [SyntaxTreeNode]() + self.variant = variant + self.value = "" + } + + func addChild(value: ConstructVariant) -> SyntaxTreeNode { + let child = SyntaxTreeNode(value, parent: self) + children.append(child) + return child + } + + func popLastChild() -> SyntaxTreeNode { + if let last: SyntaxTreeNode = children.popLast() { + return last + } + return SyntaxTreeNode(.Error) + } + + func text(_ level: Int = 0) -> String { + var text: String = "\(variant)" + if variant == .LiteralInteger { + text += "(\(value))" + } else if variant == .Variable { + text += "(\(value))" + } + for child in children { + text += "\n\(String(repeating: " ", count: level))└───\(child.text(level + 1))" + } + return text } - } catch { - print("You think I'm going to handle errors? You are mistaken.") } - return testFiles -} + 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 -func lex(string: String) -> [Substring] { - var line = string.replacing("\n", with: " ") - line = line.replacing("\t", with: " ") - line = line.replacing("{", with: " { ") - line = line.replacing("}", with: " } ") - line = line.replacing("(", with: " ( ") - line = line.replacing(")", with: " ) ") - line = line.replacing(";", with: " ; ") - line = line.replacing("-", with: " - ") - line = line.replacing("~", with: " ~ ") - line = line.replacing("!", with: " ! ") - line = line.replacing("+", with: " + ") - line = line.replacing("*", with: " * ") - line = line.replacing("/", with: " / ") - line = line.replacing("<", with: " < ") - line = line.replacing(">", with: " > ") - line = line.replacing("&&", with: " && ") - line = line.replacing("||", with: " || ") - line = line.replacing("==", with: " == ") - line = line.replacing(/! *=/, with: " != ") - line = line.replacing(/< *=/, with: " <= ") - line = line.replacing(/> *=/, with: " >= ") + case NEGATION + case BITWISE_COMPLIMENT + case LOGICAL_NEGATION - do { - let tokens: [Substring] = line.split(separator: try Regex(" +")) - print("Tokens:") - print(tokens) - return tokens - } catch { - print("Regex did something wrong") + case ADDITION + case MULTIPLICATION + case DIVISION + + case LOGICAL_AND + case LOGICAL_OR + case EQUAL + case NOT_EQUAL + case LESS_THAN + case LESS_THAN_OR_EQUAL_TO + case GREATER_THAN + case GREATER_THAN_OR_EQUAL_TO + + case ASSIGNMENT + + case UNDEFINED } - return [] -} -func generateOutput(_ node: SyntaxTreeNode) -> String { - var text: String = "" - switch node.variant { - case .Root: - for child in node.children { - text += generateOutput(child) - } - break + struct Token { + let content: Substring + let type: TokenType + } - case .ParenthesizedExpression: - for child in node.children { - text += generateOutput(child) - } - break + typealias Construct = [Element] - case .LogicalAndExpressionSequence: - var operation: ConstructVariant = .Error - let count = node.children.count - if count == 0 { - print("ERROR: \(node.variant) with no children") - break - } - for i in 0...count - 1 { - let child: SyntaxTreeNode = node.children[i] - let uuid: String = String(UUID().uuidString.split(separator: "-")[0]) + enum Element { + case List(type: ConstructType) + case OperatorLoop(type: ConstructType) + case Construct(type: ConstructType) + case Optional(type: TokenType) + case Token(type: TokenType) + } - // Operation - if i % 2 == 1 { - operation = child.variant - continue - } + enum ConstructVariant { + case Variable + case StandaloneVariable + case IntegerVariableDeclaration + case VariableAssignment - text += generateOutput(child) + case Addition + case Subtraction + case Multiplication + case Division - switch operation { - case .LogicalOr: - text += " movl\t%eax, %ecx\n" // Put e2 in ecx - text += " pop \t%eax\n" // Put e1 in eax - text += " cmpl\t$0, %eax\n" - text += " je \tlabel_\(uuid)\n" - text += " movl\t$1, %eax\n" - text += " jmp \tend_\(uuid)\n" - text += "label_\(uuid):\n" - text += " movl\t%ecx, %eax\n" // Put e2 in eax - text += " cmpl\t$0, %eax\n" - text += " movl\t$0, %eax\n" - text += " setne\t%al\n" - text += "end_\(uuid):\n" - - default: - if i != 0 { - print("Unknown operation \"\(operation)\" in \(node.variant)") + case LessThan + case LessThanOrEqualTo + case GreaterThan + case GreaterThanOrEqualTo + + case EqualTo + case NotEqualTo + + case LogicalAnd + case LogicalOr + + // Unary operation variants + case Negation + case BitwiseCompliment + case LogicalNegation + + // Expression variants + case TermSequence + case AdditiveExpressionSequence + case RelationalExpressionSequence + case EqualityExpressionSequence + case LogicalAndExpressionSequence + case LogicalOrExpressionSequence + case VariableExpression + + // Term variants + case FactorSequence + + // Factor variants + case LiteralInteger + case UnaryOperation + case ParenthesizedExpression + + // Statement variants + case StatementSequence + + case ReturnExpression + case DeclareVariable + case StandaloneExpression + + // Function Variants + case Integer + + // Program Variants + case SingleFunction + + // Misc. + case Root + case Error + } + + enum ConstructType { + case VariableFactor + case VariableDeclaration + case VariableAssignment + + case UnaryOperator + + case MultiplicationPriorityOperator + case AdditionPriorityOperator + case InequalityPriorityOperator + case EqualityPriorityOperator + case LogicalAndPriorityOperator + case LogicalOrPriorityOperator + + case Program + case Function + case StatementList + case Statement + case Expression + case LogicalOrExpression + case LogicalAndExpression + case EqualityExpression + case RelationalExpression + case AdditiveExpression + case Term + case Factor + } + + struct ConstructDefinitions { + var type: ConstructType + var variants: Dictionary + } + + let constructDefinitions: Dictionary> = [ + .VariableFactor: [ + .Variable: [ + .Token(type: .IDENTIFIER), + ], + ], + .VariableDeclaration: [ + .Variable: [ + .Token(type: .INT), + .Token(type: .IDENTIFIER), + .Optional(type: .ASSIGNMENT), + .Construct(type: .Expression), + ], + ], + .VariableAssignment: [ + .Variable: [ + .Token(type: .IDENTIFIER), + .Token(type: .ASSIGNMENT), + .Construct(type: .Expression), + ], + ], + .UnaryOperator: [ + .Negation: [ + .Token(type: .NEGATION), + ], + .BitwiseCompliment: [ + .Token(type: .BITWISE_COMPLIMENT), + ], + .LogicalNegation: [ + .Token(type: .LOGICAL_NEGATION), + ], + ], + + .AdditionPriorityOperator: [ + .Addition: [ + .Token(type: .ADDITION), + ], + .Subtraction: [ + .Token(type: .NEGATION), + ], + ], + + .MultiplicationPriorityOperator: [ + .Multiplication: [ + .Token(type: .MULTIPLICATION), + ], + .Division: [ + .Token(type: .DIVISION), + ], + ], + + .InequalityPriorityOperator: [ + .LessThan: [ + .Token(type: .LESS_THAN), + ], + .LessThanOrEqualTo: [ + .Token(type: .LESS_THAN_OR_EQUAL_TO), + ], + .GreaterThan: [ + .Token(type: .GREATER_THAN), + ], + .GreaterThanOrEqualTo: [ + .Token(type: .GREATER_THAN_OR_EQUAL_TO), + ], + ], + + .EqualityPriorityOperator: [ + .EqualTo: [ + .Token(type: .EQUAL), + ], + .NotEqualTo: [ + .Token(type: .NOT_EQUAL), + ], + ], + + .LogicalAndPriorityOperator: [ + .LogicalAnd: [ + .Token(type: .LOGICAL_AND), + ], + ], + + .LogicalOrPriorityOperator: [ + .LogicalOr: [ + .Token(type: .LOGICAL_OR), + ], + ], + + // Expressions + .Expression: [ + .VariableExpression: [ + .Construct(type: .VariableAssignment) + ], + .LogicalOrExpressionSequence: [ + .Construct(type: .LogicalOrExpression) + ], + ], + + .LogicalOrExpression: [ + .LogicalAndExpressionSequence: [ + .Construct(type: .LogicalAndExpression), + .OperatorLoop(type: .LogicalOrPriorityOperator), + ] + ], + + .LogicalAndExpression: [ + .EqualityExpressionSequence: [ + .Construct(type: .EqualityExpression), + .OperatorLoop(type: .LogicalAndPriorityOperator), + ] + ], + + .EqualityExpression: [ + .RelationalExpressionSequence: [ + .Construct(type: .RelationalExpression), + .OperatorLoop(type: .EqualityPriorityOperator), + ] + ], + + .RelationalExpression: [ + .AdditiveExpressionSequence: [ + .Construct(type: .AdditiveExpression), + .OperatorLoop(type: .InequalityPriorityOperator), + ] + ], + + .AdditiveExpression: [ + .TermSequence: [ + .Construct(type: .Term), + .OperatorLoop(type: .AdditionPriorityOperator), + ] + ], + + // Sub-expressions + .Term: [ + .FactorSequence: [ + .Construct(type: .Factor), + .OperatorLoop(type: .MultiplicationPriorityOperator), + ] + ], + + .Factor: [ + .LiteralInteger: [ + .Token(type: .LITERAL_INTEGER) + ], + .UnaryOperation: [ + .Construct(type: .UnaryOperator), + .Construct(type: .Factor) + ], + .ParenthesizedExpression: [ + .Token(type: .PARENTHESIS_OPEN), + .Construct(type: .Expression), + .Token(type: .PARENTHESIS_CLOSE) + ], + .StandaloneVariable: [ + .Construct(type: .VariableFactor) + ] + ], + + // Super-expressions + .StatementList: [ + .StatementSequence: [ + .List(type: .Statement) + ] + ], + + .Statement: [ + .ReturnExpression: [ + .Token(type: .RETURN), + .Construct(type: .Expression), + .Token(type: .SEMICOLON) + ], + .StandaloneExpression: [ + .Construct(type: .Expression), + .Token(type: .SEMICOLON) + ], + .DeclareVariable: [ + .Construct(type: .VariableDeclaration), + .Token(type: .SEMICOLON) + ], + ], + + .Function: [ + .Integer: [ + .Token(type: .INT), + .Token(type: .IDENTIFIER), + .Token(type: .PARENTHESIS_OPEN), + .Token(type: .PARENTHESIS_CLOSE), + .Token(type: .BRACE_OPEN), + .Construct(type: .StatementList), + .Token(type: .BRACE_CLOSE) + ] + ], + + .Program: [ + .SingleFunction: [ + .Construct(type: .Function) + ] + ] + ] + + let program: ConstructDefinitions = ConstructDefinitions( + type: .Function, + variants: [ + .SingleFunction: [ + .Construct(type: .Function) + ] + ] + ) + + + struct TestFile { + var name: String + var path: String + var contents: String + var valid: Bool + } + + + func getTestFiles() -> [TestFile] { + var testFiles: [TestFile] = [TestFile]() + + let fileManager = FileManager.default + let path = "c/tests/stage_5" + + do { + let validItems = try fileManager.contentsOfDirectory(atPath: path + "/valid") + for item in validItems { + if item.last?.lowercased() != "c" { + continue } + let fileURL = URL(fileURLWithPath: path + "/valid").appendingPathComponent(item) + let text = try String(contentsOf: fileURL, encoding: .utf8) + testFiles.append(TestFile(name: item, path: path + "/valid/", contents: text, valid: true)) + } + + let invalidItems = try fileManager.contentsOfDirectory(atPath: path + "/invalid") + + for item in invalidItems { + if item.last?.lowercased() != "c" { + continue + } + let fileURL = URL(fileURLWithPath: path + "/invalid").appendingPathComponent(item) + let text = try String(contentsOf: fileURL, encoding: .utf8) + testFiles.append(TestFile(name: item, path: path + "/invalid/", contents: text, valid: false)) + } + } catch { + print("You think I'm going to handle errors? You are mistaken.") + } + + return testFiles + } + + func lex(string: String) -> [Substring] { + var line = string.replacing("\n", with: " ") + line = line.replacing("\t", with: " ") + line = line.replacing("{", with: " { ") + line = line.replacing("}", with: " } ") + line = line.replacing("(", with: " ( ") + line = line.replacing(")", with: " ) ") + line = line.replacing(";", with: " ; ") + line = line.replacing("-", with: " - ") + line = line.replacing("~", with: " ~ ") + line = line.replacing("!", with: " ! ") + line = line.replacing("+", with: " + ") + line = line.replacing("*", with: " * ") + line = line.replacing("/", with: " / ") + line = line.replacing("<", with: " < ") + line = line.replacing(">", with: " > ") + line = line.replacing("=", with: " = ") + line = line.replacing("&&", with: " && ") + line = line.replacing("||", with: " || ") + line = line.replacing("==", with: " == ") + line = line.replacing(/= +=/, with: " == ") + line = line.replacing(/! *=/, with: " != ") + line = line.replacing(/< *=/, with: " <= ") + line = line.replacing(/> *=/, with: " >= ") + + do { + let tokens: [Substring] = line.split(separator: try Regex(" +")) + print("Tokens:") + print(tokens) + return tokens + } catch { + print("Regex did something wrong") + } + return [] + } + + mutating func generateOutput(_ node: SyntaxTreeNode) -> String { + var text: String = "" + switch node.variant { + case .Root: + for child in node.children { + text += generateOutput(child) + } + break + + case .StatementSequence: + for child in node.children { + text += generateOutput(child) + } + break + + case .ParenthesizedExpression: + for child in node.children { + text += generateOutput(child) + } + break + + case .StandaloneVariable: + let count = node.children.count + if count != 1 { + print("ERROR: \(node.variant) with more or less than 1 child") + break + } + //text += generateOutput(node.children[0]) + let variable: String = node.children[0].value + if let index = variables[variable] { + text += " movl\t\(index)(%ebp), %eax\n" + } else { + print("ERROR: \(variable) used before it was declared (in \(node.variant))") + } + break + + case .DeclareVariable: + let count = node.children.count + if count != 1 { + print("ERROR: \(node.variant) with more or less than 1 child") + break + } + let variable: String = node.children[0].value + + if variables.keys.contains(variable) { + print("ERROR: Redefinition of variable \"\(variable)\"") break } - if i != node.children.count - 1 { + variables.updateValue(stackIndex, forKey: variable) + stackIndex -= 4 + + let notInitialized: Bool = node.children[0].children.count == 0 + + //print("For variable \(variable), node children 0 children count == 0 : \(notInitialized)") + + if notInitialized { + text += " push\t$0\n" + } else { + text += generateOutput(node.children[0]) text += " push\t%eax\n" } - } - break - case .EqualityExpressionSequence: - var operation: ConstructVariant = .Error - let count = node.children.count - if count == 0 { - print("ERROR: \(node.variant) with no children") break - } - for i in 0...count - 1 { - let child: SyntaxTreeNode = node.children[i] - let uuid: String = String(UUID().uuidString.split(separator: "-")[0]) - // Operation - if i % 2 == 1 { - operation = child.variant - continue + case .VariableExpression: + let count = node.children.count + if count != 1 { + print("ERROR: \(node.variant) with more or less than 1 child") + break } + let variable: String = node.children[0].value + + text += generateOutput(node.children[0]) + text += " push\t%eax\n" - text += generateOutput(child) + break - switch operation { - case .LogicalAnd: - text += " movl\t%eax, %ecx\n" // Put e2 in ecx - text += " pop \t%eax\n" // Put e1 in eax - text += " cmpl\t$0, %eax\n" - text += " jne \tlabel_\(uuid)\n" - text += " jmp \tend_\(uuid)\n" - text += "label_\(uuid):\n" - text += " movl\t%ecx, %eax\n" // Put e2 in eax - text += " cmpl\t$0, %eax\n" - text += " movl\t$0, %eax\n" - text += " setne\t%al\n" - text += "end_\(uuid):\n" - - default: - if i != 0 { - print("Unknown operation \"\(operation)\" in \(node.variant)") - } + case .Variable: + let count = node.children.count + if count > 1 { + print("ERROR: \(node.variant) with more than 1 child") + break + } + let variable: String = node.value + + if !variables.keys.contains(variable) { + print("ERROR: Variable \"\(variable)\" used before it was declared") break } - if i != node.children.count - 1 { - text += " push\t%eax\n" + if count != 0 { + text += generateOutput(node.children[0]) } - } - break - case .RelationalExpressionSequence: - var operation: ConstructVariant = .Error - let count = node.children.count - if count == 0 { - print("ERROR: \(node.variant) with no children") + text += " movl\t%eax, \(variables[variable]!)(%ebp)\n" + break - } - for i in 0...count - 1 { - let child: SyntaxTreeNode = node.children[i] - // Operation - if i % 2 == 1 { - operation = child.variant - continue + case .LogicalOrExpressionSequence: + if node.children.count != 1 { + print("Error: \(node.variant) with more or less than one child") } + text += generateOutput(node.children[0]) + break - text += generateOutput(child) + case .StandaloneExpression: + if node.children.count != 1 { + print("Error: \(node.variant) with more or less than one child") + } + text += generateOutput(node.children[0]) + break - switch operation { - case .EqualTo: - text += " pop \t%ecx\n" - text += " cmpl\t%eax, %ecx\n" - text += " movl\t$0, %eax\n" - text += " sete\t%al\n" - - case .NotEqualTo: - text += " pop \t%ecx\n" - text += " cmpl\t%eax, %ecx\n" - text += " movl\t$0, %eax\n" - text += " setne\t%al\n" - - default: - if i != 0 { - print("Unknown operation \"\(operation)\" in \(node.variant)") - } + case .LogicalAndExpressionSequence: + var operation: ConstructVariant = .Error + let count = node.children.count + if count == 0 { + print("ERROR: \(node.variant) with no children") break } + for i in 0...count - 1 { + let child: SyntaxTreeNode = node.children[i] + let uuid: String = String(UUID().uuidString.split(separator: "-")[0]) - if i != node.children.count - 1 { - text += " push\t%eax\n" - } - } - break - - case .AdditiveExpressionSequence: - var operation: ConstructVariant = .Error - let count = node.children.count - if count == 0 { - print("ERROR: \(node.variant) 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 .LessThan: - text += " pop \t%ecx\n" - text += " cmpl\t%eax, %ecx\n" - text += " movl\t$0, %eax\n" - text += " setl\t%al\n" - - case .LessThanOrEqualTo: - text += " pop \t%ecx\n" - text += " cmpl\t%eax, %ecx\n" - text += " movl\t$0, %eax\n" - text += " setle\t%al\n" - - case .GreaterThan: - text += " pop \t%ecx\n" - text += " cmpl\t%eax, %ecx\n" - text += " movl\t$0, %eax\n" - text += " setg\t%al\n" - - case .GreaterThanOrEqualTo: - text += " pop \t%ecx\n" - text += " cmpl\t%eax, %ecx\n" - text += " movl\t$0, %eax\n" - text += " setge\t%al\n" - - default: - if i != 0 { - print("Unknown operation \"\(operation)\" in \(node.variant)") + // Operation + if i % 2 == 1 { + operation = child.variant + continue } - break - } - if i != node.children.count - 1 { - text += " push\t%eax\n" - } - } - break + text += generateOutput(child) - case .TermSequence: - var operation: ConstructVariant = .Error - let count = node.children.count - if count == 0 { - print("ERROR: \(node.variant) 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 \(node.variant)") - } - break - } - - if i != node.children.count - 1 { - text += " push\t%eax\n" - } - } - break - - case .FactorSequence: - 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 .Multiplication: - 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 { - print("Unknown operation \"\(operation)\" in FactorSequence") - } - break - } - - if i != node.children.count - 1 { - text += " push\t%eax\n" - } - } - break - -/* - - push %eax ; save value of e1 on the stack - - pop %ecx ; pop e1 from the stack into ecx - addl %ecx, %eax ; add e1 to e2, save results in eax -*/ - - case .Integer: - text += " .globl \(node.value)\n\(node.value):\n" - for child in node.children { - text += generateOutput(child) - } - break - - case .ReturnInteger: - if node.children.count != 1 { - print("\(node.variant) cannot have more than one child node") - return "[ERROR]" - } - - text += generateOutput(node.children[0]) - text += " ret\n" - break - - case .UnaryOperation: - if node.children.count != 2 { - print("\(node.variant) must have two child nodes") - } - let operation: SyntaxTreeNode = node.children[0] - let expression: SyntaxTreeNode = node.children[1] - - text += generateOutput(expression) - text += generateOutput(operation) - - break - - case .BitwiseCompliment: - text += " not \t%eax\n" - break - - case .Negation: - text += " neg \t%eax\n" - break - - case .LogicalNegation: - text += " cmpl\t$0, %eax\n" - text += " movl\t$0, %eax\n" - text += " sete\t%al\n" - break - - case .LiteralInteger: - text += " movl\t$\(node.value), %eax\n" - break - - default: - break - } - - return text -} - -func parse(lexed: [Substring]) -> String { - var tokens: [Token] = [Token]() - for token: Substring in lexed { - let tokenType: TokenType = categorizeToken(token: token) - tokens.append(Token(content: token, type: tokenType)) - } - tokens = tokens.reversed() - - let abstractSyntaxTree = SyntaxTreeNode(.Root) - - if validateConstruct(type: .Program, variant: .SingleFunction, tokens: &tokens, node: abstractSyntaxTree) != .Invalid { - print("Success") - print(abstractSyntaxTree.text()) - print("Assembly:") - let assembly: String = generateOutput(abstractSyntaxTree) - print(assembly) - return assembly - } - - print("Distinct lack of success") - return "" -} - -enum Validity { - case Valid - case Invalid - case Panic - case Break -} - -func validateConstruct(type: ConstructType, variant: ConstructVariant, tokens: inout [Token], node: SyntaxTreeNode) -> Validity { - var indent: String { - var count: Int = 0 - var child: SyntaxTreeNode = node - while child.parent != nil { - count += 1 - child = child.parent! - } - return String(repeating: " ", count: count) - } - - var loop: Bool = false - repeat { - let construct = constructDefinitions[type]![variant]! - for element in construct { - switch element { - case .Loop(let constructType): - var valid: Validity = .Invalid - var matchingOperator: Bool = false - print("\(indent)Determining need to loop construct of type \(constructType)") - let tokenBackup: [Token] = tokens - for constructVariant in constructDefinitions[constructType]!.keys { - let childNode = node.addChild(value: constructVariant) - print("\(indent)Testing operator \(constructType)::\(constructVariant)") - - valid = validateConstruct(type: constructType, variant: constructVariant, tokens: &tokens, node: childNode) - if valid == .Panic { - print("\(indent)Fail: panic (variant \"\(constructVariant)\"))\n") - return .Invalid - } else if valid == .Invalid { - tokens = tokenBackup - _ = node.popLastChild() - continue + switch operation { + case .LogicalOr: + text += " movl\t%eax, %ecx\n" // Put e2 in ecx + text += " pop \t%eax\n" // Put e1 in eax + text += " cmpl\t$0, %eax\n" + text += " je \tlabel_\(uuid)\n" + text += " movl\t$1, %eax\n" + text += " jmp \tend_\(uuid)\n" + text += "label_\(uuid):\n" + text += " movl\t%ecx, %eax\n" // Put e2 in eax + text += " cmpl\t$0, %eax\n" + text += " movl\t$0, %eax\n" + text += " setne\t%al\n" + text += "end_\(uuid):\n" + + default: + if i != 0 { + print("Unknown operation \"\(operation)\" in \(node.variant)") } - matchingOperator = true break } - loop = matchingOperator - - if loop { - print("\(indent)Looping") - } else { - print("\(indent)Not looping") + if i != node.children.count - 1 { + text += " push\t%eax\n" + } + } + break + + case .EqualityExpressionSequence: + var operation: ConstructVariant = .Error + let count = node.children.count + if count == 0 { + print("ERROR: \(node.variant) with no children") + break + } + for i in 0...count - 1 { + let child: SyntaxTreeNode = node.children[i] + let uuid: String = String(UUID().uuidString.split(separator: "-")[0]) + + // Operation + if i % 2 == 1 { + operation = child.variant + continue + } + + text += generateOutput(child) + + switch operation { + case .LogicalAnd: + text += " movl\t%eax, %ecx\n" // Put e2 in ecx + text += " pop \t%eax\n" // Put e1 in eax + text += " cmpl\t$0, %eax\n" + text += " jne \tlabel_\(uuid)\n" + text += " jmp \tend_\(uuid)\n" + text += "label_\(uuid):\n" + text += " movl\t%ecx, %eax\n" // Put e2 in eax + text += " cmpl\t$0, %eax\n" + text += " movl\t$0, %eax\n" + text += " setne\t%al\n" + text += "end_\(uuid):\n" + + default: + if i != 0 { + print("Unknown operation \"\(operation)\" in \(node.variant)") + } break } - case .Construct(let type): - print("\(indent)Begin validate subconstruct (type \"\(type)\")") + if i != node.children.count - 1 { + text += " push\t%eax\n" + } + } + break - var valid: Validity = .Invalid - var validVariant: ConstructVariant = .Error - let tokenBackup: [Token] = tokens - for variant in constructDefinitions[type]!.keys { - let childNode = node.addChild(value: variant) - var loopable = false - if variant == .FactorSequence || variant == .TermSequence { - loopable = true + case .RelationalExpressionSequence: + var operation: ConstructVariant = .Error + let count = node.children.count + if count == 0 { + print("ERROR: \(node.variant) 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 .EqualTo: + text += " pop \t%ecx\n" + text += " cmpl\t%eax, %ecx\n" + text += " movl\t$0, %eax\n" + text += " sete\t%al\n" + + case .NotEqualTo: + text += " pop \t%ecx\n" + text += " cmpl\t%eax, %ecx\n" + text += " movl\t$0, %eax\n" + text += " setne\t%al\n" + + default: + if i != 0 { + print("Unknown operation \"\(operation)\" in \(node.variant)") + } + break + } + + if i != node.children.count - 1 { + text += " push\t%eax\n" + } + } + break + + case .AdditiveExpressionSequence: + var operation: ConstructVariant = .Error + let count = node.children.count + if count == 0 { + print("ERROR: \(node.variant) 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 .LessThan: + text += " pop \t%ecx\n" + text += " cmpl\t%eax, %ecx\n" + text += " movl\t$0, %eax\n" + text += " setl\t%al\n" + + case .LessThanOrEqualTo: + text += " pop \t%ecx\n" + text += " cmpl\t%eax, %ecx\n" + text += " movl\t$0, %eax\n" + text += " setle\t%al\n" + + case .GreaterThan: + text += " pop \t%ecx\n" + text += " cmpl\t%eax, %ecx\n" + text += " movl\t$0, %eax\n" + text += " setg\t%al\n" + + case .GreaterThanOrEqualTo: + text += " pop \t%ecx\n" + text += " cmpl\t%eax, %ecx\n" + text += " movl\t$0, %eax\n" + text += " setge\t%al\n" + + default: + if i != 0 { + print("Unknown operation \"\(operation)\" in \(node.variant)") + } + break + } + + if i != node.children.count - 1 { + text += " push\t%eax\n" + } + } + break + + case .TermSequence: + var operation: ConstructVariant = .Error + let count = node.children.count + if count == 0 { + print("ERROR: \(node.variant) 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 \(node.variant)") + } + break + } + + if i != node.children.count - 1 { + text += " push\t%eax\n" + } + } + break + + case .FactorSequence: + 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 .Multiplication: + 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 { + print("Unknown operation \"\(operation)\" in FactorSequence") + } + break + } + + if i != node.children.count - 1 { + text += " push\t%eax\n" + } + } + break + + case .Integer: + text += """ + .globl \(node.value) + \(node.value): + push\t%ebp + movl\t%esp, %ebp + + """ + + for child in node.children { + text += generateOutput(child) + } + break + + case .ReturnExpression: + if node.children.count != 1 { + print("\(node.variant) cannot have more than one child node") + return "[ERROR]" + } + + text += generateOutput(node.children[0]) + text += """ + movl\t%ebp, %esp + pop \t%ebp + ret\n + """ + break + + case .UnaryOperation: + if node.children.count != 2 { + print("\(node.variant) must have two child nodes") + } + let operation: SyntaxTreeNode = node.children[0] + let expression: SyntaxTreeNode = node.children[1] + + text += generateOutput(expression) + text += generateOutput(operation) + + break + + case .BitwiseCompliment: + text += " not \t%eax\n" + break + + case .Negation: + text += " neg \t%eax\n" + break + + case .LogicalNegation: + text += " cmpl\t$0, %eax\n" + text += " movl\t$0, %eax\n" + text += " sete\t%al\n" + break + + case .LiteralInteger: + text += " movl\t$\(node.value), %eax\n" + break + + default: + break + } + + return text + } + + mutating func parse(lexed: [Substring]) -> String { + var tokens: [Token] = [Token]() + for token: Substring in lexed { + let tokenType: TokenType = categorizeToken(token: token) + tokens.append(Token(content: token, type: tokenType)) + } + tokens = tokens.reversed() + + let abstractSyntaxTree = SyntaxTreeNode(.Root) + + if validateConstruct(type: .Program, variant: .SingleFunction, tokens: &tokens, node: abstractSyntaxTree) != .Invalid { + print("Success") + print(abstractSyntaxTree.text()) + print("Assembly:") + let assembly: String = generateOutput(abstractSyntaxTree) + print(assembly) + return assembly + } + + print("Distinct lack of success") + return "" + } + + enum Validity { + case Valid + case Invalid + case Panic + case Break + } + + func validateConstruct(type: ConstructType, variant: ConstructVariant, tokens: inout [Token], node: SyntaxTreeNode) -> Validity { + var indent: String { + var count: Int = 0 + var child: SyntaxTreeNode = node + while child.parent != nil { + count += 1 + child = child.parent! + } + return String(repeating: " ", count: count) + } + + var loop: Bool = false + repeat { + let construct = constructDefinitions[type]![variant]! + for element in construct { + switch element { + case .OperatorLoop(let constructType): + var valid: Validity = .Invalid + var matchingOperator: Bool = false + print("\(indent)Determining need to loop construct of type \(constructType)") + let tokenBackup: [Token] = tokens + for constructVariant in constructDefinitions[constructType]!.keys { + let childNode = node.addChild(value: constructVariant) + print("\(indent)Testing operator \(constructType)::\(constructVariant)") + + valid = validateConstruct( + type: constructType, + variant: constructVariant, + tokens: &tokens, + node: childNode + ) + + if valid == .Panic { + print("\(indent)Fail: panic (variant \"\(constructVariant)\"))\n") + return .Invalid + } else if valid == .Invalid { + tokens = tokenBackup + _ = node.popLastChild() + continue + } + + matchingOperator = true + break } - print("\(indent)Testing variant \(variant) (Loop = \(loop)) (Loopable = \(loopable))") - valid = validateConstruct(type: type, variant: variant, tokens: &tokens, node: childNode) - 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 + loop = matchingOperator + + if loop { + print("\(indent)Looping") + } else { + print("\(indent)Not looping") + break } - print("\(indent)Success (variant \"\(variant)\")\n") - validVariant = variant - break - } - - - if valid == .Invalid { - print("\(indent)Subconstruct validation failed") - return .Invalid - } else if valid == .Break { - print("\(indent)End validate subconstruct (variant \"\(validVariant) by breaking\")") - break - } - - print("\(indent)End validate subconstruct (variant \"\(validVariant)\")") - continue - - case .Token(let type): - if let token: Token = tokens.popLast() { - if type != token.type { - print("\(indent)VALIDATION FAILED FOR TOKEN \"\(token.content)\"") - print("\(indent)AKA, \(type) not equal to \(token.type)") + case .Optional(let tokenType): + print("\(indent)Determining need to continue. (Testing\(tokenType))") + let tokenBackup: [Token] = tokens + if let token: Token = tokens.popLast() { + if token.type == tokenType { + print("\(indent)\(tokenType) validated. Continuing") + continue + } else { + print("\(indent)\(tokenType) NOT validated. Breaking") + tokens = tokenBackup + return .Valid + } + } else { + print("No more tokens") return .Invalid } - print("\(indent)Validated token \"\(token.content)\"") - if token.type == .LITERAL_INTEGER { - node.value = String(token.content) - } - else if token.type == .IDENTIFIER { - node.value = String(token.content) + case .Construct(let type): + print("\(indent)Begin validate subconstruct (type \"\(type)\")") + + var valid: Validity = .Invalid + var validVariant: ConstructVariant = .Error + let tokenBackup: [Token] = tokens + + + var constructVariants = Array(constructDefinitions[type]!.keys) + if constructVariants.contains(.VariableExpression) { + let index: Int = constructVariants.firstIndex(of: .VariableExpression)! + let atZero: ConstructVariant = constructVariants[0] + constructVariants[0] = constructVariants[index] + constructVariants[index] = atZero + print("\(indent)Put VariableExpression at the start of the array") } + + for variant in constructVariants { + let childNode = node.addChild(value: variant) + var loopable = false + if variant == .FactorSequence || variant == .TermSequence { + loopable = true + } + + print("\(indent)Testing variant \(variant) (Loop = \(loop)) (Loopable = \(loopable))") + valid = validateConstruct( + type: type, + variant: variant, + tokens: &tokens, + node: childNode + ) + + 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 + } + + print("\(indent)Success (variant \"\(variant)\")\n") + validVariant = variant + + break + } + + + if valid == .Invalid { + print("\(indent)Subconstruct validation failed") + return .Invalid + } else if valid == .Break { + print("\(indent)End validate subconstruct (variant \"\(validVariant) by breaking\")") + break + } + + print("\(indent)End validate subconstruct (variant \"\(validVariant)\")") continue - } else { - print("\(indent)RAN OUT OF TOKENS") - return .Invalid + case .List(let constructType): + var valid: Validity = .Invalid + var matching: Bool = false + print("\(indent)Determining need to loop construct of type \(constructType)") + let tokenBackup: [Token] = tokens + + var constructVariants = Array(constructDefinitions[constructType]!.keys) + if constructVariants.contains(.VariableExpression) { + let index: Int = constructVariants.firstIndex(of: .VariableExpression)! + let atZero: ConstructVariant = constructVariants[0] + constructVariants[0] = constructVariants[index] + constructVariants[index] = atZero + print("\(indent)Put VariableExpression at the start of the array") + } + + for constructVariant in constructVariants { + let childNode = node.addChild(value: constructVariant) + print("\(indent)Testing \(constructType)::\(constructVariant)") + + valid = validateConstruct( + type: constructType, + variant: constructVariant, + tokens: &tokens, + node: childNode + ) + + if valid == .Panic { + print("\(indent)Fail: panic (variant \"\(constructVariant)\"))\n") + return .Invalid + } else if valid == .Invalid { + tokens = tokenBackup + _ = node.popLastChild() + continue + } + + matching = true + break + } + + loop = matching + + if loop { + print("\(indent)Looping") + } else { + print("\(indent)Not looping") + break + } + + case .Token(let type): + if let token: Token = tokens.popLast() { + if token.type == .ASSIGNMENT && variant == .LogicalOrExpressionSequence { + print("\(indent)Cannot encounter assignment in \(variant)") + return .Invalid + } + else if type != token.type { + print("\(indent)Failed to validate token \"\(token.content)\". Expected \"\(type)\"") + //print("\(indent)AKA, \(type) not equal to \(token.type)") + return .Invalid + } + print("\(indent)Validated token \"\(token.content)\"") + + if token.type == .LITERAL_INTEGER { + node.value = String(token.content) + } + else if token.type == .IDENTIFIER { + node.value = String(token.content) + } + + continue + + } else { + print("\(indent)RAN OUT OF TOKENS") + return .Invalid + } } } - } - } while loop + } while loop - return .Valid + return .Valid + } + + func categorizeToken(token: Substring) -> TokenType { + if token.firstMatch(of: /^{$/) != nil { return .BRACE_OPEN } + else if token.firstMatch(of: /^}$/) != nil { return .BRACE_CLOSE } + else if token.firstMatch(of: /^\($/) != nil { return .PARENTHESIS_OPEN } + else if token.firstMatch(of: /^\)$/) != nil { return .PARENTHESIS_CLOSE } + else if token.firstMatch(of: /^;$/) != nil { return .SEMICOLON } + else if token.firstMatch(of: /^int$/) != nil { return .INT } + else if token.firstMatch(of: /^return$/) != nil { return .RETURN } + else if token.firstMatch(of: /^[a-zA-Z]\w*$/) != nil { return .IDENTIFIER } + else if token.firstMatch(of: /^[0-9]+$/) != nil { return .LITERAL_INTEGER} + 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 } + else if token.firstMatch(of: /^&&$/) != nil { return .LOGICAL_AND } + else if token.firstMatch(of: /^\|\|$/) != nil { return .LOGICAL_OR } + else if token.firstMatch(of: /^==$/) != nil { return .EQUAL } + else if token.firstMatch(of: /^!=$/) != nil { return .NOT_EQUAL } + else if token.firstMatch(of: /^<$/) != nil { return .LESS_THAN } + else if token.firstMatch(of: /^<=$/) != nil { return .LESS_THAN_OR_EQUAL_TO } + else if token.firstMatch(of: /^>$/) != nil { return .GREATER_THAN } + else if token.firstMatch(of: /^>=$/) != nil { return .GREATER_THAN_OR_EQUAL_TO } + else if token.firstMatch(of: /^=$/) != nil { return .ASSIGNMENT } + + return .UNDEFINED + } } - -func categorizeToken(token: Substring) -> TokenType { - if token.firstMatch(of: /^{$/) != nil { return .BRACE_OPEN } - else if token.firstMatch(of: /^}$/) != nil { return .BRACE_CLOSE } - else if token.firstMatch(of: /^\($/) != nil { return .PARENTHESIS_OPEN } - else if token.firstMatch(of: /^\)$/) != nil { return .PARENTHESIS_CLOSE } - else if token.firstMatch(of: /^;$/) != nil { return .SEMICOLON } - else if token.firstMatch(of: /^int$/) != nil { return .INT } - else if token.firstMatch(of: /^return$/) != nil { return .RETURN } - else if token.firstMatch(of: /^[a-zA-Z]\w*$/) != nil { return .IDENTIFIER } - else if token.firstMatch(of: /^[0-9]+$/) != nil { return .LITERAL_INTEGER} - 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 } - else if token.firstMatch(of: /^&&$/) != nil { return .LOGICAL_AND } - else if token.firstMatch(of: /^\|\|$/) != nil { return .LOGICAL_OR } - else if token.firstMatch(of: /^==$/) != nil { return .EQUAL } - else if token.firstMatch(of: /^!=$/) != nil { return .NOT_EQUAL } - else if token.firstMatch(of: /^<$/) != nil { return .LESS_THAN } - else if token.firstMatch(of: /^<=$/) != nil { return .LESS_THAN_OR_EQUAL_TO } - else if token.firstMatch(of: /^>$/) != nil { return .GREATER_THAN } - else if token.firstMatch(of: /^>=$/) != nil { return .GREATER_THAN_OR_EQUAL_TO } - - return .UNDEFINED -} - diff --git a/one b/one new file mode 100644 index 0000000..f4882b8 --- /dev/null +++ b/one @@ -0,0 +1,133 @@ +Tokens: +["int", "main", "(", ")", "{", "int", "tomas", ";", "tomas", "=", "2", ";", "return", "1", "+", "2", ";", "}"] +Begin validate subconstruct (type "Function") +Testing variant Integer (Loop = false) (Loopable = false) + Validated token "int" + Validated token "main" + Validated token "(" + Validated token ")" + Validated token "{" + Begin validate subconstruct (type "StatementList") + Testing variant StatementSequence (Loop = false) (Loopable = false) + Determining need to loop construct of type Statement + Testing Statement::ReturnExpression + Failed to validate token "int". Expected "RETURN" + Testing Statement::DeclareVariable + Begin validate subconstruct (type "VariableDeclaration") + Testing variant Variable (Loop = false) (Loopable = false) + Validated token "int" + Validated token "tomas" + Determining need to continue. (TestingASSIGNMENT) + ASSIGNMENT NOT validated. Breaking + Success (variant "Variable") + + End validate subconstruct (variant "Variable") + Validated token ";" + Looping + Determining need to loop construct of type Statement + Testing Statement::ReturnExpression + Failed to validate token "tomas". Expected "RETURN" + Testing Statement::DeclareVariable + Begin validate subconstruct (type "VariableDeclaration") + Testing variant Variable (Loop = false) (Loopable = false) + Failed to validate token "tomas". Expected "INT" + Fail: no valid variants (variant "Variable") + + Subconstruct validation failed + Testing Statement::StandaloneExpression + Begin validate subconstruct (type "Expression") + Testing variant LogicalOrExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "LogicalOrExpression") + Testing variant LogicalAndExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "LogicalAndExpression") + Testing variant EqualityExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "EqualityExpression") + Testing variant RelationalExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "RelationalExpression") + Testing variant AdditiveExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "AdditiveExpression") + Testing variant TermSequence (Loop = false) (Loopable = true) + Begin validate subconstruct (type "Term") + Testing variant FactorSequence (Loop = false) (Loopable = true) + Begin validate subconstruct (type "Factor") + Testing variant LiteralInteger (Loop = false) (Loopable = false) + Failed to validate token "tomas". Expected "LITERAL_INTEGER" + Fail: no valid variants (variant "LiteralInteger") + + Testing variant StandaloneVariable (Loop = false) (Loopable = false) + Begin validate subconstruct (type "VariableFactor") + Testing variant Variable (Loop = false) (Loopable = false) + Validated token "tomas" + Success (variant "Variable") + + End validate subconstruct (variant "Variable") + Success (variant "StandaloneVariable") + + End validate subconstruct (variant "StandaloneVariable") + Determining need to loop construct of type MultiplicationPriorityOperator + Testing operator MultiplicationPriorityOperator::Division + Failed to validate token "=". Expected "DIVISION" + Testing operator MultiplicationPriorityOperator::Multiplication + Failed to validate token "=". Expected "MULTIPLICATION" + Not looping + Success (variant "FactorSequence") + + End validate subconstruct (variant "FactorSequence") + Determining need to loop construct of type AdditionPriorityOperator + Testing operator AdditionPriorityOperator::Subtraction + Failed to validate token "=". Expected "NEGATION" + Testing operator AdditionPriorityOperator::Addition + Failed to validate token "=". Expected "ADDITION" + Not looping + Success (variant "TermSequence") + + End validate subconstruct (variant "TermSequence") + Determining need to loop construct of type InequalityPriorityOperator + Testing operator InequalityPriorityOperator::GreaterThanOrEqualTo + Failed to validate token "=". Expected "GREATER_THAN_OR_EQUAL_TO" + Testing operator InequalityPriorityOperator::LessThan + Failed to validate token "=". Expected "LESS_THAN" + Testing operator InequalityPriorityOperator::LessThanOrEqualTo + Failed to validate token "=". Expected "LESS_THAN_OR_EQUAL_TO" + Testing operator InequalityPriorityOperator::GreaterThan + Failed to validate token "=". Expected "GREATER_THAN" + Not looping + Success (variant "AdditiveExpressionSequence") + + End validate subconstruct (variant "AdditiveExpressionSequence") + Determining need to loop construct of type EqualityPriorityOperator + Testing operator EqualityPriorityOperator::EqualTo + Failed to validate token "=". Expected "EQUAL" + Testing operator EqualityPriorityOperator::NotEqualTo + Failed to validate token "=". Expected "NOT_EQUAL" + Not looping + Success (variant "RelationalExpressionSequence") + + End validate subconstruct (variant "RelationalExpressionSequence") + Determining need to loop construct of type LogicalAndPriorityOperator + Testing operator LogicalAndPriorityOperator::LogicalAnd + Failed to validate token "=". Expected "LOGICAL_AND" + Not looping + Success (variant "EqualityExpressionSequence") + + End validate subconstruct (variant "EqualityExpressionSequence") + Determining need to loop construct of type LogicalOrPriorityOperator + Testing operator LogicalOrPriorityOperator::LogicalOr + Failed to validate token "=". Expected "LOGICAL_OR" + Not looping + Success (variant "LogicalAndExpressionSequence") + + End validate subconstruct (variant "LogicalAndExpressionSequence") + Success (variant "LogicalOrExpressionSequence") + + End validate subconstruct (variant "LogicalOrExpressionSequence") + Failed to validate token "=". Expected "SEMICOLON" + Not looping + Success (variant "StatementSequence") + + End validate subconstruct (variant "StatementSequence") + Failed to validate token "tomas". Expected "BRACE_CLOSE" +Fail: no valid variants (variant "Integer") + +Subconstruct validation failed +Distinct lack of success diff --git a/test.c b/test.c index b293070..337f3aa 100644 --- a/test.c +++ b/test.c @@ -1,4 +1,4 @@ int main() { - return 1 || 0 && 2; + } diff --git a/two b/two new file mode 100644 index 0000000..1ff1e91 --- /dev/null +++ b/two @@ -0,0 +1,507 @@ +Tokens: +["int", "main", "(", ")", "{", "int", "tomas", ";", "tomas", "=", "2", ";", "return", "1", "+", "2", ";", "}"] +Begin validate subconstruct (type "Function") +Testing variant Integer (Loop = false) (Loopable = false) + Validated token "int" + Validated token "main" + Validated token "(" + Validated token ")" + Validated token "{" + Begin validate subconstruct (type "StatementList") + Testing variant StatementSequence (Loop = false) (Loopable = false) + Determining need to loop construct of type Statement + Testing Statement::StandaloneExpression + Begin validate subconstruct (type "Expression") + Testing variant VariableExpression (Loop = false) (Loopable = false) + Begin validate subconstruct (type "VariableAssignment") + Testing variant Variable (Loop = false) (Loopable = false) + Failed to validate token "int". Expected "IDENTIFIER" + Fail: no valid variants (variant "Variable") + + Subconstruct validation failed + Fail: no valid variants (variant "VariableExpression") + + Testing variant LogicalOrExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "LogicalOrExpression") + Testing variant LogicalAndExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "LogicalAndExpression") + Testing variant EqualityExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "EqualityExpression") + Testing variant RelationalExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "RelationalExpression") + Testing variant AdditiveExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "AdditiveExpression") + Testing variant TermSequence (Loop = false) (Loopable = true) + Begin validate subconstruct (type "Term") + Testing variant FactorSequence (Loop = false) (Loopable = true) + Begin validate subconstruct (type "Factor") + Testing variant LiteralInteger (Loop = false) (Loopable = false) + Failed to validate token "int". Expected "LITERAL_INTEGER" + Fail: no valid variants (variant "LiteralInteger") + + Testing variant ParenthesizedExpression (Loop = false) (Loopable = false) + Failed to validate token "int". Expected "PARENTHESIS_OPEN" + Fail: no valid variants (variant "ParenthesizedExpression") + + Testing variant StandaloneVariable (Loop = false) (Loopable = false) + Begin validate subconstruct (type "VariableFactor") + Testing variant Variable (Loop = false) (Loopable = false) + Failed to validate token "int". Expected "IDENTIFIER" + Fail: no valid variants (variant "Variable") + + Subconstruct validation failed + Fail: no valid variants (variant "StandaloneVariable") + + Testing variant UnaryOperation (Loop = false) (Loopable = false) + Begin validate subconstruct (type "UnaryOperator") + Testing variant LogicalNegation (Loop = false) (Loopable = false) + Failed to validate token "int". Expected "LOGICAL_NEGATION" + Fail: no valid variants (variant "LogicalNegation") + + Testing variant BitwiseCompliment (Loop = false) (Loopable = false) + Failed to validate token "int". Expected "BITWISE_COMPLIMENT" + Fail: no valid variants (variant "BitwiseCompliment") + + Testing variant Negation (Loop = false) (Loopable = false) + Failed to validate token "int". Expected "NEGATION" + Fail: no valid variants (variant "Negation") + + Subconstruct validation failed + Fail: no valid variants (variant "UnaryOperation") + + Subconstruct validation failed + Fail: no valid variants (variant "FactorSequence") + + Subconstruct validation failed + Fail: no valid variants (variant "TermSequence") + + Subconstruct validation failed + Fail: no valid variants (variant "AdditiveExpressionSequence") + + Subconstruct validation failed + Fail: no valid variants (variant "RelationalExpressionSequence") + + Subconstruct validation failed + Fail: no valid variants (variant "EqualityExpressionSequence") + + Subconstruct validation failed + Fail: no valid variants (variant "LogicalAndExpressionSequence") + + Subconstruct validation failed + Fail: no valid variants (variant "LogicalOrExpressionSequence") + + Subconstruct validation failed + Testing Statement::DeclareVariable + Begin validate subconstruct (type "VariableDeclaration") + Testing variant Variable (Loop = false) (Loopable = false) + Validated token "int" + Validated token "tomas" + Determining need to continue. (TestingASSIGNMENT) + ASSIGNMENT NOT validated. Breaking + Success (variant "Variable") + + End validate subconstruct (variant "Variable") + Validated token ";" + Looping + Determining need to loop construct of type Statement + Testing Statement::StandaloneExpression + Begin validate subconstruct (type "Expression") + Testing variant VariableExpression (Loop = false) (Loopable = false) + Begin validate subconstruct (type "VariableAssignment") + Testing variant Variable (Loop = false) (Loopable = false) + Validated token "tomas" + Validated token "=" + Begin validate subconstruct (type "Expression") + Testing variant VariableExpression (Loop = false) (Loopable = false) + Begin validate subconstruct (type "VariableAssignment") + Testing variant Variable (Loop = false) (Loopable = false) + Failed to validate token "2". Expected "IDENTIFIER" + Fail: no valid variants (variant "Variable") + + Subconstruct validation failed + Fail: no valid variants (variant "VariableExpression") + + Testing variant LogicalOrExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "LogicalOrExpression") + Testing variant LogicalAndExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "LogicalAndExpression") + Testing variant EqualityExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "EqualityExpression") + Testing variant RelationalExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "RelationalExpression") + Testing variant AdditiveExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "AdditiveExpression") + Testing variant TermSequence (Loop = false) (Loopable = true) + Begin validate subconstruct (type "Term") + Testing variant FactorSequence (Loop = false) (Loopable = true) + Begin validate subconstruct (type "Factor") + Testing variant LiteralInteger (Loop = false) (Loopable = false) + Validated token "2" + Success (variant "LiteralInteger") + + End validate subconstruct (variant "LiteralInteger") + Determining need to loop construct of type MultiplicationPriorityOperator + Testing operator MultiplicationPriorityOperator::Division + Failed to validate token ";". Expected "DIVISION" + Testing operator MultiplicationPriorityOperator::Multiplication + Failed to validate token ";". Expected "MULTIPLICATION" + Not looping + Success (variant "FactorSequence") + + End validate subconstruct (variant "FactorSequence") + Determining need to loop construct of type AdditionPriorityOperator + Testing operator AdditionPriorityOperator::Addition + Failed to validate token ";". Expected "ADDITION" + Testing operator AdditionPriorityOperator::Subtraction + Failed to validate token ";". Expected "NEGATION" + Not looping + Success (variant "TermSequence") + + End validate subconstruct (variant "TermSequence") + Determining need to loop construct of type InequalityPriorityOperator + Testing operator InequalityPriorityOperator::LessThan + Failed to validate token ";". Expected "LESS_THAN" + Testing operator InequalityPriorityOperator::GreaterThanOrEqualTo + Failed to validate token ";". Expected "GREATER_THAN_OR_EQUAL_TO" + Testing operator InequalityPriorityOperator::LessThanOrEqualTo + Failed to validate token ";". Expected "LESS_THAN_OR_EQUAL_TO" + Testing operator InequalityPriorityOperator::GreaterThan + Failed to validate token ";". Expected "GREATER_THAN" + Not looping + Success (variant "AdditiveExpressionSequence") + + End validate subconstruct (variant "AdditiveExpressionSequence") + Determining need to loop construct of type EqualityPriorityOperator + Testing operator EqualityPriorityOperator::EqualTo + Failed to validate token ";". Expected "EQUAL" + Testing operator EqualityPriorityOperator::NotEqualTo + Failed to validate token ";". Expected "NOT_EQUAL" + Not looping + Success (variant "RelationalExpressionSequence") + + End validate subconstruct (variant "RelationalExpressionSequence") + Determining need to loop construct of type LogicalAndPriorityOperator + Testing operator LogicalAndPriorityOperator::LogicalAnd + Failed to validate token ";". Expected "LOGICAL_AND" + Not looping + Success (variant "EqualityExpressionSequence") + + End validate subconstruct (variant "EqualityExpressionSequence") + Determining need to loop construct of type LogicalOrPriorityOperator + Testing operator LogicalOrPriorityOperator::LogicalOr + Failed to validate token ";". Expected "LOGICAL_OR" + Not looping + Success (variant "LogicalAndExpressionSequence") + + End validate subconstruct (variant "LogicalAndExpressionSequence") + Success (variant "LogicalOrExpressionSequence") + + End validate subconstruct (variant "LogicalOrExpressionSequence") + Success (variant "Variable") + + End validate subconstruct (variant "Variable") + Success (variant "VariableExpression") + + End validate subconstruct (variant "VariableExpression") + Validated token ";" + Looping + Determining need to loop construct of type Statement + Testing Statement::StandaloneExpression + Begin validate subconstruct (type "Expression") + Testing variant VariableExpression (Loop = false) (Loopable = false) + Begin validate subconstruct (type "VariableAssignment") + Testing variant Variable (Loop = false) (Loopable = false) + Failed to validate token "return". Expected "IDENTIFIER" + Fail: no valid variants (variant "Variable") + + Subconstruct validation failed + Fail: no valid variants (variant "VariableExpression") + + Testing variant LogicalOrExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "LogicalOrExpression") + Testing variant LogicalAndExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "LogicalAndExpression") + Testing variant EqualityExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "EqualityExpression") + Testing variant RelationalExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "RelationalExpression") + Testing variant AdditiveExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "AdditiveExpression") + Testing variant TermSequence (Loop = false) (Loopable = true) + Begin validate subconstruct (type "Term") + Testing variant FactorSequence (Loop = false) (Loopable = true) + Begin validate subconstruct (type "Factor") + Testing variant LiteralInteger (Loop = false) (Loopable = false) + Failed to validate token "return". Expected "LITERAL_INTEGER" + Fail: no valid variants (variant "LiteralInteger") + + Testing variant ParenthesizedExpression (Loop = false) (Loopable = false) + Failed to validate token "return". Expected "PARENTHESIS_OPEN" + Fail: no valid variants (variant "ParenthesizedExpression") + + Testing variant StandaloneVariable (Loop = false) (Loopable = false) + Begin validate subconstruct (type "VariableFactor") + Testing variant Variable (Loop = false) (Loopable = false) + Failed to validate token "return". Expected "IDENTIFIER" + Fail: no valid variants (variant "Variable") + + Subconstruct validation failed + Fail: no valid variants (variant "StandaloneVariable") + + Testing variant UnaryOperation (Loop = false) (Loopable = false) + Begin validate subconstruct (type "UnaryOperator") + Testing variant LogicalNegation (Loop = false) (Loopable = false) + Failed to validate token "return". Expected "LOGICAL_NEGATION" + Fail: no valid variants (variant "LogicalNegation") + + Testing variant BitwiseCompliment (Loop = false) (Loopable = false) + Failed to validate token "return". Expected "BITWISE_COMPLIMENT" + Fail: no valid variants (variant "BitwiseCompliment") + + Testing variant Negation (Loop = false) (Loopable = false) + Failed to validate token "return". Expected "NEGATION" + Fail: no valid variants (variant "Negation") + + Subconstruct validation failed + Fail: no valid variants (variant "UnaryOperation") + + Subconstruct validation failed + Fail: no valid variants (variant "FactorSequence") + + Subconstruct validation failed + Fail: no valid variants (variant "TermSequence") + + Subconstruct validation failed + Fail: no valid variants (variant "AdditiveExpressionSequence") + + Subconstruct validation failed + Fail: no valid variants (variant "RelationalExpressionSequence") + + Subconstruct validation failed + Fail: no valid variants (variant "EqualityExpressionSequence") + + Subconstruct validation failed + Fail: no valid variants (variant "LogicalAndExpressionSequence") + + Subconstruct validation failed + Fail: no valid variants (variant "LogicalOrExpressionSequence") + + Subconstruct validation failed + Testing Statement::DeclareVariable + Begin validate subconstruct (type "VariableDeclaration") + Testing variant Variable (Loop = false) (Loopable = false) + Failed to validate token "return". Expected "INT" + Fail: no valid variants (variant "Variable") + + Subconstruct validation failed + Testing Statement::ReturnExpression + Validated token "return" + Begin validate subconstruct (type "Expression") + Testing variant VariableExpression (Loop = false) (Loopable = false) + Begin validate subconstruct (type "VariableAssignment") + Testing variant Variable (Loop = false) (Loopable = false) + Failed to validate token "1". Expected "IDENTIFIER" + Fail: no valid variants (variant "Variable") + + Subconstruct validation failed + Fail: no valid variants (variant "VariableExpression") + + Testing variant LogicalOrExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "LogicalOrExpression") + Testing variant LogicalAndExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "LogicalAndExpression") + Testing variant EqualityExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "EqualityExpression") + Testing variant RelationalExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "RelationalExpression") + Testing variant AdditiveExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "AdditiveExpression") + Testing variant TermSequence (Loop = false) (Loopable = true) + Begin validate subconstruct (type "Term") + Testing variant FactorSequence (Loop = false) (Loopable = true) + Begin validate subconstruct (type "Factor") + Testing variant LiteralInteger (Loop = false) (Loopable = false) + Validated token "1" + Success (variant "LiteralInteger") + + End validate subconstruct (variant "LiteralInteger") + Determining need to loop construct of type MultiplicationPriorityOperator + Testing operator MultiplicationPriorityOperator::Division + Failed to validate token "+". Expected "DIVISION" + Testing operator MultiplicationPriorityOperator::Multiplication + Failed to validate token "+". Expected "MULTIPLICATION" + Not looping + Success (variant "FactorSequence") + + End validate subconstruct (variant "FactorSequence") + Determining need to loop construct of type AdditionPriorityOperator + Testing operator AdditionPriorityOperator::Addition + Validated token "+" + Looping + Begin validate subconstruct (type "Term") + Testing variant FactorSequence (Loop = true) (Loopable = true) + Begin validate subconstruct (type "Factor") + Testing variant LiteralInteger (Loop = false) (Loopable = false) + Validated token "2" + Success (variant "LiteralInteger") + + End validate subconstruct (variant "LiteralInteger") + Determining need to loop construct of type MultiplicationPriorityOperator + Testing operator MultiplicationPriorityOperator::Division + Failed to validate token ";". Expected "DIVISION" + Testing operator MultiplicationPriorityOperator::Multiplication + Failed to validate token ";". Expected "MULTIPLICATION" + Not looping + Success (variant "FactorSequence") + + End validate subconstruct (variant "FactorSequence") + Determining need to loop construct of type AdditionPriorityOperator + Testing operator AdditionPriorityOperator::Addition + Failed to validate token ";". Expected "ADDITION" + Testing operator AdditionPriorityOperator::Subtraction + Failed to validate token ";". Expected "NEGATION" + Not looping + Success (variant "TermSequence") + + End validate subconstruct (variant "TermSequence") + Determining need to loop construct of type InequalityPriorityOperator + Testing operator InequalityPriorityOperator::LessThan + Failed to validate token ";". Expected "LESS_THAN" + Testing operator InequalityPriorityOperator::GreaterThanOrEqualTo + Failed to validate token ";". Expected "GREATER_THAN_OR_EQUAL_TO" + Testing operator InequalityPriorityOperator::LessThanOrEqualTo + Failed to validate token ";". Expected "LESS_THAN_OR_EQUAL_TO" + Testing operator InequalityPriorityOperator::GreaterThan + Failed to validate token ";". Expected "GREATER_THAN" + Not looping + Success (variant "AdditiveExpressionSequence") + + End validate subconstruct (variant "AdditiveExpressionSequence") + Determining need to loop construct of type EqualityPriorityOperator + Testing operator EqualityPriorityOperator::EqualTo + Failed to validate token ";". Expected "EQUAL" + Testing operator EqualityPriorityOperator::NotEqualTo + Failed to validate token ";". Expected "NOT_EQUAL" + Not looping + Success (variant "RelationalExpressionSequence") + + End validate subconstruct (variant "RelationalExpressionSequence") + Determining need to loop construct of type LogicalAndPriorityOperator + Testing operator LogicalAndPriorityOperator::LogicalAnd + Failed to validate token ";". Expected "LOGICAL_AND" + Not looping + Success (variant "EqualityExpressionSequence") + + End validate subconstruct (variant "EqualityExpressionSequence") + Determining need to loop construct of type LogicalOrPriorityOperator + Testing operator LogicalOrPriorityOperator::LogicalOr + Failed to validate token ";". Expected "LOGICAL_OR" + Not looping + Success (variant "LogicalAndExpressionSequence") + + End validate subconstruct (variant "LogicalAndExpressionSequence") + Success (variant "LogicalOrExpressionSequence") + + End validate subconstruct (variant "LogicalOrExpressionSequence") + Validated token ";" + Looping + Determining need to loop construct of type Statement + Testing Statement::StandaloneExpression + Begin validate subconstruct (type "Expression") + Testing variant VariableExpression (Loop = false) (Loopable = false) + Begin validate subconstruct (type "VariableAssignment") + Testing variant Variable (Loop = false) (Loopable = false) + Failed to validate token "}". Expected "IDENTIFIER" + Fail: no valid variants (variant "Variable") + + Subconstruct validation failed + Fail: no valid variants (variant "VariableExpression") + + Testing variant LogicalOrExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "LogicalOrExpression") + Testing variant LogicalAndExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "LogicalAndExpression") + Testing variant EqualityExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "EqualityExpression") + Testing variant RelationalExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "RelationalExpression") + Testing variant AdditiveExpressionSequence (Loop = false) (Loopable = false) + Begin validate subconstruct (type "AdditiveExpression") + Testing variant TermSequence (Loop = false) (Loopable = true) + Begin validate subconstruct (type "Term") + Testing variant FactorSequence (Loop = false) (Loopable = true) + Begin validate subconstruct (type "Factor") + Testing variant LiteralInteger (Loop = false) (Loopable = false) + Failed to validate token "}". Expected "LITERAL_INTEGER" + Fail: no valid variants (variant "LiteralInteger") + + Testing variant ParenthesizedExpression (Loop = false) (Loopable = false) + Failed to validate token "}". Expected "PARENTHESIS_OPEN" + Fail: no valid variants (variant "ParenthesizedExpression") + + Testing variant StandaloneVariable (Loop = false) (Loopable = false) + Begin validate subconstruct (type "VariableFactor") + Testing variant Variable (Loop = false) (Loopable = false) + Failed to validate token "}". Expected "IDENTIFIER" + Fail: no valid variants (variant "Variable") + + Subconstruct validation failed + Fail: no valid variants (variant "StandaloneVariable") + + Testing variant UnaryOperation (Loop = false) (Loopable = false) + Begin validate subconstruct (type "UnaryOperator") + Testing variant LogicalNegation (Loop = false) (Loopable = false) + Failed to validate token "}". Expected "LOGICAL_NEGATION" + Fail: no valid variants (variant "LogicalNegation") + + Testing variant BitwiseCompliment (Loop = false) (Loopable = false) + Failed to validate token "}". Expected "BITWISE_COMPLIMENT" + Fail: no valid variants (variant "BitwiseCompliment") + + Testing variant Negation (Loop = false) (Loopable = false) + Failed to validate token "}". Expected "NEGATION" + Fail: no valid variants (variant "Negation") + + Subconstruct validation failed + Fail: no valid variants (variant "UnaryOperation") + + Subconstruct validation failed + Fail: no valid variants (variant "FactorSequence") + + Subconstruct validation failed + Fail: no valid variants (variant "TermSequence") + + Subconstruct validation failed + Fail: no valid variants (variant "AdditiveExpressionSequence") + + Subconstruct validation failed + Fail: no valid variants (variant "RelationalExpressionSequence") + + Subconstruct validation failed + Fail: no valid variants (variant "EqualityExpressionSequence") + + Subconstruct validation failed + Fail: no valid variants (variant "LogicalAndExpressionSequence") + + Subconstruct validation failed + Fail: no valid variants (variant "LogicalOrExpressionSequence") + + Subconstruct validation failed + Testing Statement::DeclareVariable + Begin validate subconstruct (type "VariableDeclaration") + Testing variant Variable (Loop = false) (Loopable = false) + Failed to validate token "}". Expected "INT" + Fail: no valid variants (variant "Variable") + + Subconstruct validation failed + Testing Statement::ReturnExpression + Failed to validate token "}". Expected "RETURN" + Not looping + Success (variant "StatementSequence") + + End validate subconstruct (variant "StatementSequence") + Validated token "}" +Success (variant "Integer") + +End validate subconstruct (variant "Integer") +Success