MCPcopy Create free account
hub / github.com/dylan-sutton-chavez/edge-python / lex

Function lex

compiler/src/modules/lexer/mod.rs:55–109  ·  view source on GitHub ↗

Parser-ready tokens with indentation handled. Returns lex diagnostics alongside so the caller folds them into the parser's error stream. */

(source: &str)

Source from the content-addressed store, hash-verified

53
54/* Parser-ready tokens with indentation handled. Returns lex diagnostics alongside so the caller folds them into the parser's error stream. */
55pub fn lex(source: &str) -> (Vec<Token>, Vec<LexError>) {
56 let bytes = source.as_bytes();
57 let len = source.len();
58 let mut scanner = Scanner::new(bytes);
59 // Skip UTF-8 BOM so it doesn't fuse into the first identifier.
60 if bytes.starts_with(&[0xEF, 0xBB, 0xBF]) { scanner.pos = 3; }
61
62 if len > MAX_SOURCE_SIZE {
63 scanner.errors.push(LexError {
64 start: 0, end: 0,
65 msg: "source file exceeds maximum size (10 MiB)",
66 });
67 return (
68 alloc::vec![Token { kind: TokenType::Endmarker, line: 0, start: len, end: len }],
69 scanner.errors,
70 );
71 }
72
73 let mut raw: Vec<(TokenType, usize, usize, usize)> = Vec::new();
74 while let Some(t) = scanner.next_token() {
75 raw.push(t);
76 }
77 // Drain dangling indents at EOF so blocks always close cleanly.
78 while scanner.indent_stack.pop().is_some() {
79 raw.push((TokenType::Dedent, scanner.line, len, len));
80 }
81 raw.push((TokenType::Endmarker, scanner.line, len, len));
82
83 let mut tokens = Vec::with_capacity(raw.len());
84 let mut ended = false;
85 for i in 0..raw.len() {
86 let (tok, line, start, end) = raw[i];
87 if ended { break; }
88 if tok == TokenType::Endmarker { ended = true; }
89
90 /* Soft keywords demote to Name by the next token, so `match(...)`, `case(...)`, `type(...)` parse as calls not statements. */
91 let is_soft = matches!(tok, TokenType::Type | TokenType::Match | TokenType::Case);
92 let next_demotes = matches!(
93 raw.get(i + 1),
94 Some(&(
95 TokenType::Lpar
96 | TokenType::Colon
97 | TokenType::Equal
98 | TokenType::Comma
99 | TokenType::Rpar
100 | TokenType::Rsqb
101 | TokenType::Newline,
102 _, _, _,
103 )) | None
104 );
105 let kind = if is_soft && next_demotes { TokenType::Name } else { tok };
106 tokens.push(Token { kind, line, start, end });
107 }
108 (tokens, scanner.errors)
109}
110
111impl TokenType {
112 #[inline]

Callers 12

scan_importsFunction · 0.85
parse_or_get_cachedMethod · 0.85
run_startFunction · 0.85
runFunction · 0.85
test_casesFunction · 0.85
test_casesFunction · 0.85
noop_resolver_defaultFunction · 0.85
packages_casesFunction · 0.85
test_casesFunction · 0.85
strict_casesFunction · 0.85

Calls 4

pushMethod · 0.80
lenMethod · 0.45
next_tokenMethod · 0.45
popMethod · 0.45

Tested by 8

test_casesFunction · 0.68
test_casesFunction · 0.68
noop_resolver_defaultFunction · 0.68
packages_casesFunction · 0.68
test_casesFunction · 0.68
strict_casesFunction · 0.68