diff --git a/src/protocol/parser/mod.rs b/src/protocol/parser/mod.rs index 50f002e4de01949cb9db20e76a9ee5d088d49688..79f4c0fed6768f538799073c591e410813060cff 100644 --- a/src/protocol/parser/mod.rs +++ b/src/protocol/parser/mod.rs @@ -30,7 +30,7 @@ use type_table::*; use crate::protocol::ast::*; use crate::protocol::input_source::*; -use crate::protocol::ast_printer::ASTWriter; +use crate::protocol::ast_writer::ASTWriter; use crate::protocol::parser::type_table::PolymorphicVariable; const REOWOLF_PATH_ENV: &'static str = "REOWOLF_ROOT"; // first lookup reowolf path @@ -121,6 +121,7 @@ pub struct Parser { pub(crate) modules: Vec, pub(crate) symbol_table: SymbolTable, pub(crate) type_table: TypeTable, + pub(crate) global_module_index: usize, // contains globals, implicitly imported everywhere // Compiler passes, used as little state machine that keep their memory // around. pass_tokenizer: PassTokenizer, @@ -144,6 +145,7 @@ impl Parser { modules: Vec::new(), symbol_table: SymbolTable::new(), type_table: TypeTable::new(), + global_module_index: 0, pass_tokenizer: PassTokenizer::new(), pass_symbols: PassSymbols::new(), pass_import: PassImport::new(), @@ -179,12 +181,16 @@ impl Parser { parser.arch.output_type_id = insert_builtin_type(&mut parser.type_table, vec![ConcreteTypePart::Output, ConcreteTypePart::Void], true, 8, 8); parser.arch.pointer_type_id = insert_builtin_type(&mut parser.type_table, vec![ConcreteTypePart::Pointer, ConcreteTypePart::Void], true, 8, 8); + // Parse standard library parser.feed_standard_library()?; return Ok(parser) } - pub fn feed(&mut self, mut source: InputSource) -> Result<(), ParseError> { + /// Feeds a new InputSource to the parser, which will tokenize it and store + /// it internally for later parsing (when all modules are present). Returns + /// the index of the new module. + pub fn feed(&mut self, mut source: InputSource) -> Result { let mut token_buffer = TokenBuffer::new(); self.pass_tokenizer.tokenize(&mut source, &mut token_buffer)?; @@ -196,9 +202,10 @@ impl Parser { version: None, phase: ModuleCompilationPhase::Tokenized, }; + let module_index = self.modules.len(); self.modules.push(module); - Ok(()) + return Ok(module_index); } pub fn parse(&mut self) -> Result<(), ParseError> { @@ -320,6 +327,8 @@ impl Parser { // way to do this in the future (i.e. a "std" package, containing all // of the modules) let mut file_path = PathBuf::new(); + let mut first_file = true; + for file in FILES { file_path.push(path); file_path.push(file); @@ -335,12 +344,19 @@ impl Parser { let source = source.unwrap(); let input_source = InputSource::new(file.to_string(), source); - if let Err(err) = self.feed(input_source) { + let module_index = self.feed(input_source); + if let Err(err) = module_index { // A bit of a hack, but shouldn't really happen anyway: the // compiler should ship with a decent standard library (at some // point) return Err(format!("{}", err)); } + let module_index = module_index.unwrap(); + + if first_file { + self.global_module_index = module_index; + first_file = false; + } } return Ok(())