diff --git a/ast-generator/src/deserialize.rs b/ast-generator/src/deserialize.rs index 8491925..ba0699c 100644 --- a/ast-generator/src/deserialize.rs +++ b/ast-generator/src/deserialize.rs @@ -1,4 +1,10 @@ -use crate::spec::{BooleanBuild, BuildSpec, ChildSpec, EnumBuildSpec, EnumRule, LeafEnumBuildSpec, LeafEnumRule, LeafEnumRuleBuild, LeafEnumRuleBuildChild, LeafStructBuildSpec, LeafStructChild, LeafStructChildType, SingleBooleanChildToBuild, SingleChild, SingleChildToBuild, SingleLiteralChildToBuild, SingleTypeChildToBuild, SkipChild, StructBuildSpec, VecChild, VecChildToBuild, VecTypeChildToBuild}; +use crate::spec::{ + BooleanBuild, BuildSpec, ChildSpec, EnumBuildSpec, EnumRule, LeafEnumBuildSpec, LeafEnumRule, + LeafEnumRuleBuild, LeafEnumRuleBuildChild, LeafStructBuildSpec, LeafStructChild, + LeafStructChildType, SingleBooleanChildToBuild, SingleChild, SingleChildToBuild, + SingleLiteralChildToBuild, SingleTypeChildToBuild, SkipChild, StructBuildSpec, VecChild, + VecChildToBuild, VecTypeChildToBuild, +}; use crate::util::make_build_fn_name; use convert_case::{Case, Casing}; use yaml_rust2::{Yaml, YamlLoader}; @@ -218,15 +224,13 @@ fn get_enum_rules(rule_specs: &Yaml) -> Vec { } fn get_leaf_struct_child_specs(children: &Yaml) -> Vec { - children.as_vec() + children + .as_vec() .unwrap() .iter() .map(|child_spec| { let (name, hash) = unwrap_single_member_hash(child_spec); - LeafStructChild::new( - &name, - LeafStructChildType::String - ) + LeafStructChild::new(&name, LeafStructChildType::String) }) .collect::>() } diff --git a/ast-generator/src/lib.rs b/ast-generator/src/lib.rs index 85b49c2..97d5eab 100644 --- a/ast-generator/src/lib.rs +++ b/ast-generator/src/lib.rs @@ -9,13 +9,13 @@ mod util; use crate::enum_build_fn::make_enum_build_fn; use crate::leaf_enum_build_fn::make_leaf_enum_build_fn; +use crate::leaf_struct_build_fn::make_leaf_struct_build_fn; use crate::struct_build_fn::make_struct_build_fn; use crate::type_gen::make_type; use proc_macro2::TokenStream; use quote::quote; use spec::BuildSpec; use syn::File; -use crate::leaf_struct_build_fn::make_leaf_struct_build_fn; fn debug_built_spec(build_spec: &BuildSpec, token_stream: &TokenStream) { println!("*** BuildSpec ***"); diff --git a/ast-generator/src/spec.rs b/ast-generator/src/spec.rs index 84ef085..15a6d8e 100644 --- a/ast-generator/src/spec.rs +++ b/ast-generator/src/spec.rs @@ -518,14 +518,14 @@ impl LeafStructChild { pub fn new(name: &str, r#type: LeafStructChildType) -> Self { Self { name: name.to_string(), - r#type + r#type, } } - + pub fn name(&self) -> &str { &self.name } - + pub fn r#type(&self) -> &LeafStructChildType { &self.r#type } diff --git a/ast-generator/src/struct_build_fn.rs b/ast-generator/src/struct_build_fn.rs index 2bc781b..bb1380c 100644 --- a/ast-generator/src/struct_build_fn.rs +++ b/ast-generator/src/struct_build_fn.rs @@ -2,10 +2,9 @@ use crate::spec::{ BooleanBuild, ChildSpec, SingleBooleanChildToBuild, SingleChildToBuild, SingleLiteralChildToBuild, SingleTypeChildToBuild, StructBuildSpec, VecChild, VecChildToBuild, }; -use convert_case::{Case, Casing}; +use crate::util::make_build_pair; use proc_macro2::{Ident, TokenStream}; use quote::{format_ident, quote}; -use crate::util::make_build_pair; fn make_vec_child_holder(vec_child: &VecChild) -> TokenStream { let (child_ident, child_type_ident) = match vec_child.build() { diff --git a/ast-generator/src/type_gen.rs b/ast-generator/src/type_gen.rs index 805d12a..2bed52c 100644 --- a/ast-generator/src/type_gen.rs +++ b/ast-generator/src/type_gen.rs @@ -102,15 +102,35 @@ fn handle_single_type_child( #child_ident: Box<#child_type_ident> }) } - accessors.push(quote! { - pub fn #child_ident(&self) -> &#child_type_ident { - self.#child_ident.as_ref() - } + if single_type_child.optional() { + accessors.push(quote! { + pub fn #child_ident(&self) -> Option<&#child_type_ident> { + if let Some(#child_ident) = &self.#child_ident { + Some(#child_ident.as_ref()) + } else { + None + } + } - pub fn #child_ident_mut(&mut self) -> &mut #child_type_ident { - self.#child_ident.as_mut() - } - }); + pub fn #child_ident_mut(&mut self) -> Option<&mut #child_type_ident> { + if let Some(#child_ident) = &mut self.#child_ident { + Some(#child_ident.as_mut()) + } else { + None + } + } + }) + } else { + accessors.push(quote! { + pub fn #child_ident(&self) -> &#child_type_ident { + self.#child_ident.as_ref() + } + + pub fn #child_ident_mut(&mut self) -> &mut #child_type_ident { + self.#child_ident.as_mut() + } + }); + } } fn handle_single_boolean_child( @@ -229,7 +249,7 @@ fn make_leaf_struct_type(build_spec: &LeafStructBuildSpec) -> TokenStream { } }) .collect::>(); - + quote! { pub struct #type_ident { #(#annotated_members),* diff --git a/ast-generator/src/util.rs b/ast-generator/src/util.rs index 8d94e3a..ae0220b 100644 --- a/ast-generator/src/util.rs +++ b/ast-generator/src/util.rs @@ -6,4 +6,4 @@ pub fn make_build_fn_name(s: &str) -> String { pub fn make_build_pair(s: &str) -> String { format!("{}_pair", s.to_case(Case::Snake)) -} \ No newline at end of file +} diff --git a/build.rs b/build.rs index b4e88be..de92dc2 100644 --- a/build.rs +++ b/build.rs @@ -17,7 +17,7 @@ fn generate_parser_tests(out_dir: &Path) -> io::Result<()> { fn generate_ast_files(out_dir: &Path) -> io::Result<()> { let gen_ast_dir = out_dir.join("src").join("ast"); fs::create_dir_all(&gen_ast_dir)?; - + let ast_yaml = include_str!("src/parser/ast.yaml"); let build_specs = deserialize::deserialize_yaml_spec(ast_yaml); let generated_files = generate_files(&build_specs); diff --git a/cst-test-generator/src/lib.rs b/cst-test-generator/src/lib.rs index 4f56bdc..4ced8eb 100644 --- a/cst-test-generator/src/lib.rs +++ b/cst-test-generator/src/lib.rs @@ -46,7 +46,7 @@ pub fn generate_test_files(tests_dir: &Path) -> io::Result let test_suite = quote! { mod #tests_mod_ident { use super::*; - + #(#tests)* } }; @@ -59,7 +59,7 @@ pub fn generate_test_files(tests_dir: &Path) -> io::Result // generate main test_suites file let test_suites = quote! { use super::*; - + #(#test_suites)* }; let test_suites_file: File = syn::parse2(test_suites).unwrap(); diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 17abf56..e213d71 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -5,6 +5,8 @@ pub mod node { pub mod build { //noinspection RsUnusedImport use crate::parser::Rule; - + //noinspection RsUnusedImport + use crate::ast::node::*; + include!(concat!(env!("OUT_DIR"), "/src/ast/build.rs")); } diff --git a/src/bin/dmc/main.rs b/src/bin/dmc/main.rs index 32530dc..380ae2e 100644 --- a/src/bin/dmc/main.rs +++ b/src/bin/dmc/main.rs @@ -1,14 +1,14 @@ // mod name_analysis; // mod p3; // mod unparse; -// +// // use std::path::PathBuf; -// +// // use crate::name_analysis::name_analysis; // use crate::p3::pretty_print_parse; // use crate::unparse::unparse; // use clap::{Parser, Subcommand}; -// +// // #[derive(Debug, Parser)] // #[command(name = "dmc")] // #[command(about = "Deimos Compiler", long_about = None)] @@ -16,7 +16,7 @@ // #[command(subcommand)] // command: Commands, // } -// +// // #[derive(Debug, Subcommand)] // enum Commands { // #[command(arg_required_else_help = true)] @@ -30,7 +30,7 @@ // paths: Vec, // }, // } -// +// // fn main() { // let args = Cli::parse(); // match args.command { diff --git a/src/module/mod.rs b/src/module/mod.rs index 2354a6c..924209b 100644 --- a/src/module/mod.rs +++ b/src/module/mod.rs @@ -4,14 +4,12 @@ pub struct DmModule { pub enum NamespaceVisibility { Public, - Partial { - visible_to_fqns: Vec - }, - Private + Partial { visible_to_fqns: Vec }, + Private, } pub struct DmNamespace { pub name: String, pub dependencies: Vec, - pub visibility: NamespaceVisibility + pub visibility: NamespaceVisibility, } diff --git a/src/parser/ast.yaml b/src/parser/ast.yaml index 5a81d35..cb2801d 100644 --- a/src/parser/ast.yaml +++ b/src/parser/ast.yaml @@ -415,10 +415,14 @@ InterfaceDefaultOperatorFunction: # Function Bodies FunctionBody: + type: leaf_enum rules: - - FunctionAliasBody - - FunctionEqualsBody - - FunctionBlockBody + - FunctionAliasBody: + child: true + - FunctionEqualsBody: + child: true + - FunctionBlockBody: + child: true FunctionEqualsBody: children: - expression @@ -460,14 +464,22 @@ Member: # Statements Statement: + type: leaf_enum rules: - - VariableDeclaration - - AssignmentStatement - - ExpressionStatement - - UseStatement - - IfStatement - - WhileStatement - - ForStatement + - VariableDeclaration: + child: true + - AssignmentStatement: + child: true + - ExpressionStatement: + child: true + - UseStatement: + child: true + - IfStatement: + child: true + - WhileStatement: + child: true + - ForStatement: + child: true VariableDeclaration: children: - let_kw: @@ -701,17 +713,23 @@ ObjectIndex: children: - expression PrimaryExpression: + type: leaf_enum rules: - - Literal - - FullyQualifiedName - - Closure - - ParenthesizedExpression + - Literal: + child: true + - FullyQualifiedName: + child: true + - Closure: + child: true + - ParenthesizedExpression: + child: true ParenthesizedExpression: children: - expression # Calls Call: + type: leaf_enum rules: - ParenthesesCall - NonParenthesesCall @@ -762,38 +780,46 @@ ClosureParameter: # Literals Literal: + type: leaf_enum rules: - - NumberLiteral - - StringLiteral - - BooleanLiteral + - NumberLiteral: + child: true + - StringLiteral: + child: true + - BooleanLiteral: + child: true NumberLiteral: + type: leaf_enum rules: - - DoubleLiteral - - LongLiteral - - IntLiteral + - DoubleLiteral: + child: true + - LongLiteral: + child: true + - IntLiteral: + child: true IntLiteral: children: - number_base - - literal: - build: - type: i32 LongLiteral: children: - number_base - - literal: - build: - type: i64 DoubleLiteral: + type: leaf_struct children: - literal: build: type: f64 NumberBase: + type: leaf_enum rules: - - BinaryBase - - HexadecimalBase - - DecimalBase + - BinaryBase: + child: true + - HexadecimalBase: + child: true + - DecimalBase: + child: true DecimalBase: + type: leaf_struct children: - literal: build: @@ -802,6 +828,7 @@ BinaryBase: children: - binary_digits BinaryDigits: + type: leaf_struct children: - literal: build: @@ -810,15 +837,20 @@ HexadecimalBase: children: - hexadecimal_digits HexadecimalDigits: + type: leaf_struct children: - literal: build: type: string StringLiteral: + type: leaf_enum rules: - - SingleQuoteString - - DoubleQuoteString - - BacktickString + - SingleQuoteString: + child: true + - DoubleQuoteString: + child: true + - BacktickString: + child: true SingleQuoteString: children: - string_inner: @@ -832,11 +864,13 @@ DoubleQuoteString: rule: DStringExpression vec: true StringInner: + type: leaf_struct children: - literal: build: type: string DStringInner: + type: leaf_struct children: - literal: build: @@ -853,11 +887,13 @@ BacktickString: rule: DStringExpression vec: true BacktickInner: + type: leaf_struct children: - literal: build: type: string BooleanLiteral: + type: leaf_struct children: - literal: build: diff --git a/src/util/indent_writer.rs b/src/util/indent_writer.rs index 36aa913..544fbe3 100644 --- a/src/util/indent_writer.rs +++ b/src/util/indent_writer.rs @@ -5,9 +5,13 @@ pub struct IndentWriter { } impl IndentWriter { - pub fn new(start_level: usize, indent_string: &str, out: Box) -> IndentWriter { + pub fn new( + start_level: usize, + indent_string: &str, + out: Box, + ) -> IndentWriter { IndentWriter { - indent_level: start_level, + indent_level: start_level, indent_string: indent_string.to_string(), out, } @@ -24,7 +28,7 @@ impl IndentWriter { pub fn write(&mut self, s: &str) -> std::io::Result<()> { write!(self.out, "{}", s) } - + pub fn writeln(&mut self, s: &str) -> std::io::Result<()> { self.write(&format!("{}\n", s)) } @@ -35,7 +39,7 @@ impl IndentWriter { } write!(self.out, "{}", s) } - + pub fn writeln_indented(&mut self, s: &str) -> std::io::Result<()> { self.write_indented(&format!("{}\n", s)) } diff --git a/src/vm/constant.rs b/src/vm/constant.rs index 4fbdb01..03cf434 100644 --- a/src/vm/constant.rs +++ b/src/vm/constant.rs @@ -1,7 +1,7 @@ #[derive(Debug, Clone)] pub enum DvmConstant { String(String), - Array(DvmConstantArray) + Array(DvmConstantArray), } #[derive(Debug, Clone)] @@ -13,5 +13,5 @@ pub enum DvmConstantArray { USizes(Vec), Booleans(Vec), Strings(Vec), - Arrays(Vec) -} \ No newline at end of file + Arrays(Vec), +} diff --git a/src/vm/function.rs b/src/vm/function.rs index d6cece1..909d414 100644 --- a/src/vm/function.rs +++ b/src/vm/function.rs @@ -28,7 +28,7 @@ impl DvmFunction { pub fn instructions(&self) -> &Vec { &self.instructions } - + pub fn source_code_location(&self) -> &SourceCodeLocation { &self.source_code_location } diff --git a/src/vm/instruction.rs b/src/vm/instruction.rs index e105473..f18206d 100644 --- a/src/vm/instruction.rs +++ b/src/vm/instruction.rs @@ -111,8 +111,8 @@ pub enum Instruction { }, Return, DumpState { - message: String - } + message: String, + }, } #[derive(Debug, Clone)] diff --git a/src/vm/method.rs b/src/vm/method.rs index 6b7a67e..80848d0 100644 --- a/src/vm/method.rs +++ b/src/vm/method.rs @@ -21,7 +21,7 @@ impl DvmMethod { implements, } } - + pub fn fqn(&self) -> &str { self.function.fqn() } diff --git a/src/vm/source_code_location.rs b/src/vm/source_code_location.rs index b381eda..74ab63b 100644 --- a/src/vm/source_code_location.rs +++ b/src/vm/source_code_location.rs @@ -10,7 +10,7 @@ impl SourceCodeLocation { SourceCodeLocation { source_file_name: source_file_name.to_string(), line, - col + col, } } } diff --git a/src/vm/type.rs b/src/vm/type.rs index db17db3..e8f31f8 100644 --- a/src/vm/type.rs +++ b/src/vm/type.rs @@ -7,9 +7,9 @@ pub enum DvmType { Double, Boolean, USize, - + // Other Object, Array, - ConstantPointer + ConstantPointer, } diff --git a/src/vm/value.rs b/src/vm/value.rs index 449e8fa..64e30be 100644 --- a/src/vm/value.rs +++ b/src/vm/value.rs @@ -70,7 +70,7 @@ impl DvmValue { panic!("Expected DvmValue::Int, but found DvmValue::{:?}", self); } } - + pub fn expect_int_or_else(&self, f: impl FnOnce(&Self) -> i32) -> i32 { if let DvmValue::Int(i) = self { *i