test.ha (2792B)
1 use io; 2 use fmt; 3 4 fn same(a: *token, b: *token, quick: bool) bool = { 5 if (a.name != b.name) return false; 6 match (a.value) { 7 case let avalue: f64 => 8 if (!(b.value is f64)) return false; 9 if (avalue != b.value as f64) return false; 10 case let avalue: i64 => 11 if (!(b.value is i64)) return false; 12 if (avalue != b.value as i64) return false; 13 case let avalue: size => 14 if (!(b.value is size)) return false; 15 if (avalue != b.value as size) return false; 16 case let avalue: u64 => 17 if (!(b.value is u64)) return false; 18 if (avalue != b.value as u64) return false; 19 case let avalue: str => 20 if (!(b.value is str)) return false; 21 if (avalue != b.value as str) return false; 22 case let avalue: rune => 23 if (!(b.value is rune)) return false; 24 if (avalue != b.value as rune) return false; 25 case let avalue: void => 26 if (!(b.value is void)) return false; 27 }; 28 if (a.start.line != b.start.line) return false; 29 if (a.start.col != b.start.col) return false; 30 31 if (quick) return true; 32 33 if (a.morphene != b.morphene) return false; 34 if (a.start.off != b.start.off) return false; 35 if (a.end.line != b.end.line) return false; 36 if (a.end.col != b.end.col) return false; 37 if (a.end.off != b.end.off) return false; 38 return true; 39 }; 40 41 fn error_token(tok: *token, quick: bool) (void | io::error) = { 42 switch (quick) { 43 case false => 44 fmt::errorfln("{}:{}:{}: '{}' '{}' '{}' {}:{}:{}", 45 tok.start.line, tok.start.col, tok.start.off, 46 tok.name, tok.value, tok.morphene, 47 tok.end.line, tok.end.col, tok.end.off)?; 48 case true => 49 fmt::errorfln("{}:{}: '{}' '{}'", 50 tok.start.line, tok.start.col, 51 tok.name, tok.value)?; 52 }; 53 }; 54 55 export fn testexps(lexer: *lexer, exp: []token, quick: bool = false) void = { 56 for (let exp &.. exp) { 57 const token = match (next(lexer)) { 58 case let err: error => 59 fmt::fatal(strerror(err)); 60 case let tok: *token => yield tok; 61 }; 62 63 if (!same(exp, token, quick)) { 64 fmt::errorf("Expected: ")!; 65 error_token(exp, quick)!; 66 fmt::errorf("Got: ")!; 67 error_token(token, quick)!; 68 abort(); 69 }; 70 }; 71 }; 72 73 export fn testtok( 74 name: const str, 75 value: value, 76 morphene: const str, 77 start: location, 78 end: location, 79 ) token = { 80 return token { 81 name = name, 82 value = value, 83 morphene = morphene, 84 lexeme = morphene, 85 start = start, 86 end = end, 87 tostrfn = null: *tokstrfn, 88 freefn = null: *tokfreefn, 89 }; 90 }; 91 92 export fn testtok_quick( 93 name: const str, 94 value: value, 95 line: uint, 96 col: uint, 97 ) token = { 98 return token { 99 name = name, 100 value = value, 101 lexeme = "", 102 morphene = "", 103 tostrfn = null: *tokstrfn, 104 freefn = null: *tokfreefn, 105 start = location { 106 line = line, 107 col = col, 108 ... 109 }, 110 ... 111 }; 112 }; 113 114 export fn testloc(line: uint, col: uint, off: uint) location = { 115 return location { 116 line = line, 117 col = col, 118 off = off, 119 }; 120 }; 121