diff options
| -rw-r--r-- | src/ast.rs | 73 | ||||
| -rw-r--r-- | src/semantic/translate.rs | 25 | ||||
| -rw-r--r-- | src/taiga.lalrpop | 34 | 
3 files changed, 105 insertions, 27 deletions
| @@ -1,3 +1,5 @@ +use std::ops::Deref; +  #[derive(Debug)]  pub struct WithLocation<T> {      pub value: T, @@ -35,6 +37,14 @@ impl<T> WithLocation<T> {      }  } +impl<T> Deref for WithLocation<T> { +    type Target = T; + +    fn deref(&self) -> &Self::Target { +        &self.value +    } +} +  #[derive(Debug)]  pub struct Program(pub Box<WithLocation<Expression>>); @@ -64,7 +74,7 @@ pub enum BinOp {  #[derive(Debug)]  pub enum Expression { -    Let(Vec<WithLocation<VarDec>>, Box<WithLocation<Expression>>), +    Let(Vec<WithLocation<Declaration>>, Box<WithLocation<Expression>>),      UnaryOp(UnaryOp, Box<WithLocation<Expression>>),      BinOp(BinOp, Box<WithLocation<Expression>>, Box<WithLocation<Expression>>),      Number(u64), @@ -74,19 +84,62 @@ pub enum Expression {  }  #[derive(Debug)] -pub struct VarDec { +pub struct RecordField { +    name: WithLocation<String>, +    ty: WithLocation<String>, +} + +impl RecordField { +    pub fn new(name: WithLocation<String>, ty: WithLocation<String>) -> RecordField { +        RecordField { name, ty } +    } +} + +#[derive(Debug)] +pub enum Ty { +    Name(String), +    Array(Box<Ty>), +    Record(Vec<WithLocation<RecordField>>), +} + +#[derive(Debug)] +pub struct Declaration {      pub name: WithLocation<String>, -    pub type_: Option<String>, -    pub value: Box<WithLocation<Expression>>, +    pub declaration: DeclarationBody, +} + +#[derive(Debug)] +pub enum DeclarationBody { +    Var { +        ty: Option<WithLocation<Ty>>, +        value: Box<WithLocation<Expression>>, +    }, +    Ty { +        ty: WithLocation<Ty>, +    }, +    Fun { +        ty: Box<WithLocation<Ty>>, +    },  } -impl VarDec { -    pub fn new(name: WithLocation<String>, type_: Option<String>, -               value: Box<WithLocation<Expression>>) -> VarDec { -        VarDec { +impl Declaration { +    pub fn new_var(name: WithLocation<String>, type_: Option<WithLocation<Ty>>, +                   value: Box<WithLocation<Expression>>) -> Declaration { +        Declaration {              name: name, -            type_: type_, -            value: value, +            declaration: DeclarationBody::Var { +                ty: type_, +                value: value, +            } +        } +    } + +    pub fn new_ty(name: WithLocation<String>, type_: WithLocation<Ty>) -> Declaration { +        Declaration { +            name: name, +            declaration: DeclarationBody::Ty { +                ty: type_, +            }          }      }  } diff --git a/src/semantic/translate.rs b/src/semantic/translate.rs index 9da6411..cf1dcf8 100644 --- a/src/semantic/translate.rs +++ b/src/semantic/translate.rs @@ -31,18 +31,19 @@ fn trans_exp<'a>(venv: &mut TypeEnvironment<'a>, exp: &WithLocation<ast::Express      match &exp.value {          &Let(ref decls, ref body) => { -            let mut new_env = TypeEnvironment::new(None); -            for decl in decls.iter() { -                let decl_ty = trans_exp(venv, &*decl.value.value)?; -                if let Some(_) = decl.value.type_ { -                    return err!(decl, TypeError::Unimplemented); -                } -                else { -                    new_env.add_binding(decl.value.name.value.clone(), decl_ty); -                } -            } -            new_env.set_parent(venv); -            trans_exp(&mut new_env, &*body) +            err!(exp, TypeError::Unimplemented) +            // let mut new_env = TypeEnvironment::new(None); +            // for decl in decls.iter() { +            //     let decl_ty = trans_exp(venv, &*decl.value.value)?; +            //     if let Some(_) = decl.value.type_ { +            //         return err!(decl, TypeError::Unimplemented); +            //     } +            //     else { +            //         new_env.add_binding(decl.name.clone(), decl_ty); +            //     } +            // } +            // new_env.set_parent(venv); +            // trans_exp(&mut new_env, &*body)          },          &UnaryOp(ref op, ref operand) => {              use ast::UnaryOp::*; diff --git a/src/taiga.lalrpop b/src/taiga.lalrpop index 851cb24..aa5e50e 100644 --- a/src/taiga.lalrpop +++ b/src/taiga.lalrpop @@ -7,17 +7,39 @@ pub Program: ast::Program = {      Expression => ast::Program(<>),  }; -VarDec: Box<WithLocation<ast::VarDec>> = +RecordFields: Vec<WithLocation<ast::RecordField>> = { +    <l: @L> <n:Name> ":" <v:Name> <r: @R> "," <rest: RecordFields> => { +        let mut rest = rest; +        rest.push(WithLocation::new(ast::RecordField::new(n, v), l, r)); +        rest +    }, +    <l: @L> <n:Name> ":" <v:Name> <r: @R> "," => vec![WithLocation::new(ast::RecordField::new(n, v), l, r)], +    <l: @L> <n:Name> ":" <v:Name> <r: @R> => vec![WithLocation::new(ast::RecordField::new(n, v), l, r)], +    "" => vec![], +}; + +Ty: WithLocation<ast::Ty> = { +    <Name> => <>.map(|v| ast::Ty::Name(v)), +    "array" "of" <Name> => <>.map(|v| ast::Ty::Array(Box::new(ast::Ty::Name(v)))), +    <l: @L> "{" <v: RecordFields> "}" <r: @R> => WithLocation::new(ast::Ty::Record(v), l, r), +}; + +Declaration: Box<WithLocation<ast::Declaration>> = { +    <l: @L> "var" <name: Name> ":" <ty: Ty> "=" <exp: Expression> <r: @R> => +        Box::new(WithLocation::new(ast::Declaration::new_var(name, Some(ty), exp), l, r)),      <l: @L> "var" <name: Name> "=" <exp: Expression> <r: @R> => -    Box::new(WithLocation::new(ast::VarDec::new(name, None, exp), l, r)); +        Box::new(WithLocation::new(ast::Declaration::new_var(name, None, exp), l, r)), +    <l: @L> "type" <name: Name> "=" <ty: Ty> <r: @R> => +        Box::new(WithLocation::new(ast::Declaration::new_ty(name, ty), l, r)), +}; -DeclarationsList: Vec<WithLocation<ast::VarDec>> = { -    <h: DeclarationsList> <t: VarDec> => { +DeclarationsList: Vec<WithLocation<ast::Declaration>> = { +    <h: DeclarationsList> <t: Declaration> => {          let mut h = h;          h.push(*t);          h      }, -    <VarDec> => vec![*<>], +    <Declaration> => vec![*<>],  };  Expression: Box<ast::WithLocation<ast::Expression>> = { @@ -121,6 +143,8 @@ match {      "let",      "in",      "end", +    "type", +    "function",  }  else {      r"[[:alpha:]_][[:alpha:]_0-9]*", | 
