From 06798d622327707ca3f3b42d65fc3d1a25ae3c57 Mon Sep 17 00:00:00 2001 From: Joel Kronqvist Date: Sun, 10 Aug 2025 18:38:49 +0300 Subject: Added term level type literals (for function type signatures) --- src/sexp/display.rs | 2 ++ src/sexp/mod.rs | 19 ++++++++++++++++++- src/sexp/step.rs | 24 ++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) (limited to 'src/sexp') diff --git a/src/sexp/display.rs b/src/sexp/display.rs index a978f61..5d78e93 100644 --- a/src/sexp/display.rs +++ b/src/sexp/display.rs @@ -29,6 +29,8 @@ impl fmt::Display for SLeaf { Vector => "vector".to_string(), Print => "print".to_string(), Let => "let".to_string(), + Ty(t) => t.to_string(), + Arr => "->".to_string(), Nil => "()".to_string(), }) } diff --git a/src/sexp/mod.rs b/src/sexp/mod.rs index 296553f..11c185f 100644 --- a/src/sexp/mod.rs +++ b/src/sexp/mod.rs @@ -4,6 +4,8 @@ pub mod util; pub mod subst; pub mod display; +use crate::r#type::Type; + /// A leaf node for S-Expressions. /// /// May represent built-in operators, @@ -33,6 +35,9 @@ pub enum SLeaf { Let, + Ty(Type), + Arr, + Print, Int(i32), @@ -58,6 +63,7 @@ pub enum SExp { use SExp::*; use SLeaf::*; +use crate::sexp::util::*; impl SExp { @@ -71,7 +77,7 @@ impl SExp { SCons(a, b) => SCons(a.clone(), b.clone()).check_let().is_some() || ( - (**a == Atom(Quote) || **a == Atom(Vector)) + (**a == Atom(Quote) || **a == Atom(Vector) || (**a).is_type_lit()) && b.consists_of_values() ), Atom(Var(_)) => false, @@ -85,4 +91,15 @@ impl SExp { _ => false } } + + pub fn is_type_lit(&self) -> bool { + match self { + Atom(Ty(_)) => true, + SCons(a, b) => scons(a.clone(), b.clone()) + .parts() + .into_iter() + .all(|x| x.is_type_lit()), + _ => false + } + } } diff --git a/src/sexp/step.rs b/src/sexp/step.rs index 11df257..c26dce9 100644 --- a/src/sexp/step.rs +++ b/src/sexp/step.rs @@ -1,5 +1,6 @@ use crate::sexp::{SExp, SExp::*, SLeaf::*, util::*}; +use crate::r#type::{Type::*, util::*}; impl SExp { @@ -521,6 +522,29 @@ impl SExp { } }, + // Type arrow + SCons(op, l) if *op == Atom(Arr) => { + let ls = l.parts(); + let t1 = ls.get(0).ok_or("wrong list length".to_string())?; + let t2 = ls.get(1).ok_or("wrong list length".to_string())?; + match (t1.clone().multistep()?, t2.clone().multistep()?) { + (Atom(Ty(a)), Atom(Ty(b))) => Ok(Atom(Ty(arr(a.clone(), b.clone())))), + _ => Err("invalid args".to_string()), + } + }, + + // Type list + SCons(op, l) if (*op).is_type_lit() => { + let mut res = vec![]; + for exp in std::iter::once(*op).chain(l.parts()) { + res.push(match exp.multistep()? { + Atom(Ty(t)) => Ok(t), + e => Err(format!("not a type: {e}")), + }?); + } + Ok(Atom(Ty(List(res)))) + }, + // Print SCons(op, l) if *op == Atom(Print) => { println!("{}", *l); -- cgit v1.2.3