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