# HG changeset patch # User Simon Heath # Date 1738518499 18000 # Sun Feb 02 12:48:19 2025 -0500 # Branch devel # Node ID 3db59b15d317cff69cc7abf75a0abdf140b88077 # Parent 40c754d2f7654da5706212e3f42b85670dc0a07f jfc I forgot to commit this apparently diff --git a/src/backend/rust2.rs b/src/backend/rust2.rs --- a/src/backend/rust2.rs +++ b/src/backend/rust2.rs @@ -12,8 +12,6 @@ use log::*; -use crate::typeck::Tck; -use crate::types::*; use crate::*; /// Compiles a `Type` into a a valid Rust type. @@ -161,7 +159,7 @@ output } -fn compile_import(w: &mut impl Write, ir: &hir2::Import) -> io::Result<()> { +fn compile_import(_w: &mut impl Write, _ir: &hir2::Import) -> io::Result<()> { todo!() } @@ -421,10 +419,10 @@ } E::Block { body } => format!("{{\n{}\n}}", compile_exprs(body, ";\n")), E::Let { - varname, + varname: _, typename: _, - init, - mutable, + init: _, + mutable: _, } => { todo!("tck") /* @@ -524,7 +522,7 @@ // panic!("Should never happen, structs should always be tuples by now!"); format!("{}.{}", compile_expr(expr), elt) } - E::TupleRef { expr, elt } => { + E::TupleRef { expr: _, elt: _ } => { todo!("tck") /* // We turn our structs into Rust tuples, so we need to diff --git a/src/builtins.rs b/src/builtins.rs --- a/src/builtins.rs +++ b/src/builtins.rs @@ -2,6 +2,7 @@ //! instead of having them scattered all over. use crate::backend::Backend; +use crate::hir2::{Type as Type2, TypeNode as TN}; use crate::types::*; use crate::*; @@ -11,6 +12,7 @@ pub name: Sym, /// The value's type, used for typechecking pub sig: Type, + pub sig2: hir2::TypeNode, /// The implmentation of the builtin as raw code for each particular /// backend. pub code: BTreeMap, @@ -103,6 +105,7 @@ Builtin { name: Sym::new(format!("__println_{name}")), sig: Type::Func(vec![ty.clone()], Box::new(Type::unit()), vec![]), + sig2: TN::function(vec![ty.clone()], TN::unit()), code: BTreeMap::from([(Backend::Null, "".into()), (Backend::Rust, println)]), }, Builtin { diff --git a/src/hir2.rs b/src/hir2.rs --- a/src/hir2.rs +++ b/src/hir2.rs @@ -62,6 +62,145 @@ pub fn get_mangled_name(&self) -> String { self.t.get_mangled_name() } + + pub fn struct_(body: BTreeMap) -> Self { + Self::new(Type::Struct(body)) + } + + /// Shortcut for getting the type for an unknown int + pub fn iunknown() -> Self { + Self::new(Type::Prim(PrimType::UnknownInt)) + } + + /// Shortcut for getting the Type for a signed int of a particular size + pub fn isize(size: u8) -> Self { + Self::new(Type::Prim(PrimType::Int(size, true))) + } + + /// Shortcut for getting the Type for an unsigned signed int of a particular size + pub fn usize(size: u8) -> Self { + Self::new(Type::Prim(PrimType::Int(size, false))) + } + + /// Shortcut for getting the Type for I128 + pub fn i128() -> Self { + Self::isize(16) + } + + /// Shortcut for getting the Type for I64 + pub fn i64() -> Self { + Self::isize(8) + } + + /// Shortcut for getting the Type for I32 + pub fn i32() -> Self { + Self::isize(4) + } + + /// Shortcut for getting the type for I16 + pub fn i16() -> Self { + Self::isize(2) + } + + /// Shortcut for getting the type for I8 + pub fn i8() -> Self { + Self::isize(1) + } + + /// Shortcut for getting the Type for U128 + pub fn u128() -> Self { + Self::usize(16) + } + + /// Shortcut for getting the Type for U64 + pub fn u64() -> Self { + Self::usize(8) + } + + /// Shortcut for getting the Type for U32 + pub fn u32() -> Self { + Self::usize(4) + } + + /// Shortcut for getting the type for U16 + pub fn u16() -> Self { + Self::usize(2) + } + + /// Shortcut for getting the type for U8 + pub fn u8() -> Self { + Self::usize(1) + } + + /// Shortcut for getting the type for Bool + pub fn bool() -> Self { + Self::new(Type::Prim(PrimType::Bool)) + } + + /// Shortcut for getting the type for Unit + pub fn unit() -> Self { + Self::new(Type::Tuple(vec![])) + } + + /// Shortcut for getting the type for Never + pub fn never() -> Self { + // Self::new(Named(Sym::new("Never"), vec![]) + todo!() + } + + /// Create a Tuple with the given values + pub fn tuple(args: &[Self]) -> Self { + Self::new(Type::Tuple(args.to_vec())) + } + + /// Used in some tests + pub fn array(t: &TypeNode, len: usize) -> Self { + Self::new(Type::Array(t.clone(), len)) + } + + /// Shortcut for a named type with no type params + // pub fn named0(s: impl AsRef) -> Self { + pub fn named0(_s: Sym) -> Self { + // Type::Var(s, vec![]) + todo!() + } + pub fn function(params: &[TypeNode], rettype: &Type) -> Self { + TypeNode::new(Type::Func( + Vec::from(params), + TypeNode::new(rettype.clone()), + )) + } + + pub fn is_func(&self) -> bool { + matches!(&*self.t, &Type::Func(_, _)) + } + + /// Takes a string and matches it against the builtin/ + /// primitive types, returning the appropriate `TypeDef` + /// + /// If it is not a built-in type, or is a compound such + /// as a tuple or struct, returns None. + /// + /// The effective inverse of `TypeDef::get_name()`. Compound + /// types take more parsing to turn from strings to `TypeDef`'s + /// and are handled in `parser::parse_type()`. + pub fn get_primitive_type(s: &str) -> Option { + match s { + "I8" => Some(Type::i8()), + "I16" => Some(Type::i16()), + "I32" => Some(Type::i32()), + "I64" => Some(Type::i64()), + "I128" => Some(Type::i128()), + "U8" => Some(Type::u8()), + "U16" => Some(Type::u16()), + "U32" => Some(Type::u32()), + "U64" => Some(Type::u64()), + "U128" => Some(Type::u128()), + "Bool" => Some(Type::bool()), + "Never" => Some(Type::never()), + _ => None, + } + } } impl From<&Type> for TypeNode { diff --git a/src/nbe.rs b/src/nbe.rs --- a/src/nbe.rs +++ b/src/nbe.rs @@ -45,7 +45,7 @@ // figure out around vars and indices before I actually // switch everything over. This is basically a placeholder // to make the transition simpler later. - _vals: Vector, + vals: Vector, /// Where we record our association of expressions to their types /// for type inference/unification. Maybe should be its own type passed @@ -156,10 +156,16 @@ self.types.len() } - /// Binds a variable to a name. + fn add_binding(&self, vl: ValBinding) -> Self { + let mut s = self.clone(); + s.vals.push_back(vl.clone()); + s + } + + /// Binds a type variable to a name. /// Not suuuuure yet whether we need to juggle bindings separately /// from values? Yeah we do. - fn add_binding(&self, vl: TypeBinding) -> Self { + fn add_type_binding(&self, vl: TypeBinding) -> Self { let mut s = self.clone(); s.types.push_back(vl.clone()); s @@ -171,7 +177,7 @@ fn add_neu_binding(&self, name: Sym, kind: Kind) -> Self { let varlvl = Lvl(self.size() + 1); // new var is at the top of our bindings env, plus one let vartype = NType::Neu(Neutral::Var(varlvl, name)); - self.add_binding(TypeBinding::TypeVar(vartype, kind, name)) + self.add_type_binding(TypeBinding::TypeVar(vartype, kind, name)) } /// Look up a bound value by de Bruijn index. @@ -867,6 +873,20 @@ self.set_expr_type(e, &res); Ok(res) } + + fn add_builtins(&self) -> Self { + let mut res = self.clone(); + for builtin in &*builtins::BUILTINS { + let ty = self + .eval_type(builtin.sig2.clone()) + .expect("Builtin has invalid type, shouldn't happen"); + // let binding = ValBinding::Var(NType::, ) + // *res = self.add_binding(builtin.) + // let ty = tck.insert_known(&builtin.sig); + // self.add_var(builtin.name, ty, false); + } + res + } } /// Our quote operation that just translates our NbE world back into @@ -962,7 +982,7 @@ // bind the closure's args to the given type variable names, and eval it. let mut new_env = env; for ((nm, declared_kind), arg) in nms.into_iter().zip(args) { - new_env = new_env.add_binding(TypeBinding::TypeVar( + new_env = new_env.add_type_binding(TypeBinding::TypeVar( arg.clone(), declared_kind.clone(), nm.clone(), @@ -1091,6 +1111,7 @@ /// Or just the part of the Env that pub fn typecheck(ir: &hir2::Ir) -> Result<(), String> { let env = &mut Env::default(); + *env = env.add_builtins(); predeclare_decls(env, &ir)?; typecheck_typedefs(env, &ir.typedefs)?; typecheck_consts(env, &ir.consts)?; diff --git a/src/simptbl.rs b/src/simptbl.rs --- a/src/simptbl.rs +++ b/src/simptbl.rs @@ -8,7 +8,7 @@ //! //! Just use this as a piece to build other more complicated operations atop. -use std::cell::RefCell; +// use std::cell::RefCell; use crate::*; diff --git a/tests/programs/hello1.gt b/tests/programs/test_hello2.gt rename from tests/programs/hello1.gt rename to tests/programs/test_hello2.gt