Skip to main content

Sketch

Struct Sketch 

Source
pub struct Sketch { /* private fields */ }
Expand description

A sketch made of several files: the entry and the parts its [sketch] modules lists (LSF2 §3.2).

Add the entry first, then its parts, each under its project-relative path (/-separated, no .. that leaves the root, portable to every OS). The files go into a SourceMap in the order they are added, so every diagnostic forging reports — and every span in the forged language’s warnings — points into the right file: render them with source_map. A one-file sketch forged from a Sketch gets the same spans as from Language::from_lsf, since the first file starts at position 0.

The parts merge as if the files were one document: a table may be continued in another file ([rules] in two files adds rules to one table), and a key or table defined twice, in one file or two, is an error naming both places. When rules come from more than one file, [language] start is required.

§Examples

use lang_forge::{Language, Sketch};

let mut sketch = Sketch::new();
sketch.add("calc.lsf", r#"
[sketch]
format = 2
modules = ["rules/expr.lsf"]

[language]
name = "calc"
version = "1.0.0"
start = "program"

[rules]
program = "stmts:stmt*"
stmt = "value:expr ';'"
"#)?;
sketch.add("rules/expr.lsf", r#"
[sketch]
format = 2
kind = "part"

[rules.expr]
operand = "NUMBER"
levels = [{ left = ["+"] }]
"#)?;

let calc = Language::from_sketch(&sketch)?;
assert!(!calc.parse("1 + 2; 3;").has_errors());

A problem in a part is reported in that part:

use lang_forge::{Language, Sketch};

let mut sketch = Sketch::new();
sketch.add("a.lsf", "[sketch]\nformat = 2\nmodules = [\"b.lsf\"]\n[language]\nname = \"a\"\nversion = \"1.0.0\"\nstart = \"x\"\n[rules]\nx = \"y\"\n")?;
sketch.add("b.lsf", "[sketch]\nformat = 2\nkind = \"part\"\n[rules]\ny = \"undefined_rule\"\n")?;
let err = Language::from_sketch(&sketch).unwrap_err();
assert_eq!(err.to_string(), "b.lsf:5:6: undefined rule `undefined_rule`");

Implementations§

Source§

impl Sketch

Source

pub fn new() -> Self

An empty sketch.

§Examples
use lang_forge::Sketch;

let mut sketch = Sketch::new();
assert!(sketch.is_empty());
sketch.add("main.lsf", "[language]\nname = \"m\"\n[rules]\nm = \"IDENT\"\n")?;
assert_eq!(sketch.len(), 1);
assert_eq!(sketch.source_map().iter().next().map(|(_, f)| f.name()), Some("main.lsf"));
Source

pub fn add( &mut self, path: &str, text: impl Into<Box<str>>, ) -> Result<(), Error>

Adds a file under its project-relative path. The first file added is the entry.

§Errors

Returns an Error if the path is not a portable project-relative path (LSF8001, LSF8002), is already in the sketch, or differs from one only by ASCII case (LSF2005, LSF8003), or if the file is larger than 8 MiB (LSF9001), the sketch would pass 64 MiB in total (LSF9002), or it would have more than 1024 files (LSF9003). The sketch is unchanged.

§Examples
use lang_forge::Sketch;

let mut sketch = Sketch::new();
assert!(sketch.add("lang/main.lsf", "").is_ok());
assert!(sketch.add("../outside.lsf", "").is_err());
assert!(sketch.add("C:/abs.lsf", "").is_err());
assert!(sketch.add("lang/main.lsf", "").is_err());
assert_eq!(sketch.len(), 1);
Source

pub fn source_map(&self) -> &SourceMap

The sketch’s files, for rendering diagnostics with Renderer.

Source

pub fn len(&self) -> usize

The number of files.

Source

pub fn is_empty(&self) -> bool

Whether no file has been added.

Trait Implementations§

Source§

impl Clone for Sketch

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Sketch

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Sketch

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.