diff --git a/Sources/rxcc/rxcc.swift b/Sources/rxcc/rxcc.swift index da87785..b90e410 100644 --- a/Sources/rxcc/rxcc.swift +++ b/Sources/rxcc/rxcc.swift @@ -1,3 +1,5 @@ +import Foundation + enum Constant { case Integer(value: Int) } @@ -65,19 +67,54 @@ let program: Construct = [ ] +struct TestFile { + var name: String + var contents: String + var valid: Bool +} @main struct rxcc { static func main() { - let lexed: [Substring] = lex(string: """ - int main() { - return 100; + for testFile in getTestFiles() { + print("Testing \(testFile.valid ? "valid" : "invalid") file \(testFile.name):") + print(testFile.contents) + let lexed: [Substring] = lex(string: testFile.contents) + parse(lexed: lexed) + print() } - """) - parse(lexed: lexed) } } +func getTestFiles() -> [TestFile] { + var testFiles: [TestFile] = [TestFile]() + + let fileManager = FileManager.default + let path = "c/tests/stage_1" + + do { + let validItems = try fileManager.contentsOfDirectory(atPath: path + "/valid") + + for item in validItems { + let fileURL = URL(fileURLWithPath: path + "/valid").appendingPathComponent(item) + let text = try String(contentsOf: fileURL, encoding: .utf8) + testFiles.append(TestFile(name: item, contents: text, valid: true)) + } + + let invalidItems = try fileManager.contentsOfDirectory(atPath: path + "/invalid") + + for item in invalidItems { + let fileURL = URL(fileURLWithPath: path + "/invalid").appendingPathComponent(item) + let text = try String(contentsOf: fileURL, encoding: .utf8) + testFiles.append(TestFile(name: item, 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: " ") @@ -130,6 +167,9 @@ func validateConstruct(_ construct: Construct, tokens: inout [Token]) -> Bool { print("VALIDATION FAILED FOR TOKEN \"\(token.content)\"") return false } + } else { + print("RAN OUT OF TOKENS") + return false } } } @@ -138,15 +178,15 @@ func validateConstruct(_ construct: Construct, tokens: inout [Token]) -> Bool { } 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 } + 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 } return .UNDEFINED }