Add simple error diagnostic from parser
This commit is contained in:
		
							parent
							
								
									bc59b6f575
								
							
						
					
					
						commit
						6619f1f0a9
					
				
							
								
								
									
										24
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										24
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @ -108,6 +108,12 @@ dependencies = [ | ||||
|  "windows-sys", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "crossbeam-utils" | ||||
| version = "0.8.21" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "dashmap" | ||||
| version = "5.5.3" | ||||
| @ -121,6 +127,20 @@ dependencies = [ | ||||
|  "parking_lot_core", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "dashmap" | ||||
| version = "6.1.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" | ||||
| dependencies = [ | ||||
|  "cfg-if", | ||||
|  "crossbeam-utils", | ||||
|  "hashbrown", | ||||
|  "lock_api", | ||||
|  "once_cell", | ||||
|  "parking_lot_core", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "displaydoc" | ||||
| version = "0.2.5" | ||||
| @ -653,6 +673,8 @@ dependencies = [ | ||||
| name = "reid-lsp" | ||||
| version = "0.1.0" | ||||
| dependencies = [ | ||||
|  "dashmap 6.1.0", | ||||
|  "reid", | ||||
|  "socket", | ||||
|  "tokio", | ||||
|  "tower-lsp", | ||||
| @ -903,7 +925,7 @@ dependencies = [ | ||||
|  "async-trait", | ||||
|  "auto_impl", | ||||
|  "bytes", | ||||
|  "dashmap", | ||||
|  "dashmap 5.5.3", | ||||
|  "futures", | ||||
|  "httparse", | ||||
|  "lsp-types", | ||||
|  | ||||
| @ -16,7 +16,7 @@ BINARY="$(echo $1 | cut -d'.' -f1)"".out" | ||||
| 
 | ||||
| echo $1 | ||||
| 
 | ||||
| cargo run --example cli $@ && \ | ||||
| cargo run  --example cli $@ && \ | ||||
| ./$BINARY ; echo "Return value: ""$?" | ||||
| 
 | ||||
| ## Command from: clang -v hello.o -o test | ||||
|  | ||||
| @ -52,7 +52,5 @@ fn main() { | ||||
| 
 | ||||
|     else_b.terminate(TerminatorKind::Ret(add)).unwrap(); | ||||
| 
 | ||||
|     dbg!(&context); | ||||
| 
 | ||||
|     context.compile(None, Vec::new()); | ||||
| } | ||||
|  | ||||
| @ -223,7 +223,6 @@ impl Builder { | ||||
|         unsafe { | ||||
|             let mut modules = self.modules.borrow_mut(); | ||||
|             let module = modules.get_unchecked_mut(module.0); | ||||
|             dbg!(module.functions.iter().map(|f| f.data.name.clone()).collect::<Vec<_>>()); | ||||
|             module.functions.iter().find(|f| f.data.name == *name).map(|f| f.value) | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -123,8 +123,6 @@ impl CompiledModule { | ||||
|             let llvm_ir = | ||||
|                 from_cstring(LLVMPrintModuleToString(self.module_ref)).expect("Unable to print LLVM IR to string"); | ||||
| 
 | ||||
|             println!("{}", llvm_ir); | ||||
| 
 | ||||
|             let mut err = ErrorMessageHolder::null(); | ||||
|             LLVMVerifyModule( | ||||
|                 self.module_ref, | ||||
|  | ||||
| @ -7,3 +7,5 @@ edition = "2024" | ||||
| socket = "0.0.7" | ||||
| tokio = { version = "1.47.0", features = ["full"] } | ||||
| tower-lsp = "0.20.0" | ||||
| reid = { path = "../reid", version = "1.0.0-beta.2", registry="gitea-teascade", features=[] } | ||||
| dashmap = "6.1.0" | ||||
|  | ||||
| @ -57,6 +57,9 @@ export function activate(context: ExtensionContext) { | ||||
| 
 | ||||
| 	client.info("hello"); | ||||
| 
 | ||||
| 	workspace.onDidOpenTextDocument((e) => { | ||||
| 	}); | ||||
| 
 | ||||
| 	// Start the client. This will also launch the server
 | ||||
| 	client.start(); | ||||
| } | ||||
|  | ||||
| @ -1,19 +1,51 @@ | ||||
| use std::path::PathBuf; | ||||
| 
 | ||||
| use dashmap::DashMap; | ||||
| use reid::ast::lexer::{FullToken, Position}; | ||||
| use reid::{compile_module, parse_module}; | ||||
| use tower_lsp::jsonrpc::Result; | ||||
| use tower_lsp::lsp_types::*; | ||||
| use tower_lsp::lsp_types::{ | ||||
|     self, CompletionItem, CompletionOptions, CompletionParams, CompletionResponse, Diagnostic, DiagnosticSeverity, | ||||
|     DidChangeTextDocumentParams, DidOpenTextDocumentParams, Hover, HoverContents, HoverParams, HoverProviderCapability, | ||||
|     InitializeParams, InitializeResult, InitializedParams, MarkedString, MessageType, OneOf, Range, ServerCapabilities, | ||||
|     TextDocumentItem, TextDocumentSyncCapability, TextDocumentSyncKind, TextDocumentSyncOptions, | ||||
|     WorkspaceFoldersServerCapabilities, WorkspaceServerCapabilities, | ||||
| }; | ||||
| use tower_lsp::{Client, LanguageServer, LspService, Server}; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| struct Backend { | ||||
|     client: Client, | ||||
|     tokens: DashMap<String, Vec<FullToken>>, | ||||
|     ast: DashMap<String, reid::ast::Module>, | ||||
| } | ||||
| 
 | ||||
| #[tower_lsp::async_trait] | ||||
| impl LanguageServer for Backend { | ||||
|     async fn initialize(&self, _: InitializeParams) -> Result<InitializeResult> { | ||||
|         self.client | ||||
|             .log_message(MessageType::INFO, "Initializing Reid Language Server") | ||||
|             .await; | ||||
| 
 | ||||
|         let sync = TextDocumentSyncOptions { | ||||
|             open_close: Some(true), | ||||
|             change: Some(TextDocumentSyncKind::FULL), | ||||
|             will_save: None, | ||||
|             will_save_wait_until: None, | ||||
|             save: None, | ||||
|         }; | ||||
|         Ok(InitializeResult { | ||||
|             capabilities: ServerCapabilities { | ||||
|                 hover_provider: Some(HoverProviderCapability::Simple(true)), | ||||
|                 completion_provider: Some(CompletionOptions::default()), | ||||
|                 completion_provider: Some(CompletionOptions { ..Default::default() }), | ||||
|                 text_document_sync: Some(TextDocumentSyncCapability::Options(sync)), | ||||
|                 workspace: Some(WorkspaceServerCapabilities { | ||||
|                     workspace_folders: Some(WorkspaceFoldersServerCapabilities { | ||||
|                         supported: Some(true), | ||||
|                         change_notifications: Some(OneOf::Left(true)), | ||||
|                     }), | ||||
|                     file_operations: None, | ||||
|                 }), | ||||
|                 ..Default::default() | ||||
|             }, | ||||
|             ..Default::default() | ||||
| @ -22,13 +54,146 @@ impl LanguageServer for Backend { | ||||
| 
 | ||||
|     async fn initialized(&self, _: InitializedParams) { | ||||
|         self.client | ||||
|             .log_message(MessageType::INFO, "Reid Language Server initialized!") | ||||
|             .log_message(MessageType::INFO, "Reid Language Server initialized hello!") | ||||
|             .await; | ||||
|     } | ||||
| 
 | ||||
|     async fn shutdown(&self) -> Result<()> { | ||||
|         Ok(()) | ||||
|     } | ||||
| 
 | ||||
|     async fn completion(&self, _: CompletionParams) -> Result<Option<CompletionResponse>> { | ||||
|         Ok(Some(CompletionResponse::Array(vec![ | ||||
|             CompletionItem::new_simple("Hello".to_string(), "Some detail".to_string()), | ||||
|             CompletionItem::new_simple("Bye".to_string(), "More detail".to_string()), | ||||
|         ]))) | ||||
|     } | ||||
| 
 | ||||
|     async fn hover(&self, params: HoverParams) -> Result<Option<Hover>> { | ||||
|         let path = PathBuf::from(params.text_document_position_params.text_document.uri.path()); | ||||
|         let file_name = path.file_name().unwrap().to_str().unwrap().to_owned(); | ||||
|         let tokens = self.tokens.get(&file_name).unwrap(); | ||||
|         let position = params.text_document_position_params.position; | ||||
| 
 | ||||
|         self.client | ||||
|             .log_message( | ||||
|                 MessageType::INFO, | ||||
|                 format!("line {}, col {}", position.line, position.character), | ||||
|             ) | ||||
|             .await; | ||||
|         let token = tokens.iter().find(|tok| { | ||||
|             tok.position.1 == position.line + 1 | ||||
|                 && (tok.position.0 <= position.character + 1 | ||||
|                     && (tok.position.0 + tok.token.len() as u32) > position.character + 1) | ||||
|         }); | ||||
| 
 | ||||
|         Ok(Some(Hover { | ||||
|             contents: HoverContents::Scalar(MarkedString::String(format!("{:?}", token))), | ||||
|             range: None, | ||||
|         })) | ||||
|     } | ||||
| 
 | ||||
|     async fn did_open(&self, params: DidOpenTextDocumentParams) { | ||||
|         self.client.log_message(MessageType::INFO, "opened!").await; | ||||
|         self.recompile(TextDocumentItem { | ||||
|             uri: params.text_document.uri, | ||||
|             language_id: params.text_document.language_id, | ||||
|             version: params.text_document.version, | ||||
|             text: params.text_document.text, | ||||
|         }) | ||||
|         .await | ||||
|     } | ||||
| 
 | ||||
|     async fn did_change(&self, params: DidChangeTextDocumentParams) { | ||||
|         self.client.log_message(MessageType::INFO, "changed!").await; | ||||
|         self.recompile(TextDocumentItem { | ||||
|             text: params.content_changes[0].text.clone(), | ||||
|             uri: params.text_document.uri, | ||||
|             version: params.text_document.version, | ||||
|             language_id: String::new(), | ||||
|         }) | ||||
|         .await | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Backend { | ||||
|     async fn recompile(&self, params: TextDocumentItem) { | ||||
|         let mut map = Default::default(); | ||||
|         let path = PathBuf::from(params.uri.clone().path()); | ||||
|         let file_name = path.file_name().unwrap().to_str().unwrap().to_owned(); | ||||
| 
 | ||||
|         let mut reid_error = None; | ||||
|         let mut tokens = None; | ||||
| 
 | ||||
|         match parse_module(¶ms.text, file_name.clone(), &mut map) { | ||||
|             Ok(module) => { | ||||
|                 self.client | ||||
|                     .log_message(MessageType::INFO, format!("successfully parsed!")) | ||||
|                     .await; | ||||
|                 tokens = Some(module.1.clone()); | ||||
|                 match compile_module(module.0, module.1, &mut map, Some(path), true) { | ||||
|                     Ok(_) => {} | ||||
|                     Err(e) => { | ||||
|                         reid_error = Some(e); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             Err(_) => {} | ||||
|         } | ||||
| 
 | ||||
|         if let Some(tokens) = &tokens { | ||||
|             if let Some(reid_error) = reid_error { | ||||
|                 let mut diagnostics = Vec::new(); | ||||
|                 for error in reid_error.errors { | ||||
|                     let meta = error.get_meta(); | ||||
|                     let positions = meta | ||||
|                         .range | ||||
|                         .into_position(&tokens) | ||||
|                         .unwrap_or((Position(0, 0), Position(0, 0))); | ||||
|                     self.client.log_message(MessageType::INFO, format!("{:?}", &meta)).await; | ||||
|                     self.client | ||||
|                         .log_message(MessageType::INFO, format!("{:?}", &tokens)) | ||||
|                         .await; | ||||
|                     self.client | ||||
|                         .log_message(MessageType::INFO, format!("{:?}", &positions)) | ||||
|                         .await; | ||||
| 
 | ||||
|                     diagnostics.push(Diagnostic { | ||||
|                         range: Range { | ||||
|                             start: lsp_types::Position { | ||||
|                                 line: ((positions.0.1 as i32) - 1).max(0) as u32, | ||||
|                                 character: ((positions.0.0 as i32) - 1).max(0) as u32, | ||||
|                             }, | ||||
|                             end: lsp_types::Position { | ||||
|                                 line: ((positions.1.1 as i32) - 1).max(0) as u32, | ||||
|                                 character: ((positions.1.0 as i32) - 1).max(0) as u32, | ||||
|                             }, | ||||
|                         }, | ||||
|                         severity: Some(DiagnosticSeverity::ERROR), | ||||
|                         code: None, | ||||
|                         code_description: None, | ||||
|                         source: Some(error.get_type_str().to_owned()), | ||||
|                         message: format!("{}", error), | ||||
|                         related_information: None, | ||||
|                         tags: None, | ||||
|                         data: None, | ||||
|                     }); | ||||
|                     self.client.log_message(MessageType::INFO, format!("{}", error)).await; | ||||
|                 } | ||||
|                 self.client | ||||
|                     .publish_diagnostics(params.uri.clone(), diagnostics, Some(params.version)) | ||||
|                     .await; | ||||
|             } else { | ||||
|                 self.client | ||||
|                     .publish_diagnostics(params.uri.clone(), Vec::new(), Some(params.version)) | ||||
|                     .await; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if let Some(tokens) = tokens.take() { | ||||
|             self.tokens.insert(file_name.clone(), tokens); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[tokio::main] | ||||
| @ -36,6 +201,10 @@ async fn main() { | ||||
|     let stdin = tokio::io::stdin(); | ||||
|     let stdout = tokio::io::stdout(); | ||||
| 
 | ||||
|     let (service, socket) = LspService::new(|client| Backend { client }); | ||||
|     let (service, socket) = LspService::new(|client| Backend { | ||||
|         client, | ||||
|         ast: DashMap::new(), | ||||
|         tokens: DashMap::new(), | ||||
|     }); | ||||
|     Server::new(stdin, stdout, socket).serve(service).await; | ||||
| } | ||||
|  | ||||
| @ -10,6 +10,7 @@ edition = "2021" | ||||
| default = ["color"] | ||||
| 
 | ||||
| color = ["colored"] | ||||
| log_output = [] | ||||
| 
 | ||||
| [dependencies] | ||||
| ## Make it easier to generate errors | ||||
|  | ||||
| @ -12,7 +12,6 @@ fn main() -> Result<(), std::io::Error> { | ||||
|             libraries.push(libname); | ||||
|         } | ||||
| 
 | ||||
|         dbg!(&filename); | ||||
|         let path = PathBuf::from(filename).canonicalize().unwrap(); | ||||
|         let parent = path.with_extension(""); | ||||
|         let llvm_ir_path = parent.with_extension("ll"); | ||||
| @ -21,6 +20,7 @@ fn main() -> Result<(), std::io::Error> { | ||||
|         let mir_path = parent.with_extension("mir"); | ||||
|         let asm_path = parent.with_extension("asm"); | ||||
| 
 | ||||
|         #[cfg(feature = "log_output")] | ||||
|         let before = std::time::SystemTime::now(); | ||||
| 
 | ||||
|         let text = fs::read_to_string(&path)?; | ||||
| @ -31,33 +31,39 @@ fn main() -> Result<(), std::io::Error> { | ||||
|         match compile_simple(&text, PathBuf::from(&path), Some(cpu), vec![features]) { | ||||
|             Ok(( | ||||
|                 CompileOutput { | ||||
|                     triple, | ||||
|                     triple: _triple, | ||||
|                     assembly, | ||||
|                     obj_buffer, | ||||
|                     llvm_ir, | ||||
|                     llvm_ir: _llvm_ir, | ||||
|                 }, | ||||
|                 CustomIRs { llir, mir }, | ||||
|             )) => { | ||||
|                 println!("{}", llvm_ir); | ||||
|                 #[cfg(feature = "log_output")] | ||||
|                 { | ||||
|                     println!("{}", _llvm_ir); | ||||
|                     println!("Compiled with triple: {}\n", &_triple); | ||||
|                     println!("Output LLVM IR to {:?}", llvm_ir_path); | ||||
|                     println!("Output Assembly to {:?}", asm_path); | ||||
|                     println!("Output Object-file to {:?}\n", object_path); | ||||
|                     println!("Output LLIR-file to {:?}\n", llir_path); | ||||
|                     println!("Output MIR-file to {:?}\n", mir_path); | ||||
|                 } | ||||
| 
 | ||||
|                 let after = std::time::SystemTime::now(); | ||||
|                 println!("Compiled with triple: {}\n", &triple); | ||||
|                 fs::write(&llvm_ir_path, &llvm_ir).expect("Could not write LLVM IR -file!"); | ||||
|                 println!("Output LLVM IR to {:?}", llvm_ir_path); | ||||
|                 fs::write(&llvm_ir_path, &_llvm_ir).expect("Could not write LLVM IR -file!"); | ||||
|                 fs::write(&asm_path, &assembly).expect("Could not write Assembly-file!"); | ||||
|                 println!("Output Assembly to {:?}", asm_path); | ||||
|                 fs::write(&object_path, &obj_buffer).expect("Could not write Object-file!"); | ||||
|                 println!("Output Object-file to {:?}\n", object_path); | ||||
|                 fs::write(&llir_path, &llir).expect("Could not write LLIR-file!"); | ||||
|                 println!("Output LLIR-file to {:?}\n", llir_path); | ||||
|                 fs::write(&mir_path, &mir).expect("Could not write MIR-file!"); | ||||
|                 println!("Output MIR-file to {:?}\n", mir_path); | ||||
|                 println!( | ||||
|                     "Compilation took: {:.2}ms\n", | ||||
|                     (after.duration_since(before).unwrap().as_micros() as f32) / 1000. | ||||
|                 ); | ||||
|                 #[cfg(feature = "log_output")] | ||||
|                 { | ||||
|                     let after = std::time::SystemTime::now(); | ||||
|                     println!( | ||||
|                         "Compilation took: {:.2}ms\n", | ||||
|                         (after.duration_since(before).unwrap().as_micros() as f32) / 1000. | ||||
|                     ); | ||||
| 
 | ||||
|                 println!("Linking {:?}", &object_path); | ||||
|                     println!("Linking {:?}", &object_path); | ||||
|                 } | ||||
| 
 | ||||
|                 let linker = std::env::var("LD").unwrap_or("ld".to_owned()); | ||||
|                 let mut linker = LDRunner::from_command(&linker).with_library("c"); | ||||
| @ -69,6 +75,7 @@ fn main() -> Result<(), std::io::Error> { | ||||
|             Err(e) => panic!("{}", e), | ||||
|         }; | ||||
|     } else { | ||||
|         #[cfg(feature = "log_output")] | ||||
|         println!("Please input compiled file path!") | ||||
|     } | ||||
|     Ok(()) | ||||
|  | ||||
| @ -42,13 +42,11 @@ impl<'a, 'b> TokenStream<'a, 'b> { | ||||
|     /// Useful in conjunction with [`TokenStream::next`]
 | ||||
|     pub fn expecting_err<T: Into<String>>(&mut self, expected: T) -> Result<Error, Error> { | ||||
|         let next_token = self.peek().unwrap_or(Token::Eof); | ||||
|         let pos = self.next_token(self.position).0; | ||||
|         Ok(Error::Expected( | ||||
|             expected.into(), | ||||
|             next_token, | ||||
|             TokenRange { | ||||
|                 start: self.position, | ||||
|                 end: self.position, | ||||
|             }, | ||||
|             TokenRange { start: pos, end: pos }, | ||||
|         )) | ||||
|     } | ||||
| 
 | ||||
| @ -173,7 +171,7 @@ impl<'a, 'b> TokenStream<'a, 'b> { | ||||
|     pub fn get_range_prev(&self) -> Option<TokenRange> { | ||||
|         self.ref_position.as_ref().map(|ref_pos| TokenRange { | ||||
|             start: **ref_pos, | ||||
|             end: self.position - 1, | ||||
|             end: self.previous_token(self.position).0, | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -728,7 +728,6 @@ impl mir::Statement { | ||||
|             mir::StmtKind::Let(NamedVariableRef(ty, name, meta), mutable, expression) => { | ||||
|                 let value = expression.codegen(scope, &state)?.unwrap(); | ||||
| 
 | ||||
|                 dbg!(&scope.allocator, &meta, &value.1); | ||||
|                 let alloca = scope | ||||
|                     .allocate(meta, &value.1) | ||||
|                     .unwrap() | ||||
|  | ||||
| @ -50,7 +50,7 @@ impl ErrorKind { | ||||
| } | ||||
| 
 | ||||
| impl ErrorKind { | ||||
|     fn get_meta(&self) -> Metadata { | ||||
|     pub fn get_meta(&self) -> Metadata { | ||||
|         match &self { | ||||
|             ErrorKind::LexerError(error) => error.metadata, | ||||
|             ErrorKind::ParserError(error) => error.metadata, | ||||
| @ -63,6 +63,18 @@ impl ErrorKind { | ||||
|             ErrorKind::MacroError(error) => error.metadata, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_type_str(&self) -> &str { | ||||
|         match self { | ||||
|             ErrorKind::LexerError(_) => "lexer", | ||||
|             ErrorKind::ParserError(_) => "parser", | ||||
|             ErrorKind::TypeCheckError(_) => "typechecker", | ||||
|             ErrorKind::TypeInferenceError(_) => "type-inferrer", | ||||
|             ErrorKind::LinkerError(_) => "linker", | ||||
|             ErrorKind::MacroError(_) => "macro-pass", | ||||
|             ErrorKind::CodegenError(_) => "codegen", | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl PartialOrd for ErrorKind { | ||||
| @ -120,7 +132,7 @@ impl ErrorModules { | ||||
| #[derive(Debug, Clone, PartialEq)] | ||||
| pub struct ReidError { | ||||
|     map: ErrorModules, | ||||
|     errors: Vec<ErrorKind>, | ||||
|     pub errors: Vec<ErrorKind>, | ||||
| } | ||||
| 
 | ||||
| impl ReidError { | ||||
| @ -185,9 +197,7 @@ impl std::fmt::Display for ReidError { | ||||
|             let module = self.map.module(&meta.source_module_id); | ||||
|             let position = if let Some(module) = module { | ||||
|                 if let Some(tokens) = &module.tokens { | ||||
|                     let range_tokens = meta.range.into_tokens(&tokens); | ||||
| 
 | ||||
|                     get_position(&range_tokens).or(meta.position.map(|p| (p, p))) | ||||
|                     meta.range.into_position(tokens).or(meta.position.map(|p| (p, p))) | ||||
|                 } else if let Some(position) = meta.position { | ||||
|                     Some((position, position)) | ||||
|                 } else { | ||||
| @ -237,6 +247,11 @@ impl TokenRange { | ||||
|             .take(self.end + 1 - self.start) | ||||
|             .collect::<Vec<_>>() | ||||
|     } | ||||
| 
 | ||||
|     pub fn into_position<'v>(&self, tokens: &'v Vec<FullToken>) -> Option<(Position, Position)> { | ||||
|         let tokens = self.into_tokens(tokens); | ||||
|         get_position(&tokens) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn get_position(tokens: &Vec<&FullToken>) -> Option<(Position, Position)> { | ||||
|  | ||||
| @ -26,12 +26,11 @@ impl LDRunner { | ||||
|         let dyn_linker_path = find_objectfile(&self.dynamic_linker); | ||||
|         let crt1_path = find_objectfile("crt1.o"); | ||||
| 
 | ||||
|         #[cfg(feature = "log_output")] | ||||
|         println!("LDRunner: Using dynamic linker at: {:?}", dyn_linker_path); | ||||
| 
 | ||||
|         let mut ld = Command::new(&self.command); | ||||
|         ld.arg("-dynamic-linker") | ||||
|             .arg(dyn_linker_path) | ||||
|             .arg(crt1_path); | ||||
|         ld.arg("-dynamic-linker").arg(dyn_linker_path).arg(crt1_path); | ||||
| 
 | ||||
|         for library in &self.libraries { | ||||
|             ld.arg(format!("-l{}", library)); | ||||
| @ -41,22 +40,21 @@ impl LDRunner { | ||||
|             .arg("-o") | ||||
|             .arg(out_path.to_str().unwrap()); | ||||
| 
 | ||||
|         #[cfg(feature = "log_output")] | ||||
|         println!( | ||||
|             "LDRunner: Executing linker to objfile at {:?} => {:?}", | ||||
|             input_path, out_path | ||||
|         ); | ||||
|         #[cfg(feature = "log_output")] | ||||
|         dbg!(&ld); | ||||
| 
 | ||||
|         ld.spawn().expect("Unable to execute ld!"); | ||||
| 
 | ||||
|         thread::sleep(Duration::from_millis(100)); | ||||
| 
 | ||||
|         #[cfg(feature = "log_output")] | ||||
|         println!("Setting executable bit to {:?}..", out_path); | ||||
|         Command::new("chmod") | ||||
|             .arg("+x") | ||||
|             .arg(out_path) | ||||
|             .spawn() | ||||
|             .unwrap(); | ||||
|         Command::new("chmod").arg("+x").arg(out_path).spawn().unwrap(); | ||||
|         thread::sleep(Duration::from_millis(100)); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -72,7 +72,7 @@ use crate::{ | ||||
|     mir::macros::{form_macros, MacroModule, MacroPass}, | ||||
| }; | ||||
| 
 | ||||
| mod ast; | ||||
| pub mod ast; | ||||
| mod codegen; | ||||
| pub mod error_raporting; | ||||
| pub mod ld; | ||||
| @ -93,6 +93,7 @@ pub fn parse_module<'map, T: Into<String>>( | ||||
|     map.set_tokens(id, tokens.clone()); | ||||
| 
 | ||||
|     #[cfg(debug_assertions)] | ||||
|     #[cfg(feature = "log_output")] | ||||
|     println!("{:#?}", &tokens); | ||||
| 
 | ||||
|     Ok((id, tokens)) | ||||
| @ -127,6 +128,7 @@ pub fn compile_module<'map>( | ||||
|     }; | ||||
| 
 | ||||
|     #[cfg(debug_assertions)] | ||||
|     #[cfg(feature = "log_output")] | ||||
|     dbg!(&ast_module); | ||||
| 
 | ||||
|     Ok(ast_module.process(module_id)) | ||||
| @ -137,9 +139,11 @@ pub fn perform_all_passes<'map>( | ||||
|     module_map: &'map mut ErrorModules, | ||||
| ) -> Result<(), ReidError> { | ||||
|     #[cfg(debug_assertions)] | ||||
|     #[cfg(feature = "log_output")] | ||||
|     dbg!(&context); | ||||
| 
 | ||||
|     #[cfg(debug_assertions)] | ||||
|     #[cfg(feature = "log_output")] | ||||
|     println!("{:#}", &context); | ||||
| 
 | ||||
|     let state = context.pass(&mut LinkerPass { | ||||
| @ -154,10 +158,13 @@ pub fn perform_all_passes<'map>( | ||||
|     } | ||||
| 
 | ||||
|     #[cfg(debug_assertions)] | ||||
|     #[cfg(feature = "log_output")] | ||||
|     println!("{:-^100}", "LINKER OUTPUT"); | ||||
|     #[cfg(debug_assertions)] | ||||
|     #[cfg(feature = "log_output")] | ||||
|     println!("{:#}", &context); | ||||
|     #[cfg(debug_assertions)] | ||||
|     #[cfg(feature = "log_output")] | ||||
|     dbg!(&state); | ||||
| 
 | ||||
|     if !state.errors.is_empty() { | ||||
| @ -179,10 +186,13 @@ pub fn perform_all_passes<'map>( | ||||
|     let state = context.pass(&mut macro_pass)?; | ||||
| 
 | ||||
|     #[cfg(debug_assertions)] | ||||
|     #[cfg(feature = "log_output")] | ||||
|     println!("{:-^100}", "MACRO OUTPUT"); | ||||
|     #[cfg(debug_assertions)] | ||||
|     #[cfg(feature = "log_output")] | ||||
|     println!("{:#}", &context); | ||||
|     #[cfg(debug_assertions)] | ||||
|     #[cfg(feature = "log_output")] | ||||
|     dbg!(&state); | ||||
| 
 | ||||
|     if !state.errors.is_empty() { | ||||
| @ -217,12 +227,16 @@ pub fn perform_all_passes<'map>( | ||||
|     let state = context.pass(&mut TypeInference { refs: &mut refs })?; | ||||
| 
 | ||||
|     #[cfg(debug_assertions)] | ||||
|     #[cfg(feature = "log_output")] | ||||
|     println!("{:-^100}", "TYPE INFERRER OUTPUT"); | ||||
|     #[cfg(debug_assertions)] | ||||
|     #[cfg(feature = "log_output")] | ||||
|     println!("{}", &refs); | ||||
|     #[cfg(debug_assertions)] | ||||
|     #[cfg(feature = "log_output")] | ||||
|     println!("{:#}", &context); | ||||
|     #[cfg(debug_assertions)] | ||||
|     #[cfg(feature = "log_output")] | ||||
|     dbg!(&state); | ||||
| 
 | ||||
|     if !state.errors.is_empty() { | ||||
| @ -239,10 +253,13 @@ pub fn perform_all_passes<'map>( | ||||
|     let state = context.pass(&mut TypeCheck { refs: &refs })?; | ||||
| 
 | ||||
|     #[cfg(debug_assertions)] | ||||
|     #[cfg(feature = "log_output")] | ||||
|     println!("{:-^100}", "TYPECHECKER OUTPUT"); | ||||
|     #[cfg(debug_assertions)] | ||||
|     #[cfg(feature = "log_output")] | ||||
|     println!("{:#}", &context); | ||||
|     #[cfg(debug_assertions)] | ||||
|     #[cfg(feature = "log_output")] | ||||
|     dbg!(&state); | ||||
| 
 | ||||
|     if !state.errors.is_empty() { | ||||
| @ -280,8 +297,10 @@ pub fn compile_and_pass<'map>( | ||||
|     perform_all_passes(&mut mir_context, module_map)?; | ||||
| 
 | ||||
|     #[cfg(debug_assertions)] | ||||
|     #[cfg(feature = "log_output")] | ||||
|     println!("{:-^100}", "FINAL OUTPUT"); | ||||
|     #[cfg(debug_assertions)] | ||||
|     #[cfg(feature = "log_output")] | ||||
|     println!("{:#}", &mir_context); | ||||
| 
 | ||||
|     let mut context = Context::new(format!("Reid ({})", env!("CARGO_PKG_VERSION"))); | ||||
| @ -291,6 +310,7 @@ pub fn compile_and_pass<'map>( | ||||
|     }; | ||||
| 
 | ||||
|     #[cfg(debug_assertions)] | ||||
|     #[cfg(feature = "log_output")] | ||||
|     println!("{}", &codegen_modules.context); | ||||
| 
 | ||||
|     let compiled = codegen_modules.compile(cpu, features); | ||||
|  | ||||
| @ -41,16 +41,7 @@ impl Metadata { | ||||
|     } | ||||
| 
 | ||||
|     pub fn into_positions(&self, tokens: &Vec<FullToken>) -> Option<(Position, Position)> { | ||||
|         let mut iter = tokens | ||||
|             .iter() | ||||
|             .skip(self.range.start) | ||||
|             .take(self.range.end - self.range.start); | ||||
|         if let Some(first) = iter.next() { | ||||
|             let last = iter.last().unwrap_or(first); | ||||
|             Some((first.position, last.position.add(last.token.len() as u32))) | ||||
|         } else { | ||||
|             None | ||||
|         } | ||||
|         self.range.into_position(tokens) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user