Skip to content

Commit

Permalink
AST Workspace (PLC-lang#889)
Browse files Browse the repository at this point in the history
  • Loading branch information
volsa authored Jul 26, 2023
1 parent d5eb570 commit 3fa4916
Show file tree
Hide file tree
Showing 83 changed files with 630 additions and 502 deletions.
11 changes: 10 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ default = []
verify = []

[dependencies]
plc_ast = { path = "./compiler/plc_ast" }
plc_util = { path = "./compiler/plc_util" }
logos = "0.12.0"
thiserror = "1.0"
clap = { version = "3.0", features = ["derive"] }
Expand Down Expand Up @@ -62,6 +64,7 @@ members = [
"compiler/plc_diagnostics",
"compiler/plc_project",
"compiler/plc_source",
"compiler/plc_util",
"rusty-derive",
]
default-members = [".", "compiler/plc_driver"]
Expand Down
4 changes: 3 additions & 1 deletion compiler/plc_ast/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
plc = {path = "../..", package = "rusty"}
plc_util = { path = "../plc_util" }
chrono = { version = "0.4", default-features = false }
serde = { version = "1.0", features = ["derive"] }
94 changes: 27 additions & 67 deletions src/ast.rs → compiler/plc_ast/src/ast.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,20 @@
// Copyright (c) 2020 Ghaith Hachem and Mathias Rieder
use crate::{
ast::control_statements::ForLoopStatement,
index::Index,
lexer::IdProvider,
typesystem::{
DataTypeInformation, BOOL_TYPE, CHAR_TYPE, DATE_TYPE, REAL_TYPE, SINT_TYPE, STRING_TYPE, TIME_TYPE,
USINT_TYPE, VOID_TYPE,
},
};
pub use literals::*;
use serde::{Deserialize, Serialize};

use std::{
fmt::{Debug, Display, Formatter, Result},
iter,
fmt::{Debug, Display, Formatter},
ops::Range,
unimplemented, vec,
};

use self::control_statements::{
AstControlStatement, CaseStatement, ConditionalBlock, IfStatement, LoopStatement,
};
use serde::{Deserialize, Serialize};

pub mod control_statements;
pub mod literals;
mod pre_processor;
use crate::{
control_statements::{
AstControlStatement, CaseStatement, ConditionalBlock, ForLoopStatement, IfStatement, LoopStatement,
},
literals::{AstLiteral, StringValue},
pre_processor,
provider::IdProvider,
};

pub type AstId = usize;

Expand Down Expand Up @@ -96,21 +87,6 @@ pub enum TypeNature {
}

impl TypeNature {
pub fn get_smallest_possible_type(&self) -> &str {
match self {
TypeNature::Magnitude | TypeNature::Num | TypeNature::Int => USINT_TYPE,
TypeNature::Real => REAL_TYPE,
TypeNature::Unsigned => USINT_TYPE,
TypeNature::Signed => SINT_TYPE,
TypeNature::Duration => TIME_TYPE,
TypeNature::Bit => BOOL_TYPE,
TypeNature::Chars | TypeNature::Char => CHAR_TYPE,
TypeNature::String => STRING_TYPE,
TypeNature::Date => DATE_TYPE,
_ => "",
}
}

pub fn derives_from(self, other: TypeNature) -> bool {
if other == self {
true
Expand Down Expand Up @@ -178,21 +154,6 @@ impl TypeNature {
}

impl DirectAccessType {
/// Returns true if the current index is in the range for the given type
pub fn is_in_range(&self, access_index: u64, data_type: &DataTypeInformation, index: &Index) -> bool {
(self.get_bit_width() * access_index) < data_type.get_size_in_bits(index) as u64
}

/// Returns the range from 0 for the given data type
pub fn get_range(&self, data_type: &DataTypeInformation, index: &Index) -> Range<u64> {
0..((data_type.get_size_in_bits(index) as u64 / self.get_bit_width()) - 1)
}

/// Returns true if the direct access can be used for the given type
pub fn is_compatible(&self, data_type: &DataTypeInformation, index: &Index) -> bool {
data_type.get_semantic_size(index) as u64 > self.get_bit_width()
}

/// Returns the size of the bitaccess result
pub fn get_bit_width(&self) -> u64 {
match self {
Expand All @@ -207,7 +168,7 @@ impl DirectAccessType {
}

impl Debug for Pou {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut str = f.debug_struct("POU");
str.field("name", &self.name)
.field("variable_blocks", &self.variable_blocks)
Expand Down Expand Up @@ -270,7 +231,7 @@ pub enum PouType {
}

impl Display for PouType {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
PouType::Program => write!(f, "Program"),
PouType::Function => write!(f, "Function"),
Expand Down Expand Up @@ -385,7 +346,7 @@ pub enum VariableBlockType {
}

impl Display for VariableBlockType {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
VariableBlockType::Local => write!(f, "Local"),
VariableBlockType::Temp => write!(f, "Temp"),
Expand Down Expand Up @@ -415,7 +376,7 @@ pub struct VariableBlock {
}

impl Debug for VariableBlock {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("VariableBlock")
.field("variables", &self.variables)
.field("variable_block_type", &self.variable_block_type)
Expand All @@ -433,7 +394,7 @@ pub struct Variable {
}

impl Debug for Variable {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut var = f.debug_struct("Variable");
var.field("name", &self.name).field("data_type", &self.data_type_declaration);
if self.initializer.is_some() {
Expand Down Expand Up @@ -503,7 +464,7 @@ pub struct SourceRange {
}

impl Debug for SourceRange {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut f = f.debug_struct("SourceRange");
f.field("range", &self.range);
if self.file.is_some() {
Expand Down Expand Up @@ -574,7 +535,7 @@ pub enum DataTypeDeclaration {
}

impl Debug for DataTypeDeclaration {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
DataTypeDeclaration::DataTypeReference { referenced_type, .. } => {
f.debug_struct("DataTypeReference").field("referenced_type", referenced_type).finish()
Expand Down Expand Up @@ -617,7 +578,7 @@ pub struct UserTypeDeclaration {
}

impl Debug for UserTypeDeclaration {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("UserTypeDeclaration")
.field("data_type", &self.data_type)
.field("initializer", &self.initializer)
Expand Down Expand Up @@ -691,10 +652,9 @@ impl DataType {
| DataType::StringType { name, .. }
| DataType::SubRangeType { name, .. } => name.as_ref().map(|x| x.as_str()),
DataType::GenericType { name, .. } => Some(name.as_str()),
DataType::VarArgs { referenced_type, .. } => referenced_type
.as_ref()
.and_then(|it| DataTypeDeclaration::get_name(it.as_ref()))
.or(Some(VOID_TYPE)),
DataType::VarArgs { referenced_type, .. } => {
referenced_type.as_ref().and_then(|it| DataTypeDeclaration::get_name(it.as_ref()))
}
}
}

Expand Down Expand Up @@ -858,7 +818,7 @@ pub enum AstStatement {
}

impl Debug for AstStatement {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
AstStatement::EmptyStatement { .. } => f.debug_struct("EmptyStatement").finish(),
AstStatement::DefaultValue { .. } => f.debug_struct("DefaultValue").finish(),
Expand Down Expand Up @@ -1184,7 +1144,7 @@ pub enum Operator {
}

impl Display for Operator {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let symbol = match self {
Operator::Plus => "+",
Operator::Minus => "-",
Expand Down Expand Up @@ -1234,7 +1194,7 @@ pub fn flatten_expression_list(list: &AstStatement) -> Vec<&AstStatement> {
expressions.iter().by_ref().flat_map(flatten_expression_list).collect()
}
AstStatement::MultipliedStatement { multiplier, element, .. } => {
iter::repeat(flatten_expression_list(element)).take(*multiplier as usize).flatten().collect()
std::iter::repeat(flatten_expression_list(element)).take(*multiplier as usize).flatten().collect()
}
_ => vec![list],
}
Expand All @@ -1245,7 +1205,7 @@ pub fn pre_process(unit: &mut CompilationUnit, id_provider: IdProvider) {
}
impl Operator {
/// returns true, if this operator results in a bool value
pub(crate) fn is_bool_type(&self) -> bool {
pub fn is_bool_type(&self) -> bool {
matches!(
self,
Operator::Equal
Expand All @@ -1259,7 +1219,7 @@ impl Operator {

/// returns true, if this operator is a comparison operator
/// (=, <>, >, <, >=, <=)
pub(crate) fn is_comparison_operator(&self) -> bool {
pub fn is_comparison_operator(&self) -> bool {
matches!(
self,
Operator::Equal
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::fmt::{Debug, Formatter, Result};
use std::fmt::{Debug, Formatter};

use super::AstStatement;
use crate::ast::AstStatement;

#[derive(Clone, PartialEq)]
pub struct IfStatement {
Expand Down Expand Up @@ -47,7 +47,7 @@ pub struct ConditionalBlock {
}

impl Debug for ConditionalBlock {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ConditionalBlock")
.field("condition", &self.condition)
.field("body", &self.body)
Expand Down
6 changes: 5 additions & 1 deletion compiler/plc_ast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@
//! It is currently only a re-export of the ast module from the root, but these should
//! eventually move here
pub use plc::ast::*;
pub mod ast;
pub mod control_statements;
pub mod literals;
mod pre_processor;
pub mod provider;
41 changes: 1 addition & 40 deletions src/ast/literals.rs → compiler/plc_ast/src/literals.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,8 @@
use std::fmt::{Debug, Formatter};

use crate::typesystem::{
BOOL_TYPE, DATE_AND_TIME_TYPE, DATE_TYPE, DINT_TYPE, INT_TYPE, LINT_TYPE, LREAL_TYPE, SINT_TYPE,
STRING_TYPE, TIME_OF_DAY_TYPE, TIME_TYPE, UDINT_TYPE, UINT_TYPE, ULINT_TYPE, USINT_TYPE, VOID_TYPE,
WSTRING_TYPE,
};
use chrono::NaiveDate;

use super::AstStatement;

//returns a range with the min and max value of the given type
macro_rules! is_covered_by {
($t:ty, $e:expr) => {
<$t>::MIN as i128 <= $e as i128 && $e as i128 <= <$t>::MAX as i128
};
}
use crate::ast::AstStatement;

macro_rules! impl_getters {
($type:ty, [$($name:ident),+], [$($out:ty),+]) => {
Expand Down Expand Up @@ -237,33 +225,6 @@ impl AstLiteral {
AstLiteral::Null
}

pub fn get_literal_actual_signed_type_name(&self, signed: bool) -> Option<&str> {
match self {
AstLiteral::Integer(value) => match signed {
_ if *value == 0_i128 || *value == 1_i128 => Some(BOOL_TYPE),
true if is_covered_by!(i8, *value) => Some(SINT_TYPE),
true if is_covered_by!(i16, *value) => Some(INT_TYPE),
true if is_covered_by!(i32, *value) => Some(DINT_TYPE),
true if is_covered_by!(i64, *value) => Some(LINT_TYPE),

false if is_covered_by!(u8, *value) => Some(USINT_TYPE),
false if is_covered_by!(u16, *value) => Some(UINT_TYPE),
false if is_covered_by!(u32, *value) => Some(UDINT_TYPE),
false if is_covered_by!(u64, *value) => Some(ULINT_TYPE),
_ => Some(VOID_TYPE),
},
AstLiteral::Bool { .. } => Some(BOOL_TYPE),
AstLiteral::String(StringValue { is_wide: true, .. }) => Some(WSTRING_TYPE),
AstLiteral::String(StringValue { is_wide: false, .. }) => Some(STRING_TYPE),
AstLiteral::Real { .. } => Some(LREAL_TYPE),
AstLiteral::Date { .. } => Some(DATE_TYPE),
AstLiteral::DateAndTime { .. } => Some(DATE_AND_TIME_TYPE),
AstLiteral::Time { .. } => Some(TIME_TYPE),
AstLiteral::TimeOfDay { .. } => Some(TIME_OF_DAY_TYPE),
_ => None,
}
}

pub fn get_literal_value(&self) -> String {
match self {
AstLiteral::String(StringValue { value, is_wide: true, .. }) => format!(r#""{value}""#),
Expand Down
Loading

0 comments on commit 3fa4916

Please sign in to comment.