summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.rs4
-rw-r--r--src/semantic/analysis.rs61
-rw-r--r--src/semantic/ir.rs3
-rw-r--r--src/semantic/translate.rs27
4 files changed, 71 insertions, 24 deletions
diff --git a/src/main.rs b/src/main.rs
index 0579fc8..a8114ac 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -13,6 +13,7 @@ fn main() {
let stdin = io::stdin();
let mut handle = stdin.lock();
loop {
+ let mut translate = semantic::translate::Translate::new();
let mut input = String::new();
print!("taiga> ");
io::stdout().flush().unwrap();
@@ -21,7 +22,8 @@ fn main() {
let program = taiga::parse_Program(&input);
println!("{:?}", program);
if let Ok(program) = program {
- println!("{:?}", semantic::analysis::translate(&program));
+ let result = semantic::analysis::translate(&mut translate, &program);
+ println!("{:?}", result);
}
}
else {
diff --git a/src/semantic/analysis.rs b/src/semantic/analysis.rs
index 21a9eb8..edc229f 100644
--- a/src/semantic/analysis.rs
+++ b/src/semantic/analysis.rs
@@ -5,6 +5,7 @@
use ::ast::{self, WithLocation};
use super::environment;
+use super::translate::{self, Translate};
use super::types::{self, Ty};
#[derive(Debug)]
@@ -22,14 +23,15 @@ pub enum TypeError {
}
type TypeEnvironment<'a> = environment::Environment<'a, String, Ty>;
-pub type Result = ::std::result::Result<Ty, WithLocation<TypeError>>;
+pub type Result<T> = ::std::result::Result<T, WithLocation<TypeError>>;
-pub fn translate(program: &ast::Program) -> Result {
+pub fn translate(translate: &mut Translate, program: &ast::Program)
+ -> Result<(translate::Expression, Ty)> {
let mut venv = TypeEnvironment::new(None);
let mut tenv = TypeEnvironment::new(None);
tenv.add_binding("int".into(), Ty::Int);
tenv.add_binding("string".into(), Ty::String);
- trans_exp(&mut venv, &mut tenv, &*program.0)
+ trans_exp(translate, &mut venv, &mut tenv, &*program.0)
}
macro_rules! err {
@@ -41,7 +43,7 @@ macro_rules! err {
fn trans_ty<'a>(
venv: &mut TypeEnvironment<'a>,
tenv: &mut TypeEnvironment<'a>,
- ty: &WithLocation<ast::Ty>) -> Result {
+ ty: &WithLocation<ast::Ty>) -> Result<Ty> {
match ty.value {
ast::Ty::Name(ref name) => {
tenv.lookup(&name)
@@ -64,9 +66,10 @@ fn trans_ty<'a>(
}
fn trans_decl<'a>(
+ tr: &mut Translate,
venv: &mut TypeEnvironment<'a>,
tenv: &mut TypeEnvironment<'a>,
- decl: &WithLocation<ast::Declaration>) -> Result {
+ decl: &WithLocation<ast::Declaration>) -> Result<Ty> {
match decl.declaration {
ast::DeclarationBody::Fun { ref ty, ref params, ref body } => {
let declared_ty = if let &Some(ref ty) = ty {
@@ -82,7 +85,8 @@ fn trans_decl<'a>(
new_venv.add_binding(param.name.value.clone(), arg_ty);
}
- let body_ty = trans_exp(&mut new_venv, &mut new_tenv, &*body)?;
+ let (body_exp, body_ty) =
+ trans_exp(tr, &mut new_venv, &mut new_tenv, &*body)?;
if let Some(decl_ty) = declared_ty {
if &decl_ty.value != &body_ty {
@@ -99,7 +103,8 @@ fn trans_decl<'a>(
trans_ty(venv, tenv, ty)
}
ast::DeclarationBody::Var { ref ty, ref value } => {
- let actual_ty = trans_exp(venv, tenv, &value)?;
+ let (var_exp, actual_ty) =
+ trans_exp(tr, venv, tenv, &value)?;
if let &Some(ref ty) = ty {
let decl_ty = trans_ty(venv, tenv, &ty)?;
if decl_ty != actual_ty {
@@ -115,9 +120,11 @@ fn trans_decl<'a>(
}
fn trans_exp<'a>(
+ tr: &mut Translate,
venv: &mut TypeEnvironment<'a>,
tenv: &mut TypeEnvironment<'a>,
- exp: &WithLocation<ast::Expression>) -> Result {
+ exp: &WithLocation<ast::Expression>)
+ -> Result<(translate::Expression, Ty)> {
use ast::Expression::*;
match &exp.value {
@@ -125,7 +132,7 @@ fn trans_exp<'a>(
let mut new_venv = TypeEnvironment::new(Some(venv));
let mut new_tenv = TypeEnvironment::new(Some(tenv));
for decl in decls.iter() {
- let decl_ty = trans_decl(&mut new_venv, &mut new_tenv, decl)?;
+ let decl_ty = trans_decl(tr, &mut new_venv, &mut new_tenv, decl)?;
match decl.declaration {
ast::DeclarationBody::Fun { .. } | ast::DeclarationBody::Var { .. } => {
new_venv.add_binding(decl.name.clone(), decl_ty);
@@ -135,12 +142,12 @@ fn trans_exp<'a>(
}
}
}
- trans_exp(&mut new_venv, &mut new_tenv, &*body)
+ trans_exp(tr, &mut new_venv, &mut new_tenv, &*body)
},
&Call(ref name, ref args) => {
let mut arg_types = vec![];
for arg in args {
- arg_types.push(trans_exp(venv, tenv, arg)?);
+ arg_types.push(trans_exp(tr, venv, tenv, arg)?);
}
let fun_ty = venv.lookup(name)
@@ -154,7 +161,7 @@ fn trans_exp<'a>(
actual: arg_types.len(),
});
}
- for (i, (provided_ty, expected_ty)) in
+ for (i, (&(_, ref provided_ty), expected_ty)) in
arg_types.iter().zip(expected_args).enumerate() {
if provided_ty != expected_ty {
return err!(args[i], TypeError::Mismatch {
@@ -163,12 +170,15 @@ fn trans_exp<'a>(
})
}
}
- Ok((**result).clone())
+ err!(exp, TypeError::Unimplemented)
+ // Ok((**result).clone())
},
otherwise => {
err!(exp, TypeError::Mismatch {
// TODO: better way to handle this
- expected: Ty::Function(arg_types, Box::new(Ty::Nil)),
+ expected: Ty::Function(
+ arg_types.into_iter().map(|v| v.1).collect(),
+ Box::new(Ty::Nil)),
actual: otherwise.clone(),
})
}
@@ -176,12 +186,13 @@ fn trans_exp<'a>(
},
&UnaryOp(ref op, ref operand) => {
use ast::UnaryOp::*;
- let operand_ty = trans_exp(venv, tenv, operand)?;
+ let (operand_exp, operand_ty) = trans_exp(tr, venv, tenv, operand)?;
match op {
&Neg | &Pos => {
match operand_ty {
Ty::Int => {
- Ok(Ty::Int)
+ err!(exp, TypeError::Unimplemented)
+ // Ok(Ty::Int)
}
other => {
err!(operand, TypeError::Mismatch {
@@ -198,16 +209,18 @@ fn trans_exp<'a>(
},
&BinOp(ref op, ref left, ref right) => {
use ast::BinOp::*;
- let left_ty = trans_exp(venv, tenv, left)?;
- let right_ty = trans_exp(venv, tenv, right)?;
+ let (left_exp, left_ty) = trans_exp(tr, venv, tenv, left)?;
+ let (right_exp, right_ty) = trans_exp(tr, venv, tenv, right)?;
match op {
&Add => {
match (left_ty, right_ty) {
(Ty::Int, Ty::Int) => {
- Ok(Ty::Int)
+ err!(exp, TypeError::Unimplemented)
+ // Ok(Ty::Int)
}
(Ty::String, Ty::String) => {
- Ok(Ty::String)
+ err!(exp, TypeError::Unimplemented)
+ // Ok(Ty::String)
}
(Ty::Int, other) | (other, Ty::Int) => {
err!(right, TypeError::Mismatch {
@@ -231,11 +244,13 @@ fn trans_exp<'a>(
}
}
},
- &Number(_) => Ok(Ty::Int),
- &String(_) => Ok(Ty::String),
+ &Number(n) => Ok((tr.make_num(n), Ty::Int)),
+ &String(_) => err!(exp, TypeError::Unimplemented),
+ // &String(_) => Ok(Ty::String),
&Name(ref name) => {
if let Some(ty) = venv.lookup(name) {
- Ok(ty.clone())
+ err!(exp, TypeError::Unimplemented)
+ // Ok(ty.clone())
}
else {
err!(exp, TypeError::UnboundName)
diff --git a/src/semantic/ir.rs b/src/semantic/ir.rs
index deeed96..be358c4 100644
--- a/src/semantic/ir.rs
+++ b/src/semantic/ir.rs
@@ -1,9 +1,11 @@
use super::temp;
+#[derive(Debug)]
pub enum Binop {
Plus,
}
+#[derive(Debug)]
pub enum Expression {
Const(u64),
Name(temp::TempLabel),
@@ -14,6 +16,7 @@ pub enum Expression {
Seq(Vec<Statement>, Box<Expression>),
}
+#[derive(Debug)]
pub enum Statement {
Exp(Expression),
MoveTemp(temp::TempName, Expression),
diff --git a/src/semantic/translate.rs b/src/semantic/translate.rs
index e69de29..cc5aec0 100644
--- a/src/semantic/translate.rs
+++ b/src/semantic/translate.rs
@@ -0,0 +1,27 @@
+use super::ir;
+
+#[derive(Debug)]
+pub enum Expression {
+ Exp(ir::Expression),
+ Void(ir::Statement),
+}
+
+pub struct Translate {
+
+}
+
+pub enum Level {
+ Top,
+ Level,
+}
+
+impl Translate {
+ pub fn new() -> Translate {
+ Translate {
+ }
+ }
+
+ pub fn make_num(&mut self, num: u64) -> Expression {
+ Expression::Exp(ir::Expression::Const(num))
+ }
+}