Skip to content

Commit

Permalink
Allow type as expression
Browse files Browse the repository at this point in the history
  • Loading branch information
dalance committed Oct 17, 2024
1 parent afd1711 commit 5914911
Show file tree
Hide file tree
Showing 25 changed files with 18,730 additions and 14,797 deletions.
2 changes: 1 addition & 1 deletion bacon.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

default_job = "check"
on_change_strategy = "kill_then_restart"
ignored_lines = ["warning: veryl-std.*"]
ignored_lines = ["warning: veryl-std.*", "warning: veryl-parser.*"]

[jobs.check]
command = ["cargo", "check", "--color", "always"]
Expand Down
9 changes: 5 additions & 4 deletions crates/analyzer/src/analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ use crate::msb_table;
use crate::namespace::Namespace;
use crate::namespace_table;
use crate::symbol::{
Direction, DocComment, ParameterValue, Symbol, SymbolId, SymbolKind, TypeKind,
VariableAffiniation,
Direction, DocComment, Symbol, SymbolId, SymbolKind, TypeKind, VariableAffiniation,
};
use crate::symbol_table;
use crate::type_dag;
Expand Down Expand Up @@ -319,15 +318,17 @@ fn traverse_type_symbol(id: SymbolId, path: &AssignPath) -> Vec<AssignPath> {
}
}
SymbolKind::Parameter(x) if x.r#type.kind == TypeKind::Type => {
if let ParameterValue::TypeExpression(TypeExpression::ScalarType(ref x)) = x.value {
let r#type: crate::symbol::Type = (&*x.scalar_type).into();
let r#type: Result<crate::symbol::Type, ()> = (&x.value).try_into();
if let Ok(r#type) = r#type {
if let TypeKind::UserDefined(ref x) = r#type.kind {
if let Ok(symbol) = symbol_table::resolve((x, &symbol.namespace)) {
return traverse_type_symbol(symbol.found.id, path);
}
} else {
return vec![path.clone()];
}
} else {
return vec![path.clone()];
}
}
SymbolKind::Struct(x) => {
Expand Down
2 changes: 2 additions & 0 deletions crates/analyzer/src/evaluator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,8 @@ impl Evaluator {
Factor::FactorGroup(_) => Evaluated::Unknown,
Factor::InsideExpression(_) => Evaluated::Unknown,
Factor::OutsideExpression(_) => Evaluated::Unknown,
Factor::TypeExpression(_) => Evaluated::Unknown,
Factor::FactorType(_) => Evaluated::Unknown,
}
}

Expand Down
53 changes: 5 additions & 48 deletions crates/analyzer/src/handlers/check_expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,7 @@ pub struct CheckExpression<'a> {
point: HandlerPoint,
case_condition_depth: usize,
evaluator: Evaluator,
call_stack_kind: Vec<FunctionKind>,
in_inst_declaration: bool,
in_inst_parameter: bool,
}

#[derive(Debug, Clone, Copy, PartialEq)]
enum FunctionKind {
System,
NonSystem,
}

impl<'a> CheckExpression<'a> {
Expand Down Expand Up @@ -82,32 +74,21 @@ impl<'a> VerylGrammarTrait for CheckExpression<'a> {
SymbolKind::Function(_) | SymbolKind::ModportFunctionMember(_) => {
if x.factor_opt.is_none() {
self.errors.push(error);
} else {
self.call_stack_kind.push(FunctionKind::NonSystem);
}
}
SymbolKind::SystemFunction => {
if x.factor_opt.is_none() {
self.errors.push(error);
} else {
self.call_stack_kind.push(FunctionKind::System);
}
}
// instance can be used as factor in inst_declaration
SymbolKind::Instance(_) if self.in_inst_declaration => (),
// type can be used as factor in inst_parameter
SymbolKind::TypeDef(_)
| SymbolKind::Struct(_)
| SymbolKind::Enum(_)
| SymbolKind::Union(_)
if self.in_inst_parameter => {}
SymbolKind::Module(_)
| SymbolKind::ProtoModule(_)
| SymbolKind::Interface(_)
| SymbolKind::Instance(_)
| SymbolKind::Block
| SymbolKind::Package(_)
| SymbolKind::TypeDef(_)
| SymbolKind::Modport(_)
| SymbolKind::Namespace
| SymbolKind::ClockDomain
Expand All @@ -125,7 +106,11 @@ impl<'a> VerylGrammarTrait for CheckExpression<'a> {
}
}
}
SymbolKind::Parameter(_)
SymbolKind::TypeDef(_)
| SymbolKind::Struct(_)
| SymbolKind::Enum(_)
| SymbolKind::Union(_)
| SymbolKind::Parameter(_)
| SymbolKind::EnumMember(_)
| SymbolKind::EnumMemberMangled
| SymbolKind::Genvar
Expand All @@ -136,13 +121,6 @@ impl<'a> VerylGrammarTrait for CheckExpression<'a> {
| SymbolKind::UnionMember(_)
| SymbolKind::GenericInstance(_)
| SymbolKind::Variable(_) => {}

SymbolKind::Enum(_) | SymbolKind::Union(_) | SymbolKind::Struct(_) => {
if let Some(FunctionKind::System) = self.call_stack_kind.last() {
} else {
self.errors.push(error);
}
}
}
}

