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