pub struct Builder<'a, 'f, T: BuildTarget<'a, 'f>> { /* private fields */ }
Expand description
Implementations§
Source§impl<'a, 'f: 'a> Builder<'a, 'f, Avid<'a, 'f>>
impl<'a, 'f: 'a> Builder<'a, 'f, Avid<'a, 'f>>
Sourcepub fn new(src: &'a str) -> Self
pub fn new(src: &'a str) -> Self
Creates a new instance of a Builder
with the default configuration.
For now, that means that it has the small Avid standard library, which can be found in the documentation. To change this configuration, use the Builder::remove() and Builder::register_fn() methods.
§Examples
use avid::Builder;
let src = "- + print";
let res = Builder::new(src).build();
// All of those functions are available.
assert!(res.is_ok());
Source§impl<'a> Builder<'a, 'a, Ast<'a>>
impl<'a> Builder<'a, 'a, Ast<'a>>
Sourcepub fn new_ast(src: &'a str) -> Builder<'a, 'a, Ast<'a>>
pub fn new_ast(src: &'a str) -> Builder<'a, 'a, Ast<'a>>
Start building an Ast with the default configuration.
If you want to just build the Ast with the default configuration, use Ast::new().
§Examples
use avid::{Ast, Builder};
let src = "hi";
let ast: Ast = Builder::new_ast(src)
.promise("hi")
.build()
.unwrap();
// now do stuff with ast
Source§impl<'a, 'f, T: BuildTarget<'a, 'f>> Builder<'a, 'f, T>
impl<'a, 'f, T: BuildTarget<'a, 'f>> Builder<'a, 'f, T>
Sourcepub fn build(self) -> Result<T>
pub fn build(self) -> Result<T>
Consumes the builder and creates the Avid instance
When this method is called, the source code is parsed and checked for syntax errors, then (if there were no errors) an Avid instance is returned.
§Examples
use avid::Builder;
let builder = Builder::new("/* some source code */");
match builder.build() {
Err(e) => eprintln!("There was a syntax error: {e:?}"),
Ok(avid) => todo!("Do something with the interpreter!")
}
Sourcepub fn src_name<N: ToString>(self, name: N) -> Self
pub fn src_name<N: ToString>(self, name: N) -> Self
Set the name of the source file for error reporting.
If this method is not entered, errors will default to using “
§Examples
Without changing the name of the source file:
use avid::Builder;
let src = "unknown-variable";
let should_be_error = Builder::new(src)
.build()
.unwrap_err();
assert!(should_be_error.to_string().starts_with("<provided>:1:1: Error"))
After changing the name of the source file:
use avid::Builder;
let src = "unknown-variable";
let should_be_error = Builder::new(src)
.src_name("file")
.build()
.unwrap_err();
assert!(should_be_error.to_string().starts_with("file:1:1: Error"))
Sourcepub fn promise<N: ToString>(self, name: N) -> Self
pub fn promise<N: ToString>(self, name: N) -> Self
Promise that a function will be available at runtime.
This helps get around lifetime requirements or cases when a variable is unknown until call time, such as in hooks or callbacks.
§Examples
use avid::*;
let src = "get-msg print";
let avid = Builder::new(src)
.promise("get-msg")
.build().unwrap();
// Msg is not known until after the instance is compiled
let msg = "Hello!";
let get_msg = |s: &mut Stack| {
s.push(Object::String(msg.to_string()));
Ok(())
};
let mut promises = PromiseBuilder::new()
.add_promise("get-msg", get_msg)
.build();
// Prints "Hello!"
avid.run(Some(&mut promises)).unwrap();
This can be used to provide runtime-only information.
use avid::*;
let src = "inc-x";
let mut avid = Builder::new(src)
.promise("inc-x")
.build().unwrap();
let mut x = 0;
{
let mut promises = PromiseBuilder::new()
.add_promise("inc-x", |_| {
x += 1;
Ok(())
})
.build();
// Increments x
avid.run_mut(Some(&mut promises)).unwrap();
}
// Both of these can be reused in this way as soon as `promises` goes out of scope
dbg!(&x);
dbg!(&avid);
This also can be used to not consume variables until the Avid instance goes out of scope.
Sourcepub fn register_fn<N: ToString, F: Into<T::Function> + 'f>(
self,
name: N,
func: F,
) -> Self
pub fn register_fn<N: ToString, F: Into<T::Function> + 'f>( self, name: N, func: F, ) -> Self
Registers a new function in the interpreter-to-be under the specified name.
The function gets registered under name
and must be called as such in the program.
§NOTE
If you get strange errors about lifetimes and/or closure typing while using this method,
make sure that you have annotated the argument’s type (|arg: &mut Stack|
).
Avid is still in it’s beta stage, so there are still some kinks to be worked out in the library. This is one of them. Hopefully it’ll be fixed soon!
§Examples
use avid::{Builder, Stack, Object};
let src = "msg eprint";
let avid = Builder::new(src)
// Add a function that pushes a string onto the stack.
.register_fn("msg", |stack: &mut Stack| {
stack.push(Object::String("Hi!".to_string()));
Ok(())
})
// Add a function that pops one thing from the stack and prints it
// to stderr.
.register_fn("eprint", |stack: &mut Stack| {
let [to_print] = stack.pop()?;
eprint!("{}", to_print.to_string());
Ok(())
}).build().unwrap();
// Will print "Hi!" to stderr
avid.run(None).unwrap();
Sourcepub fn remove<N: ToString>(self, name: N) -> Self
pub fn remove<N: ToString>(self, name: N) -> Self
Removes a function or object from the scope of the interpreter-to-be.
When this function is called, any function registered under name
gets unregistered
from the scope of the interpreter-to-be and, if a user tries to call it, an error
is thrown.
§Examples
use avid::{Builder, Stack};
let src = "func";
let res = Builder::new(src)
.register_fn("func", |_: &mut Stack| {
println!("func was called");
Ok(())
})
.remove("func")
.build();
// Syntax error: Unknown variable "func"
assert!(res.is_err());
Sourcepub fn allow_stack_debug(self, allowed: bool) -> Self
pub fn allow_stack_debug(self, allowed: bool) -> Self
Enable or disable the stack debugger.
Often while writing code in stack-oriented languages, it can be difficult to keep
track of what is on the stack at any particular point in the code. Avid has a
“stack debugging” function, ???
, which prints the types of the stack and then
exits.
§Warning
The stack debugger makes the thread panic! This is okay in some kinds of programs, such as a basic interpreter or single-user application, but seemingly random crashes are not good in a multi-user program! Allow with caution!
§Examples
use avid::Builder;
let src = "1 false \"Hi!\" ???";
let avid = Builder::new(src)
.allow_stack_debug(true)
.build().unwrap();
// Panics with "[Num Bool String]"
avid.run(None).unwrap();
Sourcepub fn no_io(self) -> Self
pub fn no_io(self) -> Self
Removes all standard library IO functions from the interpreter.
Often, an author of a program wants to sandbox potentially malicious code written by users. This function helps with that by removing any ability to use IO functions in the Avid interpreter.
§Examples
use avid::Builder;
let src = "\"IO D:\" print";
let res = Builder::new(src)
.no_io()
.build();
// Syntax error: Unknown value "print"
assert!(res.is_err());
When this function is called, the following functions are removed from
the standard library and will not be recognised if a user tries to use
them: print
.