Expand Down Expand Up @@ -181,19 +159,6 @@ impl<'a> VerylGrammarTrait for CheckExpression<'a> {
}
}
}
} else if let Factor::ExpressionIdentifierFactorOpt(x) = arg {
let expid = x.expression_identifier.as_ref();
if let Ok(rr) = symbol_table::resolve(expid) {
match rr.found.kind {
SymbolKind::Function(_) | SymbolKind::ModportFunctionMember(_) => {
self.call_stack_kind.pop();
}
SymbolKind::SystemFunction => {
self.call_stack_kind.pop();
}
_ => {}
}
}
}
Ok(())
}
Expand All @@ -205,12 +170,4 @@ impl<'a> VerylGrammarTrait for CheckExpression<'a> {
}
Ok(())
}

fn inst_parameter(&mut self, _arg: &InstParameter) -> Result<(), ParolError> {
match self.point {
HandlerPoint::Before => self.in_inst_parameter = true,
HandlerPoint::After => self.in_inst_parameter = false,
}
Ok(())
}
}
58 changes: 45 additions & 13 deletions crates/analyzer/src/handlers/check_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ pub struct CheckType<'a> {
text: &'a str,
point: HandlerPoint,
in_module: bool,
in_variable_type: Vec<()>,
in_user_defined_type: Vec<()>,
in_casting_type: Vec<()>,
in_generic_argument: Vec<()>,
in_modport: bool,
}
Expand Down Expand Up @@ -54,14 +55,37 @@ fn is_variable_type(symbol: &Symbol) -> bool {
}
}

fn is_casting_type(symbol: &Symbol) -> bool {
match &symbol.kind {
// U32/U64 can be used as casting type
SymbolKind::Parameter(x) => matches!(
x.r#type.kind,
TypeKind::Type | TypeKind::U32 | TypeKind::U64
),
_ => is_variable_type(symbol),
}
}

