From c28601376e92bb1b1240b08ddbdfaa851daaa9cd Mon Sep 17 00:00:00 2001 From: Greg Brown Date: Fri, 9 Apr 2021 11:08:22 +0100 Subject: Make some progress, I guess --- src/chomp/typed/context.rs | 56 +++++++++++++++++++++++++++++----------------- src/chomp/typed/error.rs | 8 +++---- src/chomp/typed/infer.rs | 48 ++++++++++++++++----------------------- src/chomp/typed/mod.rs | 28 ++++++++++++++--------- 4 files changed, 76 insertions(+), 64 deletions(-) (limited to 'src/chomp/typed') 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, + vars: Vec<(Type, bool)>, + globals: HashMap, unguard_points: Vec, } @@ -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 R, R>(&mut self, ty: Type, f: F) -> R { - self.vars.push(ty); + pub fn with_fixed_point_type 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 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, pub name: Option, @@ -29,8 +29,8 @@ impl From 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, - span: Option, - 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, @@ -132,7 +109,20 @@ impl Folder for TypeInfer<'_> { unimplemented!() } + fn fold_global(&mut self, name: Option, span: Option, global: Global) -> Self::Out { + todo!() + } + fn fold_call(&mut self, _name: Option, _span: Option, _call: Call) -> Self::Out { unimplemented!() } + + fn fold_function( + &mut self, + name: Option, + span: Option, + 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, + args: Vec, ty: Type, } -impl Variable { - pub fn index(&self) -> usize { - self.inner.index - } +#[derive(Clone, Debug)] +pub struct Function { + args: Vec>, + expr: Box, } #[derive(Clone, Debug)] @@ -309,7 +310,8 @@ enum RawTypedExpression { Cat(Cat), Alt(Alt), Fix(Fix), - Variable(Variable), + Call(Call), + Function(Function), } impl From for RawTypedExpression { @@ -342,9 +344,15 @@ impl From for RawTypedExpression { } } -impl From for RawTypedExpression { - fn from(var: Variable) -> Self { - Self::Variable(var) +impl From for RawTypedExpression { + fn from(call: Call) -> Self { + Self::Call(call) + } +} + +impl From for RawTypedExpression { + fn from(fun: Function) -> Self { + Self::Function(fun) } } -- cgit v1.2.3