Adding Node intermediate type to AST
This commit is contained in:
parent
87e68988c8
commit
282c42da3c
@ -4,22 +4,29 @@ use std::convert::From;
|
|||||||
use source_map::{SourceMap};
|
use source_map::{SourceMap};
|
||||||
use builtin::{BinOp, PrefixOp};
|
use builtin::{BinOp, PrefixOp};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Node<T> {
|
pub struct Node<T> {
|
||||||
n: T,
|
n: T,
|
||||||
meta: Meta
|
meta: Meta
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Node<T> {
|
impl<T> Node<T> {
|
||||||
fn node(&self) -> &T {
|
pub fn new(n: T) -> Node<T> {
|
||||||
|
Node { n, meta: Meta::default() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn node(&self) -> &T {
|
||||||
&self.n
|
&self.n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO this PartialEq is here to make tests work - find a way to make it not necessary
|
||||||
|
#[derive(Clone, Debug, Default, PartialEq)]
|
||||||
struct Meta {
|
struct Meta {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct AST(pub Vec<Statement>);
|
pub struct AST(pub Vec<Node<Statement>>);
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum Statement {
|
pub enum Statement {
|
||||||
@ -27,7 +34,7 @@ pub enum Statement {
|
|||||||
Declaration(Declaration),
|
Declaration(Declaration),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Block = Vec<Statement>;
|
pub type Block = Vec<Node<Statement>>;
|
||||||
pub type ParamName = Rc<String>;
|
pub type ParamName = Rc<String>;
|
||||||
pub type InterfaceName = Rc<String>; //should be a singleton I think??
|
pub type InterfaceName = Rc<String>; //should be a singleton I think??
|
||||||
pub type FormalParam = (ParamName, Option<TypeIdentifier>);
|
pub type FormalParam = (ParamName, Option<TypeIdentifier>);
|
||||||
|
@ -304,7 +304,9 @@ impl Parser {
|
|||||||
self.next();
|
self.next();
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
_ => statements.push(self.statement()?),
|
_ => statements.push(
|
||||||
|
Node::new(self.statement()?)
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(AST(statements))
|
Ok(AST(statements))
|
||||||
@ -428,8 +430,9 @@ impl Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
fn nonempty_func_body(&mut self) -> ParseResult<Vec<Statement>> {
|
fn nonempty_func_body(&mut self) -> ParseResult<Vec<Node<Statement>>> {
|
||||||
Ok(delimited!(self, LCurlyBrace, statement, Newline | Semicolon, RCurlyBrace, nonstrict))
|
let statements = delimited!(self, LCurlyBrace, statement, Newline | Semicolon, RCurlyBrace, nonstrict);
|
||||||
|
Ok(statements.into_iter().map(|s| Node::new(s)).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
@ -908,7 +911,8 @@ impl Parser {
|
|||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
fn block(&mut self) -> ParseResult<Block> {
|
fn block(&mut self) -> ParseResult<Block> {
|
||||||
Ok(delimited!(self, LCurlyBrace, statement, Newline | Semicolon, RCurlyBrace, nonstrict))
|
let block = delimited!(self, LCurlyBrace, statement, Newline | Semicolon, RCurlyBrace, nonstrict);
|
||||||
|
Ok(block.into_iter().map(|s| { Node::new(s) }).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
@ -917,7 +921,7 @@ impl Parser {
|
|||||||
LCurlyBrace => self.block(),
|
LCurlyBrace => self.block(),
|
||||||
_ => {
|
_ => {
|
||||||
let expr = self.expression()?;
|
let expr = self.expression()?;
|
||||||
Ok(vec![Statement::ExpressionStatement(expr)])
|
Ok(vec![Node::new(Statement::ExpressionStatement(expr))])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -976,7 +980,7 @@ impl Parser {
|
|||||||
Ok(match self.peek() {
|
Ok(match self.peek() {
|
||||||
LCurlyBrace => {
|
LCurlyBrace => {
|
||||||
let statements = delimited!(self, LCurlyBrace, statement, Newline | Semicolon, RCurlyBrace, nonstrict);
|
let statements = delimited!(self, LCurlyBrace, statement, Newline | Semicolon, RCurlyBrace, nonstrict);
|
||||||
StatementBlock(statements)
|
StatementBlock(statements.into_iter().map(|s| Node::new(s)).collect())
|
||||||
},
|
},
|
||||||
Keyword(Kw::Return) => {
|
Keyword(Kw::Return) => {
|
||||||
self.next();
|
self.next();
|
||||||
@ -1115,7 +1119,7 @@ mod parse_tests {
|
|||||||
use super::tokenize;
|
use super::tokenize;
|
||||||
use super::ParseResult;
|
use super::ParseResult;
|
||||||
use builtin::{PrefixOp, BinOp};
|
use builtin::{PrefixOp, BinOp};
|
||||||
use ast::{AST, Expression, Statement, IfExpressionBody, Discriminator, Pattern, PatternLiteral, TypeBody, Enumerator, ForBody};
|
use ast::{AST, Node, Expression, Statement, IfExpressionBody, Discriminator, Pattern, PatternLiteral, TypeBody, Enumerator, ForBody};
|
||||||
use super::Statement::*;
|
use super::Statement::*;
|
||||||
use super::Declaration::*;
|
use super::Declaration::*;
|
||||||
use super::Signature;
|
use super::Signature;
|
||||||
@ -1171,14 +1175,14 @@ mod parse_tests {
|
|||||||
($op:expr, $lhs:expr) => { PrefixExp(PrefixOp::from_sigil($op), bx!(Expression($lhs, None))) }
|
($op:expr, $lhs:expr) => { PrefixExp(PrefixOp::from_sigil($op), bx!(Expression($lhs, None))) }
|
||||||
}
|
}
|
||||||
macro_rules! exst {
|
macro_rules! exst {
|
||||||
($expr_type:expr) => { Statement::ExpressionStatement(Expression($expr_type, None)) };
|
($expr_type:expr) => { Node::new(Statement::ExpressionStatement(Expression($expr_type, None))) };
|
||||||
($expr_type:expr, $type_anno:expr) => { Statement::ExpressionStatement(Expression($expr_type, Some($type_anno))) };
|
($expr_type:expr, $type_anno:expr) => { Node::new(Statement::ExpressionStatement(Expression($expr_type, Some($type_anno)))) };
|
||||||
($op:expr, $lhs:expr, $rhs:expr) => { Statement::ExpressionStatement(ex!(binexp!($op, $lhs, $rhs))) };
|
($op:expr, $lhs:expr, $rhs:expr) => { Node::new(Statement::ExpressionStatement(ex!(binexp!($op, $lhs, $rhs)))) };
|
||||||
(s $statement_text:expr) => {
|
(s $statement_text:expr) => {
|
||||||
{
|
{
|
||||||
let tokens: Vec<::tokenizing::Token> = tokenize($statement_text);
|
let tokens: Vec<::tokenizing::Token> = tokenize($statement_text);
|
||||||
let mut parser = super::Parser::new(tokens);
|
let mut parser = super::Parser::new(tokens);
|
||||||
parser.statement().unwrap()
|
Node::new(parser.statement().unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1274,7 +1278,7 @@ mod parse_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parsing_functions() {
|
fn parsing_functions() {
|
||||||
parse_test!("fn oi()", AST(vec![Declaration(FuncSig(Signature { name: rc!(oi), operator: false, params: vec![], type_anno: None }))]));
|
parse_test!("fn oi()", AST(vec![Node::new(Declaration(FuncSig(Signature { name: rc!(oi), operator: false, params: vec![], type_anno: None })))]));
|
||||||
parse_test!("oi()", AST(vec![exst!(Call { f: bx!(ex!(val!("oi"))), arguments: vec![] })]));
|
parse_test!("oi()", AST(vec![exst!(Call { f: bx!(ex!(val!("oi"))), arguments: vec![] })]));
|
||||||
parse_test!("oi(a, 2 + 2)", AST(vec![exst!(Call
|
parse_test!("oi(a, 2 + 2)", AST(vec![exst!(Call
|
||||||
{ f: bx!(ex!(val!("oi"))),
|
{ f: bx!(ex!(val!("oi"))),
|
||||||
@ -1282,27 +1286,27 @@ mod parse_tests {
|
|||||||
})]));
|
})]));
|
||||||
parse_error!("a(b,,c)");
|
parse_error!("a(b,,c)");
|
||||||
|
|
||||||
parse_test!("fn a(b, c: Int): Int", AST(vec![Declaration(
|
parse_test!("fn a(b, c: Int): Int", AST(vec![Node::new(Declaration(
|
||||||
FuncSig(Signature { name: rc!(a), operator: false, params: vec![
|
FuncSig(Signature { name: rc!(a), operator: false, params: vec![
|
||||||
(rc!(b), None), (rc!(c), Some(ty!("Int")))
|
(rc!(b), None), (rc!(c), Some(ty!("Int")))
|
||||||
], type_anno: Some(ty!("Int")) }))]));
|
], type_anno: Some(ty!("Int")) })))]));
|
||||||
|
|
||||||
|
|
||||||
parse_test!("fn a(x) { x() }", AST(vec![Declaration(
|
parse_test!("fn a(x) { x() }", AST(vec![Node::new(Declaration(
|
||||||
FuncDecl(Signature { name: rc!(a), operator: false, params: vec![(rc!(x),None)], type_anno: None },
|
FuncDecl(Signature { name: rc!(a), operator: false, params: vec![(rc!(x),None)], type_anno: None },
|
||||||
vec![exst!(Call { f: bx!(ex!(val!("x"))), arguments: vec![] })]))]));
|
vec![exst!(Call { f: bx!(ex!(val!("x"))), arguments: vec![] })])))]));
|
||||||
parse_test!("fn a(x) {\n x() }", AST(vec![Declaration(
|
parse_test!("fn a(x) {\n x() }", AST(vec![Node::new(Declaration(
|
||||||
FuncDecl(Signature { name: rc!(a), operator: false, params: vec![(rc!(x),None)], type_anno: None },
|
FuncDecl(Signature { name: rc!(a), operator: false, params: vec![(rc!(x),None)], type_anno: None },
|
||||||
vec![exst!(Call { f: bx!(ex!(val!("x"))), arguments: vec![] })]))]));
|
vec![exst!(Call { f: bx!(ex!(val!("x"))), arguments: vec![] })])))]));
|
||||||
|
|
||||||
let multiline = r#"
|
let multiline = r#"
|
||||||
fn a(x) {
|
fn a(x) {
|
||||||
x()
|
x()
|
||||||
}
|
}
|
||||||
"#;
|
"#;
|
||||||
parse_test!(multiline, AST(vec![Declaration(
|
parse_test!(multiline, AST(vec![Node::new(Declaration(
|
||||||
FuncDecl(Signature { name: rc!(a), operator: false, params: vec![(rc!(x),None)], type_anno: None },
|
FuncDecl(Signature { name: rc!(a), operator: false, params: vec![(rc!(x),None)], type_anno: None },
|
||||||
vec![exst!(Call { f: bx!(ex!(val!("x"))), arguments: vec![] })]))]));
|
vec![exst!(Call { f: bx!(ex!(val!("x"))), arguments: vec![] })])))]));
|
||||||
let multiline2 = r#"
|
let multiline2 = r#"
|
||||||
fn a(x) {
|
fn a(x) {
|
||||||
|
|
||||||
@ -1310,9 +1314,9 @@ fn a(x) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
"#;
|
"#;
|
||||||
parse_test!(multiline2, AST(vec![Declaration(
|
parse_test!(multiline2, AST(vec![Node::new(Declaration(
|
||||||
FuncDecl(Signature { name: rc!(a), operator: false, params: vec![(rc!(x),None)], type_anno: None },
|
FuncDecl(Signature { name: rc!(a), operator: false, params: vec![(rc!(x),None)], type_anno: None },
|
||||||
vec![exst!(s "x()")]))]));
|
vec![exst!(s "x()")])))]));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1328,11 +1332,11 @@ fn a(x) {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parsing_types() {
|
fn parsing_types() {
|
||||||
parse_test!("type Yolo = Yolo", AST(vec![Declaration(TypeDecl { name: tys!("Yolo"), body: TypeBody(vec![UnitStruct(rc!(Yolo))]), mutable: false} )]));
|
parse_test!("type Yolo = Yolo", AST(vec![Node::new(Declaration(TypeDecl { name: tys!("Yolo"), body: TypeBody(vec![UnitStruct(rc!(Yolo))]), mutable: false} ))]));
|
||||||
parse_test!("type mut Yolo = Yolo", AST(vec![Declaration(TypeDecl { name: tys!("Yolo"), body: TypeBody(vec![UnitStruct(rc!(Yolo))]), mutable: true} )]));
|
parse_test!("type mut Yolo = Yolo", AST(vec![Node::new(Declaration(TypeDecl { name: tys!("Yolo"), body: TypeBody(vec![UnitStruct(rc!(Yolo))]), mutable: true} ))]));
|
||||||
parse_test!("type alias Sex = Drugs", AST(vec![Declaration(TypeAlias(rc!(Sex), rc!(Drugs)))]));
|
parse_test!("type alias Sex = Drugs", AST(vec![Node::new(Declaration(TypeAlias(rc!(Sex), rc!(Drugs))))]));
|
||||||
parse_test!("type Sanchez = Miguel | Alejandro(Int, Option<a>) | Esperanza { a: Int, b: String }",
|
parse_test!("type Sanchez = Miguel | Alejandro(Int, Option<a>) | Esperanza { a: Int, b: String }",
|
||||||
AST(vec![Declaration(TypeDecl{
|
AST(vec![Node::new(Declaration(TypeDecl{
|
||||||
name: tys!("Sanchez"),
|
name: tys!("Sanchez"),
|
||||||
body: TypeBody(vec![
|
body: TypeBody(vec![
|
||||||
UnitStruct(rc!(Miguel)),
|
UnitStruct(rc!(Miguel)),
|
||||||
@ -1346,21 +1350,21 @@ fn a(x) {
|
|||||||
])
|
])
|
||||||
]),
|
]),
|
||||||
mutable: false
|
mutable: false
|
||||||
})]));
|
}))]));
|
||||||
|
|
||||||
parse_test!("type Jorge<a> = Diego | Kike(a)", AST(vec![
|
parse_test!("type Jorge<a> = Diego | Kike(a)", AST(vec![
|
||||||
Declaration(TypeDecl{
|
Node::new(Declaration(TypeDecl{
|
||||||
name: TypeSingletonName { name: rc!(Jorge), params: vec![Singleton(TypeSingletonName { name: rc!(a), params: vec![] })] },
|
name: TypeSingletonName { name: rc!(Jorge), params: vec![Singleton(TypeSingletonName { name: rc!(a), params: vec![] })] },
|
||||||
body: TypeBody(vec![UnitStruct(rc!(Diego)), TupleStruct(rc!(Kike), vec![Singleton(TypeSingletonName { name: rc!(a), params: vec![] })])]),
|
body: TypeBody(vec![UnitStruct(rc!(Diego)), TupleStruct(rc!(Kike), vec![Singleton(TypeSingletonName { name: rc!(a), params: vec![] })])]),
|
||||||
mutable: false
|
mutable: false
|
||||||
}
|
}
|
||||||
)]));
|
))]));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parsing_bindings() {
|
fn parsing_bindings() {
|
||||||
parse_test!("let mut a = 10", AST(vec![Declaration(Binding { name: rc!(a), constant: false, expr: ex!(NatLiteral(10)) } )]));
|
parse_test!("let mut a = 10", AST(vec![Node::new(Declaration(Binding { name: rc!(a), constant: false, expr: ex!(NatLiteral(10)) } ))]));
|
||||||
parse_test!("let a = 2 + 2", AST(vec![Declaration(Binding { name: rc!(a), constant: true, expr: ex!(binexp!("+", NatLiteral(2), NatLiteral(2))) }) ]));
|
parse_test!("let a = 2 + 2", AST(vec![Node::new(Declaration(Binding { name: rc!(a), constant: true, expr: ex!(binexp!("+", NatLiteral(2), NatLiteral(2))) }) )]));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1434,50 +1438,53 @@ fn a(x) {
|
|||||||
#[test]
|
#[test]
|
||||||
fn parsing_interfaces() {
|
fn parsing_interfaces() {
|
||||||
parse_test!("interface Unglueable { fn unglue(a: Glue); fn mar(): Glue }", AST(vec![
|
parse_test!("interface Unglueable { fn unglue(a: Glue); fn mar(): Glue }", AST(vec![
|
||||||
Declaration(Interface {
|
Node::new(Declaration(Interface {
|
||||||
name: rc!(Unglueable),
|
name: rc!(Unglueable),
|
||||||
signatures: vec![
|
signatures: vec![
|
||||||
Signature { name: rc!(unglue), operator: false, params: vec![(rc!(a), Some(Singleton(TypeSingletonName { name: rc!(Glue), params: vec![] })))], type_anno: None },
|
Signature { name: rc!(unglue), operator: false, params: vec![(rc!(a), Some(Singleton(TypeSingletonName { name: rc!(Glue), params: vec![] })))], type_anno: None },
|
||||||
Signature { name: rc!(mar), operator: false, params: vec![], type_anno: Some(Singleton(TypeSingletonName { name: rc!(Glue), params: vec![] })) },
|
Signature { name: rc!(mar), operator: false, params: vec![], type_anno: Some(Singleton(TypeSingletonName { name: rc!(Glue), params: vec![] })) },
|
||||||
]
|
]
|
||||||
})
|
}))
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parsing_impls() {
|
fn parsing_impls() {
|
||||||
parse_test!("impl Heh { fn yolo(); fn swagg(); }", AST(vec![
|
parse_test!("impl Heh { fn yolo(); fn swagg(); }", AST(vec![
|
||||||
|
Node::new(
|
||||||
Declaration(Impl {
|
Declaration(Impl {
|
||||||
type_name: ty!("Heh"),
|
type_name: ty!("Heh"),
|
||||||
interface_name: None,
|
interface_name: None,
|
||||||
block: vec![
|
block: vec![
|
||||||
FuncSig(Signature { name: rc!(yolo), operator: false, params: vec![], type_anno: None }),
|
FuncSig(Signature { name: rc!(yolo), operator: false, params: vec![], type_anno: None }),
|
||||||
FuncSig(Signature { name: rc!(swagg), operator: false, params: vec![], type_anno: None })
|
FuncSig(Signature { name: rc!(swagg), operator: false, params: vec![], type_anno: None })
|
||||||
] })]));
|
] }))]));
|
||||||
|
|
||||||
parse_test!("impl Mondai for Lollerino { fn yolo(); fn swagg(); }", AST(vec![
|
parse_test!("impl Mondai for Lollerino { fn yolo(); fn swagg(); }", AST(vec![
|
||||||
Declaration(Impl {
|
Node::new(Declaration(Impl {
|
||||||
type_name: ty!("Lollerino"),
|
type_name: ty!("Lollerino"),
|
||||||
interface_name: Some(rc!(Mondai)),
|
interface_name: Some(rc!(Mondai)),
|
||||||
block: vec![
|
block: vec![
|
||||||
FuncSig(Signature { name: rc!(yolo), operator: false, params: vec![], type_anno: None}),
|
FuncSig(Signature { name: rc!(yolo), operator: false, params: vec![], type_anno: None}),
|
||||||
FuncSig(Signature { name: rc!(swagg), operator: false, params: vec![], type_anno: None })
|
FuncSig(Signature { name: rc!(swagg), operator: false, params: vec![], type_anno: None })
|
||||||
] })]));
|
] }))]));
|
||||||
parse_test!("impl Option<WTFMate> { fn oi() }", AST(vec![
|
parse_test!("impl Option<WTFMate> { fn oi() }", AST(vec![
|
||||||
|
Node::new(
|
||||||
Declaration(Impl {
|
Declaration(Impl {
|
||||||
type_name: Singleton(TypeSingletonName { name: rc!(Option), params: vec![ty!("WTFMate")]}),
|
type_name: Singleton(TypeSingletonName { name: rc!(Option), params: vec![ty!("WTFMate")]}),
|
||||||
interface_name: None,
|
interface_name: None,
|
||||||
block: vec![
|
block: vec![
|
||||||
FuncSig(Signature { name: rc!(oi), operator: false, params: vec![], type_anno: None }),
|
FuncSig(Signature { name: rc!(oi), operator: false, params: vec![], type_anno: None }),
|
||||||
]
|
]
|
||||||
})]));
|
}))]));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parsing_type_annotations() {
|
fn parsing_type_annotations() {
|
||||||
parse_test!("let a = b : Int", AST(vec![
|
parse_test!("let a = b : Int", AST(vec![
|
||||||
|
Node::new(
|
||||||
Declaration(Binding { name: rc!(a), constant: true, expr:
|
Declaration(Binding { name: rc!(a), constant: true, expr:
|
||||||
Expression(val!("b"), Some(ty!("Int"))) })]));
|
Expression(val!("b"), Some(ty!("Int"))) }))]));
|
||||||
|
|
||||||
parse_test!("a : Int", AST(vec![
|
parse_test!("a : Int", AST(vec![
|
||||||
exst!(val!("a"), ty!("Int"))
|
exst!(val!("a"), ty!("Int"))
|
||||||
|
@ -98,7 +98,7 @@ impl AST {
|
|||||||
pub fn reduce(&self, symbol_table: &SymbolTable) -> ReducedAST {
|
pub fn reduce(&self, symbol_table: &SymbolTable) -> ReducedAST {
|
||||||
let mut output = vec![];
|
let mut output = vec![];
|
||||||
for statement in self.0.iter() {
|
for statement in self.0.iter() {
|
||||||
output.push(statement.reduce(symbol_table));
|
output.push(statement.node().reduce(symbol_table));
|
||||||
}
|
}
|
||||||
ReducedAST(output)
|
ReducedAST(output)
|
||||||
}
|
}
|
||||||
@ -114,6 +114,10 @@ impl Statement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn reduce_block(block: &Block, symbol_table: &SymbolTable) -> Vec<Stmt> {
|
||||||
|
block.iter().map(|stmt| stmt.node().reduce(symbol_table)).collect()
|
||||||
|
}
|
||||||
|
|
||||||
impl Expression {
|
impl Expression {
|
||||||
fn reduce(&self, symbol_table: &SymbolTable) -> Expr {
|
fn reduce(&self, symbol_table: &SymbolTable) -> Expr {
|
||||||
use ast::ExpressionType::*;
|
use ast::ExpressionType::*;
|
||||||
@ -154,7 +158,7 @@ fn reduce_lambda(params: &Vec<FormalParam>, body: &Block, symbol_table: &SymbolT
|
|||||||
Expr::Func(Func::UserDefined {
|
Expr::Func(Func::UserDefined {
|
||||||
name: None,
|
name: None,
|
||||||
params: params.iter().map(|param| param.0.clone()).collect(),
|
params: params.iter().map(|param| param.0.clone()).collect(),
|
||||||
body: body.iter().map(|stmt| stmt.reduce(symbol_table)).collect(),
|
body: reduce_block(body, symbol_table),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,18 +169,18 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody,
|
|||||||
});
|
});
|
||||||
match *body {
|
match *body {
|
||||||
IfExpressionBody::SimpleConditional(ref then_clause, ref else_clause) => {
|
IfExpressionBody::SimpleConditional(ref then_clause, ref else_clause) => {
|
||||||
let then_clause = then_clause.iter().map(|expr| expr.reduce(symbol_table)).collect();
|
let then_clause = reduce_block(then_clause, symbol_table);
|
||||||
let else_clause = match else_clause {
|
let else_clause = match else_clause {
|
||||||
None => vec![],
|
None => vec![],
|
||||||
Some(stmts) => stmts.iter().map(|expr| expr.reduce(symbol_table)).collect(),
|
Some(stmts) => reduce_block(stmts, symbol_table),
|
||||||
};
|
};
|
||||||
Expr::Conditional { cond, then_clause, else_clause }
|
Expr::Conditional { cond, then_clause, else_clause }
|
||||||
},
|
},
|
||||||
IfExpressionBody::SimplePatternMatch(ref pat, ref then_clause, ref else_clause) => {
|
IfExpressionBody::SimplePatternMatch(ref pat, ref then_clause, ref else_clause) => {
|
||||||
let then_clause = then_clause.iter().map(|expr| expr.reduce(symbol_table)).collect();
|
let then_clause = reduce_block(then_clause, symbol_table);
|
||||||
let else_clause = match else_clause {
|
let else_clause = match else_clause {
|
||||||
None => vec![],
|
None => vec![],
|
||||||
Some(stmts) => stmts.iter().map(|expr| expr.reduce(symbol_table)).collect(),
|
Some(stmts) => reduce_block(stmts, symbol_table),
|
||||||
};
|
};
|
||||||
|
|
||||||
let alternatives = vec![
|
let alternatives = vec![
|
||||||
@ -200,7 +204,7 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody,
|
|||||||
for arm in guard_arms {
|
for arm in guard_arms {
|
||||||
match arm.guard {
|
match arm.guard {
|
||||||
Guard::Pat(ref p) => {
|
Guard::Pat(ref p) => {
|
||||||
let item = arm.body.iter().map(|expr| expr.reduce(symbol_table)).collect();
|
let item = reduce_block(&arm.body, symbol_table);
|
||||||
let alt = p.to_alternative(item, symbol_table);
|
let alt = p.to_alternative(item, symbol_table);
|
||||||
alternatives.push(alt);
|
alternatives.push(alt);
|
||||||
},
|
},
|
||||||
@ -360,7 +364,7 @@ impl Declaration {
|
|||||||
func: Func::UserDefined {
|
func: Func::UserDefined {
|
||||||
name: Some(name.clone()),
|
name: Some(name.clone()),
|
||||||
params: params.iter().map(|param| param.0.clone()).collect(),
|
params: params.iter().map(|param| param.0.clone()).collect(),
|
||||||
body: statements.iter().map(|stmt| stmt.reduce(symbol_table)).collect(),
|
body: reduce_block(&statements, symbol_table),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
TypeDecl { .. } => Stmt::Noop,
|
TypeDecl { .. } => Stmt::Noop,
|
||||||
|
@ -62,6 +62,7 @@ impl SymbolTable {
|
|||||||
use self::ast::{Statement, TypeIdentifier, Variant, TypeSingletonName, TypeBody};
|
use self::ast::{Statement, TypeIdentifier, Variant, TypeSingletonName, TypeBody};
|
||||||
use self::ast::Declaration::*;
|
use self::ast::Declaration::*;
|
||||||
for statement in ast.0.iter() {
|
for statement in ast.0.iter() {
|
||||||
|
let statement = statement.node();
|
||||||
if let Statement::Declaration(decl) = statement {
|
if let Statement::Declaration(decl) = statement {
|
||||||
match decl {
|
match decl {
|
||||||
FuncSig(signature) | FuncDecl(signature, _) => {
|
FuncSig(signature) | FuncDecl(signature, _) => {
|
||||||
|
@ -208,7 +208,7 @@ impl<'a> TypeContext<'a> {
|
|||||||
fn infer_block(&mut self, block: &Block) -> InferResult<Type<UVar>> {
|
fn infer_block(&mut self, block: &Block) -> InferResult<Type<UVar>> {
|
||||||
let mut output = Type::Const(TConst::Unit);
|
let mut output = Type::Const(TConst::Unit);
|
||||||
for statement in block.iter() {
|
for statement in block.iter() {
|
||||||
output = self.infer_statement(statement)?;
|
output = self.infer_statement(statement.node())?;
|
||||||
}
|
}
|
||||||
Ok(output)
|
Ok(output)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user