Skip to content

Commit

Permalink
feat: Add more type
Browse files Browse the repository at this point in the history
  • Loading branch information
sbwtw committed Nov 8, 2024
1 parent 36d03df commit 531f5e9
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 57 deletions.
4 changes: 2 additions & 2 deletions lib/src/analysis/type_analyze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,10 @@ fn analyze_op_expr_type(op1: &Option<Type>, op2: &Option<Type>) -> Option<Type>
let tc2 = op2.as_ref()?.type_class();

// Usertype is not handled
if matches!(tc1, TypeClass::UserType) {
if matches!(tc1, TypeClass::UnknownType) {
return None;
}
if matches!(tc2, TypeClass::UserType) {
if matches!(tc2, TypeClass::UnknownType) {
return None;
}

Expand Down
35 changes: 28 additions & 7 deletions lib/src/ast/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use crate::parser::{LiteralValue, Operator, StString};
use crate::parser::LiteralValue;
use crate::prelude::*;
use bitflags::bitflags;
use smallvec::SmallVec;
use std::any::Any;
use std::fmt::{self, Debug, Display, Formatter};
use std::hash::{Hash, Hasher};
use std::sync::{Arc, RwLock};
use std::sync::Arc;

mod message;
pub use message::*;
Expand Down Expand Up @@ -58,7 +59,7 @@ mod global_variable_declaration;
pub use global_variable_declaration::GlobalVariableDeclare;

mod range_expression;
pub use range_expression::RangeExpression;
pub use range_expression::{Dimensions, RangeExpression};

pub type SmallVec8<T> = SmallVec<[T; 8]>;
pub type SmallVec3<T> = SmallVec<[T; 3]>;
Expand Down Expand Up @@ -133,6 +134,15 @@ pub trait TypeTrait: Send + Sync {
fn as_any(&self) -> &dyn Any;
}

pub trait UserTypeTrait: TypeTrait {
fn get_prototype(&self, scope: Scope) -> Prototype;
}

pub trait ArrayTypeTrait: TypeTrait {
fn base_type(&self) -> &Type;
fn dimensions(&self) -> &Dimensions;
}

#[derive(Clone)]
pub struct Type {
inner: Arc<TypeEnum>,
Expand Down Expand Up @@ -174,6 +184,15 @@ impl Type {
}
}

impl<T> From<T> for Type
where
T: TypeTrait + 'static,
{
fn from(value: T) -> Self {
Type::from_object(value)
}
}

impl Display for Type {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.type_class())
Expand Down Expand Up @@ -340,10 +359,12 @@ pub enum TypeClass {
LReal,
/// 'STRING' string type
String,
/// UserType
UserType,
/// UnknownType
UnknownType,
/// ArrayType
Array,
/// StructType
Struct,
}

impl Hash for TypeClass {
Expand All @@ -354,7 +375,7 @@ impl Hash for TypeClass {
TypeClass::Byte => 3,
TypeClass::UInt => 4,
TypeClass::Int => 5,
TypeClass::UserType => 6,
TypeClass::UnknownType => 6,
TypeClass::Array => 7,
// Some type shouldn't hash directly like ArrayType or UserType
_ => unreachable!("TypeClass shouldn't hash: {:?}", self),
Expand All @@ -380,7 +401,7 @@ impl Display for TypeClass {
TypeClass::Real => write!(f, "REAL"),
TypeClass::LReal => write!(f, "LREAL"),
TypeClass::String => write!(f, "STRING"),
TypeClass::UserType | TypeClass::Array => {
TypeClass::UnknownType | TypeClass::Array | TypeClass::Struct => {
unreachable!("UserType or ArrayType can't display without Type object")
}
}
Expand Down
1 change: 1 addition & 0 deletions lib/src/ast/operator_expression.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::ast::*;
use crate::parser::Operator;
use crate::{impl_ast_display, impl_into_expression};

#[derive(Debug)]
Expand Down
10 changes: 5 additions & 5 deletions lib/src/ast/range_expression.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::Expression;
use super::{Expression, SmallVec3};

/// Lower..Upper
#[derive(Debug)]
Expand All @@ -9,8 +9,8 @@ pub struct RangeExpression {

impl RangeExpression {
pub fn new(lower: Expression, upper: Expression) -> Self {
Self {
lower, upper
}
Self { lower, upper }
}
}
}

pub type Dimensions = SmallVec3<RangeExpression>;
71 changes: 36 additions & 35 deletions lib/src/ast/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,51 +29,53 @@ builtin_type_impl!(struct LRealType, TypeClass::LReal);
builtin_type_impl!(struct StringType, TypeClass::String);

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct UserType {
pub struct UnknownType {
name: StString,
decl_id: Option<usize>,
class: Option<UserTypeClass>,
}

impl UserType {
impl UnknownType {
pub fn from_name(name: StString) -> Self {
Self {
name,
decl_id: None,
class: None,
}
}

pub fn from_proto(name: StString, proto_id: usize) -> Self {
Self {
name,
decl_id: Some(proto_id),
class: None,
}
Self { name }
}

pub fn name(&self) -> &StString {
&self.name
}
}

impl From<UserType> for Type {
fn from(value: UserType) -> Self {
Type::from_object(value)
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct StructType {
name: StString,
proto: usize,
}

impl StructType {
pub fn new(name: StString, proto: usize) -> Self {
Self { name, proto }
}
}

impl TypeTrait for UserType {
impl TypeTrait for StructType {
fn class(&self) -> TypeClass {
TypeClass::UserType
TypeClass::Struct
}

fn as_any(&self) -> &dyn Any {
self
}
}

impl Display for UserType {
impl TypeTrait for UnknownType {
fn class(&self) -> TypeClass {
TypeClass::UnknownType
}

fn as_any(&self) -> &dyn Any {
self
}
}

impl Display for UnknownType {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.name)
}
Expand Down Expand Up @@ -186,22 +188,27 @@ impl StructDeclare {

#[derive(Debug)]
pub struct ArrayType {
base_type: Arc<RwLock<Type>>,
dimensions: SmallVec3<RangeExpression>,
base_type: Type,
dimensions: Dimensions,
}

impl ArrayType {
pub fn new(base: Type, dimensions: SmallVec3<RangeExpression>) -> Self {
pub fn new(base: Type, dimensions: Dimensions) -> Self {
Self {
base_type: Arc::new(RwLock::new(base)),
base_type: base,
dimensions,
}
}
}

#[inline]
pub fn base_type(&self) -> &Arc<RwLock<Type>> {
impl ArrayTypeTrait for ArrayType {
fn base_type(&self) -> &Type {
&self.base_type
}

fn dimensions(&self) -> &Dimensions {
&self.dimensions
}
}

impl Display for ArrayType {
Expand All @@ -225,12 +232,6 @@ impl Clone for ArrayType {
}
}

impl From<ArrayType> for Type {
fn from(value: ArrayType) -> Self {
Type::from_object(value)
}
}

impl TypeTrait for ArrayType {
fn class(&self) -> TypeClass {
TypeClass::Array
Expand Down
8 changes: 2 additions & 6 deletions lib/src/context/module_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,10 @@ impl PrototypeImpl {
}

pub fn create_user_type(&self) -> Option<Type> {
// Only Structure types can be created as UserType
match self.decl.kind {
DeclKind::Struct(_) | DeclKind::Alias(_) | DeclKind::Enum(_) => {}
_ => return None,
DeclKind::Struct(_) => Some(StructType::new(self.name().clone(), self.id).into()),
_ => None,
}

let user_ty = UserType::from_proto(self.decl.identifier().clone(), self.id);
Some(user_ty.into())
}

/// Get return value of prototype
Expand Down
2 changes: 1 addition & 1 deletion lib/src/parser/default_impl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ impl<I: Iterator<Item = LexerResult>> DefaultParserImpl<I> {
TokenKind::Byte => Ok(Some(ByteType::new_type())),
TokenKind::Int => Ok(Some(IntType::new_type())),
TokenKind::Real => Ok(Some(RealType::new_type())),
TokenKind::Identifier(ident) => Ok(Some(UserType::from_name(ident.clone()).into())),
TokenKind::Identifier(ident) => Ok(Some(UnknownType::from_name(ident.clone()).into())),
_ => {
self.next = pos;
Ok(None)
Expand Down
2 changes: 1 addition & 1 deletion lib/src/parser/lalrpop_impl/st.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ pub Type: Type = {
"BOOL" => BoolType::new_type(),
"BYTE" => ByteType::new_type(),
"REAL" => RealType::new_type(),
"IDENTIFIER" => UserType::from_name(<>).into(),
"IDENTIFIER" => UnknownType::from_name(<>).into(),
<arr: ArrayType> => arr.into(),
}

Expand Down

0 comments on commit 531f5e9

Please sign in to comment.