diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index b9dd6e1..2f210eb 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -4,14 +4,14 @@ on: push: branches: [ "main" ] paths: - - ocean_helpers/** + - ocean-macros/** - src/** - std/** - examples/** pull_request: branches: [ "main" ] paths: - - ocean_helpers/** + - ocean-macros/** - src/** - std/** - examples/** diff --git a/Cargo.lock b/Cargo.lock index 76a41c9..eec4521 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -267,19 +267,19 @@ dependencies = [ "graphviz-rust", "itertools", "lazy_static", - "ocean_helpers", + "ocean-macros", "rustyline", "uuid", "which", ] [[package]] -name = "ocean_helpers" +name = "ocean-macros" version = "0.1.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 1.0.109", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index bad114d..d78983a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ debug = true graphviz-rust = "0.6.6" itertools = "0.11.0" lazy_static = "1.4.0" -ocean_helpers = { path = "ocean_helpers" } +ocean-macros = { path = "ocean-macros" } rustyline = "12.0.0" uuid = "1.7.0" which = "5.0.0" diff --git a/ocean_helpers/Cargo.lock b/ocean-macros/Cargo.lock similarity index 63% rename from ocean_helpers/Cargo.lock rename to ocean-macros/Cargo.lock index 992ea82..270d8a6 100644 --- a/ocean_helpers/Cargo.lock +++ b/ocean-macros/Cargo.lock @@ -3,7 +3,7 @@ version = 3 [[package]] -name = "ocean_macros" +name = "ocean-macros" version = "0.1.0" dependencies = [ "proc-macro2", @@ -13,27 +13,27 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.31" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] [[package]] name = "syn" -version = "2.0.26" +version = "2.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" dependencies = [ "proc-macro2", "quote", @@ -42,6 +42,6 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" diff --git a/ocean_helpers/Cargo.toml b/ocean-macros/Cargo.toml similarity index 80% rename from ocean_helpers/Cargo.toml rename to ocean-macros/Cargo.toml index 15f12cd..f326375 100644 --- a/ocean_helpers/Cargo.toml +++ b/ocean-macros/Cargo.toml @@ -1,10 +1,10 @@ [package] -name = "ocean_helpers" +name = "ocean-macros" version = "0.1.0" edition = "2021" [lib] -name = "ocean_helpers" +name = "ocean_macros" path = "src/lib.rs" proc-macro = true diff --git a/ocean_helpers/src/lib.rs b/ocean-macros/src/lib.rs similarity index 92% rename from ocean_helpers/src/lib.rs rename to ocean-macros/src/lib.rs index 2884f90..a4f668f 100644 --- a/ocean_helpers/src/lib.rs +++ b/ocean-macros/src/lib.rs @@ -45,8 +45,7 @@ fn impl_ast_node_macro(ast: &syn::DeriveInput) -> TokenStream { gen.into() } - -#[proc_macro_derive(New)] +#[proc_macro_derive(New, attributes(default))] pub fn new_macro_derive(input: TokenStream) -> TokenStream { let ast = syn::parse(input).unwrap(); impl_new_macro(&ast) @@ -65,9 +64,16 @@ fn impl_new_macro(ast: &syn::DeriveInput) -> TokenStream { match &struct_data.fields { Fields::Named(named_fields) => { for field in &named_fields.named { + let default_value_attribute = field.attrs.iter().filter(|x| x.path.segments.len() == 1 && x.path.segments[0].ident == "default").nth(0); + let optional_default_value = if let Some(attr) = default_value_attribute { + Some(attr.tokens.to_token_stream()) + } else { + None + }; + match &field.ident { Some(field_name) => { - typed_args.push((field_name.to_string(), field.ty.to_token_stream())) + typed_args.push((field_name.to_string(), field.ty.to_token_stream(), optional_default_value)) } None => {} } @@ -77,7 +83,9 @@ fn impl_new_macro(ast: &syn::DeriveInput) -> TokenStream { } token_stream += "pub fn new("; - for (idx, (arg_name, arg_type)) in typed_args.iter().enumerate() { + for (idx, (arg_name, arg_type, arg_default_value)) in typed_args.iter().enumerate() { + if arg_default_value.is_some() { continue } + token_stream += arg_name.to_string().as_str(); token_stream += ": "; token_stream += arg_type.to_string().as_str(); @@ -86,8 +94,12 @@ fn impl_new_macro(ast: &syn::DeriveInput) -> TokenStream { } } token_stream += ") -> Self { Self { "; - for (idx, (arg_name, _)) in typed_args.iter().enumerate() { + for (idx, (arg_name, _, arg_default_value)) in typed_args.iter().enumerate() { token_stream += arg_name; + if let Some(value) = arg_default_value { + token_stream += ": "; + token_stream += value.to_string().as_str(); + } if idx != typed_args.len() - 1 { token_stream += ", " } diff --git a/src/hydro/executioncontext.rs b/src/hydro/executioncontext.rs index 7e010b8..51db444 100644 --- a/src/hydro/executioncontext.rs +++ b/src/hydro/executioncontext.rs @@ -2,7 +2,7 @@ use super::value::Value; use crate::hydro::exception::Exception; use crate::hydro::value::Reference; -use ocean_helpers::{make_add_operations, make_bit_operations, make_comparison_operations}; +use ocean_macros::{make_add_operations, make_bit_operations, make_comparison_operations}; use std::collections::HashMap; use std::ops::Deref; diff --git a/src/hydro/frontend/parser.rs b/src/hydro/frontend/parser.rs index 3a2e33a..f959cff 100644 --- a/src/hydro/frontend/parser.rs +++ b/src/hydro/frontend/parser.rs @@ -502,7 +502,7 @@ impl Parser { fn create_default_value_from_type_string(type_lexeme: String) -> Value { match type_lexeme.as_str() { "bool" => Value::Boolean(false), - "string" => Value::Array(Array::new(Type::Unsigned8, Box::new(Value::Unsigned8(0)))), + "string" => Value::Array(Array::new(Type::Unsigned8, Box::new(Value::Unsigned8(0)), Vec::new())), "u8" => Value::Unsigned8(0), "u16" => Value::Unsigned16(0), "u32" => Value::Unsigned32(0), diff --git a/src/hydro/function.rs b/src/hydro/function.rs index 1dea7ee..3b82062 100644 --- a/src/hydro/function.rs +++ b/src/hydro/function.rs @@ -2,6 +2,7 @@ use crate::hydro::function::Target::{Index, Label}; use crate::hydro::instruction::*; use crate::hydro::value::{Reference, Type, Value, VariableRef}; use std::collections::HashMap; +use ocean_macros::New; #[derive(Debug, Clone)] pub enum Target { @@ -9,19 +10,16 @@ pub enum Target { Index(usize), } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, New)] pub struct Function { pub name: String, pub parameters: Vec, pub body: Vec, + #[default(HashMap::new())] pub jump_labels: HashMap, } impl Function { - pub fn new(name: String, parameters: Vec, body: Vec) -> Self { - Self { name, parameters, body, jump_labels: HashMap::new() } - } - pub fn get_target_pointer(&self, target: Target) -> Result { match target { Label(label_name) => match self.jump_labels.get(label_name.as_str()) { diff --git a/src/hydro/instruction.rs b/src/hydro/instruction.rs index fb5a906..2eceb9e 100644 --- a/src/hydro/instruction.rs +++ b/src/hydro/instruction.rs @@ -1,7 +1,7 @@ use super::value::Value; use crate::hydro::function::Target; use crate::hydro::value::Type; -use ocean_helpers::Debuggable; +use ocean_macros::Debuggable; // Intellij thinks these are unused but they are used by the Debuggable derive macro use crate::hydro::compilationunit::CompilationUnit; use crate::hydro::debugcontext::DebugContext; diff --git a/src/hydro/intrinsic.rs b/src/hydro/intrinsic.rs index 9287ecc..450907e 100644 --- a/src/hydro/intrinsic.rs +++ b/src/hydro/intrinsic.rs @@ -1,9 +1,10 @@ use crate::hydro::value::Type; use std::collections::HashMap; +use ocean_macros::New; pub mod intrinsicmanager; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, New)] pub struct Intrinsic { pub name: String, pub parameters: Vec, @@ -11,10 +12,6 @@ pub struct Intrinsic { } impl Intrinsic { - pub fn new(name: String, parameters: Vec, target_map: HashMap) -> Self { - Self { name, parameters, target_map } - } - pub fn get_intrinsic_code(&self, target: String) -> Result { match self.target_map.get(target.as_str()) { None => Err(format!("Could not find code for target {}", target)), diff --git a/src/hydro/layouttemplate.rs b/src/hydro/layouttemplate.rs index 0427bf0..ae96820 100644 --- a/src/hydro/layouttemplate.rs +++ b/src/hydro/layouttemplate.rs @@ -1,17 +1,14 @@ use crate::hydro::value::{Layout, Type, Value}; use std::collections::HashMap; +use ocean_macros::New; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, New)] pub struct LayoutTemplate { pub name: String, pub members: HashMap, } impl LayoutTemplate { - pub fn new(name: String, members: HashMap) -> Self { - Self { name, members } - } - pub fn build(name: &str) -> Self { Self { name: name.to_string(), members: HashMap::new() } } diff --git a/src/hydro/value.rs b/src/hydro/value.rs index 6b20c72..e9570ed 100644 --- a/src/hydro/value.rs +++ b/src/hydro/value.rs @@ -1,5 +1,6 @@ use std::cmp::Ordering; use std::collections::HashMap; +use ocean_macros::New; #[derive(Debug, Clone, PartialEq)] pub enum Type { @@ -143,7 +144,7 @@ pub enum Value { impl Value { pub fn string(value: String) -> Value { let bytes = value.clone().into_bytes().iter().map(|x| Value::Unsigned8(*x)).collect::>(); - Value::Array(Array::create(Type::Unsigned8, Box::new(Value::Unsigned64(value.len() as u64)), bytes)) + Value::Array(Array::new(Type::Unsigned8, Box::new(Value::Unsigned64(value.len() as u64)), bytes)) } pub fn type_of(&self) -> Type { @@ -330,18 +331,12 @@ impl Value { } } -#[derive(Debug, Clone, PartialEq, PartialOrd)] +#[derive(Debug, Clone, PartialEq, PartialOrd, New)] pub struct FunctionPointer { pub module: Option, pub function: String, } -impl FunctionPointer { - pub fn new(module: Option, function: String) -> Self { - Self { module, function } - } -} - #[derive(Debug, Clone, PartialEq, PartialOrd)] pub enum Reference { Variable(VariableRef), @@ -349,71 +344,37 @@ pub enum Reference { LayoutIndex(LayoutIndexRef), } -#[derive(Debug, Clone, PartialEq, PartialOrd)] +#[derive(Debug, Clone, PartialEq, PartialOrd, New)] pub struct VariableRef { pub name: String, } -impl VariableRef { - pub fn new(name: String) -> Self { - Self { name } - } -} - -#[derive(Debug, Clone, PartialEq, PartialOrd)] +#[derive(Debug, Clone, PartialEq, PartialOrd, New)] pub struct ArrayIndexRef { pub reference: Box, pub index: Box, } -impl ArrayIndexRef { - pub fn new(reference: Box, index: Box) -> Self { - Self { reference, index } - } -} - -#[derive(Debug, Clone, PartialEq, PartialOrd)] +#[derive(Debug, Clone, PartialEq, PartialOrd, New)] pub struct LayoutIndexRef { pub reference: Box, pub index: String, } -impl LayoutIndexRef { - pub fn new(reference: Box, index: String) -> Self { - Self { reference, index } - } -} - -#[derive(Debug, Clone, PartialEq, PartialOrd)] +#[derive(Debug, Clone, PartialEq, PartialOrd, New)] pub struct Array { pub value_type: Type, pub length: Box, pub values: Vec, } -impl Array { - pub fn new(value_type: Type, length: Box) -> Self { - Self { value_type, length, values: Vec::new() } - } - - pub fn create(value_type: Type, length: Box, values: Vec) -> Self { - Self { value_type, length, values } - } -} - -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, New)] pub struct Layout { pub module_name: String, pub layout_name: String, pub values: HashMap, } -impl Layout { - pub fn new(module_name: String, layout_name: String, values: HashMap) -> Self { - Self { module_name, layout_name, values } - } -} - impl PartialOrd for Layout { fn partial_cmp(&self, _other: &Self) -> Option { todo!() diff --git a/src/ocean/frontend/ast.rs b/src/ocean/frontend/ast.rs index c437fa5..511f207 100644 --- a/src/ocean/frontend/ast.rs +++ b/src/ocean/frontend/ast.rs @@ -1,7 +1,7 @@ use crate::ocean::frontend::tokentype::TokenType; use crate::util::token::Token; use itertools::Either; -use ocean_helpers::New; +use ocean_macros::New; #[derive(Clone, Debug, New)] pub struct Program { @@ -26,18 +26,13 @@ pub struct Comment { pub token: Token, } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, New)] pub struct Annotation { pub token: Token, + #[default(None)] pub annotation_ast: Option, } -impl Annotation { - pub fn new(token: Token) -> Self { - Self { token, annotation_ast: None } - } -} - #[derive(Clone, Debug)] pub enum Statement { WhileLoop(WhileLoop), @@ -370,19 +365,13 @@ pub struct UsingPathEntry { pub dot_token: Option>, } -// This may result in multiple sub expressions -#[derive(Clone, Debug)] +#[derive(Clone, Debug, New)] pub struct ExpressionNode { pub tokens: Vec, AstNodeExpression>>, + #[default(None)] pub parsed_expression: Option, } -impl ExpressionNode { - pub fn new(tokens: Vec, AstNodeExpression>>) -> Self { - Self { tokens, parsed_expression: None } - } -} - // Expression ast nodes #[derive(Clone, Debug)] diff --git a/src/ocean/frontend/parser/astsymbolstack.rs b/src/ocean/frontend/parser/astsymbolstack.rs index b92bb81..939c7fb 100644 --- a/src/ocean/frontend/parser/astsymbolstack.rs +++ b/src/ocean/frontend/parser/astsymbolstack.rs @@ -1,4 +1,5 @@ use itertools::Either; +use ocean_macros::New; use crate::ocean::frontend::ast::*; use crate::ocean::frontend::tokentype::TokenType; use crate::util::token::Token; @@ -39,16 +40,13 @@ pub enum AstSymbol { ExpressionTokenList(Vec, AstNodeExpression>>), } -#[derive(Debug)] +#[derive(Debug, New)] pub struct AstSymbolStack { + #[default(Vec::new())] stack: Vec, } impl AstSymbolStack { - pub fn new() -> Self { - Self { stack: Vec::new() } - } - pub fn peek(&self) -> Option { if self.stack.is_empty() { None diff --git a/src/ocean/frontend/parser/parsestatestack.rs b/src/ocean/frontend/parser/parsestatestack.rs index b60ed4d..bffbf78 100644 --- a/src/ocean/frontend/parser/parsestatestack.rs +++ b/src/ocean/frontend/parser/parsestatestack.rs @@ -1,3 +1,5 @@ +use ocean_macros::New; + #[derive(Clone, Debug, PartialEq)] pub enum ParseState { StatementList, @@ -82,15 +84,13 @@ pub enum ParseState { CompoundStatement, } +#[derive(New)] pub struct ParseStateStack { + #[default(Vec::new())] stack: Vec, } impl ParseStateStack { - pub fn new() -> Self { - Self { stack: Vec::new() } - } - pub fn print(&self) { print!("STATE STACK: "); for entry in &self.stack { diff --git a/src/ocean/frontend/parser/precedencetable.rs b/src/ocean/frontend/parser/precedencetable.rs index 3b5dbcb..9814033 100644 --- a/src/ocean/frontend/parser/precedencetable.rs +++ b/src/ocean/frontend/parser/precedencetable.rs @@ -1,21 +1,14 @@ use std::collections::HashMap; +use ocean_macros::New; -#[derive(Clone, Debug)] +#[derive(Clone, Debug, New)] pub struct PrecedenceTable { - prefix_op_table: HashMap, - postfix_op_table: HashMap, - binary_table: HashMap, + #[default(HashMap::new())] prefix_op_table: HashMap, + #[default(HashMap::new())] postfix_op_table: HashMap, + #[default(HashMap::new())] binary_table: HashMap, } impl PrecedenceTable { - pub fn new() -> Self { - Self { - prefix_op_table: HashMap::new(), - postfix_op_table: HashMap::new(), - binary_table: HashMap::new(), - } - } - pub fn is_prefix_operator(&self, operator: &String) -> bool { self.prefix_op_table.contains_key(operator) } diff --git a/src/ocean/frontend/semanticanalysis.rs b/src/ocean/frontend/semanticanalysis.rs index 1e7ea4c..479e0ec 100644 --- a/src/ocean/frontend/semanticanalysis.rs +++ b/src/ocean/frontend/semanticanalysis.rs @@ -1,5 +1,3 @@ -#![allow(unused_variables)] - use std::cell::RefCell; use std::rc::Rc; use itertools::Either; @@ -140,7 +138,7 @@ impl SemanticallyAnalyzable for WhileLoop { impl SemanticallyAnalyzable for ForLoop { fn analyze(&self, table: Rc>, context: AnalyzerContext) -> (Option, Vec) { - let mut new_table = SymbolTable::soft_scope(Some(table)); + let new_table = SymbolTable::soft_scope(Some(table)); let (iterable_type, mut results) = self.iterable.analyze(new_table.clone(), context); join_errors(&mut results, &mut self.iterator.analyze(new_table.clone(), context.create_assignment_target(iterable_type))); @@ -240,7 +238,7 @@ impl SemanticallyAnalyzable for Function { }; if let Some(cmpd_stmt) = &self.compound_statement { - let mut new_scope = SymbolTable::hard_scope(Some(table)); + let new_scope = SymbolTable::hard_scope(Some(table)); for (param_name, param_span, param_type) in param_types { match new_scope.borrow_mut().add_variable(param_name, param_span, param_type) { Ok(()) => (), diff --git a/src/ocean/frontend/symboltable.rs b/src/ocean/frontend/symboltable.rs index b2d6643..60c425d 100644 --- a/src/ocean/frontend/symboltable.rs +++ b/src/ocean/frontend/symboltable.rs @@ -1,7 +1,7 @@ -use std::cell::{Cell, RefCell}; +use std::cell::RefCell; use std::collections::HashMap; use std::rc::Rc; -use ocean_helpers::New; +use ocean_macros::New; use uuid::Uuid; use crate::util::errors::{Error, ErrorMetadata, Severity}; diff --git a/src/util/errors.rs b/src/util/errors.rs index 0b63398..74a33c8 100644 --- a/src/util/errors.rs +++ b/src/util/errors.rs @@ -1,10 +1,10 @@ -use ocean_helpers::New; - /* this was taken from the SerentiyOS/jakt repo and modified slightly to work how I wanted it to. */ +use ocean_macros::New; + #[derive(Clone, Debug)] pub enum Severity { Hint, @@ -30,20 +30,15 @@ impl Severity { } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, New)] pub struct ErrorMetadata { + #[default(Vec::new())] suggestions: Vec, + #[default(Vec::new())] extra_code_spans: Vec<((usize, usize), String)> } impl ErrorMetadata { - pub fn new() -> Self { - Self { - suggestions: Vec::new(), - extra_code_spans: Vec::new(), - } - } - pub fn suggestion(mut self, message: String) -> Self { self.suggestions.push(message); self @@ -55,24 +50,16 @@ impl ErrorMetadata { } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, New)] pub struct Error { pub severity: Severity, pub span: (usize, usize), pub message: String, + #[default(None)] pub metadata: Option, } impl Error { - pub fn new(severity: Severity, span: (usize, usize), message: String) -> Self { - Self { - severity, - span, - message, - metadata: None, - } - } - pub fn new_with_metadata(severity: Severity, span: (usize, usize), message: String, metadata: ErrorMetadata) -> Self { Self { severity, diff --git a/src/util/metrictracker.rs b/src/util/metrictracker.rs index 8505850..71c0d5f 100644 --- a/src/util/metrictracker.rs +++ b/src/util/metrictracker.rs @@ -2,17 +2,15 @@ use itertools::Itertools; use std::cmp::Ordering; use std::collections::HashMap; use std::time::{Duration, Instant}; +use ocean_macros::New; +#[derive(New)] pub struct MetricTracker { - current_metrics: HashMap<(Vec, String), Vec>, - finished_metrics: HashMap<(Vec, String), Vec>, + #[default(HashMap::new())] current_metrics: HashMap<(Vec, String), Vec>, + #[default(HashMap::new())] finished_metrics: HashMap<(Vec, String), Vec>, } impl MetricTracker { - pub fn new() -> Self { - Self { current_metrics: HashMap::new(), finished_metrics: HashMap::new() } - } - pub fn start(&mut self, stack: Vec, metric_name: String) { let mut new_metric = Metric::new(); @@ -175,7 +173,7 @@ impl MetricTracker { } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, New)] pub struct Flamegraph { pub stack: Vec, pub metric_name: String, @@ -185,10 +183,6 @@ pub struct Flamegraph { } impl Flamegraph { - pub fn new(stack: Vec, metric_name: String, start: Instant, duration: Duration, subgraph: Vec) -> Self { - Self { stack, metric_name, start, duration, subgraph } - } - pub fn print(&self, units: String) { self.print_internal("".to_string(), units); } @@ -301,20 +295,16 @@ impl MetricResults { } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, New)] pub struct Metric { - start_time: Option, + #[default(None)] start_time: Option, // if the metric wasn't paused this is just a single Duration - durations: Vec, - current_instant: Option, - is_paused: bool, + #[default(Vec::new())] durations: Vec, + #[default(None)] current_instant: Option, + #[default(false)] is_paused: bool, } impl Metric { - pub fn new() -> Self { - Self { start_time: None, durations: Vec::new(), current_instant: None, is_paused: false } - } - pub fn start(&mut self) { self.start_time = match self.start_time { Some(instant) => Some(instant),