From e5c6400f75029124474ee989388bf2c0abdc7e0a Mon Sep 17 00:00:00 2001 From: David Li Date: Sun, 5 Nov 2017 21:12:44 -0500 Subject: Parse type and variable declarations --- src/ast.rs | 73 ++++++++++++++++++++++++++++++++++++++++------- src/semantic/translate.rs | 25 ++++++++-------- src/taiga.lalrpop | 34 ++++++++++++++++++---- 3 files changed, 105 insertions(+), 27 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index d60edc0..d9ce406 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -1,3 +1,5 @@ +use std::ops::Deref; + #[derive(Debug)] pub struct WithLocation { pub value: T, @@ -35,6 +37,14 @@ impl WithLocation { } } +impl Deref for WithLocation { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.value + } +} + #[derive(Debug)] pub struct Program(pub Box>); @@ -64,7 +74,7 @@ pub enum BinOp { #[derive(Debug)] pub enum Expression { - Let(Vec>, Box>), + Let(Vec>, Box>), UnaryOp(UnaryOp, Box>), BinOp(BinOp, Box>, Box>), Number(u64), @@ -74,19 +84,62 @@ pub enum Expression { } #[derive(Debug)] -pub struct VarDec { +pub struct RecordField { + name: WithLocation, + ty: WithLocation, +} + +impl RecordField { + pub fn new(name: WithLocation, ty: WithLocation) -> RecordField { + RecordField { name, ty } + } +} + +#[derive(Debug)] +pub enum Ty { + Name(String), + Array(Box), + Record(Vec>), +} + +#[derive(Debug)] +pub struct Declaration { pub name: WithLocation, - pub type_: Option, - pub value: Box>, + pub declaration: DeclarationBody, +} + +#[derive(Debug)] +pub enum DeclarationBody { + Var { + ty: Option>, + value: Box>, + }, + Ty { + ty: WithLocation, + }, + Fun { + ty: Box>, + }, } -impl VarDec { - pub fn new(name: WithLocation, type_: Option, - value: Box>) -> VarDec { - VarDec { +impl Declaration { + pub fn new_var(name: WithLocation, type_: Option>, + value: Box>) -> Declaration { + Declaration { name: name, - type_: type_, - value: value, + declaration: DeclarationBody::Var { + ty: type_, + value: value, + } + } + } + + pub fn new_ty(name: WithLocation, type_: WithLocation) -> 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 { - 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> = +RecordFields: Vec> = { + ":" "," => { + let mut rest = rest; + rest.push(WithLocation::new(ast::RecordField::new(n, v), l, r)); + rest + }, + ":" "," => vec![WithLocation::new(ast::RecordField::new(n, v), l, r)], + ":" => vec![WithLocation::new(ast::RecordField::new(n, v), l, r)], + "" => vec![], +}; + +Ty: WithLocation = { + => <>.map(|v| ast::Ty::Name(v)), + "array" "of" => <>.map(|v| ast::Ty::Array(Box::new(ast::Ty::Name(v)))), + "{" "}" => WithLocation::new(ast::Ty::Record(v), l, r), +}; + +Declaration: Box> = { + "var" ":" "=" => + Box::new(WithLocation::new(ast::Declaration::new_var(name, Some(ty), exp), l, r)), "var" "=" => - 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)), + "type" "=" => + Box::new(WithLocation::new(ast::Declaration::new_ty(name, ty), l, r)), +}; -DeclarationsList: Vec> = { - => { +DeclarationsList: Vec> = { + => { let mut h = h; h.push(*t); h }, - => vec![*<>], + => vec![*<>], }; Expression: Box> = { @@ -121,6 +143,8 @@ match { "let", "in", "end", + "type", + "function", } else { r"[[:alpha:]_][[:alpha:]_0-9]*", -- cgit v1.2.3