1mod args;
4mod expr;
5mod header;
6
7use std::fmt::{Debug, Formatter, Result as FmtResult};
8
9use gc::Gc;
10
11pub use ast::args::{Args, ArgsBindingError, ArgsConvertError};
12pub use ast::expr::Expr;
13pub use ast::header::{ModuleHeaderError, parse_module_header};
14use context::Context;
15use symbol::Symbol;
16use util::{as_list, as_shl};
17use value::Value;
18
19pub enum ConvertError<C: 'static + Context> {
21 ArgsConvertError(ArgsConvertError<C>),
23
24 InvalidBuiltin(&'static str, Gc<Value<C>>),
26
27 InvalidDecl(Gc<Value<C>>),
30
31 InvalidDef(Gc<Value<C>>),
33
34 InvalidDefn(Gc<Value<C>>),
36
37 InvalidExpr(Gc<Value<C>>),
39}
40
41impl<C: 'static + Context> Debug for ConvertError<C> {
42 fn fmt(&self, fmt: &mut Formatter) -> FmtResult {
43 match *self {
44 ConvertError::ArgsConvertError(ref err) => {
45 fmt.debug_tuple("ArgsConvertError").field(err).finish()
46 }
47 ConvertError::InvalidBuiltin(ref name, ref val) => {
48 fmt.debug_tuple("InvalidBuiltin")
49 .field(name)
50 .field(val)
51 .finish()
52 }
53 ConvertError::InvalidDecl(ref val) => {
54 fmt.debug_tuple("InvalidDecl").field(val).finish()
55 }
56 ConvertError::InvalidDef(ref val) => fmt.debug_tuple("InvalidDef").field(val).finish(),
57 ConvertError::InvalidDefn(ref val) => {
58 fmt.debug_tuple("InvalidDefn").field(val).finish()
59 }
60 ConvertError::InvalidExpr(ref val) => {
61 fmt.debug_tuple("InvalidExpr").field(val).finish()
62 }
63 }
64 }
65}
66
67impl<C: 'static + Context> From<ArgsConvertError<C>> for ConvertError<C> {
68 fn from(err: ArgsConvertError<C>) -> ConvertError<C> {
69 ConvertError::ArgsConvertError(err)
70 }
71}
72
73pub fn convert_body<C: 'static + Context>(
75 body: Vec<Gc<Value<C>>>,
76) -> Result<Vec<(Symbol, Gc<Expr<C>>)>, ConvertError<C>> {
77 body.into_iter().map(convert_decl).collect()
78}
79
80pub fn convert_decl<C: 'static + Context>(
82 value: Gc<Value<C>>,
83) -> Result<(Symbol, Gc<Expr<C>>), ConvertError<C>> {
84 let (head, mut rest) = as_shl(value.clone()).ok_or_else(|| {
85 ConvertError::InvalidDecl(value.clone())
86 })?;
87 match head.as_str() {
88 "def" => {
89 if rest.len() == 2 {
90 let value = rest.pop().unwrap();
91 let name = rest.pop().unwrap();
92 assert_eq!(rest.len(), 0);
93 if let Value::Symbol(name, _) = *name {
94 convert_expr(value).map(|expr| (name, expr))
95 } else {
96 Err(ConvertError::InvalidDef(value))
97 }
98 } else {
99 Err(ConvertError::InvalidDef(value))
100 }
101 }
102 "defn" => {
103 if rest.len() > 2 {
104 let name = if let Value::Symbol(sym, _) = *rest.remove(0) {
105 sym
106 } else {
107 return Err(ConvertError::InvalidDefn(value));
108 };
109 let args = rest.remove(0);
110 let expr = convert_fn(Some(name), args, rest)?;
111 Ok((name, expr))
112 } else {
113 Err(ConvertError::InvalidDefn(value))
114 }
115 }
116 _ => Err(ConvertError::InvalidDecl(value)),
117 }
118}
119
120pub fn convert_expr<C: 'static + Context>(
122 value: Gc<Value<C>>,
123) -> Result<Gc<Expr<C>>, ConvertError<C>> {
124 match *value.clone() {
125 Value::Cons(..) => {
126 if let Some(mut l) = as_list(value.clone()) {
127 let func = l.remove(0);
128 match *func {
129 Value::Symbol(s, _) if s.as_str() == "def" || s.as_str() == "defn" => {
130 let (n, e) = convert_decl(value)?;
131 Ok(Gc::new(Expr::Def(n, e)))
132 }
133 Value::Symbol(s, _) if s.as_str() == "fn" => {
134 if l.len() > 1 {
135 let args = l.remove(0);
136 convert_fn(None, args, l)
137 } else {
138 unimplemented!("invalid lambda: {:?}", l);
139 }
140 }
141 Value::Symbol(s, _) if s.as_str() == "if" => {
142 if l.len() == 2 {
143 let t = convert_expr(l.pop().unwrap())?;
144 let c = convert_expr(l.pop().unwrap())?;
145 let nil = Gc::new(Value::Nil(Default::default()));
146 let nil = Gc::new(Expr::Literal(nil));
147 Ok(Gc::new(Expr::If(c, t, nil)))
148 } else if l.len() == 3 {
149 let e = convert_expr(l.pop().unwrap())?;
150 let t = convert_expr(l.pop().unwrap())?;
151 let c = convert_expr(l.pop().unwrap())?;
152 Ok(Gc::new(Expr::If(c, t, e)))
153 } else {
154 Err(ConvertError::InvalidBuiltin("if".into(), value))
155 }
156 }
157 Value::Symbol(s, _) if s.as_str() == "macro-progn" || s.as_str() == "progn" => {
158 let exprs = l.into_iter().map(convert_expr).collect::<Result<_, _>>()?;
159 Ok(Gc::new(Expr::Progn(exprs)))
160 }
161 Value::Symbol(s, _) if s.as_str() == "quote" => {
162 if l.len() == 1 {
163 let value = l.pop().unwrap();
164 Ok(Gc::new(Expr::Literal(value)))
165 } else {
166 Err(ConvertError::InvalidBuiltin("quote".into(), value))
167 }
168 }
169 _ => {
170 let args = l.into_iter()
171 .map(convert_expr)
172 .collect::<Result<Vec<_>, _>>()?;
173 convert_expr(func).map(|func| Gc::new(Expr::Call(func, args)))
174 }
175 }
176 } else {
177 Err(ConvertError::InvalidExpr(value))
178 }
179 }
180 Value::Bytes(..) |
181 Value::Fixnum(..) |
182 Value::String(..) => Ok(Gc::new(Expr::Literal(value))),
183 Value::Symbol(sym, _) => Ok(Gc::new(Expr::Variable(sym))),
184 Value::Vector(ref v, _) => {
185 let v = v.iter()
186 .cloned()
187 .map(|v| convert_expr(v))
188 .collect::<Result<_, _>>()?;
189 Ok(Gc::new(Expr::Vector(v)))
190 }
191 _ => Err(ConvertError::InvalidExpr(value)),
192 }
193}
194
195pub(crate) fn convert_fn<C: 'static + Context>(
196 name: Option<Symbol>,
197 args: Gc<Value<C>>,
198 body: Vec<Gc<Value<C>>>,
199) -> Result<Gc<Expr<C>>, ConvertError<C>> {
200 let mut body = body.into_iter()
201 .map(convert_expr)
202 .collect::<Result<Vec<_>, _>>()?;
203 let tail = body.pop().unwrap();
204 let args = Args::from_value(args)?;
205 Ok(Gc::new(Expr::Lambda(name, Gc::new(args), body, tail)))
206}