summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Li <li.davidm96@gmail.com>2017-11-05 21:12:44 -0500
committerDavid Li <li.davidm96@gmail.com>2017-11-05 21:12:44 -0500
commite5c6400f75029124474ee989388bf2c0abdc7e0a (patch)
treec713adc4c05559bb082375218a9eca9badffc531
parent44570e6b300961cdcf080b82e7cc1d89fc553b0a (diff)
Parse type and variable declarations
-rw-r--r--src/ast.rs73
-rw-r--r--src/semantic/translate.rs25
-rw-r--r--src/taiga.lalrpop34
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<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]*",