1use std::{collections::BTreeSet, fmt::Debug};
2
3use anyhow::{Result, anyhow};
4use dynamic::{ConstIntOp, Dynamic, Type};
5use smol_str::SmolStr;
6
7mod expr;
8pub use expr::{BinaryOp, Expr, ExprKind, UnaryOp};
9
10mod pattern;
11pub use pattern::{Pattern, PatternKind};
12
13mod stmt;
14pub use stmt::{Stmt, StmtKind};
15
16#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
17pub struct Span {
18 pub start: usize,
19 pub end: usize,
20}
21
22impl Span {
23 pub const fn new(start: usize, end: usize) -> Self {
24 Self { start, end }
25 }
26
27 pub const fn empty(pos: usize) -> Self {
28 Self { start: pos, end: pos }
29 }
30
31 pub fn merge(self, other: Self) -> Self {
32 Self { start: self.start.min(other.start), end: self.end.max(other.end) }
33 }
34}
35
36#[derive(Debug)]
37#[derive(Default, Clone)]
41pub(crate) struct ScopeDepths {
42 pub(crate) impl_depth: usize,
45 pub(crate) impl_body_depth: usize,
48 pub(crate) fn_body_depth: usize,
51 pub(crate) depth: usize,
53}
54
55pub struct Parser {
56 pos: usize, buf: Vec<u8>, spans: Vec<usize>,
59 decl_scopes: Vec<BTreeSet<SmolStr>>,
60 scope_depths: ScopeDepths,
61 pub(crate) match_counter: usize,
64 fatal: bool, }
66
67struct SpanGuard {
77 parser: *mut Parser,
78}
79
80unsafe impl Send for SpanGuard {}
84unsafe impl Sync for SpanGuard {}
85
86impl Drop for SpanGuard {
87 fn drop(&mut self) {
88 unsafe {
91 if !(*self.parser).spans.is_empty() {
92 (*self.parser).spans.pop();
93 }
94 }
95 }
96}
97
98pub const MAX_PARSE_DEPTH: usize = 128;
105
106const NOT_IDENT: &[u8] = &[b' ', b'\t', b'\n', b'\r', b'/', b'*', b'+', b'-', b'=', b'(', b')', b'{', b'}', b'[', b']', b';', b':', b',', b'.', b'<', b'>', b'!', b'#', b'$', b'%', b'^', b'&', b'|', b'\\', b'"', b'\''];
107const WHITE_SPACE: &[u8] = &[b' ', b'\t', b'\n', b'\r'];
108const TYPES: &[(&str, Type)] = &[
109 ("bool", Type::Bool),
110 ("string", Type::Str),
111 ("i8", Type::I8),
112 ("i16", Type::I16),
113 ("i32", Type::I32),
114 ("i64", Type::I64),
115 ("u8", Type::U8),
116 ("u16", Type::U16),
117 ("u32", Type::U32),
118 ("u64", Type::U64),
119 ("f16", Type::F16),
120 ("f32", Type::F32),
121 ("f64", Type::F64),
122];
123const KEYWORDS: &[&str] = &["true", "false", "null", "let", "if", "else", "for", "in", "while", "loop", "pub", "fn", "struct", "impl", "const", "static", "continue", "return", "break", "match"];
124
125#[macro_export]
126macro_rules! parse_list {
127 ($self: ident, $start: expr, $end: expr, $sep: expr, $item_expr: expr) => {{
128 let mut items = $start;
129 loop {
130 $self.whitespace()?;
131 if $self.get()? == $end {
132 $self.pos += 1;
133 break;
134 }
135 let item = $item_expr;
136 items.push(item);
137 $self.whitespace()?;
138 if $self.get()? == $sep {
139 $self.pos += 1;
140 }
141 }
142 items
143 }};
144}
145
146#[macro_export]
147macro_rules! try_parse {
148 ($self: ident, $method: expr) => {{
149 let save_pos = $self.pos; let save_decl_scopes = $self.decl_scopes.clone();
151 let save_impl_depth = $self.scope_depths.impl_depth;
152 match $method {
153 Ok(expr) => Ok(expr),
154 Err(e) if $self.fatal => Err(e),
156 Err(e) => {
157 $self.pos = save_pos;
158 $self.decl_scopes = save_decl_scopes;
159 $self.scope_depths.impl_depth = save_impl_depth;
160 Err(e)
161 }
162 }
163 }};
164}
165
166#[derive(Debug, thiserror::Error)]
167pub enum ParserErr {
168 #[error("{message}")]
169 Spanned { message: String, span: Span },
170}
171
172impl ParserErr {
173 pub fn new(message: impl Into<String>, span: Span) -> Self {
175 Self::Spanned { message: message.into(), span }
176 }
177
178 pub fn at(message: impl Into<String>, pos: usize) -> Self {
180 Self::Spanned { message: message.into(), span: Span::new(pos, pos) }
181 }
182
183 pub fn span(&self) -> Span {
184 match self {
185 Self::Spanned { span, .. } => *span,
186 }
187 }
188
189 pub fn message(&self) -> &str {
190 match self {
191 Self::Spanned { message, .. } => message,
192 }
193 }
194}
195
196#[derive(Debug, thiserror::Error)]
199#[error("{err}")]
200pub struct SpannedParseError {
201 pub err: ParserErr,
202 pub pos: usize,
203}
204
205impl SpannedParseError {
206 pub fn new(err: ParserErr, pos: usize) -> Self {
207 Self { err, pos }
208 }
209}
210
211impl Parser {
212 pub fn new(buf: Vec<u8>) -> Self {
213 Self { pos: 0, buf, spans: Vec::new(), decl_scopes: vec![BTreeSet::new()], scope_depths: ScopeDepths::default(), match_counter: 0, fatal: false }
214 }
215
216 fn with_stmt_span(&mut self) -> SpanGuard {
229 self.spans.push(self.pos);
230 SpanGuard { parser: self as *mut Parser }
231 }
232
233 fn enter_depth(&mut self) -> Result<()> {
240 self.scope_depths.depth += 1;
241 if self.scope_depths.depth > MAX_PARSE_DEPTH {
242 self.scope_depths.depth -= 1;
243 self.fatal = true;
244 return Err(ParserErr::at("表达式嵌套过深", self.current_pos()).into());
245 }
246 Ok(())
247 }
248
249 fn exit_depth(&mut self) {
250 self.scope_depths.depth = self.scope_depths.depth.saturating_sub(1);
251 }
252
253 fn check_fatal(&self) -> Result<()> {
255 if self.fatal { Err(ParserErr::at("表达式嵌套过深", self.current_pos()).into()) } else { Ok(()) }
256 }
257
258 pub(crate) fn push_decl_scope(&mut self) {
259 self.decl_scopes.push(BTreeSet::new());
260 }
261
262 pub(crate) fn pop_decl_scope(&mut self) {
263 if self.decl_scopes.len() > 1 {
264 self.decl_scopes.pop();
265 }
266 }
267
268 fn declare_symbol(&mut self, name: &SmolStr) -> Result<()> {
269 if name.is_empty() {
270 return Ok(());
271 }
272 if self.decl_scopes.iter().rev().any(|scope| scope.contains(name)) {
273 return Err(ParserErr::at(format!("符号 {} 已经声明", name), self.current_pos()).into());
274 }
275 self.decl_scopes.last_mut().expect("parser always has a declaration scope").insert(name.clone());
276 Ok(())
277 }
278
279 pub(crate) fn declare_symbol_in_current_scope(&mut self, name: &SmolStr) -> Result<()> {
280 if name.is_empty() {
281 return Ok(());
282 }
283 let scope = self.decl_scopes.last_mut().expect("parser always has a declaration scope");
284 if scope.contains(name) {
285 return Err(ParserErr::at(format!("符号 {} 已经声明", name), self.current_pos()).into());
286 }
287 scope.insert(name.clone());
288 Ok(())
289 }
290
291 fn declare_function_name(&mut self, name: &SmolStr) -> Result<()> {
292 if self.scope_depths.impl_depth > 0 { self.declare_symbol_in_current_scope(name) } else { self.declare_symbol(name) }
293 }
294
295 fn declare_args(&mut self, args: &[(SmolStr, Type)]) -> Result<()> {
296 for (name, _) in args {
297 self.declare_symbol(name)?;
298 }
299 Ok(())
300 }
301
302 pub(crate) fn declare_pattern_symbols(&mut self, pat: &Pattern) -> Result<()> {
303 match &pat.kind {
304 PatternKind::Ident { name, .. } => self.declare_symbol_in_current_scope(name),
305 PatternKind::Tuple(items) => {
306 for item in items {
307 self.declare_pattern_symbols(item)?;
308 }
309 Ok(())
310 }
311 PatternKind::List { elems, .. } => {
312 for item in elems {
313 self.declare_pattern_symbols(item)?;
314 }
315 Ok(())
316 }
317 PatternKind::Struct { fields, .. } => {
318 for (name, sub) in fields {
319 if let Some(sub) = sub {
320 self.declare_pattern_symbols(sub)?;
321 } else {
322 self.declare_symbol_in_current_scope(name)?;
323 }
324 }
325 Ok(())
326 }
327 PatternKind::Wildcard | PatternKind::Var { .. } | PatternKind::Literal(_) | PatternKind::Member(_, _) | PatternKind::Idx(_, _) => Ok(()),
328 }
329 }
330
331 fn function_body(&mut self, args: &[(SmolStr, Type)]) -> Result<Stmt> {
332 self.push_decl_scope();
333 self.scope_depths.fn_body_depth += 1;
334 let result = (|| {
335 self.declare_args(args)?;
336 self.block()
337 })();
338 self.scope_depths.fn_body_depth -= 1;
339 self.pop_decl_scope();
340 result
341 }
342
343 fn impl_body(&mut self) -> Result<Stmt> {
344 self.push_decl_scope();
345 self.scope_depths.impl_depth += 1;
346 self.scope_depths.impl_body_depth += 1;
347 let result = self.block();
348 self.scope_depths.impl_body_depth -= 1;
349 self.scope_depths.impl_depth -= 1;
350 self.pop_decl_scope();
351 result
352 }
353
354 pub fn is_eof(&self) -> bool {
355 self.pos >= self.buf.len()
356 }
357
358 pub fn get(&self) -> Result<u8> {
359 self.buf.get(self.pos).cloned().ok_or_else(|| ParserErr::at("输入结束", self.pos).into())
361 }
362
363 pub fn take(&mut self, ch: u8) -> Result<()> {
364 if self.buf.get(self.pos).map(|b| *b == ch).unwrap_or(false) {
366 self.pos += 1;
367 Ok(())
368 } else {
369 let actual_desc = match self.buf.get(self.pos) {
372 Some(byte) => format!("实际字符 {}", *byte as char),
373 None => "已到文件末尾".to_string(),
374 };
375 Err(SpannedParseError::new(ParserErr::at(format!("期望字符 {} {}", ch as char, actual_desc), self.pos), self.pos).into())
376 }
377 }
378
379 pub fn until(&mut self, ch: u8) -> Result<()> {
380 self.whitespace()?;
382 self.take(ch)
383 }
384
385 pub fn ahead(&self) -> Result<u8> {
386 self.buf.get(self.pos + 1).cloned().ok_or_else(|| ParserErr::at("输入结束", self.pos).into())
388 }
389
390 pub fn get_str(&self, start: usize, stop: usize) -> SmolStr {
391 SmolStr::from(String::from_utf8_lossy(&self.buf[start..stop]))
392 }
393
394 pub fn error_stmt(&self) -> SmolStr {
395 SmolStr::from(String::from_utf8_lossy(&self.buf[self.spans.last().cloned().unwrap_or(0)..self.pos]))
396 }
397
398 pub fn current_pos(&self) -> usize {
399 self.pos
400 }
401
402 pub fn span_from(&self, start: usize) -> Span {
403 Span::new(start, self.pos)
404 }
405
406 pub fn collect<F: Fn(u8) -> bool>(&mut self, f: F) -> Result<(usize, usize)> {
407 let start = self.pos;
408 while self.pos < self.buf.len() && f(self.buf[self.pos]) {
409 self.pos += 1;
410 }
411 if self.pos > start { Ok((start, self.pos)) } else { Err(ParserErr::at("未发现期望字符", start).into()) }
412 }
413
414 pub fn just(&mut self, pattern: &str) -> Result<()> {
415 if self.buf.len() - self.pos >= pattern.len() && self.buf[self.pos..self.pos + pattern.len()].eq(pattern.as_bytes()) {
416 self.pos += pattern.len();
417 Ok(())
418 } else {
419 Err(ParserErr::at(format!("期望字符串 {}", pattern), self.pos).into())
420 }
421 }
422
423 pub fn keyword(&mut self, pattern: &str) -> Result<()> {
424 self.just(pattern)?;
425 if self.pos < self.buf.len() && !NOT_IDENT.contains(&self.buf[self.pos]) {
426 self.pos -= pattern.len();
427 return Err(ParserErr::at(format!("期望字符串 {}", pattern), self.pos).into());
428 }
429 Ok(())
430 }
431
432 pub fn get_type(&mut self) -> Result<Type> {
433 self.whitespace()?;
434 if self.get()? == b'[' {
435 self.pos += 1;
436 let ty = self.get_type()?;
437 self.until(b';')?;
438 self.whitespace()?;
439 let len = self.get_type_param()?;
440 self.until(b']')?;
441 if let Type::ConstInt(number) = len {
442 let number = u32::try_from(number).map_err(|_| anyhow!("数组长度超出 u32 范围"))?;
443 Ok(Type::Array(std::rc::Rc::new(ty), number))
444 } else {
445 Ok(Type::ArrayParam(std::rc::Rc::new(ty), std::rc::Rc::new(len)))
446 }
447 } else {
448 for ty in TYPES {
449 if self.just(ty.0).is_ok() {
450 return Ok(ty.1.clone());
451 }
452 }
453 let name = self.ident()?;
454 if self.take(b'<').is_ok() {
455 let params = crate::parse_list!(self, Vec::new(), b'>', b',', self.get_type_param()?);
456 Ok(Type::Ident { name, params })
457 } else {
458 Ok(Type::Ident { name, params: Vec::new() })
459 }
460 }
461 }
462
463 pub fn get_type_param(&mut self) -> Result<Type> {
464 self.const_type_param_add()
465 }
466
467 fn const_type_param_add(&mut self) -> Result<Type> {
468 let mut left = self.const_type_param_mul()?;
469 loop {
470 self.whitespace()?;
471 let op = if self.take(b'+').is_ok() {
472 Some(ConstIntOp::Add)
473 } else if self.take(b'-').is_ok() {
474 Some(ConstIntOp::Sub)
475 } else {
476 None
477 };
478 let Some(op) = op else { break };
479 let right = self.const_type_param_mul()?;
480 left = Self::fold_const_type_binary(op, left, right)?;
481 }
482 Ok(left)
483 }
484
485 fn const_type_param_mul(&mut self) -> Result<Type> {
486 let mut left = self.const_type_param_primary()?;
487 loop {
488 self.whitespace()?;
489 let op = if self.take(b'*').is_ok() {
490 Some(ConstIntOp::Mul)
491 } else if self.take(b'/').is_ok() {
492 Some(ConstIntOp::Div)
493 } else if self.take(b'%').is_ok() {
494 Some(ConstIntOp::Mod)
495 } else {
496 None
497 };
498 let Some(op) = op else { break };
499 let right = self.const_type_param_primary()?;
500 left = Self::fold_const_type_binary(op, left, right)?;
501 }
502 Ok(left)
503 }
504
505 fn const_type_param_primary(&mut self) -> Result<Type> {
506 self.whitespace()?;
507 if self.take(b'(').is_ok() {
508 let ty = self.get_type_param()?;
509 self.until(b')')?;
510 return Ok(ty);
511 }
512 if self.get()?.is_ascii_digit() {
513 let value = self.number()?;
514 if let Some(value) = value.as_uint() {
515 let value = i64::try_from(value).map_err(|_| anyhow!("模板数字参数超出 i64 范围"))?;
516 Ok(Type::ConstInt(value))
517 } else if let Some(value) = value.as_int() {
518 Ok(Type::ConstInt(value))
519 } else {
520 Err(anyhow!("模板数字参数必须是整数"))
521 }
522 } else {
523 self.get_type()
524 }
525 }
526
527 fn fold_const_type_binary(op: ConstIntOp, left: Type, right: Type) -> Result<Type> {
528 if let (Type::ConstInt(left), Type::ConstInt(right)) = (&left, &right) {
529 let value = match op {
530 ConstIntOp::Add => left + right,
531 ConstIntOp::Sub => left - right,
532 ConstIntOp::Mul => left * right,
533 ConstIntOp::Div => {
534 if *right == 0 {
535 return Err(anyhow!("模板整数除以 0"));
536 }
537 left / right
538 }
539 ConstIntOp::Mod => {
540 if *right == 0 {
541 return Err(anyhow!("模板整数取模 0"));
542 }
543 left % right
544 }
545 };
546 Ok(Type::ConstInt(value))
547 } else {
548 Ok(Type::ConstBinary { op, left: std::rc::Rc::new(left), right: std::rc::Rc::new(right) })
549 }
550 }
551
552 pub fn comment(&mut self) -> Result<()> {
553 if self.get()? == b'/' && self.ahead()? == b'/' {
554 self.pos += 2;
555 while self.pos < self.buf.len() && self.buf[self.pos] != b'\n' {
556 self.pos += 1;
557 }
558 Ok(())
559 } else if self.get()? == b'/' && self.ahead()? == b'*' {
560 self.pos += 2;
561 while self.pos + 1 < self.buf.len() {
562 if self.buf[self.pos] == b'*' && self.buf[self.pos + 1] == b'/' {
563 self.pos += 2;
564 return Ok(());
565 }
566 self.pos += 1;
567 }
568 Err(ParserErr::at("未关闭的注释", self.pos).into())
569 } else {
570 Ok(())
571 }
572 }
573
574 pub fn whitespace(&mut self) -> Result<()> {
575 while self.pos < self.buf.len() {
576 self.comment()?;
577 if self.pos >= self.buf.len() || !WHITE_SPACE.contains(&self.buf[self.pos]) {
578 break;
579 }
580 self.pos += 1;
581 }
582 Ok(())
583 }
584
585 pub fn ident(&mut self) -> Result<SmolStr> {
586 let (start, mut stop) = self.collect(|ch| !NOT_IDENT.contains(&ch))?;
587 loop {
588 let save_pos = self.pos;
589 if self.just("::").is_err() {
590 break;
591 }
592 match self.collect(|ch| !NOT_IDENT.contains(&ch)) {
593 Ok((_, next_stop)) => {
594 stop = next_stop;
595 }
596 Err(_) => {
597 self.pos = save_pos;
598 break;
599 }
600 }
601 }
602 if KEYWORDS.iter().position(|k| k.as_bytes() == &self.buf[start..stop]).is_some() {
603 return Err(anyhow!("发现关键字{}", String::from_utf8_lossy(&self.buf[start..stop])));
604 }
605 Ok(self.get_str(start, stop))
606 }
607
608 pub fn string(&mut self) -> Result<SmolStr> {
609 if self.get()? != b'"' {
610 return Err(ParserErr::at("非字符串", self.current_pos()).into());
611 }
612 self.pos += 1;
613 let mut text_buf = Vec::new();
614 while self.pos < self.buf.len() {
615 if self.buf[self.pos] == b'\\' {
616 self.pos += 1;
618 match self.buf[self.pos] {
619 b'n' => {
620 text_buf.push(b'\n');
621 self.pos += 1;
622 }
623 b'r' => {
624 text_buf.push(b'\r');
625 self.pos += 1;
626 }
627 b't' => {
628 text_buf.push(b'\t');
629 self.pos += 1;
630 }
631 ch @ (b'\\' | b'"') => {
632 text_buf.push(ch);
633 self.pos += 1;
634 }
635 b'u' => {
636 self.pos += 1;
637 let unicode = if self.take(b'{').is_ok() {
638 let code = self.hex()?;
639 self.pos += 1;
640 code
641 } else {
642 self.hex()?
643 };
644 let ch = char::from_u32(unicode as u32).ok_or(anyhow!("非法 unicode {}", unicode))?;
645 let mut utf8_buf = [0u8; 4];
646 let s = ch.encode_utf8(&mut utf8_buf);
647 text_buf.extend_from_slice(s.as_bytes());
648 }
649 b'x' => {
650 self.pos += 1;
651 if self.pos + 2 > self.buf.len() {
652 return Err(anyhow!("非法 \\x 转义:需要 2 位十六进制"));
653 }
654 let start = self.pos;
655 self.pos += 2;
656 let hex = &self.buf[start..self.pos];
657 if hex.iter().any(|b| !b.is_ascii_hexdigit()) {
658 return Err(anyhow!("非法 \\x 转义:仅允许十六进制字符"));
659 }
660 let code = u32::from_str_radix(String::from_utf8_lossy(hex).as_ref(), 16)?;
661 if code > 0xFF {
662 return Err(anyhow!("\\x 转义值 0x{:02X} 超出 0xFF", code));
663 }
664 text_buf.push(code as u8);
665 }
666 other => {
667 return Err(anyhow!("invalid escape character: {}", other as char));
668 }
669 }
670 } else {
671 if self.buf[self.pos] == b'"' {
672 self.pos += 1;
673 return Ok(String::from_utf8(text_buf)?.into());
674 }
675 text_buf.push(self.buf[self.pos]);
676 self.pos += 1;
677 }
678 }
679 Err(ParserErr::at("未关闭字符串", self.pos).into())
680 }
681
682 pub fn text(&mut self) -> Result<SmolStr> {
683 if self.get()? == b'r' && [b'#', b'"'].contains(&self.ahead()?) {
684 self.pos += 1;
685 let mut hash_count: usize = 0;
690 while self.pos < self.buf.len() && self.buf[self.pos] == b'#' {
691 hash_count += 1;
692 self.pos += 1;
693 }
694 if self.get()? != b'"' {
697 return Err(ParserErr::at("非法的原始字符串", self.current_pos()).into());
698 }
699 self.pos += 1;
700 let mut end: Vec<u8> = Vec::with_capacity(hash_count + 1);
704 end.push(b'"');
705 for _ in 0..hash_count {
706 end.push(b'#');
707 }
708 let start_pos = self.pos;
709 while self.pos < self.buf.len() {
710 if self.pos + end.len() <= self.buf.len() && self.buf[self.pos..self.pos + end.len()].eq(&end) {
711 break;
712 }
713 self.pos += 1;
714 }
715 if self.pos + end.len() > self.buf.len() {
717 return Err(ParserErr::at("未关闭字符串", self.current_pos()).into());
718 }
719 let stop = self.pos;
721 self.pos += end.len();
722 Ok(self.get_str(start_pos, stop))
723 } else {
724 self.string()
725 }
726 }
727
728 fn hex(&mut self) -> Result<i32> {
729 let (start, stop) = self.collect(|ch| (ch >= b'0' && ch <= b'9') || (ch >= b'a' && ch <= b'f') || (ch >= b'A' && ch <= b'F'))?;
731 Ok(i32::from_str_radix(&String::from_utf8_lossy(&self.buf[start..stop]), 16)?)
732 }
733
734 fn numeric_suffix(&mut self) -> Option<Type> {
735 let save = self.pos;
736 for (name, ty) in TYPES {
737 if !ty.is_native() {
738 continue;
739 }
740 if self.buf.len() >= self.pos + name.len() && self.buf[self.pos..self.pos + name.len()].eq(name.as_bytes()) {
741 self.pos += name.len();
742 return Some(ty.clone());
743 }
744 }
745 self.pos = save;
746 None
747 }
748
749 fn int_literal(&mut self, digits: &str, radix: u32, suffix: Option<Type>) -> Result<Dynamic> {
750 let ty = suffix.unwrap_or(Type::I64);
752 let magnitude = u128::from_str_radix(digits, radix).map_err(|_| anyhow!("整数字面量 {} 超出可表示范围", digits))?;
754 let (signed, bits) = match ty {
755 Type::I8 => (true, 8u32),
756 Type::I16 => (true, 16),
757 Type::I32 => (true, 32),
758 Type::I64 => (true, 64),
759 Type::U8 => (false, 8),
760 Type::U16 => (false, 16),
761 Type::U32 => (false, 32),
762 Type::U64 => (false, 64),
763 Type::F16 => return Ok(Dynamic::F16(dynamic::f64_to_f16(magnitude as f64))),
764 Type::F32 => return Ok(Dynamic::F32(magnitude as f32)),
765 Type::F64 => return Ok(Dynamic::F64(magnitude as f64)),
766 ty => return Err(anyhow!("{:?} 不能作为数字后缀", ty)),
767 };
768 let unsigned_max = (1u128 << bits) - 1;
769 let max_allowed = if radix == 10 { if signed { unsigned_max / 2 + 1 } else { unsigned_max } } else { unsigned_max };
772 if magnitude > max_allowed {
773 return Err(anyhow!("整数字面量 {} 超出 {:?} 的范围", digits, ty));
774 }
775 Ok(match ty {
776 Type::I8 => Dynamic::I8(magnitude as i8),
777 Type::I16 => Dynamic::I16(magnitude as i16),
778 Type::I32 => Dynamic::I32(magnitude as i32),
779 Type::I64 => Dynamic::I64(magnitude as i64),
780 Type::U8 => Dynamic::U8(magnitude as u8),
781 Type::U16 => Dynamic::U16(magnitude as u16),
782 Type::U32 => Dynamic::U32(magnitude as u32),
783 Type::U64 => Dynamic::U64(magnitude as u64),
784 _ => unreachable!(),
785 })
786 }
787
788 fn float_literal(&mut self, digits: &str, suffix: Option<Type>) -> Result<Dynamic> {
789 let value: f64 = digits.parse()?;
790 if let Some(ref ty) = suffix {
791 let is_int_suffix = matches!(ty, Type::I8 | Type::I16 | Type::I32 | Type::I64 | Type::U8 | Type::U16 | Type::U32 | Type::U64);
794 if is_int_suffix {
795 let (min, max): (f64, f64) = match ty {
796 Type::I8 => (i8::MIN as f64, i8::MAX as f64),
797 Type::I16 => (i16::MIN as f64, i16::MAX as f64),
798 Type::I32 => (i32::MIN as f64, i32::MAX as f64),
799 Type::I64 => (i64::MIN as f64, i64::MAX as f64),
800 Type::U8 => (0.0, u8::MAX as f64),
801 Type::U16 => (0.0, u16::MAX as f64),
802 Type::U32 => (0.0, u32::MAX as f64),
803 Type::U64 => (0.0, u64::MAX as f64),
804 _ => unreachable!(),
805 };
806 if !value.is_finite() || value < min || value > max || value.fract() != 0.0 {
807 return Err(anyhow!("浮点字面量 {:?} 超出 {:?} 范围", value, ty));
808 }
809 } else if !value.is_finite() {
810 return Err(anyhow!("非法浮点字面量: {:?}", value));
811 }
812 }
813 Ok(match suffix.unwrap_or(Type::F32) {
814 Type::I8 => Dynamic::I8(value as i8),
815 Type::I16 => Dynamic::I16(value as i16),
816 Type::I32 => Dynamic::I32(value as i32),
817 Type::I64 => Dynamic::I64(value as i64),
818 Type::U8 => Dynamic::U8(value as u8),
819 Type::U16 => Dynamic::U16(value as u16),
820 Type::U32 => Dynamic::U32(value as u32),
821 Type::U64 => Dynamic::U64(value as u64),
822 Type::F16 => Dynamic::F16(dynamic::f64_to_f16(value)),
823 Type::F32 => Dynamic::F32(value as f32),
824 Type::F64 => Dynamic::F64(value),
825 ty => return Err(anyhow!("{:?} 不能作为浮点数字后缀", ty)),
826 })
827 }
828
829 pub fn number(&mut self) -> Result<Dynamic> {
830 if self.get()? == b'0' {
831 if [b'b', b'B'].contains(&self.ahead()?) {
832 self.pos += 2;
833 let (start, stop) = self.collect(|ch| ch == b'0' || ch == b'1')?;
834 let s = String::from_utf8_lossy(&self.buf[start..stop]).to_string();
835 let suffix = self.numeric_suffix();
836 return self.int_literal(&s, 2, suffix);
837 } else if [b'o', b'O'].contains(&self.ahead()?) {
838 self.pos += 2;
839 let (start, stop) = self.collect(|ch| ch >= b'0' && ch <= b'7')?;
840 let s = String::from_utf8_lossy(&self.buf[start..stop]).to_string();
841 let suffix = self.numeric_suffix();
842 return self.int_literal(&s, 8, suffix);
843 } else if [b'x', b'X'].contains(&self.ahead()?) {
844 self.pos += 2;
845 let (start, stop) = self.collect(|ch| (ch >= b'0' && ch <= b'9') || (ch >= b'a' && ch <= b'f') || (ch >= b'A' && ch <= b'F'))?;
846 let s = String::from_utf8_lossy(&self.buf[start..stop]).to_string();
847 let suffix = self.numeric_suffix();
848 return self.int_literal(&s, 16, suffix);
849 }
850 }
851 let start = self.pos;
852 while self.pos < self.buf.len() && self.buf[self.pos] <= b'9' && self.buf[self.pos] >= b'0' {
853 self.pos += 1;
854 }
855 let mut is_float = false;
856 if self.pos < self.buf.len() && self.buf[self.pos] == b'.' && self.ahead().map(|ch| ch <= b'9' && ch >= b'0').unwrap_or(false) {
857 is_float = true;
858 self.pos += 1;
859 while self.pos < self.buf.len() && self.buf[self.pos] <= b'9' && self.buf[self.pos] >= b'0' {
860 self.pos += 1;
861 }
862 }
863 if self.pos < self.buf.len() && (self.buf[self.pos] == b'e' || self.buf[self.pos] == b'E') {
864 let mut exp_pos = self.pos + 1;
865 if exp_pos < self.buf.len() && (self.buf[exp_pos] == b'+' || self.buf[exp_pos] == b'-') {
866 exp_pos += 1;
867 }
868 if exp_pos < self.buf.len() && self.buf[exp_pos] <= b'9' && self.buf[exp_pos] >= b'0' {
869 is_float = true;
870 self.pos = exp_pos + 1;
871 while self.pos < self.buf.len() && self.buf[self.pos] <= b'9' && self.buf[self.pos] >= b'0' {
872 self.pos += 1;
873 }
874 }
875 }
876 if self.pos > start {
877 let text = String::from_utf8_lossy(&self.buf[start..self.pos]).to_string();
878 let suffix = self.numeric_suffix();
879 if is_float {
880 return self.float_literal(&text, suffix);
881 }
882 return self.int_literal(&text, 10, suffix);
883 }
884 Err(ParserErr::at("非数字", start).into())
885 }
886}
887
888#[cfg(test)]
889mod tests {
890 use super::*;
891
892 fn parse_all(code: &str) -> Result<Vec<Stmt>> {
893 let mut parser = Parser::new(code.as_bytes().to_vec());
894 let mut stmts = Vec::new();
895 loop {
896 match parser.stmt(false) {
897 Ok(stmt) => stmts.push(stmt),
898 Err(err) => {
899 if parser.is_eof() {
900 return Ok(stmts);
901 }
902 return Err(err);
903 }
904 }
905 }
906 }
907
908 fn run_with_big_stack(f: impl FnOnce() + Send + 'static) {
912 std::thread::Builder::new().stack_size(64 * 1024 * 1024).spawn(f).unwrap().join().unwrap();
913 }
914
915 #[test]
916 fn deeply_nested_parens_error_instead_of_stack_overflow() {
917 run_with_big_stack(|| {
918 let depth = MAX_PARSE_DEPTH + 50;
919 let code = format!("{}1{}", "(".repeat(depth), ")".repeat(depth));
920 let mut parser = Parser::new(code.into_bytes());
921 let err = parser.get_expr().unwrap_err();
922 assert!(err.to_string().contains("嵌套过深"), "got: {err}");
923 });
924 }
925
926 #[test]
927 fn deeply_nested_blocks_error_instead_of_stack_overflow() {
928 run_with_big_stack(|| {
929 let depth = MAX_PARSE_DEPTH + 50;
930 let code = format!("fn f() {}{}{}", "{".repeat(depth), "1", "}".repeat(depth));
931 let err = parse_all(&code).unwrap_err();
932 assert!(err.to_string().contains("嵌套过深"), "got: {err}");
933 });
934 }
935
936 #[test]
937 fn normal_nesting_within_limit_parses() {
938 let code = format!("{}1{}", "(".repeat(32), ")".repeat(32));
940 let mut parser = Parser::new(code.into_bytes());
941 parser.get_expr().unwrap();
942 }
943
944 fn parse_literal(code: &str) -> Result<Dynamic> {
945 let mut parser = Parser::new(code.as_bytes().to_vec());
946 match parser.get_expr()?.kind {
947 crate::ExprKind::Value(value) => Ok(value),
948 other => Err(anyhow!("不是字面量: {:?}", other)),
949 }
950 }
951
952 #[test]
953 fn unsuffixed_integer_defaults_to_i64() {
954 assert_eq!(parse_literal("5").unwrap(), Dynamic::I64(5));
955 assert_eq!(parse_literal("3000000000").unwrap(), Dynamic::I64(3000000000));
957 }
958
959 #[test]
960 fn out_of_range_integer_literals_error() {
961 assert!(parse_literal("99999999999999999999999999999999999999999").is_err());
963 assert!(parse_literal("255i8").unwrap_err().to_string().contains("超出"));
965 assert!(parse_literal("70000i16").unwrap_err().to_string().contains("超出"));
966 assert!(parse_literal("256u8").unwrap_err().to_string().contains("超出"));
967 }
968
969 #[test]
970 fn signed_min_magnitude_literals_allowed() {
971 assert_eq!(parse_literal("128i8").unwrap(), Dynamic::I8(-128));
973 assert_eq!(parse_literal("9223372036854775808").unwrap(), Dynamic::I64(i64::MIN));
974 }
975
976 #[test]
977 fn hex_literals_keep_bit_pattern() {
978 assert_eq!(parse_literal("0xFFFFFFFF").unwrap(), Dynamic::I64(0xFFFFFFFF));
980 assert_eq!(parse_literal("0xFFi8").unwrap(), Dynamic::I8(-1));
982 assert_eq!(parse_literal("0xFFFFFFFFu32").unwrap(), Dynamic::U32(u32::MAX));
983 }
984
985 fn shape(code: &str) -> String {
987 let mut parser = Parser::new(code.as_bytes().to_vec());
988 let expr = parser.get_expr().expect("parse");
989 fmt_shape(&expr)
990 }
991
992 fn binop_sym(op: &crate::BinaryOp) -> &'static str {
993 op.symbol()
994 }
995
996 fn fmt_shape(expr: &crate::Expr) -> String {
997 use crate::ExprKind::*;
998 match &expr.kind {
999 Value(v) => format!("{:?}", v).replace("I64(", "").replace("I32(", "").trim_end_matches(')').to_string(),
1000 Ident(name) => name.to_string(),
1001 Unary { op, value } => {
1002 let s = if matches!(op, crate::UnaryOp::Neg) { "-" } else { "!" };
1003 format!("({} {})", s, fmt_shape(value))
1004 }
1005 Binary { left, op, right } => format!("({} {} {})", binop_sym(op), fmt_shape(left), fmt_shape(right)),
1006 Range { start, stop, inclusive } => format!("({} {} {})", if *inclusive { "..=" } else { ".." }, fmt_shape(start), fmt_shape(stop)),
1007 Typed { value, ty } => format!("(as {} {:?})", fmt_shape(value), ty),
1008 other => format!("{:?}", other),
1009 }
1010 }
1011
1012 #[test]
1013 fn precedence_and_associativity_golden() {
1014 assert_eq!(shape("1 + 2 * 3"), "(+ 1 (* 2 3))");
1016 assert_eq!(shape("1 * 2 + 3"), "(+ (* 1 2) 3)");
1017 assert_eq!(shape("1 - 2 - 3"), "(- (- 1 2) 3)");
1019 assert_eq!(shape("8 / 4 / 2"), "(/ (/ 8 4) 2)");
1020 assert_eq!(shape("2 + 3 << 4"), "(<< (+ 2 3) 4)");
1022 assert_eq!(shape("1 | 2 ^ 3 & 4"), "(| 1 (^ 2 (& 3 4)))");
1024 assert_eq!(shape("1 + 2 == 3"), "(== (+ 1 2) 3)");
1026 assert_eq!(shape("a && b || c"), "(|| (&& a b) c)");
1028 assert_eq!(shape("-a * b"), "(* (- a) b)");
1030 assert_eq!(shape("!a == b"), "(== (! a) b)");
1031 }
1032
1033 #[test]
1034 fn assignment_range_and_as_precedence_golden() {
1035 assert_eq!(shape("a = b + c"), "(= a (+ b c))");
1037 assert_eq!(shape("a = b = c"), "(= a (= b c))");
1038 assert_eq!(shape("a = b = c = d"), "(= a (= b (= c d)))");
1039 assert_eq!(shape("a += b * c"), "(+= a (* b c))");
1041 assert_eq!(shape("1 + 1 .. n * 2"), "(.. (+ 1 1) (* n 2))");
1043 assert_eq!(shape("0 ..= n - 1"), "(..= 0 (- n 1))");
1044 assert_eq!(shape("a + b as i64"), "(+ a (as b I64))");
1046 assert_eq!(shape("a as i64 + b"), "(+ (as a I64) b)");
1047 assert_eq!(shape("(a + b) as i64"), "(as (+ a b) I64)");
1048 }
1049
1050 #[test]
1054 fn parser_never_panics_on_random_input() {
1055 run_with_big_stack(|| {
1056 const FRAGMENTS: &[&str] = &[
1057 "fn", "let", "if", "else", "for", "in", "while", "return", "struct", "impl", "pub", "(", ")", "{", "}", "[", "]", "<", ">", "+", "-", "*", "/", "%", "=", "==", "&&", "||", "..", "..=", "as", "i32",
1058 "u64", "f64", ".", ",", ";", ":", "::", "x", "0", "1", "255i8", "0xFF", "\"s\"", "true", "null", "|a|", "->",
1059 ];
1060 let mut state: u64 = 0x9E3779B97F4A7C15;
1062 let mut next = || {
1063 state ^= state >> 12;
1064 state ^= state << 25;
1065 state ^= state >> 27;
1066 state = state.wrapping_mul(0x2545F4914F6CDD1D);
1067 state
1068 };
1069
1070 for _ in 0..4000 {
1071 let mut code = String::new();
1072 let tokens = (next() % 40) as usize;
1073 for _ in 0..tokens {
1074 code.push_str(FRAGMENTS[(next() as usize) % FRAGMENTS.len()]);
1075 if next() % 2 == 0 {
1076 code.push(' ');
1077 }
1078 }
1079 let result = std::panic::catch_unwind(|| {
1081 let mut parser = Parser::new(code.clone().into_bytes());
1082 let mut count = 0;
1083 loop {
1084 match parser.stmt(false) {
1085 Ok(_) => {
1086 count += 1;
1087 if parser.is_eof() || count > 1000 {
1088 break;
1089 }
1090 }
1091 Err(_) => break,
1092 }
1093 }
1094 });
1095 assert!(result.is_ok(), "parser panicked on input: {:?}", code);
1096 }
1097 });
1098 }
1099
1100 #[test]
1101 fn allows_local_name_to_shadow_prior_function() {
1102 parse_all(
1103 r#"
1104 fn chunk_id(x, y) {
1105 x + y
1106 }
1107
1108 fn open() {
1109 let chunk_id = 1;
1110 chunk_id
1111 }
1112 "#,
1113 )
1114 .unwrap();
1115 }
1116
1117 #[test]
1118 fn rejects_duplicate_function_args() {
1119 let err = parse_all("fn open(value, value) { value }").unwrap_err();
1120 assert!(err.to_string().contains("符号 value 已经声明"));
1121 }
1122
1123 #[test]
1124 fn rejects_duplicate_local_let_names() {
1125 let err = parse_all(
1126 r#"
1127 fn open() {
1128 let value = 1;
1129 let value = 2;
1130 value
1131 }
1132 "#,
1133 )
1134 .unwrap_err();
1135 assert!(err.to_string().contains("符号 value 已经声明"));
1136 }
1137
1138 #[test]
1139 fn allows_same_method_name_in_different_impl_blocks() {
1140 parse_all(
1141 r#"
1142 struct A {}
1143 struct B {}
1144
1145 impl A {
1146 fn zero() { 0 }
1147 }
1148
1149 impl B {
1150 fn zero() { 0 }
1151 }
1152 "#,
1153 )
1154 .unwrap();
1155 }
1156
1157 #[test]
1158 fn rejects_nested_fn_inside_function_body() {
1159 let err = parse_all("fn outer() { fn inner() { 1 } }").unwrap_err();
1160 assert!(err.to_string().contains("函数体内不能定义"), "got: {err}");
1161 }
1162
1163 #[test]
1164 fn rejects_nested_struct_inside_function_body() {
1165 let err = parse_all("fn outer() { struct S { x: i32 } S{x: 1} }").unwrap_err();
1166 assert!(err.to_string().contains("函数体内不能定义"), "got: {err}");
1167 }
1168
1169 #[test]
1170 fn rejects_nested_const_inside_function_body() {
1171 let err = parse_all("fn outer() { const K = 1 } K").unwrap_err();
1172 assert!(err.to_string().contains("函数体内不能定义"), "got: {err}");
1173 }
1174
1175 #[test]
1178 fn raw_string_with_only_hashes_does_not_panic_at_eof() {
1179 for input in [b"r#" as &[u8], b"r##", b"r###", b"r########", b"r#\"", b"r#\"unterminated"] {
1180 let mut p = Parser::new(input.to_vec());
1181 let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| p.text()));
1183 assert!(result.is_ok(), "raw-string parser panicked on input {:?}", input);
1184 }
1185 }
1186
1187 #[test]
1188 fn raw_string_unterminated_returns_error_not_panic() {
1189 let mut p = Parser::new(b"r#\"abc".to_vec());
1191 let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| p.text()));
1192 assert!(result.is_ok(), "raw-string unterminated input should not panic");
1193 let err = result.unwrap().expect_err("unterminated raw string should error");
1194 assert!(err.to_string().contains("未关闭") || err.to_string().contains("unclosed"), "got: {err}");
1195 }
1196
1197 #[test]
1198 fn raw_string_simple_still_parses() {
1199 let mut p = Parser::new(b"r\"abc\"".to_vec());
1201 assert_eq!(p.text().unwrap().as_str(), "abc");
1202 let mut p = Parser::new(b"r#\"a\"#".to_vec());
1203 assert_eq!(p.text().unwrap().as_str(), "a");
1204 let mut p = Parser::new(b"r##\"b\"##".to_vec());
1205 assert_eq!(p.text().unwrap().as_str(), "b");
1206 }
1207
1208 #[test]
1209 fn hex_escape_at_end_of_string_preserves_byte() {
1210 let mut p = Parser::new(br#""abc\x41""#.to_vec());
1211 let s = p.string().unwrap();
1212 assert_eq!(s.as_str(), "abcA");
1213 }
1214
1215 #[test]
1216 fn hex_escape_truncated_reports_clear_error() {
1217 let mut p = Parser::new(br#""abc\x""#.to_vec());
1218 let err = p.string().unwrap_err();
1219 assert!(err.to_string().contains("\\x"), "got: {err}");
1220 }
1221
1222 #[test]
1223 fn hex_escape_non_hex_char_reports_clear_error() {
1224 let mut p = Parser::new(br#""abc\xZZ""#.to_vec());
1225 let err = p.string().unwrap_err();
1226 assert!(err.to_string().contains("\\x"), "got: {err}");
1227 }
1228
1229 #[test]
1230 fn else_with_invalid_body_reports_error() {
1231 let err = parse_all("fn f() { if true { 1 } else }").unwrap_err();
1233 let msg = err.to_string();
1234 assert!(msg.contains("not code block") || msg.contains("未结束的"), "got: {msg}");
1235 }
1236
1237 #[test]
1238 fn float_literal_with_int_suffix_out_of_range_errors() {
1239 let mut p = Parser::new(b"1e30u8".to_vec());
1240 let err = p.number().unwrap_err();
1241 assert!(err.to_string().contains("超出"), "got: {err}");
1242 }
1243
1244 #[test]
1245 fn float_literal_with_int_suffix_fractional_errors() {
1246 let mut p = Parser::new(b"1.5i32".to_vec());
1247 let err = p.number().unwrap_err();
1248 assert!(err.to_string().contains("超出"), "got: {err}");
1249 }
1250
1251 #[test]
1252 fn float_literal_with_float_suffix_accepts_fractional() {
1253 let mut p = Parser::new(b"1e-3f32".to_vec());
1254 assert!(matches!(p.number().unwrap(), Dynamic::F32(v) if (v - 1e-3).abs() < 1e-8));
1255 }
1256
1257 #[test]
1258 fn allows_closure_inside_function_body() {
1259 parse_all("fn outer() { let f = |x: i32| { x + 1 }; f(1) }").unwrap();
1260 }
1261
1262 #[test]
1267 fn dict_shorthand_accepts_unicode_first_char() {
1268 let stmts = parse_all("fn f() { let d = { 中文key }; d }").expect("unicode shorthand should parse");
1270 assert_eq!(stmts.len(), 1);
1271 }
1272
1273 #[test]
1278 fn stmt_spans_cleaned_up_after_partial_failure() {
1279 let mut p = Parser::new(b"fn f() { 1".to_vec());
1280 let _ = p.stmt(false).expect_err("first stmt should fail (unclosed brace)");
1282 assert!(p.spans.is_empty(), "第一个 stmt 失败后 spans 应被清空。got: {:?}", p.spans);
1283
1284 for _ in 0..5 {
1286 let _ = p.stmt(false);
1287 assert!(p.spans.is_empty(), "spans 应保持空(没有累积)。got: {:?}", p.spans);
1288 }
1289 }
1290
1291 #[test]
1292 fn rejects_const_inside_impl_body() {
1293 let err = parse_all("struct S {}\nimpl S { const K = 1 }").unwrap_err();
1294 let msg = err.to_string();
1295 assert!(msg.contains("impl 体内不能定义") && msg.contains("const"), "got: {msg}");
1296 }
1297
1298 #[test]
1299 fn allows_fn_inside_impl_body() {
1300 parse_all("struct S {}\nimpl S { pub fn m(self: S) { 1 } }").unwrap();
1301 }
1302
1303 #[test]
1306 fn take_at_eof_reports_clean_eof_message() {
1307 let mut p = Parser::new(b"fn f(".to_vec());
1308 p.whitespace().unwrap();
1310 while p.current_pos() < p.buf.len() {
1311 p.whitespace().unwrap();
1313 break;
1314 }
1315 let mut p = Parser::new(b"fn f(".to_vec());
1317 p.pos = p.buf.len();
1319 let err = p.take(b')').expect_err("take at EOF should error");
1320 let msg = err.downcast_ref::<crate::ParserErr>().map(|e| e.message().to_string()).unwrap_or_else(|| format!("{err:#}"));
1321 assert!(msg.contains("已到文件末尾") || msg.contains("末尾"), "expected EOF message, got: {msg}");
1322 assert!(!msg.contains(' '), "should not contain NUL char, got: {msg}");
1323 }
1324
1325 #[test]
1326 fn parser_err_carries_span() {
1327 let src = "fn f() {}\nfn f() {}\n";
1329 let err = parse_all(src).unwrap_err();
1330 eprintln!("err display: {err}");
1331 let downcast = err.downcast_ref::<ParserErr>().expect("ParserErr");
1332 eprintln!("message: {}", downcast.message());
1333 eprintln!("span: {:?}", downcast.span());
1334 assert!(downcast.message().contains("f"));
1335 assert!(downcast.span().start < src.len());
1337 }
1338
1339 #[test]
1340 fn block_as_let_value_is_expression() {
1341 parse_all("pub fn f() { let x = { let y = 1; y + 1 }; x }").unwrap();
1342 }
1343
1344 #[test]
1345 fn dict_still_takes_priority_over_block() {
1346 parse_all("pub fn f() { let d = { key: 1 }; d }").unwrap();
1348 }
1349
1350 #[test]
1351 fn list_pattern_with_rest_parses() {
1352 parse_all("pub fn f(items) { let [first, ..rest] = items; first }").unwrap();
1353 }
1354
1355 #[test]
1356 fn list_pattern_with_only_rest_parses() {
1357 parse_all("pub fn f(items) { let [..all] = items; all }").unwrap();
1358 }
1359
1360 #[test]
1361 fn take_error_carries_precise_pos() {
1362 use crate::SpannedParseError;
1365 let mut p = Parser::new(b"ab".to_vec());
1366 let pos_before = p.current_pos();
1367 let err = p.take(b'c').unwrap_err();
1368 let spanned = err.downcast_ref::<SpannedParseError>().expect("take should wrap in SpannedParseError");
1369 assert_eq!(spanned.pos, pos_before);
1371 }
1372
1373 #[test]
1374 fn parses_scientific_float_suffixes() {
1375 let mut parser = Parser::new(b"1.7976931348623157e308f64".to_vec());
1376 assert_eq!(parser.number().unwrap(), Dynamic::F64(1.7976931348623157e308));
1377
1378 let mut parser = Parser::new(b"1e-3f32".to_vec());
1379 assert_eq!(parser.number().unwrap(), Dynamic::F32(1e-3f32));
1380 }
1381
1382 #[test]
1383 fn parses_immediate_closure_call() {
1384 let mut parser = Parser::new(b"|| { 1i32 }()".to_vec());
1385 let expr = parser.get_expr().unwrap();
1386 let ExprKind::Call { obj, params } = expr.kind else {
1387 panic!("expected closure call, got {expr:?}");
1388 };
1389 assert!(params.is_empty());
1390 let ExprKind::Closure { args, .. } = obj.kind else {
1391 panic!("expected closure callee, got {obj:?}");
1392 };
1393 assert!(args.is_empty());
1394 }
1395
1396 #[test]
1397 fn parses_empty_tuple_expression() {
1398 let mut parser = Parser::new(b"()".to_vec());
1399 let expr = parser.get_expr().unwrap();
1400 let ExprKind::Tuple(items) = expr.kind else {
1401 panic!("expected empty tuple, got {expr:?}");
1402 };
1403 assert!(items.is_empty());
1404 }
1405
1406 #[test]
1407 fn parses_explicit_generic_function_call() {
1408 let mut parser = Parser::new(b"value::<4>()".to_vec());
1409 let expr = parser.get_expr().unwrap();
1410 let ExprKind::Call { obj, params } = expr.kind else {
1411 panic!("expected function call, got {expr:?}");
1412 };
1413 assert!(params.is_empty());
1414 let ExprKind::Generic { obj, params } = obj.kind else {
1415 panic!("expected generic callee, got {obj:?}");
1416 };
1417 assert!(matches!(obj.kind, ExprKind::Ident(name) if name.as_str() == "value"));
1418 assert!(matches!(params.as_slice(), [Type::ConstInt(4)]));
1419 }
1420
1421 #[test]
1422 fn parses_import_top_level_declaration() {
1423 let stmts = parse_all(r#"import "foo";"#).expect("parse import decl");
1425 assert_eq!(stmts.len(), 1);
1426 let StmtKind::Import { module, path, is_pub } = &stmts[0].kind else {
1427 panic!("expected StmtKind::Import, got {:?}", stmts[0].kind);
1428 };
1429 assert_eq!(module.as_str(), "foo");
1430 assert_eq!(path.as_str(), "foo.zs", "省略路径时默认 <module>.zs");
1431 assert!(!*is_pub);
1432
1433 let stmts = parse_all(r#"import "foo", "bar.zs";"#).expect("parse import decl with path");
1434 let StmtKind::Import { module, path, .. } = &stmts[0].kind else {
1435 panic!("expected StmtKind::Import, got {:?}", stmts[0].kind);
1436 };
1437 assert_eq!(module.as_str(), "foo");
1438 assert_eq!(path.as_str(), "bar.zs");
1439
1440 let stmts = parse_all(r#"pub import "foo";"#).expect("parse pub import");
1441 let StmtKind::Import { module, is_pub, .. } = &stmts[0].kind else {
1442 panic!("expected StmtKind::Import, got {:?}", stmts[0].kind);
1443 };
1444 assert_eq!(module.as_str(), "foo");
1445 assert!(*is_pub);
1446 }
1447
1448 #[test]
1449 fn import_call_form_is_still_recognized_as_expression() {
1450 let stmts = parse_all(r#"import("foo", "foo.zs");"#).expect("parse import call");
1454 assert_eq!(stmts.len(), 1);
1455 let StmtKind::Expr(expr, _) = &stmts[0].kind else {
1456 panic!("expected StmtKind::Expr, got {:?}", stmts[0].kind);
1457 };
1458 let ExprKind::Call { obj, params } = &expr.kind else {
1459 panic!("expected ExprKind::Call, got {expr:?}");
1460 };
1461 let ExprKind::Ident(name) = &obj.kind else {
1462 panic!("expected ident callee, got {:?}", obj.kind);
1463 };
1464 assert_eq!(name.as_str(), "import");
1465 assert_eq!(params.len(), 2);
1466 }
1467
1468 #[test]
1469 fn parses_bigfloat_cmp_context_segment() {
1470 let code = r#"
1471 struct BigFloat<N> { data: [u32; N], exp: i32, sign: bool }
1472
1473 impl BigFloat<N> {
1474 fn abs_cmp(self: BigFloat<N>, rhs: BigFloat<N>) {
1475 let self_high = self.exp + ((N - 1) as i32);
1476 let rhs_high = rhs.exp + ((N - 1) as i32);
1477 let high = if self_high >= rhs_high { self_high } else { rhs_high };
1478 let low = if self.exp <= rhs.exp { self.exp } else { rhs.exp };
1479 let result = 0i32;
1480 let power = high;
1481
1482 while power >= low && result == 0i32 {
1483 let a_idx = power - self.exp;
1484 let b_idx = power - rhs.exp;
1485 let a_limb = 0u32;
1486 let b_limb = 0u32;
1487
1488 if a_idx >= 0i32 && a_idx < (N as i32) {
1489 a_limb = self.data[a_idx as u32];
1490 }
1491 if b_idx >= 0i32 && b_idx < (N as i32) {
1492 b_limb = rhs.data[b_idx as u32];
1493 }
1494
1495 if a_limb > b_limb {
1496 result = 1i32;
1497 } else if a_limb < b_limb {
1498 result = -1i32;
1499 }
1500
1501 power -= 1i32;
1502 }
1503
1504 result
1505 }
1506
1507 pub fn cmp(self: BigFloat<N>, rhs: BigFloat<N>) {
1508 if self.is_zero() && rhs.is_zero() {
1509 0i32
1510 } else if self.sign != rhs.sign {
1511 if self.sign { -1i32 } else { 1i32 }
1512 } else {
1513 let cmp = self.abs_cmp(rhs);
1514 if self.sign { -cmp } else { cmp }
1515 }
1516 }
1517 }
1518 "#;
1519 parse_all(code).unwrap();
1520 }
1521
1522 #[test]
1523 fn parses_bigfloat_file() {
1524 let code = include_str!("../../zusts/bigfloat.zs");
1525 parse_all(code).unwrap();
1526 }
1527}