From 8a6d8b144f45c509602a598f962d872a98226997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Thu, 21 Jan 2021 21:56:29 +0100 Subject: call external functions without parameters --- src/compiler.rs | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'src/compiler.rs') 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>>, blobs: Vec, + + functions: HashMap, } 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 { + self.functions.get(name).map(|(i, _)| *i) + } + fn find_variable(&mut self, name: &str) -> Option { 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 { @@ -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> { + pub fn compile(&mut self, name: &str, file: &Path, functions: &[(String, RustFunction)]) -> Result> { 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> { - Compiler::new(file, tokens).compile(name, file) +pub fn compile(name: &str, file: &Path, tokens: TokenStream, functions: &[(String, RustFunction)]) -> Result> { + Compiler::new(file, tokens).compile(name, file, functions) } -- cgit v1.2.1