text: Vec<IR>,
imports: Vec<Rc<IRModule>>,
exports: Vec<String>,
+ externs: Vec<String>,
// TODO these next two should form an enum, not two options
source_file: Option<PathBuf>,
std_specifier: Option<String>,
impl IRModule {
fn get_label_for_call(&self, name: &String) -> String {
+ if self.externs.contains(name) {
+ return name.clone();
+ }
let mut found: Option<usize> = None;
for imported in &self.imports {
if imported.exports.contains(name) {
}
let contents = &std::fs::read_to_string(&path)?;
- let module = self.generate_internal(Some(path), None, &Module::parse(tokenize(&contents)?, is_entrypoint)?);
+ let tokens = tokenize(&contents)?;
+ let parsed = &Module::parse(tokens, is_entrypoint)?;
+
+ let module = self.generate_internal(Some(path), None, parsed);
let module = Rc::new(module);
self.all_modules.insert(path_key, module.clone());
if is_entrypoint {
s.to_string()
}).collect();
+ let externs = module.externs.iter().map(|s| s.to_string()).collect();
text.push(module.words.iter().map(|def| {
let mut body = def.instructions.iter().map(|inst| {
data,
imports,
exports,
+ externs,
source_file: path,
std_specifier,
number,
pub words: Vec<WordDefinition<'a>>,
pub imports: Vec<&'a str>,
pub exports: Vec<&'a str>,
+ pub externs: Vec<&'a str>,
}
impl<'a> Module<'a> {
let mut main = vec![];
let mut exports = vec![];
let mut imports = vec![];
+ let mut externs = vec![];
let mut current_word: Option<WordDefinition> = None;
let mut about_to_start_word_def = false;
let mut last_was_import = false;
let mut last_was_export = false;
+ let mut last_was_extern = false;
for token in input {
if about_to_start_word_def {
last_was_import = true;
} else if word == "export" {
last_was_export = true;
+ } else if word == "extern" {
+ last_was_extern = true;
} else {
if last_was_export {
exports.push(word);
last_was_export = false;
+ } else if last_was_extern {
+ externs.push(word);
+ last_was_extern = false;
} else {
main.push(token.clone());
}
});
}
- Ok(Module { words: result, imports, exports })
+ Ok(Module { words: result, imports, exports, externs })
}
#[cfg(test)]
--- /dev/null
+#include <stdio.h>
+
+extern unsigned long data_stack_end;
+register unsigned long * stack_pointer asm("s2");
+
+void putstack() {
+ unsigned long * stack_index = &data_stack_end;
+ printf("stack: ");
+ while (stack_index != stack_pointer) {
+ printf("%ld ", *stack_index);
+ stack_index -= 1;
+ }
+ printf("%ld\n", *stack_pointer);
+}
+
+
CMD_PREFIX=$([ "$UNAME" = "riscv64" ] && echo "" || echo "riscv64-unknown-linux-gnu-")
AS="${CMD_PREFIX}as"
LD="${CMD_PREFIX}ld"
+CC="${CMD_PREFIX}cc"
../target/debug/sorelc test1.sorel
$AS -g -o test1.o test1.asm
-$LD -o test1.out test1.o
+$CC -O1 -no-pie -o test1.out test1.o putstack.c -nostartfiles
+# $LD -o test1.out test1.o
./test1.out