diff options
author | Greg Brown <gmb60@cam.ac.uk> | 2021-04-09 11:08:22 +0100 |
---|---|---|
committer | Greg Brown <gmb60@cam.ac.uk> | 2021-04-09 11:08:22 +0100 |
commit | c28601376e92bb1b1240b08ddbdfaa851daaa9cd (patch) | |
tree | ad61809dc2f40f930ff492182c32971e15f7267b /src/chomp/typed | |
parent | fa69e4edd87e3ec319ac4962c619b04e2203628e (diff) |
Make some progress, I guesstypes
Diffstat (limited to 'src/chomp/typed')
-rw-r--r-- | src/chomp/typed/context.rs | 56 | ||||
-rw-r--r-- | src/chomp/typed/error.rs | 8 | ||||
-rw-r--r-- | src/chomp/typed/infer.rs | 48 | ||||
-rw-r--r-- | src/chomp/typed/mod.rs | 28 |
4 files changed, 76 insertions, 64 deletions
diff --git a/src/chomp/typed/context.rs b/src/chomp/typed/context.rs index aaf01a7..3656da1 100644 --- a/src/chomp/typed/context.rs +++ b/src/chomp/typed/context.rs @@ -1,10 +1,13 @@ -use crate::chomp::ast::Variable; +use std::collections::HashMap; + +use crate::chomp::ast::Parameter; use super::{GroundType, Type}; #[derive(Default)] pub struct Context { - vars: Vec<Type>, + vars: Vec<(Type, bool)>, + globals: HashMap<String, Type>, unguard_points: Vec<usize>, } @@ -24,27 +27,38 @@ impl Context { res } - pub fn get_variable_type(&self, var: Variable) -> Result<&Type, GetVariableError> { + pub fn get_param_type(&self, param: Parameter) -> Result<&Type, GetParameterError> { self.vars .iter() - .nth_back(var.index) - .ok_or(GetVariableError::FreeVariable) - .and_then(|ty| { - self.unguard_points - .last() - .and_then(|point| { - if point + var.index >= self.vars.len() { - Some(ty) - } else { - None - } - }) - .ok_or(GetVariableError::GuardedVariable) + .nth_back(param.index) + .ok_or(GetParameterError::FreeParameter) + .and_then(|(ty, unguard)| { + if *unguard { + Ok(ty) + } else { + self.unguard_points + .last() + .and_then(|point| { + if point + param.index >= self.vars.len() { + Some(ty) + } else { + None + } + }) + .ok_or(GetParameterError::GuardedParameter) + } }) } - pub fn with_variable_type<F: FnOnce(&mut Self) -> R, R>(&mut self, ty: Type, f: F) -> R { - self.vars.push(ty); + pub fn with_fixed_point_type<F: FnOnce(&mut Self) -> R, R>(&mut self, ty: Type, f: F) -> R { + self.vars.push((ty, false)); + let res = f(self); + self.vars.pop(); + res + } + + pub fn with_parameter_type<F: FnOnce(&mut Self) -> R, R>(&mut self, ty: Type, f: F) -> R { + self.vars.push((ty, true)); let res = f(self); self.vars.pop(); res @@ -52,7 +66,7 @@ impl Context { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum GetVariableError { - FreeVariable, - GuardedVariable, +pub enum GetParameterError { + FreeParameter, + GuardedParameter, } diff --git a/src/chomp/typed/error.rs b/src/chomp/typed/error.rs index 405568b..4cc55b9 100644 --- a/src/chomp/typed/error.rs +++ b/src/chomp/typed/error.rs @@ -7,12 +7,12 @@ use proc_macro2::Span; use crate::chomp::{ast::Variable, Name}; -use super::{context::GetVariableError, TypedExpression}; +use super::{context::GetParameterError, TypedExpression}; /// A type error when using a fix point variable. #[derive(Debug)] pub struct VariableError { - pub inner: GetVariableError, + pub inner: GetParameterError, pub var: Variable, pub span: Option<Span>, pub name: Option<Name>, @@ -29,8 +29,8 @@ impl From<VariableError> for syn::Error { impl Display for VariableError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match &self.inner { - GetVariableError::FreeVariable => write!(f, "unbound variable: "), - GetVariableError::GuardedVariable => write!(f, "usage of guarded variable: "), + GetParameterError::FreeParameter => write!(f, "unbound variable: "), + GetParameterError::GuardedParameter => write!(f, "usage of guarded variable: "), }?; if let Some(name) = &self.name { diff --git a/src/chomp/typed/infer.rs b/src/chomp/typed/infer.rs index 01fe9c8..03deb8d 100644 --- a/src/chomp/typed/infer.rs +++ b/src/chomp/typed/infer.rs @@ -1,7 +1,7 @@ use proc_macro2::Span; use crate::chomp::{ - ast::{Alt, Call, Cat, Epsilon, Fix, Literal, Parameter, Variable}, + ast::{Alt, Call, Cat, Epsilon, Fix, Function, Global, Literal, Parameter}, visit::{Folder, Visitable}, Name, }; @@ -79,9 +79,11 @@ impl Folder for TypeInfer<'_> { loop { let last = ty; - let res = self.context.with_variable_type(last.clone().into(), |context| { - fix.inner.clone().fold(&mut TypeInfer { context }) - })?; + let res = self + .context + .with_variable_type(last.clone().into(), |context| { + fix.inner.clone().fold(&mut TypeInfer { context }) + })?; ty = res.get_type().as_ground(span)?.clone(); @@ -98,31 +100,6 @@ impl Folder for TypeInfer<'_> { } } - fn fold_variable( - &mut self, - name: Option<Name>, - span: Option<Span>, - var: Variable, - ) -> Self::Out { - let ty = match self.context.get_variable_type(var) { - Ok(ty) => ty.clone(), - Err(inner) => { - return Err(VariableError { - inner, - var, - span, - name, - } - .into()) - } - }; - Ok(TypedExpression { - inner: super::Variable { inner: var, ty }.into(), - name, - span, - }) - } - fn fold_parameter( &mut self, _name: Option<Name>, @@ -132,7 +109,20 @@ impl Folder for TypeInfer<'_> { unimplemented!() } + fn fold_global(&mut self, name: Option<Name>, span: Option<Span>, global: Global) -> Self::Out { + todo!() + } + fn fold_call(&mut self, _name: Option<Name>, _span: Option<Span>, _call: Call) -> Self::Out { unimplemented!() } + + fn fold_function( + &mut self, + name: Option<Name>, + span: Option<Span>, + fun: Function, + ) -> Self::Out { + todo!() + } } diff --git a/src/chomp/typed/mod.rs b/src/chomp/typed/mod.rs index 10514f0..1a171c1 100644 --- a/src/chomp/typed/mod.rs +++ b/src/chomp/typed/mod.rs @@ -291,15 +291,16 @@ impl Fix { } #[derive(Clone, Debug)] -pub struct Variable { - inner: ast::Variable, +pub struct Call { + fun: Box<TypedExpression>, + args: Vec<TypedExpression>, ty: Type, } -impl Variable { - pub fn index(&self) -> usize { - self.inner.index - } +#[derive(Clone, Debug)] +pub struct Function { + args: Vec<Option<Name>>, + expr: Box<TypedExpression>, } #[derive(Clone, Debug)] @@ -309,7 +310,8 @@ enum RawTypedExpression { Cat(Cat), Alt(Alt), Fix(Fix), - Variable(Variable), + Call(Call), + Function(Function), } impl From<Epsilon> for RawTypedExpression { @@ -342,9 +344,15 @@ impl From<Fix> for RawTypedExpression { } } -impl From<Variable> for RawTypedExpression { - fn from(var: Variable) -> Self { - Self::Variable(var) +impl From<Call> for RawTypedExpression { + fn from(call: Call) -> Self { + Self::Call(call) + } +} + +impl From<Function> for RawTypedExpression { + fn from(fun: Function) -> Self { + Self::Function(fun) } } |