1#![allow(dead_code)]
2use super::{
3 lexer::Lexer,
4 pair::GenericPair,
5 pair::{PairIterItem, Pairable},
6 Datum, DatumBody, DatumList, Result, SyntaxTemplateElement, Transformer,
7};
8use crate::error::ToLocated;
9use crate::{environment::LexicalScope, error::*, parser::lexer::Token};
10use crate::{interpreter::error::LogicError, parser::lexer::TokenData};
11use fmt::Display;
12use itertools::Itertools;
13use std::{collections::HashSet, fmt, mem, rc::Rc};
14use std::{
15 iter::{repeat, FromIterator, Iterator, Peekable},
16 path::PathBuf,
17};
18
19use either::Either;
20
21use super::{
22 error::SyntaxError, Primitive, SyntaxPattern, SyntaxPatternBody, SyntaxTemplate,
23 SyntaxTemplateBody, UserDefinedTransformer,
24};
25
26pub type ParseResult = Result<Option<(Statement, Option<[u32; 2]>)>>;
27
28#[derive(PartialEq, Debug, Clone)]
29pub struct LibraryDefinition(pub LibraryName, pub Vec<Located<LibraryDeclaration>>);
30impl ToLocated for LibraryDefinition {}
31#[derive(PartialEq, Debug, Clone)]
32pub enum LibraryDeclaration {
33 ImportDeclaration(Located<ImportDeclaration>),
34 Export(Vec<Located<ExportSpec>>),
35 Begin(Vec<Statement>),
36}
37impl ToLocated for LibraryDeclaration {}
38
39#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
43pub enum LibraryNameElement {
44 Identifier(String),
45 Integer(u32),
46}
47
48impl ToLocated for LibraryNameElement {}
49
50impl Display for LibraryNameElement {
51 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52 match self {
53 LibraryNameElement::Identifier(s) => write!(f, "{}", s),
54 LibraryNameElement::Integer(i) => write!(f, "{}", i),
55 }
56 }
57}
58
59impl From<&str> for LibraryNameElement {
60 fn from(s: &str) -> Self {
61 Self::Identifier(s.to_string())
62 }
63}
64
65impl From<u32> for LibraryNameElement {
66 fn from(i: u32) -> Self {
67 Self::Integer(i)
68 }
69}
70
71#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
72pub struct LibraryName(pub Vec<LibraryNameElement>);
73
74#[macro_export]
75macro_rules! library_name {
76 ($($e:expr),+) => {
77 LibraryName(vec![$($e.into()),+])
78 };
79}
80
81impl ToLocated for LibraryName {}
82
83impl FromIterator<LibraryNameElement> for LibraryName {
84 fn from_iter<T: IntoIterator<Item = LibraryNameElement>>(iter: T) -> Self {
85 Self(iter.into_iter().collect::<Vec<_>>())
86 }
87}
88
89impl From<Vec<LibraryNameElement>> for LibraryName {
90 fn from(value: Vec<LibraryNameElement>) -> Self {
91 Self(value)
92 }
93}
94impl From<LibraryNameElement> for LibraryName {
95 fn from(value: LibraryNameElement) -> Self {
96 Self(vec![value])
97 }
98}
99
100impl Display for LibraryName {
101 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
102 write!(f, "({})", self.0.iter().join(" "))
103 }
104}
105#[test]
106fn library_name_display() {
107 assert_eq!(format!("{}", library_name!("foo", 0, "bar")), "(foo 0 bar)");
108 assert_eq!(format!("{}", library_name!(1, 0, 2)), "(1 0 2)");
109}
110impl LibraryName {
111 pub fn join(self, other: impl Into<Self>) -> Self {
112 Self(
113 self.0
114 .into_iter()
115 .chain(other.into().0.into_iter())
116 .collect(),
117 )
118 }
119}
120#[test]
121fn library_name_join() {
122 assert_eq!(
123 library_name!("a", "b").join(library_name!("c")),
124 library_name!("a", "b", "c")
125 );
126 assert_eq!(
127 library_name!("a", "b").join(LibraryNameElement::Integer(0)),
128 library_name!("a", "b", 0)
129 );
130}
131
132impl LibraryName {
133 pub fn path(&self) -> PathBuf {
134 self.0
135 .iter()
136 .map(|element| PathBuf::from(format!("{}", element)))
137 .collect()
138 }
139}
140
141#[derive(PartialEq, Debug, Clone)]
142pub enum ExportSpec {
143 Direct(String),
144 Rename(String, String),
145}
146impl ToLocated for ExportSpec {}
147#[derive(PartialEq, Debug, Clone)]
148pub struct ImportDeclaration(pub Vec<ImportSet>);
149
150impl ToLocated for ImportDeclaration {}
151
152#[derive(PartialEq, Debug, Clone)]
153pub enum Statement {
154 ImportDeclaration(Located<ImportDeclaration>),
155 Definition(Definition),
156 SyntaxDefinition(SyntaxDef),
157 Expression(Expression),
158 LibraryDefinition(Located<LibraryDefinition>),
159}
160
161impl Statement {
162 pub fn location(&self) -> Option<[u32; 2]> {
163 match self {
164 Statement::ImportDeclaration(located) => located.location,
165 Statement::Definition(located) => located.location,
166 Statement::SyntaxDefinition(located) => located.location,
167 Statement::Expression(located) => located.location,
168 Statement::LibraryDefinition(located) => located.location,
169 }
170 }
171 pub fn expect_expression(self) -> Result<Expression> {
172 let location = self.location();
173 match self {
174 Self::Expression(expression) => Ok(expression),
175 _ => located_error!(
176 SyntaxError::ExpectSomething("expression".to_string(), "other".to_string()),
177 location
178 ),
179 }
180 }
181}
182
183impl Into<Statement> for Expression {
184 fn into(self) -> Statement {
185 Statement::Expression(self)
186 }
187}
188
189impl Into<Statement> for SyntaxDef {
190 fn into(self) -> Statement {
191 Statement::SyntaxDefinition(self)
192 }
193}
194
195impl Into<Statement> for Definition {
196 fn into(self) -> Statement {
197 Statement::Definition(self)
198 }
199}
200
201impl Into<Statement> for Located<ImportDeclaration> {
202 fn into(self) -> Statement {
203 Statement::ImportDeclaration(self)
204 }
205}
206
207impl Into<Statement> for Located<LibraryDefinition> {
208 fn into(self) -> Statement {
209 Statement::LibraryDefinition(self)
210 }
211}
212
213#[derive(PartialEq, Debug, Clone)]
214pub struct DefinitionBody(pub String, pub Expression);
215
216impl ToLocated for DefinitionBody {}
217
218#[derive(PartialEq, Debug, Clone)]
219pub struct SyntaxDefBody(pub String, pub UserDefinedTransformer);
220
221impl ToLocated for SyntaxDefBody {}
222
223pub type Definition = Located<DefinitionBody>;
224pub type SyntaxDef = Located<SyntaxDefBody>;
225pub type ImportSet = Located<ImportSetBody>;
226
227#[derive(PartialEq, Debug, Clone)]
228pub enum ImportSetBody {
229 Direct(Located<LibraryName>),
230 Only(Box<ImportSet>, Vec<String>),
231 Except(Box<ImportSet>, Vec<String>),
232 Prefix(Box<ImportSet>, String),
233 Rename(Box<ImportSet>, Vec<(String, String)>),
234}
235
236impl ToLocated for ImportSetBody {}
237
238pub type Expression = Located<ExpressionBody>;
239#[derive(PartialEq, Debug, Clone)]
240pub enum ExpressionBody {
241 Symbol(String),
242 Primitive(Primitive),
243 Period,
244 Assignment(String, Box<Expression>),
245 Procedure(SchemeProcedure),
246 ProcedureCall(Box<Expression>, Vec<Expression>),
247 Conditional(Box<(Expression, Expression, Option<Expression>)>),
248 Quote(Box<Datum>),
249 Datum(Datum),
250}
251
252impl From<i32> for ExpressionBody {
253 fn from(integer: i32) -> Self {
254 ExpressionBody::Datum(DatumBody::Primitive(Primitive::Integer(integer)).into())
255 }
256}
257
258impl ToLocated for ExpressionBody {}
259
260impl From<Primitive> for ExpressionBody {
261 fn from(p: Primitive) -> Self {
262 ExpressionBody::Primitive(p)
263 }
264}
265
266impl From<Primitive> for Expression {
267 fn from(p: Primitive) -> Self {
268 ExpressionBody::Primitive(p).into()
269 }
270}
271
272#[derive(PartialEq, Debug, Clone)]
273pub enum ParameterFormalsBody {
274 Name(String), Pair(Box<GenericPair<ParameterFormals>>), }
277
278pub type ParameterFormals = Located<ParameterFormalsBody>;
279
280impl ToLocated for ParameterFormalsBody {}
281
282impl ParameterFormals {
283 pub fn new_non_located(parameters: impl Iterator<Item = String>, last: Option<String>) -> Self {
284 ParameterFormals::from_pair_iter(
285 parameters
286 .map(|s| PairIterItem::Proper(ParameterFormalsBody::Name(s).no_locate()))
287 .chain(last.into_iter().map(|last| {
288 PairIterItem::Improper(ParameterFormalsBody::Name(last).no_locate())
289 })),
290 )
291 }
292
293 pub fn split(self) -> Result<(Vec<String>, Option<String>)> {
294 Ok(match self.data {
295 ParameterFormalsBody::Name(name) => (Vec::new(), Some(name)),
296 ParameterFormalsBody::Pair(pair) => {
297 let mut proper_list = Vec::new();
298 let mut cdr = None;
299 for item in pair.into_pair_iter() {
300 match item {
301 PairIterItem::Proper(ParameterFormals {
302 data: ParameterFormalsBody::Name(fixed),
303 ..
304 }) => proper_list.push(fixed),
305 PairIterItem::Improper(ParameterFormals {
306 data: ParameterFormalsBody::Name(last),
307 ..
308 }) => cdr = Some(last),
309 other => {
310 return located_error!(
311 SyntaxError::IllegalParameter(other.get_inside()),
312 other.get_inside().location
313 );
314 }
315 }
316 }
317 (proper_list, cdr)
318 }
319 })
320 }
321
322 pub fn len(&self) -> (usize, bool) {
323 let mut fixed = 0;
324 let variadic = self.iter_to_last(|_| fixed += 1).is_some();
325 (fixed, variadic)
326 }
327
328 pub fn as_name(&self) -> String {
329 match &self.data {
330 ParameterFormalsBody::Name(name) => name.clone(),
331 ParameterFormalsBody::Pair(_) => {
332 unreachable!("parameter name can only be a identifier")
333 }
334 }
335 }
336
337 pub fn iter_to_last(
338 &self,
339 mut visitor: impl FnMut(&ParameterFormals) -> (),
340 ) -> Option<&ParameterFormals> {
341 let mut next: Option<&ParameterFormals> = Some(self);
342 loop {
343 match next.take().map(|p| p.either_pair_ref()) {
344 Some(Either::Left(GenericPair::Some(car, cdr))) => {
345 visitor(&car);
346 next = Some(&cdr);
347 }
348 Some(Either::Right(improper)) => return Some(&improper),
349 None | Some(Either::Left(GenericPair::Empty)) => return None,
350 }
351 }
352 }
353
354 pub fn append(&mut self, mut x: ParameterFormals) -> Result<()> {
355 let mut next = self as *mut ParameterFormals;
356 loop {
357 match unsafe { &mut *next }.either_pair_mut() {
358 Either::Left(GenericPair::Some(_, cdr)) => {
359 next = cdr as *mut ParameterFormals;
360 }
361 Either::Right(improper) => {
362 return error!(LogicError::InproperList(improper.to_string()))
363 }
364 _empty => {
365 mem::swap(&mut x, unsafe { &mut *next });
366 break Ok(());
367 }
368 }
369 }
370 }
371}
372
373impl Pairable for ParameterFormals {
374 impl_located_pairable!(ParameterFormalsBody);
375}
376
377#[macro_export]
378macro_rules! param_fixed {
379 ($($x:expr),+) => {{
380 use $crate::error::ToLocated;
381 use $crate::parser::ParameterFormalsBody;
382 use $crate::parser::ParameterFormals;
383 use $crate::parser::pair::GenericPair;
384 use $crate::list;
385 ParameterFormals::from(list![$(ParameterFormalsBody::Name($x.to_string()).no_locate()),*])
386}};
387 () => {
388 ParameterFormals::from(list![])
389 }
390}
391
392#[macro_export]
393macro_rules! append_variadic_param {
394 ($fixed:expr, $append:expr) => {{
395 let mut pair = $fixed;
396 use $crate::error::ToLocated;
397 use $crate::parser::ParameterFormalsBody;
398 pair.append(ParameterFormalsBody::Name($append.to_string()).no_locate())?;
399 pair
400 }};
401}
402
403impl From<GenericPair<ParameterFormals>> for ParameterFormals {
404 fn from(pair: GenericPair<ParameterFormals>) -> Self {
405 ParameterFormalsBody::Pair(Box::new(pair)).no_locate()
406 }
407}
408
409impl Display for ParameterFormalsBody {
410 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
411 match self {
412 ParameterFormalsBody::Name(s) => write!(f, "{}", s),
413 ParameterFormalsBody::Pair(pair) => write!(f, "{}", pair),
414 }
415 }
416}
417
418#[test]
419fn test_parameter_formals() -> Result<()> {
420 let test_cases = vec![
421 (
422 vec!["x1".to_string(), "x2".to_string(), "x3".to_string()],
423 Some("x".to_string()),
424 ),
425 (
426 vec!["x1".to_string(), "x2".to_string(), "x3".to_string()],
427 None,
428 ),
429 (vec![], Some("x".to_string())),
430 (vec![], None),
431 ];
432
433 for (fixed, variadic) in test_cases.into_iter() {
434 let parameters =
435 ParameterFormals::new_non_located(fixed.clone().into_iter(), variadic.clone());
436 assert_eq!(parameters.split()?, (fixed.clone(), variadic.clone()));
437 }
438
439 Ok(())
440}
441
442#[derive(PartialEq, Debug, Clone)]
443pub struct SchemeProcedure(
444 pub ParameterFormals,
445 pub Vec<Definition>,
446 pub Vec<Expression>,
447);
448
449impl SchemeProcedure {
450 pub fn get_body_location(&self) -> Option<[u32; 2]> {
451 let SchemeProcedure(_, defs, exprs) = self;
452 defs.first()
453 .and_then(|d| d.location)
454 .or(exprs.first().and_then(|e| e.location))
455 }
456}
457
458impl fmt::Display for SchemeProcedure {
459 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
460 let SchemeProcedure(formals, ..) = self;
461 write!(f, "(lambda {})", formals,)
462 }
463}
464
465pub struct Parser<TokenIter: Iterator<Item = Result<Token>>> {
466 pub current: Option<Token>,
467 pub lexer: Peekable<TokenIter>,
468 pub syntax_env: Rc<LexicalScope<Transformer>>,
469 location: Option<[u32; 2]>,
470}
471
472impl<TokenIter: Iterator<Item = Result<Token>>> Iterator for Parser<TokenIter> {
473 type Item = Result<Statement>;
474 fn next(&mut self) -> Option<Self::Item> {
475 match self.parse(self.syntax_env.clone()) {
476 Ok(Some(statement)) => Some(Ok(statement)),
477 Ok(None) => None,
478 Err(e) => Some(Err(e)),
479 }
480 }
481}
482
483fn create_syntax_binding() -> Rc<LexicalScope<Transformer>> {
484 thread_local! {static BINDINGS: Rc<LexicalScope<Transformer>> = {
485 let mut parser = Parser::from_lexer_primary_syntax(Lexer::from_char_stream(
486 include_str!("grammar.sld").chars(),
487 ));
488 while parser.next().is_some() {} parser.syntax_env
490 };
491 }
492 BINDINGS.with(|bindings| bindings.clone())
493}
494
495impl<TokenIter: Iterator<Item = Result<Token>>> Parser<TokenIter> {
496 fn from_lexer_primary_syntax(lexer: TokenIter) -> Parser<TokenIter> {
497 Self {
498 current: None,
499 lexer: lexer.peekable(),
500 syntax_env: Rc::new(LexicalScope::new()),
501 location: None,
502 }
503 }
504
505 pub fn from_lexer(lexer: TokenIter) -> Parser<TokenIter> {
506 Self {
507 current: None,
508 lexer: lexer.peekable(),
509 syntax_env: create_syntax_binding(),
510 location: None,
511 }
512 }
513
514 pub fn parse_current(
515 &mut self,
516 syntax_env: &Rc<LexicalScope<Transformer>>,
517 ) -> Result<Option<Statement>> {
518 Ok(match self.current_datum()? {
519 Some(datum) => Some(Self::transform_to_statement(datum, syntax_env)?),
520 None => None,
521 })
522 }
523
524 pub fn transform_to_statement(
525 datum: Datum,
526 syntax_env: &Rc<LexicalScope<Transformer>>,
527 ) -> Result<Statement> {
528 let location = datum.location;
529 Ok(match datum.data {
530 DatumBody::Primitive(p) => ExpressionBody::Primitive(p).locate(location).into(),
531 DatumBody::Symbol(s) => ExpressionBody::Symbol(s).locate(location).into(),
532 DatumBody::Pair(mut pair) => {
533 let first = pair.pop_proper()?;
534 match first {
535 None => return error!(SyntaxError::EmptyCall),
536 Some(first) => {
537 match &first.data {
538 DatumBody::Symbol(keyword) => match keyword.as_str() {
539 "define" => {
540 Self::transform_definition(pair.into_iter(), syntax_env)?
541 .locate(datum.location)
542 .into()
543 }
544 "define-library" => {
545 Self::transform_library(pair.into_iter(), syntax_env)?
546 .locate(datum.location)
547 .into()
548 }
549 "lambda" => Self::transform_lambda(pair.into_iter(), syntax_env)?
550 .locate(datum.location)
551 .into(),
552 "if" => Self::transform_condition(pair.into_iter(), syntax_env)?
553 .locate(datum.location)
554 .into(),
555 "import" => Self::transform_import_decl(pair.into_iter())?
556 .locate(datum.location)
557 .into(),
558 "quote" => Self::transform_quote(pair.into_iter())?
559 .locate(datum.location)
560 .into(),
561 "set!" => Self::transform_assignment(pair.into_iter(), syntax_env)?
562 .locate(datum.location)
563 .into(),
564 "define-syntax" => {
565 Self::transform_syntax_definition(pair.into_iter(), syntax_env)?
566 .locate(datum.location)
567 .into()
568 }
569 keyword => {
570 if let Some(transformer) =
571 syntax_env.get(&first.expect_symbol()?)
572 {
573 let remained = DatumBody::Pair(pair).locate(location);
574 let expanded_datum =
575 transformer.transform(keyword, remained)?;
576 Self::transform_to_statement(expanded_datum, syntax_env)?
577 } else {
578 Self::transform_procedure_call(
579 first,
580 pair.into_iter(),
581 syntax_env,
582 )?
583 .locate(datum.location)
584 .into()
585 }
586 }
587 },
588 _ => {
590 Self::transform_procedure_call(first, pair.into_iter(), syntax_env)?
591 .locate(datum.location)
592 .into()
593 }
594 }
595 }
596 }
597 }
598 other => ExpressionBody::Datum(Datum {
599 data: other,
600 location,
601 })
602 .locate(location)
603 .into(),
604 })
605 }
606
607 pub fn transform_to_expression(
608 datum: Datum,
609 syntax_env: &Rc<LexicalScope<Transformer>>,
610 ) -> Result<Expression> {
611 match Self::transform_to_statement(datum, syntax_env)? {
612 Statement::Expression(expression) => Ok(expression),
613 _ => error!(SyntaxError::ExpectSomething(
614 "expression".to_string(),
615 "other statement".to_string(),
616 )),
617 }
618 }
619
620 pub fn current_datum(&mut self) -> Result<Option<Datum>> {
621 match self.current.take() {
622 None => Ok(None),
623 Some(current) => match current {
624 Token { data, location } => Ok(match data {
625 TokenData::Primitive(p) => Datum {
626 data: DatumBody::Primitive(p),
627 location,
628 }
629 .into(),
630 TokenData::Identifier(a) => Datum {
631 data: DatumBody::Symbol(a),
632 location,
633 }
634 .into(),
635 TokenData::LeftParen => Some(self.current_list_or_pair()?),
636 TokenData::RightParen => {
637 return located_error!(SyntaxError::UnmatchedParentheses, location)
638 }
639 TokenData::VecConsIntro => self.vector()?.into(),
640 TokenData::Quote => {
641 self.advance(1)?;
642 self.parse_quoted()?
643 }
644 .into(),
645 other => return located_error!(SyntaxError::UnexpectedToken(other), location),
646 }),
647 },
648 }
649 }
650
651 pub fn unwrap_non_end<T>(op: Option<T>) -> Result<T> {
652 op.ok_or(ErrorData::from(SyntaxError::UnexpectedEnd).no_locate())
653 }
654
655 pub fn current_list_or_pair(&mut self) -> Result<Datum> {
656 let mut head = Box::new(DatumList::Empty);
657 let mut tail = head.as_mut();
658 let list_location = self.location;
659 let mut encounter_period = false;
660 loop {
661 match self.advance_unwrap(1)? {
662 Token { data, location } => match data {
663 TokenData::Period => {
664 if encounter_period {
665 return located_error!(
666 SyntaxError::UnexpectedToken(TokenData::Period),
667 location.clone()
668 );
669 }
670 encounter_period = true;
671 continue;
672 }
673 TokenData::RightParen => break,
674 _ => {
675 let element = Self::unwrap_non_end(self.current_datum()?)?;
676 match tail {
677 DatumList::Empty => {
678 head = Box::new(DatumList::Some(
679 element,
680 Datum::from(DatumList::Empty),
681 ));
682 tail = head.as_mut();
683 }
684 DatumList::Some(_, cdr) => {
685 if encounter_period {
686 *cdr = element;
687 self.expect_next_nth(1, TokenData::RightParen)?;
688 break;
689 }
690 assert_eq!(*cdr, Datum::from(DatumList::Empty));
691 let new_tail =
692 DatumList::Some(element, Datum::from(DatumList::Empty));
693 *cdr = Datum::from(new_tail);
694 tail = cdr.either_pair_mut().left().unwrap();
695 }
696 }
697 }
698 },
699 }
700 }
701 Ok(DatumBody::Pair(head).locate(list_location))
702 }
703
704 pub fn parse_root(&mut self) -> Result<Option<Statement>> {
705 self.parse(self.syntax_env.clone())
706 }
707
708 fn statement(&mut self, syntax_env: &Rc<LexicalScope<Transformer>>) -> Result<Statement> {
709 match self.parse_current(syntax_env)? {
710 Some(statement) => Ok(statement),
711 None => located_error!(SyntaxError::UnexpectedEnd, self.location),
712 }
713 }
714 pub fn parse(
715 &mut self,
716 syntax_env: Rc<LexicalScope<Transformer>>,
717 ) -> Result<Option<Statement>> {
718 self.advance(1)?;
719 self.parse_current(&syntax_env)
720 }
721
722 fn transform_library(
723 mut datums: impl Iterator<Item = Datum>,
724 syntax_env: &Rc<LexicalScope<Transformer>>,
725 ) -> Result<LibraryDefinition> {
726 let library_name = Self::transform_library_name(
727 Self::unwrap_non_end(datums.next())?
728 .expect_list()?
729 .into_iter(),
730 )?;
731 let library_declarations = datums
732 .map(|datum| Self::transform_library_declaration(datum, syntax_env))
733 .collect::<Result<_>>()?;
734 Ok(LibraryDefinition(library_name, library_declarations))
735 }
736
737 fn transform_library_declaration(
738 datum: Datum,
739 syntax_env: &Rc<LexicalScope<Transformer>>,
740 ) -> Result<Located<LibraryDeclaration>> {
741 let location = datum.location;
742 let mut iter = datum.expect_list()?.into_iter().peekable();
743 Ok(match &Self::unwrap_non_end(iter.peek())?.data {
744 DatumBody::Symbol(first) if first == "export" => LibraryDeclaration::Export(
745 iter.skip(1)
746 .map(Self::transform_export_spec)
747 .collect::<Result<_>>()?,
748 ),
749 DatumBody::Symbol(first) if first == "begin" => LibraryDeclaration::Begin(
750 iter.skip(1)
751 .map(|datum| Self::transform_to_statement(datum, syntax_env))
752 .collect::<Result<_>>()?,
753 ),
754 _ => LibraryDeclaration::ImportDeclaration(
755 Self::transform_import_decl(iter.skip(1))?.locate(location),
756 ),
757 }
758 .locate(location))
759 }
760
761 fn transform_export_spec(datum: Datum) -> Result<Located<ExportSpec>> {
762 Ok(match datum.data {
763 DatumBody::Symbol(ident) => ExportSpec::Direct(ident),
764 DatumBody::Pair(list) => {
765 let mut iter = list.into_iter();
766 match Self::unwrap_non_end(iter.next())? {
767 Datum {
768 data: DatumBody::Symbol(ident),
769 ..
770 } if ident == "rename" => (),
771 o => return error!(SyntaxError::UnexpectedDatum(o)),
772 };
773 ExportSpec::Rename(
774 Self::transform_identifier(Self::unwrap_non_end(iter.next())?)?,
775 Self::transform_identifier(Self::unwrap_non_end(iter.next())?)?,
776 )
777 }
778 _ => return error!(SyntaxError::UnexpectedDatum(datum)),
779 }
780 .locate(datum.location))
781 }
782
783 fn transform_identifier(datum: Datum) -> Result<String> {
784 match datum.data {
785 DatumBody::Symbol(ident) => Ok(ident.clone()),
786 other => located_error!(
787 SyntaxError::ExpectSomething("identifier".to_string(), other.to_string()),
788 datum.location
789 ),
790 }
791 }
792
793 fn transform_identifier_pair(datum: Datum) -> Result<(String, String)> {
794 let mut iter = datum.expect_list()?.into_iter();
795 let car = Self::transform_identifier(Self::unwrap_non_end(iter.next())?)?;
796 let cdr = Self::transform_identifier(Self::unwrap_non_end(iter.next())?)?;
797 Ok((car, cdr))
798 }
799
800 fn expect_next_nth(&mut self, n: usize, tobe: TokenData) -> Result<()> {
801 match self.advance_unwrap(n)? {
802 Token { data, .. } if data == &tobe => Ok(()),
803 Token { data, .. } => located_error!(
804 SyntaxError::TokenMisMatch(tobe, Some(data.clone())),
805 self.location
806 ),
807 }
808 }
809
810 fn repeat<'a, T>(
812 &'a mut self,
813 get_element: fn(&mut Self) -> Result<T>,
814 ) -> impl Iterator<Item = Result<T>> + 'a
815 where
816 T: std::fmt::Debug + 'a,
817 {
818 repeat(())
819 .map(move |_| match self.peek_next_token()?.map(|t| &t.data) {
820 Some(TokenData::RightParen) => {
821 self.advance(1)?;
822 Ok(None)
823 }
824 None => located_error!(SyntaxError::UnexpectedEnd, self.location),
825 _ => {
826 self.advance(1)?;
827 Some(get_element(self)).transpose()
828 }
829 })
830 .map(|e| e.transpose())
831 .take_while(|e| e.is_some())
832 .map(|e| e.unwrap())
833 }
834
835 fn vector(&mut self) -> Result<Datum> {
836 let vec = self.repeat(Self::datum).collect::<Result<_>>()?;
837 Ok(self.locate(DatumBody::Vector(vec)))
838 }
839
840 fn transform_formals(args: Datum) -> Result<ParameterFormals> {
841 let location = args.location;
842 Ok(match args {
843 Datum {
844 data: DatumBody::Pair(pair),
845 ..
846 } => ParameterFormalsBody::Pair(Box::new(pair.map_ok(&mut |datum| {
847 let sub_location = datum.location;
848 Ok(
849 ParameterFormalsBody::Name(Self::transform_identifier(datum)?)
850 .locate(sub_location),
851 )
852 })?))
853 .locate(location),
854 single => {
855 ParameterFormalsBody::Name(Self::transform_identifier(single)?).locate(location)
856 }
857 })
858 }
859
860 fn parse_quoted(&mut self) -> Result<Datum> {
861 let quote_location = self.location;
862 let inner = self.datum()?;
863 Ok(Datum {
864 location: quote_location,
865 data: DatumBody::Pair(Box::new(list![
866 Datum {
867 data: DatumBody::Symbol("quote".to_string()),
868 location: quote_location,
869 },
870 inner
871 ])),
872 })
873 }
874
875 fn transform_quote(mut datums: impl Iterator<Item = Datum>) -> Result<ExpressionBody> {
876 Ok(ExpressionBody::Quote(Box::new(Self::unwrap_non_end(
877 datums.next(),
878 )?)))
879 }
880
881 fn datum(&mut self) -> Result<Datum> {
882 let location = self.location;
883 Ok(match &self.advance_unwrap(0)?.data {
884 TokenData::LeftParen => self.current_list_or_pair()?,
885 TokenData::VecConsIntro => {
886 DatumBody::Vector(self.repeat(Self::datum).collect::<Result<_>>()?).locate(location)
887 }
888 TokenData::Identifier(symbol) => DatumBody::Symbol(symbol.clone()).locate(location),
889 TokenData::Primitive(p) => DatumBody::Primitive(p.clone()).locate(location),
890 other => return located_error!(SyntaxError::UnexpectedToken(other.clone()), location),
891 })
892 }
893
894 fn transform_lambda(
895 mut datums: impl Iterator<Item = Datum>,
896 syntax_env: &Rc<LexicalScope<Transformer>>,
897 ) -> Result<ExpressionBody> {
898 let formals = Self::transform_formals(Self::unwrap_non_end(datums.next())?)?;
899 let lambda_syntax_env = Rc::new(LexicalScope::new_child(syntax_env.clone()));
900 let (definitions, expressions) =
901 Self::transform_procedure_body(datums, &lambda_syntax_env)?;
902 Ok(ExpressionBody::Procedure(SchemeProcedure(
903 formals,
904 definitions,
905 expressions,
906 )))
907 }
908
909 fn transform_procedure_body(
910 datums: impl Iterator<Item = Datum>,
911 syntax_env: &Rc<LexicalScope<Transformer>>,
912 ) -> Result<(Vec<Definition>, Vec<Expression>)> {
913 let mut definitions = vec![];
914 let mut expressions = vec![];
915 for datum in datums {
916 let location = datum.location;
917 let statement = Self::transform_to_statement(datum, syntax_env)?;
918 match statement {
919 Statement::Definition(def) => {
920 if expressions.is_empty() {
921 definitions.push(def)
922 } else {
923 return located_error!(
924 SyntaxError::InvalidDefinitionContext(def.data),
925 def.location
926 );
927 }
928 }
929 Statement::Expression(expr) => expressions.push(expr),
930 _ => {
931 return located_error!(
932 SyntaxError::ExpectSomething(
933 "expression or definition".to_string(),
934 "other statement".to_string(),
935 ),
936 location
937 )
938 }
939 }
940 }
941 if expressions.is_empty() {
942 return error!(SyntaxError::LambdaBodyNoExpression);
943 }
944 Ok((definitions, expressions))
945 }
946
947 fn transform_import_decl(datums: impl Iterator<Item = Datum>) -> Result<ImportDeclaration> {
948 Ok(ImportDeclaration(
949 datums
950 .map(|import_set| Self::transform_import_set(import_set))
951 .collect::<Result<_>>()?,
952 ))
953 }
954
955 fn transform_condition(
956 mut asts: impl Iterator<Item = Datum>,
957 syntax_env: &Rc<LexicalScope<Transformer>>,
958 ) -> Result<ExpressionBody> {
959 let test = Self::transform_to_expression(Self::unwrap_non_end(asts.next())?, syntax_env)?;
960 let consequent =
961 Self::transform_to_expression(Self::unwrap_non_end(asts.next())?, syntax_env)?;
962 let alternative = asts
963 .next()
964 .map(|datum| Self::transform_to_expression(datum, syntax_env))
965 .transpose()?;
966 Ok(ExpressionBody::Conditional(Box::new((
967 test,
968 consequent,
969 alternative,
970 ))))
971 }
972
973 fn transform_library_name_part(datum: Datum) -> Result<LibraryNameElement> {
974 let location = datum.location;
975 match datum.data {
976 DatumBody::Symbol(identifier) => Ok(LibraryNameElement::Identifier(identifier)),
977 DatumBody::Primitive(Primitive::Integer(i)) if i >= 0 => {
978 Ok(LibraryNameElement::Integer(i as u32))
979 }
980 o => located_error!(SyntaxError::UnexpectedDatum(o.locate(location)), location),
981 }
982 }
983
984 fn transform_library_name(datums: impl Iterator<Item = Datum>) -> Result<LibraryName> {
985 Ok(LibraryName(
986 datums
987 .map(Self::transform_library_name_part)
988 .collect::<Result<_>>()?,
989 ))
990 }
991
992 fn transform_import_set(datum: Datum) -> Result<ImportSet> {
993 let mut iter = datum.expect_list()?.into_iter().peekable();
994 let first = Self::unwrap_non_end(iter.peek())?;
995 let location = first.location;
996 Ok(match Self::transform_identifier(first.clone())? {
997 spec if spec == "only" => {
998 iter.next();
999 let sub_import = Self::transform_import_set(Self::unwrap_non_end(iter.next())?)?;
1000 let idents = iter
1001 .map(Self::transform_identifier)
1002 .collect::<Result<_>>()?;
1003 ImportSetBody::Only(Box::new(sub_import), idents)
1004 }
1005 spec if spec == "except" => {
1006 iter.next();
1007 let sub_import = Self::transform_import_set(Self::unwrap_non_end(iter.next())?)?;
1008 let idents = iter
1009 .map(Self::transform_identifier)
1010 .collect::<Result<_>>()?;
1011 ImportSetBody::Except(Box::new(sub_import), idents)
1012 }
1013 spec if spec == "prefix" => {
1014 iter.next();
1015 let sub_import = Self::transform_import_set(Self::unwrap_non_end(iter.next())?)?;
1016 let ident = Self::transform_identifier(Self::unwrap_non_end(iter.next())?)?;
1017 ImportSetBody::Prefix(Box::new(sub_import), ident)
1018 }
1019 spec if spec == "rename" => {
1020 iter.next();
1021 let sub_import = Self::transform_import_set(Self::unwrap_non_end(iter.next())?)?;
1022 let renaming = iter
1023 .map(Self::transform_identifier_pair)
1024 .collect::<Result<_>>()?;
1025 ImportSetBody::Rename(Box::new(sub_import), renaming)
1026 }
1027 _ => ImportSetBody::Direct(Self::transform_library_name(iter)?.locate(location)),
1028 }
1029 .locate(location))
1030 }
1031
1032 fn transform_definition(
1033 mut datums: impl Iterator<Item = Datum>,
1034 syntax_env: &Rc<LexicalScope<Transformer>>,
1035 ) -> Result<DefinitionBody> {
1036 let first = Self::unwrap_non_end(datums.next())?;
1037 let location = first.location;
1038 match first.data {
1039 DatumBody::Symbol(symbol) => {
1040 let body = Self::transform_to_expression(
1041 Self::unwrap_non_end(datums.next())?,
1042 syntax_env,
1043 )?;
1044 Ok(DefinitionBody(symbol, body))
1045 }
1046 DatumBody::Pair(pair) => match *pair {
1047 GenericPair::Some(name, formals) => {
1048 let location = name.location;
1049 let name = Self::transform_identifier(name)?;
1050 let formals = Self::transform_formals(formals)?;
1051 let (defs, exprs) = Self::transform_procedure_body(datums, syntax_env)?;
1052 let procedure =
1053 ExpressionBody::Procedure(SchemeProcedure(formals, defs, exprs))
1054 .locate(location);
1055 Ok(DefinitionBody(name, procedure))
1056 }
1057 other => {
1058 return located_error!(
1059 SyntaxError::InvalidDefinition(Datum::from(other)),
1060 location
1061 )
1062 }
1063 },
1064 other => {
1065 return located_error!(SyntaxError::DefineNonSymbol(other.no_locate()), location)
1066 }
1067 }
1068 }
1069
1070 fn transform_transformer(keyword: &String, datum: Datum) -> Result<UserDefinedTransformer> {
1071 let mut iter = datum.expect_list()?.into_iter().skip(1);
1073
1074 let first = Self::unwrap_non_end(iter.next())?;
1075 let location = first.location;
1076
1077 let (ellipsis, pattern_literals) = match first.data {
1078 DatumBody::Symbol(ellipsis) => (
1079 Some(ellipsis),
1080 Self::unwrap_non_end(iter.next())?
1081 .expect_list()?
1082 .into_iter()
1083 .map(Self::transform_identifier)
1084 .collect::<Result<HashSet<_>>>()?,
1085 ),
1086 DatumBody::Pair(list) => (
1087 None,
1088 list.into_iter()
1089 .map(Self::transform_identifier)
1090 .collect::<Result<HashSet<_>>>()?,
1091 ),
1092 _ => return located_error!(SyntaxError::UnexpectedDatum(first), location),
1093 };
1094
1095 let rules = iter
1096 .map(|datum| Self::transform_syntax_rule(keyword, datum))
1097 .collect::<Result<_>>()?;
1098
1099 Ok(UserDefinedTransformer {
1100 ellipsis,
1101 literals: pattern_literals,
1102 rules,
1103 })
1104 }
1105
1106 fn transform_syntax_definition(
1107 mut datums: impl Iterator<Item = Datum>,
1108 syntax_env: &Rc<LexicalScope<Transformer>>,
1109 ) -> Result<SyntaxDefBody> {
1110 let keyword = Self::transform_identifier(Self::unwrap_non_end(datums.next())?)?;
1111 let syntax_body =
1112 Self::transform_transformer(&keyword, Self::unwrap_non_end(datums.next())?)?;
1113 syntax_env.define(keyword.clone(), Transformer::Scheme(syntax_body.clone()));
1114 Ok(SyntaxDefBody(keyword, syntax_body))
1115 }
1116
1117 fn transform_syntax_rule(
1118 keyword: &String,
1119 datum: Datum,
1120 ) -> Result<(SyntaxPattern, SyntaxTemplate)> {
1121 let mut iter = datum.expect_list()?.into_iter();
1122 let pattern = Self::transform_pattern_root(
1123 keyword,
1124 Self::unwrap_non_end(iter.next())?.expect_list()?,
1125 )?;
1126 let template = Self::transform_template(Self::unwrap_non_end(iter.next())?)?;
1127 Ok((pattern, template))
1128 }
1129
1130 fn transform_pattern_root(
1131 keyword: &String,
1132 mut datum_list: DatumList,
1133 ) -> Result<SyntaxPattern> {
1134 let first = Self::unwrap_non_end(datum_list.pop_proper()?)?;
1135 let location = first.location;
1136 let providing_keyword = first.expect_symbol()?;
1137 if keyword != &providing_keyword {
1138 return located_error!(
1139 SyntaxError::MacroKeywordMissMatch(keyword.clone(), providing_keyword),
1140 location
1141 );
1142 }
1143 Ok(
1144 SyntaxPatternBody::Pair(Box::new(datum_list.map_ok(&mut Self::transform_pattern)?))
1145 .locate(location),
1146 )
1147 }
1148
1149 fn transform_pattern(datum: Datum) -> Result<SyntaxPattern> {
1150 let location = datum.location;
1151 let data = match datum.data {
1152 DatumBody::Symbol(ident) if ident == "_" => SyntaxPatternBody::Underscore,
1153 DatumBody::Symbol(ident) if ident == "..." => SyntaxPatternBody::Ellipsis,
1154 DatumBody::Symbol(ident) => SyntaxPatternBody::Identifier(ident),
1155 DatumBody::Primitive(p) => SyntaxPatternBody::Primitive(p),
1156 DatumBody::Pair(list) => {
1157 SyntaxPatternBody::Pair(Box::new(list.map_ok(&mut Self::transform_pattern)?))
1158 }
1159 DatumBody::Vector(v) => SyntaxPatternBody::Vector(
1160 v.into_iter()
1161 .map(Self::transform_pattern)
1162 .collect::<Result<Vec<_>>>()?,
1163 ),
1164 };
1165 Ok(SyntaxPattern {
1166 data,
1167 location: location,
1168 })
1169 }
1170
1171 fn collect_template_elements(
1172 mut datums: impl Iterator<Item = Datum>,
1173 ) -> Result<impl IntoIterator<Item = SyntaxTemplateElement>> {
1174 let mut last_template = None;
1175 let mut elements = vec![];
1176 while let Some(datum) = datums.next() {
1177 let location = datum.location;
1178 match datum.data {
1179 DatumBody::Symbol(symbol) if symbol == "..." => match last_template {
1180 Some(SyntaxTemplateElement(template, false)) => {
1181 elements.push(SyntaxTemplateElement(template, true));
1182 last_template = None;
1183 }
1184 _ => {
1185 return located_error!(
1186 SyntaxError::UnexpectedDatum(
1187 DatumBody::Symbol(symbol).locate(location)
1188 ),
1189 location
1190 );
1191 }
1192 },
1193 other => {
1194 if let Some(last_template) = last_template {
1195 elements.push(last_template)
1196 };
1197 last_template = Some(SyntaxTemplateElement(
1198 Self::transform_template(Datum {
1199 data: other,
1200 location,
1201 })?,
1202 false,
1203 ))
1204 }
1205 }
1206 }
1207 if let Some(last_template) = last_template {
1208 elements.push(last_template)
1209 };
1210 Ok(elements)
1211 }
1212
1213 fn transform_template(datum: Datum) -> Result<SyntaxTemplate> {
1214 let data = match datum.data {
1222 DatumBody::Symbol(ident) => SyntaxTemplateBody::Identifier(ident),
1223 DatumBody::Primitive(p) => SyntaxTemplateBody::Primitive(p),
1224 DatumBody::Pair(list) => {
1225 let elements = Self::collect_template_elements(list.into_iter())?
1226 .into_iter()
1227 .collect::<GenericPair<_>>();
1228 SyntaxTemplateBody::Pair(Box::new(elements))
1229 }
1230 DatumBody::Vector(vec) => SyntaxTemplateBody::Vector(
1231 Self::collect_template_elements(vec.into_iter())?
1232 .into_iter()
1233 .collect::<Vec<_>>(),
1234 ),
1235 };
1236 Ok(SyntaxTemplate {
1237 data,
1238 location: datum.location,
1239 })
1240 }
1241
1242 fn transform_assignment(
1243 mut datums: impl Iterator<Item = Datum>,
1244 syntax_env: &Rc<LexicalScope<Transformer>>,
1245 ) -> Result<ExpressionBody> {
1246 let symbol = match Self::unwrap_non_end(datums.next())? {
1247 Datum {
1248 data: DatumBody::Symbol(symbol),
1249 ..
1250 } => symbol,
1251 other => return error!(SyntaxError::DefineNonSymbol(other)),
1252 };
1253 let body = Self::transform_to_expression(Self::unwrap_non_end(datums.next())?, syntax_env)?;
1254 Ok(ExpressionBody::Assignment(symbol, Box::new(body)))
1255 }
1256
1257 fn transform_procedure_call(
1258 first: Datum,
1259 datum: impl Iterator<Item = Datum>,
1260 syntax_env: &Rc<LexicalScope<Transformer>>,
1261 ) -> Result<ExpressionBody> {
1262 Ok(ExpressionBody::ProcedureCall(
1263 Box::new(Self::transform_to_expression(first, syntax_env)?),
1264 datum
1265 .map(|datum| Self::transform_to_expression(datum, syntax_env))
1266 .collect::<Result<Vec<_>>>()?,
1267 ))
1268 }
1269
1270 fn advance(&mut self, count: usize) -> Result<&mut Option<Token>> {
1271 for _ in 1..count {
1272 self.lexer.next();
1273 }
1274 if count > 0 {
1275 self.current = self.lexer.next().transpose()?;
1276 self.location = self.current.as_ref().and_then(|t| t.location);
1277 }
1278 Ok(&mut self.current)
1279 }
1280
1281 fn advance_unwrap<'a>(&'a mut self, count: usize) -> Result<&'a mut Token> {
1282 let location = self.location;
1283 let token = self.advance(count)?;
1284 match token {
1285 Some(tok) => Ok(tok),
1286 None => located_error!(SyntaxError::UnexpectedEnd, location),
1287 }
1288 }
1289
1290 fn advance_unwrap_take(&mut self, count: usize) -> Result<Token> {
1291 let token = self.advance(count)?.take();
1292 match token {
1293 Some(tok) => Ok(tok),
1294 None => located_error!(SyntaxError::UnexpectedEnd, self.location),
1295 }
1296 }
1297
1298 fn peek_next_token(&mut self) -> Result<Option<&Token>> {
1299 match self.lexer.peek() {
1300 Some(ret) => match ret {
1301 Ok(t) => Ok(Some(t)),
1302 Err(e) => Err((*e).clone()),
1303 },
1304 None => Ok(None),
1305 }
1306 }
1307
1308 fn locate<T: PartialEq>(&self, data: T) -> Located<T> {
1309 Located {
1310 data,
1311 location: self.location,
1312 }
1313 }
1314}
1315
1316#[cfg(test)]
1330pub fn simple_procedure(formals: ParameterFormals, expression: Expression) -> Expression {
1331 ExpressionBody::Procedure(SchemeProcedure(formals, vec![], vec![expression])).into()
1332}
1333#[test]
1334fn empty() -> Result<()> {
1335 let tokens = Vec::new();
1336 let mut parser = token_stream_to_parser(tokens.into_iter());
1337 assert_eq!(parser.parse_root(), Ok(None));
1338 Ok(())
1339}
1340
1341fn expr_body_to_statement(t: ExpressionBody) -> Option<Statement> {
1342 Some(Located::from(t).into())
1343}
1344
1345fn def_body_to_statement(t: DefinitionBody) -> Option<Statement> {
1346 Some(Located::from(t).into())
1347}
1348
1349#[cfg(test)]
1350pub fn token_stream_to_parser(
1351 token_stream: impl Iterator<Item = Token>,
1352) -> Parser<impl Iterator<Item = Result<Token>>> {
1353 let mapped = token_stream.map(|t| -> Result<Token> { Ok(t) });
1354 Parser {
1355 current: None,
1356 lexer: mapped.peekable(),
1357 syntax_env: Rc::new(LexicalScope::new()),
1358 location: None,
1359 }
1360}
1361
1362#[test]
1363fn integer() -> Result<()> {
1364 let tokens = convert_located(vec![TokenData::Primitive(Primitive::Integer(1))]);
1365 let mut parser = token_stream_to_parser(tokens.into_iter());
1366 let ast = parser.parse_root()?;
1367 assert_eq!(ast, expr_body_to_statement(Primitive::Integer(1).into()));
1368 Ok(())
1369}
1370
1371#[test]
1372fn real_number() -> Result<()> {
1373 let tokens = convert_located(vec![TokenData::Primitive(Primitive::Real(
1374 "1.2".to_string(),
1375 ))]);
1376 let mut parser = token_stream_to_parser(tokens.into_iter());
1377 let ast = parser.parse_root()?;
1378 assert_eq!(
1379 ast,
1380 expr_body_to_statement(Primitive::Real("1.2".to_string()).into())
1381 );
1382 Ok(())
1383}
1384
1385#[test]
1386fn rational() -> Result<()> {
1387 let tokens = convert_located(vec![TokenData::Primitive(Primitive::Rational(1, 2))]);
1388 let mut parser = token_stream_to_parser(tokens.into_iter());
1389 let ast = parser.parse_root()?;
1390 assert_eq!(
1391 ast,
1392 expr_body_to_statement(Primitive::Rational(1, 2).into())
1393 );
1394 Ok(())
1395}
1396
1397#[test]
1398fn identifier() -> Result<()> {
1399 let tokens = convert_located(vec![TokenData::Identifier("test".to_string())]);
1400 let mut parser = token_stream_to_parser(tokens.into_iter());
1401 let ast = parser.parse_root()?;
1402 assert_eq!(
1403 ast,
1404 expr_body_to_statement(ExpressionBody::Symbol("test".to_string()))
1405 );
1406 Ok(())
1407}
1408
1409#[test]
1410fn vector() -> Result<()> {
1411 let tokens = convert_located(vec![
1412 TokenData::VecConsIntro,
1413 TokenData::Primitive(Primitive::Integer(1)),
1414 TokenData::Primitive(Primitive::Boolean(false)),
1415 TokenData::RightParen,
1416 ]);
1417 let mut parser = token_stream_to_parser(tokens.into_iter());
1418 let ast = parser.parse_root()?;
1419 assert_eq!(
1420 ast,
1421 expr_body_to_statement(ExpressionBody::Datum(
1422 DatumBody::Vector(convert_located(vec![
1423 DatumBody::Primitive(Primitive::Integer(1)),
1424 DatumBody::Primitive(Primitive::Boolean(false))
1425 ]))
1426 .into()
1427 ))
1428 );
1429 Ok(())
1430}
1431
1432#[test]
1433fn string() -> Result<()> {
1434 let tokens = convert_located(vec![TokenData::Primitive(Primitive::String(
1435 "hello world".to_string(),
1436 ))]);
1437 let mut parser = token_stream_to_parser(tokens.into_iter());
1438 let ast = parser.parse_root()?;
1439 assert_eq!(
1440 ast,
1441 expr_body_to_statement(Primitive::String("hello world".to_string()).into())
1442 );
1443 Ok(())
1444}
1445
1446#[test]
1447fn procedure_call() -> Result<()> {
1448 let tokens = convert_located(vec![
1449 TokenData::LeftParen,
1450 TokenData::Identifier("+".to_string()),
1451 TokenData::Primitive(Primitive::Integer(1)),
1452 TokenData::Primitive(Primitive::Integer(2)),
1453 TokenData::Primitive(Primitive::Integer(3)),
1454 TokenData::RightParen,
1455 ]);
1456 let mut parser = token_stream_to_parser(tokens.into_iter());
1457 let ast = parser.parse_root()?;
1458 assert_eq!(
1459 ast,
1460 expr_body_to_statement(ExpressionBody::ProcedureCall(
1461 Box::new(ExpressionBody::Symbol("+".to_string()).into()),
1462 vec![
1463 Primitive::Integer(1).into(),
1464 Primitive::Integer(2).into(),
1465 Primitive::Integer(3).into(),
1466 ]
1467 ))
1468 );
1469 Ok(())
1470}
1471
1472#[test]
1473fn unmatched_parantheses() {
1474 let tokens = convert_located(vec![
1475 TokenData::LeftParen,
1476 TokenData::Identifier("+".to_string()),
1477 TokenData::Primitive(Primitive::Integer(1)),
1478 TokenData::Primitive(Primitive::Integer(2)),
1479 TokenData::Primitive(Primitive::Integer(3)),
1480 ]);
1481 let mut parser = token_stream_to_parser(tokens.into_iter());
1482 assert_eq!(
1483 parser.parse_root(),
1484 located_error!(SyntaxError::UnexpectedEnd, None)
1485 );
1486}
1487
1488#[test]
1489fn definition() -> Result<()> {
1490 {
1491 {
1492 let tokens = convert_located(vec![
1493 TokenData::LeftParen,
1494 TokenData::Identifier("define".to_string()),
1495 TokenData::Identifier("a".to_string()),
1496 TokenData::Primitive(Primitive::Integer(1)),
1497 TokenData::RightParen,
1498 ]);
1499 let mut parser = token_stream_to_parser(tokens.into_iter());
1500 let ast = parser.parse_root()?;
1501 assert_eq!(
1502 ast,
1503 def_body_to_statement(DefinitionBody(
1504 "a".to_string(),
1505 Primitive::Integer(1).into()
1506 ))
1507 );
1508 }
1509 {
1510 let tokens = convert_located(vec![
1511 TokenData::LeftParen,
1512 TokenData::Identifier("define".to_string()),
1513 TokenData::LeftParen,
1514 TokenData::Identifier("add".to_string()),
1515 TokenData::Identifier("x".to_string()),
1516 TokenData::Identifier("y".to_string()),
1517 TokenData::RightParen,
1518 TokenData::LeftParen,
1519 TokenData::Identifier("+".to_string()),
1520 TokenData::Identifier("x".to_string()),
1521 TokenData::Identifier("y".to_string()),
1522 TokenData::RightParen,
1523 TokenData::RightParen,
1524 ]);
1525 let mut parser = token_stream_to_parser(tokens.into_iter());
1526 let ast = parser.parse_root()?;
1527 assert_eq!(
1528 ast,
1529 def_body_to_statement(DefinitionBody(
1530 "add".to_string(),
1531 simple_procedure(
1532 param_fixed!["x", "y"],
1533 ExpressionBody::ProcedureCall(
1534 Box::new(ExpressionBody::Symbol("+".to_string()).into()),
1535 vec![
1536 ExpressionBody::Symbol("x".to_string()).into(),
1537 ExpressionBody::Symbol("y".to_string()).into(),
1538 ]
1539 )
1540 .into()
1541 )
1542 ))
1543 )
1544 }
1545 {
1546 let tokens = convert_located(vec![
1547 TokenData::LeftParen,
1548 TokenData::Identifier("define".to_string()),
1549 TokenData::LeftParen,
1550 TokenData::Identifier("add".to_string()),
1551 TokenData::Period,
1552 TokenData::Identifier("x".to_string()),
1553 TokenData::RightParen,
1554 TokenData::Identifier("x".to_string()),
1555 TokenData::RightParen,
1556 ]);
1557 let mut parser = token_stream_to_parser(tokens.into_iter());
1558 let ast = parser.parse_root()?;
1559 assert_eq!(
1560 ast,
1561 def_body_to_statement(DefinitionBody(
1562 "add".to_string(),
1563 simple_procedure(
1564 append_variadic_param!(param_fixed![], "x"),
1565 ExpressionBody::Symbol("x".to_string()).into()
1566 )
1567 ))
1568 )
1569 }
1570 Ok(())
1571 }
1572}
1573
1574#[test]
1575fn nested_procedure_call() -> Result<()> {
1576 let tokens = convert_located(vec![
1577 TokenData::LeftParen,
1578 TokenData::Identifier("+".to_string()),
1579 TokenData::Primitive(Primitive::Integer(1)),
1580 TokenData::LeftParen,
1581 TokenData::Identifier("-".to_string()),
1582 TokenData::Primitive(Primitive::Integer(2)),
1583 TokenData::Primitive(Primitive::Integer(3)),
1584 TokenData::RightParen,
1585 TokenData::RightParen,
1586 ]);
1587 let mut parser = token_stream_to_parser(tokens.into_iter());
1588 let ast = parser.parse_root()?;
1589 assert_eq!(
1590 ast,
1591 expr_body_to_statement(ExpressionBody::ProcedureCall(
1592 Box::new(ExpressionBody::Symbol("+".to_string()).into()),
1593 vec![
1594 Primitive::Integer(1).into(),
1595 ExpressionBody::ProcedureCall(
1596 Box::new(ExpressionBody::Symbol("-".to_string()).into()),
1597 vec![Primitive::Integer(2).into(), Primitive::Integer(3).into()]
1598 )
1599 .into(),
1600 ]
1601 ))
1602 );
1603 Ok(())
1604}
1605
1606#[test]
1607fn lambda() -> Result<()> {
1608 {
1609 let tokens = convert_located(vec![
1610 TokenData::LeftParen,
1611 TokenData::Identifier("lambda".to_string()),
1612 TokenData::LeftParen,
1613 TokenData::Identifier("x".to_string()),
1614 TokenData::Identifier("y".to_string()),
1615 TokenData::RightParen,
1616 TokenData::LeftParen,
1617 TokenData::Identifier("+".to_string()),
1618 TokenData::Identifier("x".to_string()),
1619 TokenData::Identifier("y".to_string()),
1620 TokenData::RightParen,
1621 TokenData::RightParen,
1622 ]);
1623 let mut parser = token_stream_to_parser(tokens.into_iter());
1624 let ast = parser.parse_root()?;
1625 assert_eq!(
1626 ast,
1627 Some(Statement::Expression(simple_procedure(
1628 param_fixed!["x", "y"],
1629 ExpressionBody::ProcedureCall(
1630 Box::new(ExpressionBody::Symbol("+".to_string()).into()),
1631 vec![
1632 ExpressionBody::Symbol("x".to_string()).into(),
1633 ExpressionBody::Symbol("y".to_string()).into()
1634 ]
1635 )
1636 .into()
1637 )))
1638 );
1639 }
1640
1641 {
1642 let tokens = convert_located(vec![
1643 TokenData::LeftParen,
1644 TokenData::Identifier("lambda".to_string()),
1645 TokenData::LeftParen,
1646 TokenData::Identifier("x".to_string()),
1647 TokenData::RightParen,
1648 TokenData::LeftParen,
1649 TokenData::Identifier("define".to_string()),
1650 TokenData::Identifier("y".to_string()),
1651 TokenData::Primitive(Primitive::Integer(1)),
1652 TokenData::RightParen,
1653 TokenData::LeftParen,
1654 TokenData::Identifier("+".to_string()),
1655 TokenData::Identifier("x".to_string()),
1656 TokenData::Identifier("y".to_string()),
1657 TokenData::RightParen,
1658 TokenData::RightParen,
1659 ]);
1660 let mut parser = token_stream_to_parser(tokens.into_iter());
1661 let ast = parser.parse_root()?;
1662 assert_eq!(
1663 ast,
1664 Some(Statement::Expression(
1665 ExpressionBody::Procedure(SchemeProcedure(
1666 param_fixed!["x".to_string()],
1667 vec![Definition::from(DefinitionBody(
1668 "y".to_string(),
1669 Primitive::Integer(1).into()
1670 ))],
1671 vec![ExpressionBody::ProcedureCall(
1672 Box::new(ExpressionBody::Symbol("+".to_string()).into()),
1673 vec![
1674 ExpressionBody::Symbol("x".to_string()).into(),
1675 ExpressionBody::Symbol("y".to_string()).into()
1676 ]
1677 )
1678 .into()]
1679 ))
1680 .into()
1681 ))
1682 );
1683 }
1684
1685 {
1686 let tokens = convert_located(vec![
1687 TokenData::LeftParen,
1688 TokenData::Identifier("lambda".to_string()),
1689 TokenData::LeftParen,
1690 TokenData::Identifier("x".to_string()),
1691 TokenData::RightParen,
1692 TokenData::LeftParen,
1693 TokenData::Identifier("define".to_string()),
1694 TokenData::Identifier("y".to_string()),
1695 TokenData::Primitive(Primitive::Integer(1)),
1696 TokenData::RightParen,
1697 TokenData::RightParen,
1698 ]);
1699 let mut parser = token_stream_to_parser(tokens.into_iter());
1700 let err = parser.parse_root();
1701 assert_eq!(
1702 err,
1703 located_error!(SyntaxError::LambdaBodyNoExpression, None)
1704 );
1705 }
1706
1707 {
1708 let tokens = convert_located(vec![
1709 TokenData::LeftParen,
1710 TokenData::Identifier("lambda".to_string()),
1711 TokenData::LeftParen,
1712 TokenData::Identifier("x".to_string()),
1713 TokenData::Period,
1714 TokenData::Identifier("y".to_string()),
1715 TokenData::RightParen,
1716 TokenData::LeftParen,
1717 TokenData::Identifier("+".to_string()),
1718 TokenData::Identifier("x".to_string()),
1719 TokenData::Identifier("y".to_string()),
1720 TokenData::RightParen,
1721 TokenData::RightParen,
1722 ]);
1723 let mut parser = token_stream_to_parser(tokens.into_iter());
1724 let ast = parser.parse_root()?;
1725 assert_eq!(
1726 ast,
1727 Some(Statement::Expression(
1728 ExpressionBody::Procedure(SchemeProcedure(
1729 append_variadic_param!(param_fixed!["x"], "y"),
1730 vec![],
1731 vec![ExpressionBody::ProcedureCall(
1732 Box::new(ExpressionBody::Symbol("+".to_string()).into()),
1733 vec![
1734 ExpressionBody::Symbol("x".to_string()).into(),
1735 ExpressionBody::Symbol("y".to_string()).into()
1736 ]
1737 )
1738 .into()]
1739 ))
1740 .into()
1741 ))
1742 );
1743 }
1744
1745 Ok(())
1746}
1747
1748#[test]
1749fn conditional() -> Result<()> {
1750 let tokens = convert_located(vec![
1751 TokenData::LeftParen,
1752 TokenData::Identifier("if".to_string()),
1753 TokenData::Primitive(Primitive::Boolean(true)),
1754 TokenData::Primitive(Primitive::Integer(1)),
1755 TokenData::Primitive(Primitive::Integer(2)),
1756 TokenData::RightParen,
1757 ]);
1758 let mut parser = token_stream_to_parser(tokens.into_iter());
1759 assert_eq!(
1760 parser.parse_root()?,
1761 Some(Statement::Expression(
1762 ExpressionBody::Conditional(Box::new((
1763 Primitive::Boolean(true).into(),
1764 Primitive::Integer(1).into(),
1765 Some(Primitive::Integer(2).into())
1766 )))
1767 .into()
1768 ))
1769 );
1770 assert_eq!(parser.parse_root()?, None);
1771 Ok(())
1772}
1773
1774#[test]
1775fn import_set() -> Result<()> {
1776 {
1777 let tokens = convert_located(vec![
1778 TokenData::LeftParen,
1779 TokenData::Identifier("import".to_string()),
1780 TokenData::LeftParen,
1781 TokenData::Identifier("foo".to_string()),
1782 TokenData::Primitive(Primitive::Integer(5)),
1783 TokenData::RightParen,
1784 TokenData::RightParen,
1785 ]);
1786 let mut parser = token_stream_to_parser(tokens.into_iter());
1787 let import_set = parser.parse_root()?;
1788 assert_eq!(
1789 import_set,
1790 Some(Statement::ImportDeclaration(
1791 ImportDeclaration(vec![
1792 ImportSetBody::Direct(library_name!("foo", 5).into()).into()
1793 ])
1794 .into()
1795 ))
1796 );
1797 }
1798 {
1799 let tokens = convert_located(vec![
1800 TokenData::LeftParen,
1801 TokenData::Identifier("import".to_string()),
1802 TokenData::LeftParen,
1803 TokenData::Identifier("only".to_string()),
1804 TokenData::LeftParen,
1805 TokenData::Identifier("foo".to_string()),
1806 TokenData::Primitive(Primitive::Integer(5)),
1807 TokenData::RightParen,
1808 TokenData::Identifier("a".to_string()),
1809 TokenData::RightParen,
1810 TokenData::RightParen,
1811 ]);
1812 let mut parser = token_stream_to_parser(tokens.into_iter());
1813 let import_set = parser.parse_root()?;
1814 assert_eq!(
1815 import_set,
1816 Some(Statement::ImportDeclaration(
1817 ImportDeclaration(vec![ImportSetBody::Only(
1818 Box::new(
1819 ImportSetBody::Direct(library_name!("foo", 5).no_locate()).no_locate()
1820 ),
1821 vec!["a".to_string()]
1822 )
1823 .into()])
1824 .into()
1825 ))
1826 );
1827 }
1828 {
1829 let tokens = convert_located(vec![
1830 TokenData::LeftParen,
1831 TokenData::Identifier("import".to_string()),
1832 TokenData::LeftParen,
1833 TokenData::Identifier("except".to_string()),
1834 TokenData::LeftParen,
1835 TokenData::Identifier("foo".to_string()),
1836 TokenData::Primitive(Primitive::Integer(5)),
1837 TokenData::RightParen,
1838 TokenData::Identifier("a".to_string()),
1839 TokenData::Identifier("b".to_string()),
1840 TokenData::RightParen,
1841 TokenData::RightParen,
1842 ]);
1843 let mut parser = token_stream_to_parser(tokens.into_iter());
1844 let import_set = parser.parse_root()?;
1845 assert_eq!(
1846 import_set,
1847 Some(Statement::ImportDeclaration(
1848 ImportDeclaration(vec![ImportSetBody::Except(
1849 Box::new(
1850 ImportSetBody::Direct(library_name!("foo", 5).no_locate()).no_locate()
1851 ),
1852 vec!["a".to_string(), "b".to_string()]
1853 )
1854 .into()])
1855 .into()
1856 ))
1857 );
1858 }
1859 {
1860 let tokens = convert_located(vec![
1861 TokenData::LeftParen,
1862 TokenData::Identifier("import".to_string()),
1863 TokenData::LeftParen,
1864 TokenData::Identifier("prefix".to_string()),
1865 TokenData::LeftParen,
1866 TokenData::Identifier("foo".to_string()),
1867 TokenData::Primitive(Primitive::Integer(5)),
1868 TokenData::RightParen,
1869 TokenData::Identifier("a-".to_string()),
1870 TokenData::RightParen,
1871 TokenData::RightParen,
1872 ]);
1873 let mut parser = token_stream_to_parser(tokens.into_iter());
1874 let import_set = parser.parse_root()?;
1875 assert_eq!(
1876 import_set,
1877 Some(Statement::ImportDeclaration(
1878 ImportDeclaration(vec![ImportSetBody::Prefix(
1879 Box::new(
1880 ImportSetBody::Direct(library_name!("foo", 5).no_locate()).no_locate()
1881 ),
1882 "a-".to_string()
1883 )
1884 .into()])
1885 .into()
1886 ))
1887 );
1888 }
1889 {
1890 let tokens = convert_located(vec![
1891 TokenData::LeftParen,
1892 TokenData::Identifier("import".to_string()),
1893 TokenData::LeftParen,
1894 TokenData::Identifier("rename".to_string()),
1895 TokenData::LeftParen,
1896 TokenData::Identifier("foo".to_string()),
1897 TokenData::Primitive(Primitive::Integer(5)),
1898 TokenData::RightParen,
1899 TokenData::LeftParen,
1900 TokenData::Identifier("a".to_string()),
1901 TokenData::Identifier("b".to_string()),
1902 TokenData::RightParen,
1903 TokenData::LeftParen,
1904 TokenData::Identifier("c".to_string()),
1905 TokenData::Identifier("d".to_string()),
1906 TokenData::RightParen,
1907 TokenData::RightParen,
1908 TokenData::RightParen,
1909 ]);
1910 let mut parser = token_stream_to_parser(tokens.into_iter());
1911 let import_set = parser.parse_root()?;
1912 assert_eq!(
1913 import_set,
1914 Some(Statement::ImportDeclaration(
1915 ImportDeclaration(vec![ImportSetBody::Rename(
1916 Box::new(
1917 ImportSetBody::Direct(library_name!("foo", 5).no_locate()).no_locate()
1918 ),
1919 vec![
1920 ("a".to_string(), "b".to_string()),
1921 ("c".to_string(), "d".to_string()),
1922 ]
1923 )
1924 .into()])
1925 .into()
1926 ))
1927 );
1928 }
1929 Ok(())
1930}
1931#[test]
1937fn import_declaration() -> Result<()> {
1938 {
1939 let tokens = convert_located(vec![
1940 TokenData::LeftParen,
1941 TokenData::Identifier("import".to_string()),
1942 TokenData::LeftParen,
1943 TokenData::Identifier("only".to_string()),
1944 TokenData::LeftParen,
1945 TokenData::Identifier("example-lib".to_string()),
1946 TokenData::RightParen,
1947 TokenData::Identifier("a".to_string()),
1948 TokenData::Identifier("b".to_string()),
1949 TokenData::RightParen,
1950 TokenData::LeftParen,
1951 TokenData::Identifier("rename".to_string()),
1952 TokenData::LeftParen,
1953 TokenData::Identifier("example-lib".to_string()),
1954 TokenData::RightParen,
1955 TokenData::LeftParen,
1956 TokenData::Identifier("old".to_string()),
1957 TokenData::Identifier("new".to_string()),
1958 TokenData::RightParen,
1959 TokenData::RightParen,
1960 TokenData::RightParen,
1961 ]);
1962
1963 let mut parser = token_stream_to_parser(tokens.into_iter());
1964 let ast = parser.parse_root()?;
1965 assert_eq!(
1966 ast,
1967 Some(
1968 ImportDeclaration(convert_located(vec![
1969 ImportSetBody::Only(
1970 Box::new(
1971 ImportSetBody::Direct(
1972 LibraryName(vec![LibraryNameElement::Identifier(
1973 "example-lib".to_string()
1974 )])
1975 .into()
1976 )
1977 .into()
1978 ),
1979 vec!["a".to_string(), "b".to_string()]
1980 ),
1981 ImportSetBody::Rename(
1982 Box::new(
1983 ImportSetBody::Direct(
1984 LibraryName(vec![LibraryNameElement::Identifier(
1985 "example-lib".to_string()
1986 )])
1987 .into()
1988 )
1989 .into()
1990 ),
1991 vec![("old".to_string(), "new".to_string())]
1992 )
1993 ]))
1994 .no_locate()
1995 .into()
1996 )
1997 );
1998 }
1999 Ok(())
2000}
2001
2002#[test]
2003fn literals() -> Result<()> {
2004 {
2006 let tokens = convert_located(vec![
2007 TokenData::Quote,
2008 TokenData::Primitive(Primitive::Integer(1)),
2009 TokenData::Quote,
2010 TokenData::Identifier("a".to_string()),
2011 TokenData::Quote,
2012 TokenData::LeftParen,
2013 TokenData::Primitive(Primitive::Integer(1)),
2014 TokenData::RightParen,
2015 TokenData::VecConsIntro,
2016 TokenData::Primitive(Primitive::Integer(1)),
2017 TokenData::RightParen,
2018 TokenData::Quote,
2019 TokenData::VecConsIntro,
2020 TokenData::Primitive(Primitive::Integer(1)),
2021 TokenData::RightParen,
2022 ]);
2023 let parser = token_stream_to_parser(tokens.into_iter());
2024 let asts = parser.collect::<Result<Vec<_>>>()?;
2025 assert_eq!(
2026 asts,
2027 vec![
2028 Statement::Expression(
2029 ExpressionBody::Quote(Box::new(
2030 DatumBody::Primitive(Primitive::Integer(1)).into()
2031 ))
2032 .into()
2033 ),
2034 Statement::Expression(
2035 ExpressionBody::Quote(Box::new(DatumBody::Symbol("a".to_string()).into(),))
2036 .into()
2037 ),
2038 Statement::Expression(
2039 ExpressionBody::Quote(Box::new(
2040 DatumBody::Pair(Box::new(list!(DatumBody::Primitive(Primitive::Integer(
2041 1
2042 ))
2043 .no_locate())))
2044 .into()
2045 ))
2046 .into()
2047 ),
2048 Statement::Expression(
2049 ExpressionBody::Datum(
2050 DatumBody::Vector(vec![
2051 DatumBody::Primitive(Primitive::Integer(1)).no_locate()
2052 ])
2053 .into()
2054 )
2055 .into()
2056 ),
2057 Statement::Expression(
2058 ExpressionBody::Quote(Box::new(
2059 DatumBody::Vector(vec![
2060 DatumBody::Primitive(Primitive::Integer(1)).no_locate()
2061 ])
2062 .into()
2063 ))
2064 .into()
2065 ),
2066 ]
2067 );
2068 }
2069 Ok(())
2070}
2071
2072#[test]
2073fn macros() -> Result<()> {
2074 let tokens = convert_located(vec![
2075 TokenData::LeftParen,
2076 TokenData::Identifier("define-syntax".to_string()),
2077 TokenData::Identifier("begin".to_string()),
2078 TokenData::LeftParen,
2079 TokenData::Identifier("syntax-rules".to_string()),
2080 TokenData::LeftParen,
2081 TokenData::RightParen,
2082 TokenData::LeftParen,
2083 TokenData::LeftParen,
2084 TokenData::Identifier("begin".to_string()),
2085 TokenData::Identifier("exp".to_string()),
2086 TokenData::Identifier("...".to_string()),
2087 TokenData::RightParen,
2088 TokenData::LeftParen,
2089 TokenData::LeftParen,
2090 TokenData::Identifier("lambda".to_string()),
2091 TokenData::LeftParen,
2092 TokenData::RightParen,
2093 TokenData::Identifier("exp".to_string()),
2094 TokenData::Identifier("...".to_string()),
2095 TokenData::RightParen,
2096 TokenData::RightParen,
2097 TokenData::RightParen,
2098 TokenData::RightParen,
2099 TokenData::RightParen,
2100 ]);
2101
2102 let parser = token_stream_to_parser(tokens.into_iter());
2103 let asts = parser.collect::<Result<Vec<_>>>()?;
2104 assert_eq!(
2105 asts,
2106 vec![Statement::SyntaxDefinition(
2107 SyntaxDefBody(
2108 "begin".to_owned(),
2109 UserDefinedTransformer {
2110 ellipsis: None,
2111 literals: HashSet::new(),
2112 rules: vec![(
2113 SyntaxPatternBody::Pair(Box::new(list![
2114 SyntaxPatternBody::Identifier("exp".to_string()).into(),
2115 SyntaxPatternBody::Ellipsis.into()
2116 ]))
2117 .into(),
2118 SyntaxTemplateBody::Pair(Box::new(list![SyntaxTemplateElement(
2119 SyntaxTemplateBody::Pair(Box::new(list![
2120 SyntaxTemplateElement(
2121 SyntaxTemplateBody::Identifier("lambda".to_string()).into(),
2122 false
2123 ),
2124 SyntaxTemplateElement(
2125 SyntaxTemplateBody::Pair(Box::new(list![])).into(),
2126 false
2127 ),
2128 SyntaxTemplateElement(
2129 SyntaxTemplateBody::Identifier("exp".to_string()).into(),
2130 true
2131 )
2132 ]))
2133 .into(),
2134 false
2135 )]))
2136 .into()
2137 )],
2138 }
2139 )
2140 .into()
2141 )]
2142 );
2143
2144 Ok(())
2145}
2146
2147#[test]
2148fn library_name() -> Result<()> {
2149 {
2150 let tokens = convert_located(vec![
2151 TokenData::LeftParen,
2152 TokenData::Identifier("import".to_string()),
2153 TokenData::LeftParen,
2154 TokenData::Identifier("f".to_string()),
2155 TokenData::Primitive(Primitive::Integer(5)),
2156 TokenData::RightParen,
2157 TokenData::RightParen,
2158 ]);
2159 let mut parser = token_stream_to_parser(tokens.into_iter());
2160 let library_name = parser.parse_root()?;
2161 assert_eq!(
2162 library_name,
2163 Some(Statement::ImportDeclaration(
2164 ImportDeclaration(vec![
2165 ImportSetBody::Direct(library_name!("f", 5).into()).into()
2166 ])
2167 .into()
2168 ))
2169 );
2170 }
2171 {
2172 let tokens = convert_located(vec![
2173 TokenData::LeftParen,
2174 TokenData::Identifier("import".to_string()),
2175 TokenData::LeftParen,
2176 TokenData::Identifier("f".to_string()),
2177 TokenData::Primitive(Primitive::Integer(-5)),
2178 TokenData::RightParen,
2179 TokenData::RightParen,
2180 ]);
2181 let mut parser = token_stream_to_parser(tokens.into_iter());
2182 let library_name = parser.parse_root();
2183 assert!(library_name.is_err());
2184 }
2185 {
2186 let tokens = convert_located(vec![
2187 TokenData::LeftParen,
2188 TokenData::Identifier("import".to_string()),
2189 TokenData::LeftParen,
2190 TokenData::Identifier("f".to_string()),
2191 TokenData::Primitive(Primitive::String("haha".to_string())),
2192 TokenData::RightParen,
2193 TokenData::RightParen,
2194 ]);
2195 let mut parser = token_stream_to_parser(tokens.into_iter());
2196 let library_name = parser.parse_root();
2197 assert!(library_name.is_err());
2198 }
2199 Ok(())
2200}
2201#[test]
2202fn export_spec() -> Result<()> {
2203 {
2204 let tokens = convert_located(vec![
2205 TokenData::LeftParen,
2206 TokenData::Identifier("define-library".to_string()),
2207 TokenData::LeftParen,
2208 TokenData::Identifier("foo".to_string()),
2209 TokenData::RightParen,
2210 TokenData::LeftParen,
2211 TokenData::Identifier("export".to_string()),
2212 TokenData::Identifier("a".to_string()),
2213 TokenData::RightParen,
2214 TokenData::RightParen,
2215 ]);
2216 let mut parser = token_stream_to_parser(tokens.into_iter());
2217 let export_spec = parser.parse_root()?;
2218
2219 assert_eq!(
2220 export_spec,
2221 Some(Statement::LibraryDefinition(
2222 LibraryDefinition(
2223 library_name!("foo").into(),
2224 vec![LibraryDeclaration::Export(vec![
2225 ExportSpec::Direct("a".to_string()).into()
2226 ])
2227 .into()]
2228 )
2229 .into()
2230 ))
2231 );
2232 }
2233 {
2234 let tokens = convert_located(vec![
2235 TokenData::LeftParen,
2236 TokenData::Identifier("define-library".to_string()),
2237 TokenData::LeftParen,
2238 TokenData::Identifier("foo".to_string()),
2239 TokenData::RightParen,
2240 TokenData::LeftParen,
2241 TokenData::Identifier("export".to_string()),
2242 TokenData::LeftParen,
2243 TokenData::Identifier("rename".to_string()),
2244 TokenData::Identifier("a".to_string()),
2245 TokenData::Identifier("b".to_string()),
2246 TokenData::RightParen,
2247 TokenData::RightParen,
2248 TokenData::RightParen,
2249 ]);
2250 let mut parser = token_stream_to_parser(tokens.into_iter());
2251 let export_spec = parser.parse_root()?;
2252 assert_eq!(
2253 export_spec,
2254 Some(Statement::LibraryDefinition(
2255 LibraryDefinition(
2256 library_name!("foo").into(),
2257 vec![LibraryDeclaration::Export(vec![ExportSpec::Rename(
2258 "a".to_string(),
2259 "b".to_string()
2260 )
2261 .into()])
2262 .into()]
2263 )
2264 .into()
2265 ))
2266 );
2267 }
2268 {
2269 let tokens = convert_located(vec![
2270 TokenData::LeftParen,
2271 TokenData::Identifier("define-library".to_string()),
2272 TokenData::LeftParen,
2273 TokenData::Identifier("foo".to_string()),
2274 TokenData::RightParen,
2275 TokenData::LeftParen,
2276 TokenData::Identifier("export".to_string()),
2277 TokenData::LeftParen,
2278 TokenData::Identifier("c".to_string()),
2279 TokenData::Identifier("a".to_string()),
2280 TokenData::Identifier("b".to_string()),
2281 TokenData::RightParen,
2282 TokenData::RightParen,
2283 TokenData::RightParen,
2284 ]);
2285 let mut parser = token_stream_to_parser(tokens.into_iter());
2286 assert!(parser.parse_root().is_err());
2287 }
2288 Ok(())
2289}
2290#[test]
2291fn library_declaration() -> Result<()> {
2292 {
2293 let tokens = convert_located(vec![
2294 TokenData::LeftParen,
2295 TokenData::Identifier("define-library".to_string()),
2296 TokenData::LeftParen,
2297 TokenData::Identifier("foo".to_string()),
2298 TokenData::RightParen,
2299 TokenData::LeftParen,
2300 TokenData::Identifier("import".to_string()),
2301 TokenData::LeftParen,
2302 TokenData::Identifier("a".to_string()),
2303 TokenData::Identifier("b".to_string()),
2304 TokenData::RightParen,
2305 TokenData::RightParen,
2306 TokenData::RightParen,
2307 ]);
2308 let mut parser = token_stream_to_parser(tokens.into_iter());
2309
2310 let library_declaration = parser.parse_root()?;
2311 assert_eq!(
2312 library_declaration,
2313 Some(Statement::LibraryDefinition(
2314 LibraryDefinition(
2315 library_name!("foo").into(),
2316 vec![LibraryDeclaration::ImportDeclaration(
2317 ImportDeclaration(vec![ImportSetBody::Direct(
2318 library_name!("a", "b").no_locate()
2319 )
2320 .no_locate()])
2321 .no_locate()
2322 )
2323 .into()]
2324 )
2325 .into()
2326 ))
2327 );
2328 }
2329 {
2330 let tokens = convert_located(vec![
2331 TokenData::LeftParen,
2332 TokenData::Identifier("define-library".to_string()),
2333 TokenData::LeftParen,
2334 TokenData::Identifier("foo".to_string()),
2335 TokenData::RightParen,
2336 TokenData::LeftParen,
2337 TokenData::Identifier("export".to_string()),
2338 TokenData::Identifier("a".to_string()),
2339 TokenData::Identifier("b".to_string()),
2340 TokenData::RightParen,
2341 TokenData::RightParen,
2342 ]);
2343 let mut parser = token_stream_to_parser(tokens.into_iter());
2344 let library_declaration = parser.parse_root()?;
2345 assert_eq!(
2346 library_declaration,
2347 Some(Statement::LibraryDefinition(
2348 LibraryDefinition(
2349 library_name!("foo").into(),
2350 vec![LibraryDeclaration::Export(vec![
2351 ExportSpec::Direct("a".to_string()).no_locate(),
2352 ExportSpec::Direct("b".to_string()).no_locate()
2353 ])
2354 .into()]
2355 )
2356 .into()
2357 ))
2358 );
2359 }
2360 {
2361 let tokens = convert_located(vec![
2362 TokenData::LeftParen,
2363 TokenData::Identifier("define-library".to_string()),
2364 TokenData::LeftParen,
2365 TokenData::Identifier("foo".to_string()),
2366 TokenData::RightParen,
2367 TokenData::LeftParen,
2368 TokenData::Identifier("begin".to_string()),
2369 TokenData::LeftParen,
2370 TokenData::Identifier("define".to_string()),
2371 TokenData::Identifier("s".to_string()),
2372 TokenData::Primitive(Primitive::String("a".to_string())),
2373 TokenData::RightParen,
2374 TokenData::RightParen,
2375 TokenData::RightParen,
2376 ]);
2377 let mut parser = token_stream_to_parser(tokens.into_iter());
2378 let library_declaration = parser.parse_root()?;
2379 assert_eq!(
2380 library_declaration,
2381 Some(Statement::LibraryDefinition(
2382 LibraryDefinition(
2383 library_name!("foo").into(),
2384 vec![LibraryDeclaration::Begin(vec![Statement::Definition(
2385 DefinitionBody(
2386 "s".to_string(),
2387 ExpressionBody::Primitive(Primitive::String("a".to_string()))
2388 .no_locate()
2389 )
2390 .no_locate()
2391 )])
2392 .into()]
2393 )
2394 .into()
2395 ))
2396 );
2397 }
2398 Ok(())
2399}
2400#[test]
2414fn library() {
2415 {
2416 let tokens = convert_located(vec![
2417 TokenData::LeftParen,
2418 TokenData::Identifier("define-library".to_string()),
2419 TokenData::LeftParen,
2420 TokenData::Identifier("lib-a".to_string()),
2421 TokenData::Primitive(Primitive::Integer(0)),
2422 TokenData::Identifier("base".to_string()),
2423 TokenData::RightParen,
2424 TokenData::LeftParen,
2425 TokenData::Identifier("import".to_string()),
2426 TokenData::LeftParen,
2427 TokenData::Identifier("lib-b".to_string()),
2428 TokenData::RightParen,
2429 TokenData::RightParen,
2430 TokenData::LeftParen,
2431 TokenData::Identifier("begin".to_string()),
2432 TokenData::LeftParen,
2433 TokenData::Identifier("define".to_string()),
2434 TokenData::Identifier("c".to_string()),
2435 TokenData::Primitive(Primitive::Integer(0)),
2436 TokenData::RightParen,
2437 TokenData::LeftParen,
2438 TokenData::Identifier("define".to_string()),
2439 TokenData::Identifier("d".to_string()),
2440 TokenData::Primitive(Primitive::Integer(1)),
2441 TokenData::RightParen,
2442 TokenData::RightParen,
2443 TokenData::LeftParen,
2444 TokenData::Identifier("export".to_string()),
2445 TokenData::Identifier("c".to_string()),
2446 TokenData::LeftParen,
2447 TokenData::Identifier("rename".to_string()),
2448 TokenData::Identifier("d".to_string()),
2449 TokenData::Identifier("e".to_string()),
2450 TokenData::RightParen,
2451 TokenData::Identifier("f".to_string()),
2452 TokenData::RightParen,
2453 TokenData::LeftParen,
2454 TokenData::Identifier("begin".to_string()),
2455 TokenData::LeftParen,
2456 TokenData::Identifier("define".to_string()),
2457 TokenData::Identifier("f".to_string()),
2458 TokenData::Primitive(Primitive::Integer(2)),
2459 TokenData::RightParen,
2460 TokenData::RightParen,
2461 TokenData::RightParen,
2462 ]);
2463 let mut parser = token_stream_to_parser(tokens.into_iter());
2464 let ast = parser.parse_root();
2465
2466 assert_eq!(
2467 ast,
2468 Ok(Some(Statement::LibraryDefinition(
2469 LibraryDefinition(
2470 library_name!("lib-a", 0, "base").into(),
2471 vec![
2472 LibraryDeclaration::ImportDeclaration(
2473 ImportDeclaration(vec![ImportSetBody::Direct(
2474 LibraryName(vec![LibraryNameElement::Identifier(
2475 "lib-b".to_string()
2476 )])
2477 .into()
2478 )
2479 .into()])
2480 .no_locate()
2481 )
2482 .into(),
2483 LibraryDeclaration::Begin(vec![
2484 Statement::Definition(
2485 DefinitionBody(
2486 "c".to_string(),
2487 ExpressionBody::Primitive(Primitive::Integer(0)).into()
2488 )
2489 .into()
2490 ),
2491 Statement::Definition(
2492 DefinitionBody(
2493 "d".to_string(),
2494 ExpressionBody::Primitive(Primitive::Integer(1)).into()
2495 )
2496 .into()
2497 )
2498 ])
2499 .into(),
2500 LibraryDeclaration::Export(vec![
2501 ExportSpec::Direct("c".to_string()).into(),
2502 ExportSpec::Rename("d".to_string(), "e".to_string()).into(),
2503 ExportSpec::Direct("f".to_string()).into(),
2504 ])
2505 .into(),
2506 LibraryDeclaration::Begin(vec![Statement::Definition(
2507 DefinitionBody(
2508 "f".to_string(),
2509 ExpressionBody::Primitive(Primitive::Integer(2)).into()
2510 )
2511 .into()
2512 ),])
2513 .into()
2514 ]
2515 )
2516 .no_locate()
2517 )))
2518 )
2519 }
2520}