From d079d3ae2dae298d54fd49419521aa86071da4c9 Mon Sep 17 00:00:00 2001 From: Giordano Salvador <73959795+e3m3@users.noreply.github.com> Date: Wed, 11 Sep 2024 17:47:48 -0400 Subject: [PATCH] Refactoring after clippy lint --- Cargo.toml | 3 ++ src/ast.rs | 11 ++--- src/irgen.rs | 16 +++---- src/lex.rs | 58 +++++++++++++----------- src/main.rs | 42 +++++++++--------- src/maingen.rs | 26 +++++------ src/module.rs | 86 +++++++++++------------------------- src/options.rs | 6 +-- src/parse.rs | 21 ++++----- src/sem.rs | 64 ++------------------------- src/target.rs | 50 ++------------------- tests/lit-llvm/sem_repr.calc | 16 ------- 12 files changed, 118 insertions(+), 281 deletions(-) delete mode 100644 tests/lit-llvm/sem_repr.calc diff --git a/Cargo.toml b/Cargo.toml index 5408fdc..1725c03 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,6 @@ llvm-sys = { version = "=181.1.1", features = ["force-dynamic"] } [dev-dependencies] lit = "1.0.4" + +[lints.clippy] +unused_unit = "allow" diff --git a/src/ast.rs b/src/ast.rs index 47a5efa..0df64fe 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -55,8 +55,9 @@ pub fn op_to_string(op: &Operator) -> String { pub type Vars = Vec; -#[derive(Clone)] +#[derive(Clone,Default)] pub enum ExprKind<'a> { + #[default] Undefined, Factor(Factor), BinaryOp(Operator, &'a Expr<'a>, &'a Expr<'a>), @@ -67,12 +68,6 @@ pub fn vars_to_string(vars: &Vars) -> String { format!("Vars([{}])", vars.join(",")) } -impl <'a> Default for ExprKind<'a> { - fn default() -> Self { - ExprKind::Undefined - } -} - pub struct Expr<'a> { expr: ExprKind<'a>, vars: usize, @@ -80,7 +75,7 @@ pub struct Expr<'a> { impl <'a> Expr<'a> { pub fn new(expr: ExprKind<'a>, n: usize) -> Self { - Expr{expr: expr, vars: n} + Expr{expr, vars: n} } pub fn new_number(n: i64) -> Self { diff --git a/src/irgen.rs b/src/irgen.rs index 6561961..70c7dc9 100644 --- a/src/irgen.rs +++ b/src/irgen.rs @@ -15,7 +15,6 @@ use std::ffi::c_uint; use crate::ast; use crate::exit_code; use crate::module; -use crate::options; use ast::Ast; use ast::AstGenerator; @@ -29,19 +28,14 @@ use exit_code::exit; use exit_code::ExitCode; use module::FunctionSignature; use module::ModuleBundle; -use options::RunOptions; pub struct IRGen<'a, 'b> { bundle: &'a mut ModuleBundle<'b>, - _options: &'a RunOptions, } impl <'a, 'b> IRGen<'a, 'b> { - pub fn new(bundle: &'a mut ModuleBundle<'b>, options: &'a RunOptions) -> Self { - IRGen{ - bundle: bundle, - _options: options, - } + pub fn new(bundle: &'a mut ModuleBundle<'b>) -> Self { + IRGen{bundle} } fn gen_entry(&mut self, n: usize) -> LLVMBasicBlockRef { @@ -131,7 +125,7 @@ impl <'a, 'b> IRGen<'a, 'b> { /// needed if longer multi-statement programs are implemented. fn gen_expr_withdecl(&mut self, vars: &Vars, e: &Expr) -> GenResult { let f = self.bundle.f.expect("Missing parent function"); - for (i, var) in vars.into_iter().enumerate() { + for (i, var) in vars.iter().enumerate() { unsafe { let alloca_value = self.bundle.gen_alloca(var.as_str(), self.bundle.t_i64); let init_value = LLVMGetParam(f, i as c_uint); @@ -141,8 +135,8 @@ impl <'a, 'b> IRGen<'a, 'b> { self.visit(e) } - pub fn gen(ast: &dyn Ast, bundle: &'a mut ModuleBundle<'b>, options: &'a RunOptions) -> bool { - let mut ir_gen = IRGen::new(bundle, options); + pub fn gen(ast: &dyn Ast, bundle: &'a mut ModuleBundle<'b>) -> bool { + let mut ir_gen = IRGen::new(bundle); let n = ast.get_vars(); let bb = ir_gen.gen_entry(n); let ir_gen_result: GenResult = ast.accept_gen(&mut ir_gen); diff --git a/src/lex.rs b/src/lex.rs index 1165baa..36cd955 100644 --- a/src/lex.rs +++ b/src/lex.rs @@ -1,6 +1,8 @@ // Copyright 2024, Giordano Salvador // SPDX-License-Identifier: BSD-3-Clause +use std::fmt; +use std::fmt::Display; use std::io::BufRead; use std::io::BufReader; use std::io::Read; @@ -12,8 +14,10 @@ use exit_code::exit; use exit_code::ExitCode; use options::RunOptions; -#[derive(Clone,Copy,Eq,PartialEq)] +#[derive(Clone,Copy,Default,Eq,PartialEq)] pub enum TokenKind { + #[default] + Unknown, Comma, Comment, Colon, @@ -27,7 +31,6 @@ pub enum TokenKind { Plus, Slash, Star, - Unknown, With, } @@ -51,12 +54,6 @@ pub fn token_kind_to_string(k: TokenKind) -> String { }) } -impl Default for TokenKind { - fn default() -> Self { - TokenKind::Unknown - } -} - #[derive(Clone)] pub struct Token { pub kind: TokenKind, @@ -71,7 +68,7 @@ impl Default for Token { impl Token { pub fn new(k: TokenKind, text: String) -> Self { - Token{kind: k, text: text} + Token{kind: k, text} } pub fn is(&self, k: TokenKind) -> bool { @@ -89,9 +86,11 @@ impl Token { } f(self, false, ks) } +} - pub fn to_string(&self) -> String { - format!("{}:{}", token_kind_to_string(self.kind), self.text) +impl Display for Token { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}:{}", token_kind_to_string(self.kind), self.text) } } @@ -105,14 +104,13 @@ pub struct Lexer<'a, T: Read> { impl <'a, T: Read> Lexer<'a, T> { pub fn new(readable: T, options: &'a RunOptions) -> Self { - let lexer = Lexer{ + Lexer{ buffer: BufReader::new(readable), line: String::new(), line_count: 0, position: 0, - options: options, - }; - lexer + options, + } } fn has_next(&mut self) -> bool { @@ -192,14 +190,12 @@ impl <'a, T: Read> Lexer<'a, T> { if Self::is_whitespace(c) { self.form_token(t, pos_start, pos_start + 1, TokenKind::Eol); } else if Self::is_digit(c) { - if c == '0' { - if self.has_next_in_line(pos_start + 1) { - c = self.next_char_in_line(pos_start + 1); - if c == 'x' { - let pos_end: usize = self.collect_token_sequence(pos_start + 2, Self::is_hex_digit); - self.form_token(t, pos_start, pos_end, TokenKind::Number); - return; - } + if c == '0' && self.has_next_in_line(pos_start + 1) { + c = self.next_char_in_line(pos_start + 1); + if c == 'x' { + let pos_end: usize = self.collect_token_sequence(pos_start + 2, Self::is_hex_digit); + self.form_token(t, pos_start, pos_end, TokenKind::Number); + return; } } let pos_end: usize = self.collect_token_sequence(pos_start + 1, Self::is_digit); @@ -269,7 +265,7 @@ impl <'a, T: Read> Lexer<'a, T> { } fn is_digit(c: char) -> bool { - c >= '0' && c <= '9' + c.is_ascii_digit() } fn is_ident(c: char) -> bool { @@ -277,11 +273,19 @@ impl <'a, T: Read> Lexer<'a, T> { } fn is_hex_digit(c: char) -> bool { - (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') + Self::is_digit(c) || Self::is_letter_lower(c) || Self::is_letter_upper(c) + } + + fn is_letter_lower(c:char) -> bool { + c.is_ascii_lowercase() + } + + fn is_letter_upper(c:char) -> bool { + c.is_ascii_uppercase() } fn is_letter(c: char) -> bool { - (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' + Self::is_letter_lower(c) || Self::is_letter_upper(c) || c == '_' } pub fn lex_input(ts: &mut Vec, lex: &mut Lexer<'a, T>, options: &RunOptions) -> () { @@ -292,7 +296,7 @@ impl <'a, T: Read> Lexer<'a, T> { eprintln!("Found unknown token '{}' in lexer", t.text); if !options.drop_token { exit(ExitCode::LexerError); } } else if options.verbose { - eprintln!("Lexed token '{}'", t.to_string()); + eprintln!("Lexed token '{}'", t); } if t.is(TokenKind::Comment) || t.is(TokenKind::Eol) { // Drop the comments and end of lines before parsing diff --git a/src/main.rs b/src/main.rs index 46e3d79..d1cdb00 100644 --- a/src/main.rs +++ b/src/main.rs @@ -95,12 +95,12 @@ fn output_type_to_string(t: OutputType) -> String { } fn parse_args<'a>( - args: &'a Vec, + args: &'a [String], input: &mut InputType<'a>, output: &mut OutputType<'a>, options: &mut RunOptions ) { - let _bin_name: &String = args.get(0).unwrap(); + let _bin_name: &String = args.first().unwrap(); let mut arg: &'a String; let mut i: usize = 1; @@ -114,7 +114,7 @@ fn parse_args<'a>( "-h" => help(ExitCode::Ok), "--help" => help(ExitCode::Ok), "--lex" => options.lex_exit = true, - "--llvmir" => options.codegen_type = CodeGenType::LLVMIR, + "--llvmir" => options.codegen_type = CodeGenType::Llvmir, "--nomain" => options.no_main = true, "--notarget" => options.no_target = true, "-o" => *output = OutputType::File(parse_arg_after(args, &mut i)), @@ -124,7 +124,7 @@ fn parse_args<'a>( "-O3" => options.opt_level = OptLevel::O3, "--parse" => options.parse_exit = true, "--sem" => options.sem_exit = true, - "-S" => options.codegen_type = CodeGenType::LLVMIR, + "-S" => options.codegen_type = CodeGenType::Llvmir, "-v" => options.verbose = true, "--verbose" => options.verbose = true, "--version" => print_pkg_info(true), @@ -152,10 +152,10 @@ fn parse_args<'a>( if ext != ".bc" && ext != ".ll" { eprintln!("Output name '{}' should end in '.bc' or '.ll", f); exit(ExitCode::ArgParseError); - } else if ext == ".bc" && options.codegen_type == CodeGenType::LLVMIR { + } else if ext == ".bc" && options.codegen_type == CodeGenType::Llvmir { eprintln!("LLVM IR file type (with '-S' flag) should match output name ('.ll' extension)"); exit(ExitCode::ArgParseError); - } else if ext == ".ll" && options.codegen_type == CodeGenType::BYTECODE { + } else if ext == ".ll" && options.codegen_type == CodeGenType::Bytecode { eprintln!("Bytecode file type (missing '-S' flag) should match output name ('.bc' extension)"); exit(ExitCode::ArgParseError); } @@ -167,7 +167,7 @@ fn parse_args<'a>( } } -fn parse_arg_after<'a>(args: &'a Vec, i: &mut usize) -> &'a str { +fn parse_arg_after<'a>(args: &'a [String], i: &mut usize) -> &'a str { let name_option = args.get(*i).unwrap(); match args.get(*i + 1) { Some(arg) => { @@ -205,15 +205,13 @@ fn parse_arg_complex<'a>( } } } + } else if *input != InputType::None { + eprintln!("Found more than one input ('{}' and '{}')", input_type_to_string(*input), arg); + help(ExitCode::ArgParseError); + } else if arg.len() == 1 && lead_char == '-' { + *input = InputType::Stdin; } else { - if *input != InputType::None { - eprintln!("Found more than one input ('{}' and '{}')", input_type_to_string(*input), arg); - help(ExitCode::ArgParseError); - } else if arg.len() == 1 && lead_char == '-' { - *input = InputType::Stdin; - } else { - *input = InputType::File(arg.as_str()); - } + *input = InputType::File(arg.as_str()); } } @@ -226,11 +224,11 @@ fn write_module(bundle: &mut ModuleBundle, codegen_type: CodeGenType, output: &O match *output { OutputType::Stdout => { match codegen_type { - CodeGenType::LLVMIR => { + CodeGenType::Llvmir => { let string: String = bundle.to_string(); println!("{}", string); }, - CodeGenType::BYTECODE => { + CodeGenType::Bytecode => { eprintln!("Unimplemented: writing bytecode to Stdout"); return false; }, @@ -238,7 +236,7 @@ fn write_module(bundle: &mut ModuleBundle, codegen_type: CodeGenType, output: &O }, OutputType::File(f) => { match codegen_type { - CodeGenType::LLVMIR => { + CodeGenType::Llvmir => { let string: String = bundle.to_string(); let mut file = match File::create(f) { Ok(file) => file, @@ -255,12 +253,12 @@ fn write_module(bundle: &mut ModuleBundle, codegen_type: CodeGenType, output: &O } } }, - CodeGenType::BYTECODE => bundle.write_bitcode_to_file(f), + CodeGenType::Bytecode => bundle.write_bitcode_to_file(f), } }, } - return true; + true } fn main() -> ! { @@ -302,7 +300,7 @@ fn main() -> ! { let module_name_irgen = String::from("calcc"); let mut module_irgen = ModuleBundle::new(&module_name_irgen, options.verbose); - let irgen_status: bool = IRGen::gen(*ast, &mut module_irgen, &options); + let irgen_status: bool = IRGen::gen(*ast, &mut module_irgen); assert!(irgen_status); let irgen_verify: bool = module_irgen.verify_module(); if !irgen_verify { @@ -321,7 +319,7 @@ fn main() -> ! { //let f_sig = module_main.get_f_sig_from_context(&module_irgen.f_sig.clone().unwrap()); let f_sig = &module_irgen.f_sig.clone().unwrap(); - let maingen_status: bool = MainGen::gen(&mut module_main, &f_sig, &options); + let maingen_status: bool = MainGen::gen(&mut module_main, f_sig); assert!(maingen_status); // NOTE: Linking modules causes verifier errors for unmatched contexts of LLVMTypeRef. Skip verification. diff --git a/src/maingen.rs b/src/maingen.rs index 0a73e76..36ea934 100644 --- a/src/maingen.rs +++ b/src/maingen.rs @@ -20,11 +20,9 @@ use std::ffi::c_char; use std::ffi::c_uint; use crate::module; -use crate::options; use module::FunctionSignature; use module::ModuleBundle; -use options::RunOptions; static NAME_ATOLL : &str = "atoll"; static NAME_CALCC_MAIN : &str = "calcc_main"; @@ -45,33 +43,29 @@ static NAME_ARGV : &str = "vArgv"; pub struct MainGen<'a, 'b> { bundle: &'a mut ModuleBundle<'b>, - _options: &'a RunOptions, } impl <'a, 'b> MainGen<'a, 'b> { - pub fn new(bundle: &'a mut ModuleBundle<'b>, options: &'a RunOptions) -> Self { - MainGen{ - bundle: bundle, - _options: options, - } + pub fn new(bundle: &'a mut ModuleBundle<'b>) -> Self { + MainGen{bundle} } - pub fn gen(bundle: &'a mut ModuleBundle<'b>, callee_sig: &'a FunctionSignature, options: &'a RunOptions) -> bool { - let mut maingen: Self = Self::new(bundle, &options); + pub fn gen(bundle: &'a mut ModuleBundle<'b>, callee_sig: &'a FunctionSignature) -> bool { + let mut maingen: Self = Self::new(bundle); let _printf = maingen.declare_atoll(); let _fprintf = maingen.declare_fprintf(); let _printf = maingen.declare_printf(); let _stderr = maingen.declare_stderr(); - let _calcc_main = maingen.declare_calcc_main(&callee_sig); + let _calcc_main = maingen.declare_calcc_main(callee_sig); let bb_entry = maingen.make_entry_block(); let bb_err = maingen.make_err_block(); let bb_body = maingen.make_body_block(); let bb_ret = maingen.make_ret_block(); maingen.declare_global_strings(); // NOTE: Needs to be called after first use of builder - let callee_values = maingen.gen_entry_stack(bb_entry, &callee_sig); + let callee_values = maingen.gen_entry_stack(bb_entry, callee_sig); maingen.gen_entry_branch(bb_entry, bb_err, bb_body, callee_sig.params.len()); maingen.gen_err_block(bb_err, bb_ret, callee_sig.params.len()); - maingen.gen_body(bb_body, bb_ret, &callee_sig, &callee_values); + maingen.gen_body(bb_body, bb_ret, callee_sig, &callee_values); maingen.gen_ret(bb_ret); true } @@ -168,7 +162,7 @@ impl <'a, 'b> MainGen<'a, 'b> { bb_body: LLVMBasicBlockRef, bb_ret: LLVMBasicBlockRef, callee_sig: &'a FunctionSignature, - callee_values: &Vec + callee_values: &[LLVMValueRef] ) -> () { unsafe { LLVMPositionBuilderAtEnd(self.bundle.builder, bb_body); } let name_retval = ModuleBundle::value_name(NAME_RETVAL); @@ -368,11 +362,11 @@ impl <'a, 'b> MainGen<'a, 'b> { fn gen_call_calcc_main( &mut self, callee_sig: &'a FunctionSignature, - callee_values: &Vec + callee_values: &[LLVMValueRef] ) -> LLVMValueRef { let name_calcc = ModuleBundle::value_name(NAME_CALCC_MAIN); let value_calcc = self.bundle.get_value(&name_calcc); - let value_result = callee_values.get(0).unwrap(); + let value_result = callee_values.first().unwrap(); let mut args: Vec = Vec::new(); for i in 1..callee_values.len() { let name = self.bundle.scope.next_value_name(); diff --git a/src/module.rs b/src/module.rs index cda7b59..7bac11c 100644 --- a/src/module.rs +++ b/src/module.rs @@ -21,6 +21,8 @@ use std::ffi::c_int; use std::ffi::c_uint; use std::ffi::c_ulonglong; use std::ffi::CStr; +use std::fmt; +use std::fmt::Display; use std::ptr; use crate::exit_code; @@ -36,10 +38,7 @@ pub struct FunctionSignature { impl FunctionSignature { pub fn new(t_ret: LLVMTypeRef, params: Vec) -> Self { - FunctionSignature{ - t_ret: t_ret, - params: params, - } + FunctionSignature{t_ret, params} } } @@ -68,14 +67,14 @@ impl <'a> ModuleBundle<'a> { builder: b, context: c, module: m, - name: name, + name, scope: Scope::new(), t_i32: LLVMInt32TypeInContext(c), t_i64: LLVMInt64TypeInContext(c), t_opaque: LLVMPointerTypeInContext(c, 0 as c_uint), f: None, f_sig: None, - verbose: verbose, + verbose, } }; bundle @@ -102,7 +101,7 @@ impl <'a> ModuleBundle<'a> { let t_f = LLVMFunctionType(t_ret, params.as_mut_ptr(), params.len() as c_uint, is_va_arg as LLVMBool); LLVMAddFunction(self.module, name.as_ptr() as *const c_char, t_f) }; - self.insert_value(&name, value); + self.insert_value(name, value); value } @@ -123,47 +122,13 @@ impl <'a> ModuleBundle<'a> { } } - /// Kludge! LLVMGetTypeName2 returned null pointers. - //pub fn from_type_name(&self, name: *const c_char) -> LLVMTypeRef { - // let c_string = unsafe { CStr::from_ptr(name) }; - // let s = c_string.to_str().unwrap(); - // match s { - // "i32" => self.t_i32, - // "i64" => self.t_i64, - // "ptr" => self.t_opaque, - // _ => { - // eprintln!("Type conversion for '{}' unimplemented", s); - // exit(ExitCode::ModuleError); - // }, - // } - //} - - /// Kludge! Workaround for verifier errors from unmatched module contexts for LLVMTypeRef. - //pub fn get_f_sig_from_context(&mut self, f_sig: &FunctionSignature) -> FunctionSignature { - // let t_ret: LLVMTypeRef = unsafe { - // let name: *mut c_char = LLVMPrintTypeToString(f_sig.t_ret); - // self.from_type_name(name) - // }; - // assert!(!t_ret.is_null()); - // let mut params: Vec = Vec::new(); - // for param in &f_sig.params { - // let t: LLVMTypeRef = unsafe { - // let name: *mut c_char = LLVMPrintTypeToString(*param); - // self.from_type_name(name) - // }; - // assert!(!t.is_null()); - // params.push(t); - // } - // FunctionSignature::new(t_ret, params) - //} - pub fn get_value(&mut self, name: &String) -> LLVMValueRef { self.scope.get_value(name, self.verbose) } pub fn insert_value(&mut self, name: &String, value: LLVMValueRef) -> () { let result = self.scope.add_var(name, value, self.verbose); - if !result.is_none() { + if result.is_some() { eprintln!("Tried to declare value {} more than once", name); exit(ExitCode::ModuleError); } @@ -177,20 +142,6 @@ impl <'a> ModuleBundle<'a> { result == false as LLVMBool } - pub fn to_string(&self) -> String { - let c_string_ptr: *mut c_char = unsafe { - LLVMPrintModuleToString(self.module) - }; - let c_string: &CStr = unsafe { - CStr::from_ptr(c_string_ptr) - }; - let string: String = String::from(c_string.to_str().unwrap()); - unsafe { - LLVMDisposeMessage(c_string_ptr) - }; - string - } - pub fn value_name(s: &str) -> String { String::from(s) + "\0" } @@ -207,7 +158,7 @@ impl <'a> ModuleBundle<'a> { unsafe { let c_string = CStr::from_ptr(error_ptr as *const c_char); let s = c_string.to_str().expect("Unable to read module verification error string"); - if s.len() > 0 { + if !s.is_empty() { eprintln!("{}", s); } LLVMDisposeMessage(error_ptr); @@ -225,6 +176,23 @@ impl <'a> ModuleBundle<'a> { } } +impl <'a> Display for ModuleBundle<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let c_string_ptr: *mut c_char = unsafe { + LLVMPrintModuleToString(self.module) + }; + let c_string: &CStr = unsafe { + CStr::from_ptr(c_string_ptr) + }; + let string: String = String::from(c_string.to_str().unwrap()); + unsafe { + LLVMDisposeMessage(c_string_ptr) + }; + write!(f, "{}", string) + } +} + + impl <'a> Drop for ModuleBundle<'a> { fn drop(&mut self) -> () { self.scope.clear(); @@ -267,7 +235,7 @@ impl Scope { if verbose { eprintln!("Found var '{}' in scope", var); }; - value.clone() + *value }, None => { eprintln!("Unexpected unbound var '{}' in scope", var); @@ -277,7 +245,7 @@ impl Scope { } pub fn next_value_name(&mut self) -> String { - let name = String::from(format!("v{}\0", self.value_idx)); + let name = format!("v{}\0", self.value_idx); self.value_idx += 1; name } diff --git a/src/options.rs b/src/options.rs index 89af045..514ae58 100644 --- a/src/options.rs +++ b/src/options.rs @@ -17,7 +17,7 @@ pub struct RunOptions { impl RunOptions { pub fn new() -> Self { RunOptions{ - codegen_type: CodeGenType::BYTECODE, + codegen_type: CodeGenType::Bytecode, drop_token: false, lex_exit: false, no_main: false, @@ -52,6 +52,6 @@ pub fn opt_level_to_str(opt_level: OptLevel) -> String { #[repr(u8)] #[derive(Clone,Copy,PartialEq)] pub enum CodeGenType { - LLVMIR = 0, - BYTECODE = 1, + Llvmir = 0, + Bytecode = 1, } diff --git a/src/parse.rs b/src/parse.rs index 394c85d..11589bc 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -32,7 +32,7 @@ impl ParserIter { token: Default::default(), vars: Vec::new(), position: 0, - end: end, + end, } } @@ -48,14 +48,11 @@ pub struct Parser<'a> { impl <'a> Parser<'a> { pub fn new(tokens: &'a Vec, options: &'a RunOptions) -> Self { - if tokens.len() < 1 { + if tokens.is_empty() { eprintln!("Found empty program while parsing"); exit(ExitCode::ParserError); } - Parser{ - tokens: tokens, - options: options, - } + Parser{tokens, options} } pub fn iter(&self) -> ParserIter { @@ -86,10 +83,8 @@ impl <'a> Parser<'a> { false } - fn expect(&self, iter: &mut ParserIter, k: TokenKind, add_var: bool) { - if self.consume(iter, k, add_var) { - return - } else { + fn expect(&self, iter: &mut ParserIter, k: TokenKind, add_var: bool) -> () { + if !self.consume(iter, k, add_var) { eprintln!("Expected '{}' token at position {}", token_kind_to_string(k), iter.position); exit(ExitCode::ParserError); } @@ -101,13 +96,14 @@ impl <'a> Parser<'a> { fn get_token(&self, iter: &mut ParserIter) -> &Token { if iter.has_next() { - &self.tokens.get(iter.position).unwrap() + self.tokens.get(iter.position).unwrap() } else { eprintln!("Token out of bounds at {}", iter.position); exit(ExitCode::ParserError); } } + #[allow(clippy::redundant_allocation)] fn parse_calc(&self, iter: &mut ParserIter) -> Box<&mut dyn Ast> { let mut expr: Box; if self.consume(iter, TokenKind::With, false) { @@ -159,7 +155,7 @@ impl <'a> Parser<'a> { e_left } - fn is_hex_number(text: &String) -> bool { + fn is_hex_number(text: &str) -> bool { text.len() >= 2 && "0x" == &text[0..2] } @@ -213,6 +209,7 @@ impl <'a> Parser<'a> { } } + #[allow(clippy::redundant_allocation)] pub fn parse_input(ret: &mut Box<&'a mut dyn Ast>, parser: &'a mut Parser<'a>, options: &RunOptions) { let mut iter = parser.iter(); *ret = parser.parse_calc(&mut iter); diff --git a/src/sem.rs b/src/sem.rs index 3b3de6d..e22133c 100644 --- a/src/sem.rs +++ b/src/sem.rs @@ -54,7 +54,7 @@ struct DeclCheck<'a> { impl <'a> DeclCheck<'a> { pub fn new(options: &'a RunOptions) -> Self { - DeclCheck{scope: Scope::new(), options: options} + DeclCheck{scope: Scope::new(), options} } pub fn check_expr_undefined(&self) -> bool { @@ -64,7 +64,7 @@ impl <'a> DeclCheck<'a> { pub fn check_expr_factor(&self, f: &Factor) -> bool { match f { Factor::Number(_) => true, - Factor::Ident(var) => self.scope.contains_var(&var, self.options), + Factor::Ident(var) => self.scope.contains_var(var, self.options), } } @@ -99,58 +99,6 @@ impl <'a> AstVisitor for DeclCheck<'a> { } } -struct ReprCheck<'a> { - options: &'a RunOptions, -} - -impl <'a> ReprCheck<'a> { - pub fn new(options: &'a RunOptions) -> Self { - ReprCheck{options: options} - } - - pub fn check_expr_undefined(&self) -> bool { - false - } - - pub fn check_expr_factor(&self, f: &Factor) -> bool { - match f { - Factor::Ident(_) => true, - Factor::Number(n) => { - let result: bool = *n <= std::i64::MAX && *n >= std::i64::MIN; - if self.options.verbose && result { - eprintln!("Number '{}' passed repr check", *n); - } else if !result { - eprintln!("Number '{}' failed repr check", *n); - } - result - } - } - } - - pub fn check_expr_binop(&mut self, _op: &Operator, e_left: &Expr, e_right: &Expr) -> bool { - self.visit(e_left) && self.visit(e_right) - } - - pub fn check_expr_withdecl(&mut self, _vars: &Vars, e: &Expr) -> bool { - self.visit(e) - } -} - -impl <'a> AstVisitor for ReprCheck<'a> { - fn visit(&mut self, ast: &dyn Ast) -> bool { - if ast.is_expr() { - let expr: &ExprKind = ast.get_expr(); - return match expr { - ExprKind::Undefined => self.check_expr_undefined(), - ExprKind::Factor(f) => self.check_expr_factor(f), - ExprKind::BinaryOp(op, e_left, e_right) => self.check_expr_binop(op, e_left, e_right), - ExprKind::WithDecl(vars, e) => self.check_expr_withdecl(vars, e), - } - } - false - } -} - pub struct Semantics {} impl Semantics { @@ -161,13 +109,7 @@ impl Semantics { eprintln!("AST failed DeclCheck semantics check"); exit(ExitCode::SemanticError); } - let mut repr_check: ReprCheck = ReprCheck::new(options); - let repr_result: bool = ast.accept(&mut repr_check); - if !repr_result { - eprintln!("AST failed ReprCheck semantics check"); - exit(ExitCode::SemanticError); - } if options.sem_exit { exit(ExitCode::Ok); } - decl_result && repr_result + decl_result } } diff --git a/src/target.rs b/src/target.rs index 2518a40..c59b55a 100644 --- a/src/target.rs +++ b/src/target.rs @@ -55,7 +55,7 @@ impl Target { if !error_ptr.is_null() { let c_string = CStr::from_ptr(error_ptr as *const c_char); let s = c_string.to_str().expect("Unable to read target triple error string"); - if s.len() > 0 { + if !s.is_empty() { eprintln!("{}", s); LLVMDisposeMessage(error_ptr); exit(ExitCode::TargetError); @@ -68,10 +68,7 @@ impl Target { eprintln!("Failed to lookup target for target string '{}'", Self::string_from(&string)); exit(ExitCode::TargetError); } - Target { - string: string, - target: target, - } + Target{string, target} } pub fn get_string(&self) -> String { @@ -136,47 +133,8 @@ impl <'a> TargetMachine<'a> { machine_options, )}; let data_layout = unsafe { LLVMCreateTargetDataLayout(machine) }; - TargetMachine { - data_layout: data_layout, - machine: machine, - machine_options: machine_options, - target: target, - } + TargetMachine{data_layout, machine, machine_options, target} } - - // NOTE: Unused because the optimization level settings are not respected by the backend machine codegen. - //pub fn run_opt_to_file(&mut self, bundle: &mut ModuleBundle, name: &String, codegen_type: CodeGenType) -> bool { - // let mut error_ptr: *mut c_char = ptr::null_mut(); - // let result: LLVMBool = unsafe { - // LLVMSetModuleDataLayout(bundle.module, self.data_layout); - // LLVMSetTarget(bundle.module, self.target.string); - // let result: LLVMBool = LLVMTargetMachineEmitToFile( - // self.machine, - // bundle.module, - // name.as_ptr() as *const c_char, - // match codegen_type { - // CodeGenType::Assembly => LLVMCodeGenFileType::LLVMAssemblyFile, - // CodeGenType::Object => LLVMCodeGenFileType::LLVMObjectFile, - // }, - // &mut error_ptr as *mut *mut c_char, - // ); - // result - // }; - // let maingen_string: String = bundle.to_string(); - // println!("{}", maingen_string); - // if !error_ptr.is_null() { unsafe { - // let c_string = CStr::from_ptr(error_ptr as *const c_char); - // let s = c_string.to_str().expect("Unable to read codegen emit error string"); - // if s.len() > 0 { - // eprintln!("{}", s); - // LLVMDisposeMessage(error_ptr); - // exit(ExitCode::TargetError); - // } else { - // LLVMDisposeMessage(error_ptr); - // } - // }} - // result == true as LLVMBool - //} } impl <'a> Drop for TargetMachine<'a> { @@ -196,7 +154,7 @@ pub struct PassBuilder { impl PassBuilder { pub fn new() -> Self { let builder = unsafe { LLVMCreatePassBuilderOptions() }; - PassBuilder{builder: builder} + PassBuilder{builder} } pub fn run( diff --git a/tests/lit-llvm/sem_repr.calc b/tests/lit-llvm/sem_repr.calc deleted file mode 100644 index 3c5c9e4..0000000 --- a/tests/lit-llvm/sem_repr.calc +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: @calcc --verbose --sem -e "10" 2>&1 | @filecheck %s --check-prefix=CHECK_A -// RUN: @calcc --verbose --sem -e "9223372036854775807" 2>&1 | @filecheck %s --check-prefix=CHECK_B -// RUN: @calcc --verbose --sem -e "-9223372036854775808" 2>&1 | @filecheck %s --check-prefix=CHECK_C -// RUN: @calcc --verbose --sem -e "0x7FFFFFFFFFFFFFFF" 2>&1 | @filecheck %s --check-prefix=CHECK_D -// RUN: @calcc --verbose --sem -e "with: a,b,c: 10 + a*b*c" 2>&1 | @filecheck %s --check-prefix=CHECK_E - -// CHECK_A: Number '10' passed repr check - -// CHECK_B: Number '9223372036854775807' passed repr check - -// CHECK_C: Number '-9223372036854775808' passed repr check - -// CHECK_D: Number '9223372036854775807' passed repr check - -// CHECK_E: Number '10' passed repr check -// CHECK_E-NOT: Number '10' failed repr check