diff options
| author | Gustav Sörnäs <gustav@sornas.net> | 2021-01-21 21:56:29 +0100 |
|---|---|---|
| committer | Gustav Sörnäs <gustav@sornas.net> | 2021-01-29 20:44:36 +0100 |
| commit | 8a6d8b144f45c509602a598f962d872a98226997 (patch) | |
| tree | c9966ba2b6605accdfce66768935528065232dc4 /src/compiler.rs | |
| parent | 28b84aca844222c3dcccc3ef4b32bac6571ea881 (diff) | |
| download | sylt-8a6d8b144f45c509602a598f962d872a98226997.tar.gz | |
call external functions without parameters
Diffstat (limited to 'src/compiler.rs')
| -rw-r--r-- | src/compiler.rs | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/src/compiler.rs b/src/compiler.rs index 3c5498e..d31ee0d 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -181,6 +181,8 @@ impl Frame { } } +pub type RustFunction = fn(&[Value]) -> Value; + #[derive(Debug, Clone)] pub struct Blob { pub name: String, @@ -220,6 +222,8 @@ struct Compiler { blocks: Vec<Rc<RefCell<Block>>>, blobs: Vec<Blob>, + + functions: HashMap<String, (usize, RustFunction)>, } macro_rules! push_frame { @@ -283,6 +287,8 @@ impl Compiler { blocks: Vec::new(), blobs: Vec::new(), + + functions: HashMap::new(), } } @@ -509,6 +515,10 @@ impl Compiler { None } + fn find_extern_function(&self, name: &str) -> Option<usize> { + self.functions.get(name).map(|(i, _)| *i) + } + fn find_variable(&mut self, name: &str) -> Option<Variable> { if let Some(res) = self.frame().find_local(name) { return Some(res); @@ -518,7 +528,7 @@ impl Compiler { return Some(res); } - return Self::find_and_capture_variable(name, self.frames.iter_mut().rev()); + Self::find_and_capture_variable(name, self.frames.iter_mut().rev()) } fn find_blob(&self, name: &str) -> Option<usize> { @@ -672,6 +682,9 @@ impl Compiler { if self.peek() == Token::LeftParen { self.call(block); } + } else if let Some(slot) = self.find_extern_function(&name) { + block.add(Op::Constant(Value::ExternFunction(slot)), self.line()); + self.call(block); } else { error!(self, format!("Using undefined variable {}.", name)); } @@ -1028,8 +1041,14 @@ impl Compiler { } - pub fn compile(&mut self, name: &str, file: &Path) -> Result<Prog, Vec<Error>> { + pub fn compile(&mut self, name: &str, file: &Path, functions: &[(String, RustFunction)]) -> Result<Prog, Vec<Error>> { println!("=== START COMPILATION ==="); + self.functions = functions + .to_vec() + .into_iter() + .enumerate() + .map(|(i, (s, f))| (s, (i, f))) + .collect(); self.stack_mut().push(Variable { name: String::from("/main/"), typ: Type::Void, @@ -1065,6 +1084,6 @@ impl Compiler { } } -pub fn compile(name: &str, file: &Path, tokens: TokenStream) -> Result<Prog, Vec<Error>> { - Compiler::new(file, tokens).compile(name, file) +pub fn compile(name: &str, file: &Path, tokens: TokenStream, functions: &[(String, RustFunction)]) -> Result<Prog, Vec<Error>> { + Compiler::new(file, tokens).compile(name, file, functions) } |
