Stage 1 passing

This commit is contained in:
2026-01-25 21:39:09 -05:00
parent e5e75b344f
commit 9fd722edd9

View File

@@ -1,3 +1,5 @@
import Foundation
enum Constant {
case Integer(value: Int)
}
@@ -65,17 +67,52 @@ 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()
}
}
}
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] {
@@ -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
}