From 1ca04834d34ca45174836384d2c57230fbb17487 Mon Sep 17 00:00:00 2001 From: Lennart Van Hirtum Date: Tue, 2 Jan 2024 13:58:27 +0100 Subject: [PATCH] Add typing assert to compile-time code --- src/flattening.rs | 4 ++-- src/instantiation/mod.rs | 1 + src/value.rs | 31 +++++++++++++++++++++++++++---- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/flattening.rs b/src/flattening.rs index be4ecfc..f859a16 100644 --- a/src/flattening.rs +++ b/src/flattening.rs @@ -223,10 +223,10 @@ impl<'l, 'm, 'fl> FlatteningContext<'l, 'm, 'fl> { Expression::Named(LocalOrGlobal::Global(g)) => { let r = self.module.link_info.global_references[*g]; let cst = self.linker.try_get_constant(r, &self.errors)?; - self.instantiations.alloc(Instantiation::Wire(WireInstance{typ : cst.get_type(), is_compiletime : true, span : *expr_span, inst : WireSource::Constant{value : cst}})) + self.instantiations.alloc(Instantiation::Wire(WireInstance{typ : cst.get_type_of_constant(), is_compiletime : true, span : *expr_span, inst : WireSource::Constant{value : cst}})) } Expression::Constant(cst) => { - self.instantiations.alloc(Instantiation::Wire(WireInstance{typ : cst.get_type(), is_compiletime : true, span : *expr_span, inst : WireSource::Constant{value : cst.clone()}})) + self.instantiations.alloc(Instantiation::Wire(WireInstance{typ : cst.get_type_of_constant(), is_compiletime : true, span : *expr_span, inst : WireSource::Constant{value : cst.clone()}})) } Expression::UnaryOp(op_box) => { let (op, _op_pos, operate_on) = op_box.deref(); diff --git a/src/instantiation/mod.rs b/src/instantiation/mod.rs index 04be788..2ec2985 100644 --- a/src/instantiation/mod.rs +++ b/src/instantiation/mod.rs @@ -339,6 +339,7 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> { }; if w.is_compiletime { let Some(value_computed) = self.compute_compile_time(&w.inst, &typ) else {return}; + assert!(value_computed.is_of_type(&typ)); SubModuleOrWire::CompileTimeValue(value_computed) } else { let (name, source) = match &w.inst { diff --git a/src/value.rs b/src/value.rs index 50f8b75..3ed2572 100644 --- a/src/value.rs +++ b/src/value.rs @@ -1,6 +1,8 @@ +use std::ops::Deref; + use num::BigInt; -use crate::{typing::Type, linker::get_builtin_uuid, ast::Operator, tokenizer::kw}; +use crate::{typing::{Type, ConcreteType}, linker::get_builtin_uuid, ast::Operator, tokenizer::kw}; #[derive(Debug,Clone,PartialEq,Eq)] pub enum Value { @@ -12,12 +14,12 @@ pub enum Value { } impl Value { - pub fn get_type(&self) -> Type { + pub fn get_type_of_constant(&self) -> Type { match self { Value::Bool(_) => Type::Named(get_builtin_uuid("bool")), Value::Integer(_) => Type::Named(get_builtin_uuid("int")), - Value::Array(b) => { - Type::Error + Value::Array(_b) => { + unreachable!("Can't express arrays as constants (yet?)"); /*let content_typ = if let Some(b_first) = b.first() { b_first.get_type() } else { @@ -29,6 +31,27 @@ impl Value { Value::Error => Type::Error, } } + pub fn is_of_type(&self, typ : &ConcreteType) -> bool { + match (self, typ) { + (Self::Integer(_), ConcreteType::Named(name)) if *name == get_builtin_uuid("int") => true, + (Self::Bool(_), ConcreteType::Named(name)) if *name == get_builtin_uuid("bool") => true, + (Self::Array(arr_slice), ConcreteType::Array(arr_typ_box)) => { + let (arr_content_typ, arr_size_typ) = arr_typ_box.deref(); + if arr_slice.len() != *arr_size_typ as usize { + return false; + } + for v in arr_slice.iter() { + if !v.is_of_type(arr_content_typ) { + return false; + } + } + true + }, + (Self::Unset, _) => true, + (Self::Error, _) => true, + _other => false + } + } pub fn extract_integer(&self) -> &BigInt { let Self::Integer(i) = self else {panic!("{:?} is not an integer!", self)}; i