($num:ident) => { IR::StackPush(*$num as u64) }
}
-fn import(specifier: &str, imported: &mut HashSet<PathBuf>) -> Option<ModuleWithImports> {
+fn import(specifier: &str, imported: &mut HashSet<PathBuf>, is_entrypoint: bool) -> Option<ModuleWithImports> {
// TODO paths relative to the files, not just the invocation
let path = PathBuf::from(specifier).canonicalize().unwrap();
if imported.contains(&path) {
let contents = std::fs::read_to_string(&path).unwrap();
- Some(generate_internal(&Module::parse(tokenize(&contents)), imported))
+ Some(generate_internal(&Module::parse(tokenize(&contents), is_entrypoint), imported))
}
fn collapse_module(mut module_w: ModuleWithImports) -> IRModule {
prev_data_len += mod_data_len;
});
-
+
IRModule {
data,
text,
pub fn compile(path: &str) -> IRModule {
let mut imported = HashSet::new();
- let module = import(path, &mut imported).unwrap();
+ let module = import(path, &mut imported, true).unwrap();
collapse_module(module) // TODO remove unused words
}
+#[derive(Debug)]
struct ModuleWithImports {
module: Option<IRModule>,
imports: Option<Vec<ModuleWithImports>>
},
Token::String(text) => {
if last_was_import {
- if let Some(module) = import(text, imported) {
+ if let Some(module) = import(text, imported, false) {
imports.push(module);
}
IR::ImportString // This will be elided later
_ => false,
};
mapped_ir
+ }).filter(|ir| {
+ // Elide IRs that shouldn't actually be in the output IR.
+ match ir {
+ IR::Import => false,
+ IR::ImportString => false,
+ _ => true,
+ }
}).collect::<Vec<_>>();
let mut result = vec![IR::Label(def.name.to_string())];
text: text.into_iter().flatten().collect::<Vec<_>>(),
data,
}),
- imports: Some(Vec::new()) // TODO
+ imports: Some(imports)
}
}
}
impl<'a> Module<'a> {
- pub fn parse(input: Vec<Token<'a>>) -> Self {
+ pub fn parse(input: Vec<Token<'a>>, is_entrypoint: bool) -> Self {
let mut result = vec![];
let mut main = vec![];
let mut current_word: Option<WordDefinition> = None;
panic!("unfinished word definition!");
}
- result.push(WordDefinition {
- name: "main",
- instructions: main,
- });
+ if is_entrypoint {
+ result.push(WordDefinition {
+ name: "main",
+ instructions: main,
+ });
+ }
Module { words: result }
}
: soup chicken 4.5 hello ;
hello soup
-"));
+"), true);
result.debug_print();
}
}
let mut string_start: Option<usize> = None;
let mut word_or_num_start: Option<usize> = None;
let mut last_is_escape = false;
- let mut last_is_whitespace = false;
+ let mut last_is_whitespace = true;
let mut in_comment = false;
let mut index = 0;
let mut first_char = true;