impl<'a> VerylGrammarTrait for CheckType<'a> {
fn variable_type(&mut self, _arg: &VariableType) -> Result<(), ParolError> {
fn user_defined_type(&mut self, _arg: &UserDefinedType) -> Result<(), ParolError> {
match self.point {
HandlerPoint::Before => {
self.in_variable_type.push(());
self.in_user_defined_type.push(());
}
HandlerPoint::After => {
self.in_variable_type.pop();
self.in_user_defined_type.pop();
}
}
Ok(())
}

fn casting_type(&mut self, _arg: &CastingType) -> Result<(), ParolError> {
match self.point {
HandlerPoint::Before => {
self.in_casting_type.push(());
}
HandlerPoint::After => {
self.in_casting_type.pop();
}
}
Ok(())
Expand Down Expand Up @@ -99,7 +123,7 @@ impl<'a> VerylGrammarTrait for CheckType<'a> {
fn scoped_identifier(&mut self, arg: &ScopedIdentifier) -> Result<(), ParolError> {
if let HandlerPoint::Before = self.point {
// Check variable type
if !self.in_variable_type.is_empty() && self.in_generic_argument.is_empty() {
if !self.in_user_defined_type.is_empty() && self.in_generic_argument.is_empty() {
if let Ok(symbol) = symbol_table::resolve(arg) {
if self.in_modport {
if !matches!(symbol.found.kind, SymbolKind::Modport(_)) {
Expand All @@ -111,14 +135,22 @@ impl<'a> VerylGrammarTrait for CheckType<'a> {
&arg.identifier().token.into(),
));
}
} else if !is_variable_type(&symbol.found) {
self.errors.push(AnalyzerError::mismatch_type(
&symbol.found.token.to_string(),
"enum or union or struct",
&symbol.found.kind.to_kind_name(),
self.text,
&arg.identifier().token.into(),
));
} else {
let type_error = if !self.in_casting_type.is_empty() {
!is_casting_type(&symbol.found)
} else {
!is_variable_type(&symbol.found)
};
if type_error {
dbg!(&symbol.found);
self.errors.push(AnalyzerError::mismatch_type(
&symbol.found.token.to_string(),
"enum or union or struct",
&symbol.found.kind.to_kind_name(),
self.text,
&arg.identifier().token.into(),
));
}
}
}
}
Expand Down
22 changes: 10 additions & 12 deletions crates/analyzer/src/handlers/create_symbol_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ use crate::symbol::{
ConnectTarget, DocComment, EnumMemberProperty, EnumMemberValue, EnumProperty, FunctionProperty,
GenericBoundKind, GenericParameterProperty, InstanceProperty, InterfaceProperty,
ModportFunctionMemberProperty, ModportProperty, ModportVariableMemberProperty, ModuleProperty,
PackageProperty, Parameter, ParameterKind, ParameterProperty, ParameterValue, Port,
PortProperty, ProtoModuleProperty, StructMemberProperty, StructProperty, Symbol, SymbolId,
SymbolKind, TestProperty, TestType, TypeDefProperty, TypeKind, UnionMemberProperty,
UnionProperty, VariableAffiniation, VariableProperty,
PackageProperty, Parameter, ParameterKind, ParameterProperty, Port, PortProperty,
ProtoModuleProperty, StructMemberProperty, StructProperty, Symbol, SymbolId, SymbolKind,
TestProperty, TestType, TypeDefProperty, TypeKind, UnionMemberProperty, UnionProperty,
VariableAffiniation, VariableProperty,
};
use crate::symbol_path::{GenericSymbolPath, SymbolPath, SymbolPathNamespace};
use crate::symbol_table;
Expand Down Expand Up @@ -614,26 +614,25 @@ impl<'a> VerylGrammarTrait for CreateSymbolTable<'a> {
fn const_declaration(&mut self, arg: &ConstDeclaration) -> Result<(), ParolError> {
if let HandlerPoint::Before = self.point {
let token = arg.identifier.identifier_token.token;
let value = *arg.expression.clone();
let property = match &*arg.const_declaration_group {
ConstDeclarationGroup::ArrayTypeEquExpression(x) => {
ConstDeclarationGroup::ArrayType(x) => {
let r#type: SymType = x.array_type.as_ref().into();
let value = ParameterValue::Expression(*x.expression.clone());
ParameterProperty {
token,
r#type,
kind: ParameterKind::Const,
value,
}
}
ConstDeclarationGroup::TypeEquTypeExpression(x) => {
ConstDeclarationGroup::Type(_) => {
let r#type: SymType = SymType {
modifier: vec![],
kind: TypeKind::Type,
width: vec![],
array: vec![],
is_const: false,
};
let value = ParameterValue::TypeExpression(*x.type_expression.clone());
ParameterProperty {
token,
r#type,
Expand Down Expand Up @@ -892,26 +891,25 @@ impl<'a> VerylGrammarTrait for CreateSymbolTable<'a> {
WithParameterItemGroup::Param(_) => ParameterKind::Param,
WithParameterItemGroup::Const(_) => ParameterKind::Const,
};
let value = *arg.expression.clone();
let property = match &*arg.with_parameter_item_group0 {
WithParameterItemGroup0::ArrayTypeEquExpression(x) => {
WithParameterItemGroup0::ArrayType(x) => {
let r#type: SymType = x.array_type.as_ref().into();
let value = ParameterValue::Expression(*x.expression.clone());
ParameterProperty {
token,
r#type,
kind,
value,
}
}
WithParameterItemGroup0::TypeEquTypeExpression(x) => {
WithParameterItemGroup0::Type(_) => {
let r#type: SymType = SymType {
modifier: vec![],
kind: TypeKind::Type,
width: vec![],
array: vec![],
is_const: false,
};
let value = ParameterValue::TypeExpression(*x.type_expression.clone());
ParameterProperty {
token,
r#type,
Expand Down
Loading

0 comments on commit 5914911

Please sign in to comment.