summaryrefslogtreecommitdiff
path: root/src/chomp/typed
diff options
context:
space:
mode:
authorGreg Brown <gmb60@cam.ac.uk>2021-04-09 11:08:22 +0100
committerGreg Brown <gmb60@cam.ac.uk>2021-04-09 11:08:22 +0100
commitc28601376e92bb1b1240b08ddbdfaa851daaa9cd (patch)
treead61809dc2f40f930ff492182c32971e15f7267b /src/chomp/typed
parentfa69e4edd87e3ec319ac4962c619b04e2203628e (diff)
Make some progress, I guesstypes
Diffstat (limited to 'src/chomp/typed')
-rw-r--r--src/chomp/typed/context.rs56
-rw-r--r--src/chomp/typed/error.rs8
-rw-r--r--src/chomp/typed/infer.rs48
-rw-r--r--src/chomp/typed/mod.rs28
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)
}
}