Browse Source

move parser to root of vire, add test code

master
Alison Watson 1 week ago
parent
commit
6bf7f8d92e
5 changed files with 125 additions and 124 deletions
  1. +15
    -1
      bl/main.rs
  2. +95
    -3
      fw/vire.rs
  3. +0
    -97
      fw/vire/parser.rs
  4. +12
    -20
      fw/vire/tki.rs
  5. +3
    -3
      fw/vire/tok.rs

+ 15
- 1
bl/main.rs View File

@@ -2,10 +2,23 @@

use blonkus_fw as fw;

fn entry(conf: &fw::conf::Conf) -> Result<(), Box<dyn std::error::Error>> {
fn entry(_conf: &fw::conf::Conf) -> Result<(), Box<dyn std::error::Error>> {
let mut vfs = fw::data::vfs::Vfs::default();
vfs.add_path("testres")?;

let mut sym_t = fw::types::sym::SymbolTable::new();
log::trace!(
"{:#?}",
fw::vire::Cell::parse(
fw::vire::Token::read_all(
"main.vire",
vfs.get("main.vire").unwrap().text()?
)?,
&mut sym_t
)?
);

/*
let hal = fw::hal::ctx::Context::new()?;
let win = fw::hal::win::Window::new(&hal, fw::c_str!("BLONKUS"), 640, 480)?;
let mut ren = fw::render::Renderer::new(
@@ -28,6 +41,7 @@ fn entry(conf: &fw::conf::Conf) -> Result<(), Box<dyn std::error::Error>> {

ren.draw_frame()?;
}
*/

Ok(())
}


+ 95
- 3
fw/vire.rs View File

@@ -1,9 +1,12 @@
use crate::types::sym;
mod tki;
mod tok;

pub mod parser;
pub mod rt;

//mod llvm;
use crate::types::sym;

pub use tki::TokenIter;
pub use tok::{Token, Type};

#[derive(Clone, Debug)]
pub enum Cell {
@@ -23,4 +26,93 @@ pub enum Cell {
// struct Fixed(i64); // Q47.16s
// struct Angle(i32); // Q0.31s

#[derive(thiserror::Error, Debug)]
pub enum Err {
#[error(transparent)]
Iter(#[from] tki::Err),
#[error(transparent)]
Symb(#[from] sym::SymbolOverflowError),
}

impl Cell {
pub fn parse(
mut tki: TokenIter, syms: &mut sym::SymbolTable,
) -> Result<Vec<Self>, Err> {
let mut cells = Vec::new();

while tki.peek().is_some() {
cells.push(cell(&mut tki, syms)?);
}

Ok(cells)
}
}

fn cell(
tki: &mut TokenIter, syms: &mut sym::SymbolTable,
) -> Result<Cell, Err> {
use self::Type::*;
match tki.err_next()? {
// atoms
| Token { typ: Bool, cel, .. }
| Token { typ: Char, cel, .. }
| Token { typ: Numb, cel, .. }
| Token { typ: Strn, cel, .. } => Ok(cel),
| Token { typ: Symb, cel: Cell::Strn(s), .. } => {
Ok(Cell::Symb(syms.intern(s)?))
}

// lists
| Token { typ: Br1O, .. } => list(tki, syms, Br1C),
| Token { typ: Br3O, .. } => list(tki, syms, Br3C),

// abbreviations
| Token { typ: QQuo, .. } => abbrev(tki, syms, "quasiquote"),
| Token { typ: QSyn, .. } => abbrev(tki, syms, "quasisyntax"),
| Token { typ: Quot, .. } => abbrev(tki, syms, "quote"),
| Token { typ: Synt, .. } => abbrev(tki, syms, "syntax"),
| Token { typ: UnQS, .. } => abbrev(tki, syms, "unquote-splicing"),
| Token { typ: UnQu, .. } => abbrev(tki, syms, "unquote"),
| Token { typ: UnSS, .. } => abbrev(tki, syms, "unsyntax-splicing"),
| Token { typ: UnSy, .. } => abbrev(tki, syms, "unsyntax"),

| Token { typ, pos, .. } => Err(tki::Err::Unexpected(typ, pos).into()),
}
}

fn abbrev(
tki: &mut TokenIter, syms: &mut sym::SymbolTable, name: &'static str,
) -> Result<Cell, Err> {
let cdr = {
let cdr = Box::new(Cell::Null);
let car = Box::new(cell(tki, syms)?);
Box::new(Cell::Cons { cdr, car })
};
let car = Box::new(Cell::Symb(syms.intern(name)?));
Ok(Cell::Cons { cdr, car })
}

fn list(
tki: &mut TokenIter, syms: &mut sym::SymbolTable, end: Type,
) -> Result<Cell, Err> {
let mut data_v = Vec::new();
let mut cdr = Cell::Null;

while !tki.drop(end)? {
if tki.drop(Type::Peri)? {
cdr = cell(tki, syms)?;
tki.expect(end)?;
break;
} else {
data_v.push(cell(tki, syms)?);
}
}

for car in data_v.into_iter().rev() {
cdr = Cell::Cons { car: Box::new(car), cdr: Box::new(cdr) };
}

Ok(cdr)
}

// EOF

+ 0
- 97
fw/vire/parser.rs View File

@@ -1,97 +0,0 @@
pub mod tki;
pub mod tok;

use self::{
tki::TokenIter,
tok::{Token, Type::*},
};
use super::Cell;
use crate::types::sym;

#[derive(thiserror::Error, Debug)]
pub enum Err {
#[error(transparent)]
Iter(#[from] tki::Err),
#[error(transparent)]
Symb(#[from] sym::SymbolOverflowError),
}

pub fn parse(
tki: &mut TokenIter, syms: &mut sym::SymbolTable,
) -> Result<Vec<Cell>, Err> {
let mut cells = Vec::new();

while tki.peek().is_some() {
cells.push(cell(tki, syms)?);
}

Ok(cells)
}

fn cell(
tki: &mut TokenIter, syms: &mut sym::SymbolTable,
) -> Result<Cell, Err> {
match tki.err_next()? {
// atoms
| Token { typ: Bool, cel, .. }
| Token { typ: Char, cel, .. }
| Token { typ: Numb, cel, .. }
| Token { typ: Strn, cel, .. } => Ok(cel),
| Token { typ: Symb, cel: Cell::Strn(s), .. } => {
Ok(Cell::Symb(syms.intern(s)?))
}

// lists
| Token { typ: Br1O, .. } => list(tki, syms, Br1C),
| Token { typ: Br3O, .. } => list(tki, syms, Br3C),

// abbreviations
| Token { typ: QQuo, .. } => abbrev(tki, syms, "quasiquote"),
| Token { typ: QSyn, .. } => abbrev(tki, syms, "quasisyntax"),
| Token { typ: Quot, .. } => abbrev(tki, syms, "quote"),
| Token { typ: Synt, .. } => abbrev(tki, syms, "syntax"),
| Token { typ: UnQS, .. } => abbrev(tki, syms, "unquote-splicing"),
| Token { typ: UnQu, .. } => abbrev(tki, syms, "unquote"),
| Token { typ: UnSS, .. } => abbrev(tki, syms, "unsyntax-splicing"),
| Token { typ: UnSy, .. } => abbrev(tki, syms, "unsyntax"),

| Token { typ, pos, .. } => Err(tki::Err::Unexpected(typ, pos).into()),
}
}

fn abbrev(
tki: &mut TokenIter, syms: &mut sym::SymbolTable, name: &'static str,
) -> Result<Cell, Err> {
let cdr = {
let cdr = Box::new(Cell::Null);
let car = Box::new(cell(tki, syms)?);
Box::new(Cell::Cons { cdr, car })
};
let car = Box::new(Cell::Symb(syms.intern(name)?));
Ok(Cell::Cons { cdr, car })
}

fn list(
tki: &mut TokenIter, syms: &mut sym::SymbolTable, end: tok::Type,
) -> Result<Cell, Err> {
let mut data_v = Vec::new();
let mut cdr = Cell::Null;

while !tki.drop(end)? {
if tki.drop(Peri)? {
cdr = cell(tki, syms)?;
tki.expect(end)?;
break;
} else {
data_v.push(cell(tki, syms)?);
}
}

for car in data_v.into_iter().rev() {
cdr = Cell::Cons { car: Box::new(car), cdr: Box::new(cdr) };
}

Ok(cdr)
}

// EOF

fw/vire/parser/tki.rs → fw/vire/tki.rs View File

@@ -1,4 +1,4 @@
use super::tok::{self, Token, Type};
use super::tok::{Token, Type};
use crate::data::text::Position;
use std::{iter::Peekable, vec};

@@ -13,19 +13,9 @@ pub enum Err {
}

#[derive(Debug)]
pub struct TokenIter {
it: Peekable<vec::IntoIter<Token>>,
}
pub struct TokenIter(pub(super) Peekable<vec::IntoIter<Token>>);

impl TokenIter {
pub fn new(v: Vec<Token>) -> Self {
Self { it: v.into_iter().peekable() }
}

pub fn from_data(name: &str, data: &str) -> Result<Self, tok::Err> {
Ok(Self::new(Token::read_all(name, data)?))
}

pub fn drop(&mut self, typ: Type) -> Result<bool, Err> {
let tk = self.err_peek()?;
if tk.typ == typ {
@@ -53,19 +43,21 @@ impl TokenIter {
pub fn err_next(&mut self) -> Result<Token, Err> {
self.next().ok_or(Err::Eof)
}

pub fn peek(&mut self) -> Option<&Token> {
self.0.peek()
}
}

impl std::ops::Deref for TokenIter {
type Target = Peekable<vec::IntoIter<Token>>;
impl Iterator for TokenIter {
type Item = Token;

fn deref(&self) -> &Self::Target {
&self.it
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
}

impl std::ops::DerefMut for TokenIter {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.it
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}


fw/vire/parser/tok.rs → fw/vire/tok.rs View File

@@ -1,4 +1,4 @@
use super::Cell;
use super::{Cell, TokenIter};
use crate::data::text::{self, PosReader, Position};
use std::{fmt, ops::ControlFlow};

@@ -348,7 +348,7 @@ impl Token {
Ok(ControlFlow::Continue(Some(tk)))
}

pub fn read_all(name: &str, data: &str) -> Result<Vec<Self>, Err> {
pub fn read_all(name: &str, data: &str) -> Result<TokenIter, Err> {
let mut tokens = Vec::new();
let rd = &mut PosReader::new(data, text::ellipsize_small_str(name));

@@ -358,7 +358,7 @@ impl Token {
}
}

Ok(tokens)
Ok(TokenIter(tokens.into_iter().peekable()))
}
}


Loading…
Cancel
Save