use std::rc::Rc; use crate::ast::*; use crate::ast::visitor::ASTVisitor; use std::ops::Deref; pub fn ast(v: &mut V, ast: &AST) { v.block(&ast.statements); } pub fn block(v: &mut V, block: &Vec) { for statement in block { v.statement(statement); } } pub fn statement(v: &mut V, statement: &Statement) { use StatementKind::*; match statement.kind { Expression(ref expr) => v.expression(expr), Declaration(ref decl) => v.declaration(decl), Import(ref import_spec) => v.import(import_spec), } } pub fn declaration(v: &mut V, decl: &Declaration) { use Declaration::*; match decl { FuncSig(sig) => { v.signature(&sig); }, FuncDecl(sig, block) => { v.signature(&sig); v.block(&block); }, TypeDecl { .. } => unimplemented!(), TypeAlias(_, _) => unimplemented!(), Binding { name, constant, type_anno, expr } => { v.binding(name, *constant, type_anno.as_ref(), expr); }, /* Impl { type_name: TypeIdentifier, interface_name: Option, block: Vec, }, Interface { name: Rc, signatures: Vec } */ _ => (), } } pub fn expression(v: &mut V, expression: &Expression) { v.expression_kind(&expression.kind); v.maybe_type_identifier(expression.type_anno.as_ref()); } pub fn maybe_type_identifier(v: &mut V, maybe_ty_identifier: Option<&TypeIdentifier>) { } pub fn call(v: &mut V, f: &Expression, args: &Vec) { v.expression(f); for arg in args.iter() { v.invocation_argument(arg); } } pub fn index(v: &mut V, indexee: &Expression, indexers: &Vec) { v.expression(indexee); for i in indexers.iter() { v.expression(i); } } pub fn named_struct(v: &mut V, n: &QualifiedName, fields: &Vec<(Rc, Expression)>) { v.qualified_name(n); for (_, expr) in fields.iter() { v.expression(expr); } } pub fn lambda(v: &mut V, params: &Vec, type_anno: Option<&TypeIdentifier>, body: &Block) { for param in params { v.formal_param(param); } type_anno.map(|anno| v.type_anno(anno)); v.block(body); } pub fn formal_param(v: &mut V, param: &FormalParam) { param.default.as_ref().map(|p| v.expression(p)); param.anno.as_ref().map(|a| v.type_anno(a)); } pub fn expression_kind(v: &mut V, expression_kind: &ExpressionKind) { use ExpressionKind::*; match expression_kind { NatLiteral(n) => v.nat_literal(*n), FloatLiteral(f) => v.float_literal(*f), StringLiteral(s) => v.string_literal(s), BoolLiteral(b) => v.bool_literal(*b), BinExp(op, lhs, rhs) => v.binexp(op, lhs, rhs), PrefixExp(op, arg) => v.prefix_exp(op, arg), TupleLiteral(exprs) => { for expr in exprs { v.expression(expr); } }, Value(name) => v.qualified_name(name), NamedStruct { name, fields } => v.named_struct(name, fields), Call { f, arguments } => v.call(f, arguments), Index { indexee, indexers } => v.index(indexee, indexers), IfExpression { discriminator, body } => v.if_expression(discriminator, body), WhileExpression { condition, body } => v.while_expression(condition.as_ref().map(|b: &Box| Deref::deref(b)), body), ForExpression { enumerators, body } => v.for_expression(enumerators, body), Lambda { params , type_anno, body } => v.lambda(params, type_anno.as_ref(), body), ListLiteral(exprs) => { for expr in exprs { v.expression(expr); } }, } }