Skip to content

Commit

Permalink
Merge branch 'macros'
Browse files Browse the repository at this point in the history
  • Loading branch information
OJarrisonn committed Jan 24, 2024
2 parents fe21dd3 + d7436a2 commit 5608892
Show file tree
Hide file tree
Showing 23 changed files with 309 additions and 92 deletions.
2 changes: 1 addition & 1 deletion vaca-build/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "vaca-build"
version = "0.1.1"
version = "0.2.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
4 changes: 2 additions & 2 deletions vaca-build/src/builder.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use vaca_core::ErrorStack;
use speedy::Writable;

use crate::parse;
use crate::parse_program;



Expand All @@ -13,7 +13,7 @@ pub fn build(input: String, output: Option<String>) -> Result<(), Box<dyn std::e
}

let source = std::fs::read_to_string(&input)?;
let compiled = parse(format!("{{{}}}", source));
let compiled = parse_program(source);

let output = output.unwrap_or(input.replace(".vaca", ".casco"));

Expand Down
4 changes: 3 additions & 1 deletion vaca-build/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@

mod parser;
mod builder;
// mod program;
// mod library;

pub use crate::{parser::{parse, VacaParser}, builder::build};
pub use crate::{parser::{parse_program, parse_form}, builder::build};

#[cfg(test)]
mod tests {
Expand Down
Empty file added vaca-build/src/library.rs
Empty file.
84 changes: 51 additions & 33 deletions vaca-build/src/parser.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
use pest::{Parser, iterators::Pair};
use pest_derive::Parser;
use vaca_core::{Form, Symbol, form::Literal, ErrorStack};
use vaca_core::{form::Literal, ErrorStack, Form, Symbol};

#[derive(Parser)]
#[grammar = "./parser/grammar.pest"]
pub struct VacaParser;

pub fn parse(form: String) -> Result<Form, ErrorStack>{
pub fn parse_program(form: String) -> Result<Form, ErrorStack>{
let res = VacaParser::parse(Rule::program, &form);

match res {
Ok(mut pairs) => pair_walk(pairs.next().unwrap()),
Err(e) => Err(format!("{}", e).into()),
}
}

pub fn parse_form(form: String) -> Result<Form, ErrorStack>{
let res = VacaParser::parse(Rule::form, &form);

match res {
Expand All @@ -16,6 +25,7 @@ pub fn parse(form: String) -> Result<Form, ErrorStack>{
}

fn pair_walk(pair: Pair<'_, Rule>) -> Result<Form, ErrorStack>{
let src = Some(format!("[L {} C {}]: {}", pair.line_col().0, pair.line_col().1, pair.as_span().as_str()));
match pair.as_rule() {
// Unreachble
Rule::keyword => unreachable!(),
Expand Down Expand Up @@ -49,7 +59,7 @@ fn pair_walk(pair: Pair<'_, Rule>) -> Result<Form, ErrorStack>{
acc.push((symbol, *form));
Ok(acc)
},
Ok(_) => panic!("This must be an assinment"),
Ok(_) => panic!("This must be an assignment"),
Err(e) => Err(e)
},
e => e
Expand Down Expand Up @@ -106,43 +116,51 @@ fn pair_walk(pair: Pair<'_, Rule>) -> Result<Form, ErrorStack>{

Ok(Form::Function(params, Box::new(body)))
},
Rule::macrodef => {
let mut params = vec![];
let mut body = vec![];

for p in pair.into_inner() {
match p.as_rule() {
Rule::symbol => params.push(p.as_str().into()),
Rule::form => body.push(pair_walk(p)?),
_ => panic!("No other rule should be inside a function rule")
}
}

let body = Form::CodeBlock(body);

Ok(Form::Macro(params, Box::new(body)))
},
Rule::call => {
let res = pair.into_inner()
.map(|pair| pair_walk(pair));
let res: Result<Vec<Form>, ErrorStack> = pair.clone().into_inner()
.map(|pair| pair_walk(pair))
.collect();

if let Some(err) = res.clone().into_iter().find(|r| r.is_err()) {
err
} else {
let mut iter = res.map(|e| e.unwrap());
let func = iter.next().expect("There should be a first Formession in the function");
match res {
Err(e) => Err(ErrorStack::Stream { src, from: Box::new(e), note: Some("During parsing of a `Form` in a `Call`".into()) }),
Ok(vec) => {
let mut iter = vec.into_iter();

match &func {
Form::Function(_, _) | Form::CodeBlock(_) | Form::Literal(Literal::Symbol(_)) | Form::Call(_, _) => Ok(Form::Call(Box::new(func), iter.collect())),
e => Err(format!("Passing {e:?} as a callable function, but it isn't").into())
match iter.next() {
Some(func) => match func {
Form::Function(_, _) | Form::CodeBlock(_) | Form::Literal(Literal::Symbol(_)) | Form::Call(_, _) => Ok(Form::Call(Box::new(func), iter.collect())),
e => Err(ErrorStack::Top{ src, msg: format!("Passing {e:?} as a callable, but it isn't") })
},
None => Err(ErrorStack::Top { src, msg: "Empty call not allowed".into() }),
}
}
}
},
Rule::code_block => {
let res = pair.into_inner()
.map(|pair| pair_walk(pair));
Rule::code_block | Rule::program => {
let res: Result<Vec<Form>, ErrorStack> = pair.into_inner()
.map(|pair| pair_walk(pair))
.collect();

if let Some(err) = res.clone().into_iter().find(|r| r.is_err()) {
err
} else {
Ok(Form::CodeBlock(res.map(|e| e.unwrap()).collect()))
}
res.map(|ok| Form::CodeBlock(ok)).map_err(|err| ErrorStack::Stream { src: src, from: Box::new(err), note: Some("During parsing of a `Form` of a `Block`".into()) })
},
}
}

#[cfg(tests)]
mod tests {
use std::fs;

use super::parse;

#[test]
fn crude_parse() {
let _ = dbg!(parse(format!("{{{}}}", fs::read_to_string("./tests/hello_world.vaca").unwrap())));
Rule::lib => Err(ErrorStack::Top { src, msg: "Libraries aren't implemented yet".into() }),
Rule::dontcare => Err(ErrorStack::Top { src, msg: "Don't Cares aren't implemented yet".into() }),
Rule::vacaimport => todo!(),
}
}
22 changes: 17 additions & 5 deletions vaca-build/src/parser/grammar.pest
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
program = { vacaimport* ~ form* }

lib = {
export_list ~
assingment_list*
}

form = {
assingment_list
| export_list
| array_list
| function
| macrodef
| array_list
| code_block
| call
| literal
| dontcare
}

literal = {
Expand All @@ -20,14 +29,15 @@ literal = {
}

keyword = { bool | nil }
operators = { "$" | "<(" | "#(" | "@(" | "{" | "[" | "]" | "}" | ")" | "_" | "->" }
operators = { ":" | "<)" | "(>" | "<(" | "[(" | "#(" | "@(" | "{" | "[" | "]" | "}" | ")" | "_" | "->" }

symbol = @{
!keyword ~ ('a'..'z' | 'A'..'Z' ) ~ ('a'..'z' | 'A'..'Z' | '0'..'9' | "-")*
!keyword ~ ('a'..'z' | 'A'..'Z' ) ~ ('a'..'z' | 'A'..'Z' | '0'..'9' | "-" | "/")*
| !operators ~ ("!" | "@" | "#" | "$" | "%" | "&" | "*" | "(" | ")" | "-" | "+" | "=" | "'" | "`" | "[" | "]" | "{" | "}" | "~" | "^" | ":" | ">" | "<" | "." | "," | "|" | "\\" | "/" | "?")+
}

atom = @{ "$" ~ ('a'..'z' | 'A'..'Z' ) ~ ('a'..'z' | 'A'..'Z' | '0'..'9' | "-")* }
dontcare = { "_" }
atom = @{ ":" ~ ('a'..'z' | 'A'..'Z' ) ~ ('a'..'z' | 'A'..'Z' | '0'..'9' | "-")* }
float = @{ "-"? ~ ('0'..'9')* ~ "." ~ ('0'..'9')+ | ('0'..'9')+ ~ "." ~ ('0'..'9')* }
integer = @{ "-"? ~ ('0'..'9')+ }

Expand All @@ -52,7 +62,9 @@ assingment = { symbol ~ form }

array_list = { "[" ~ form* ~ "]" }

function = { "<(" ~ (symbol ~ (!"->" ~ symbol)* ~ "->")? ~ form+ ~ ")" }
function = { "<(" ~ (symbol ~ (!"->" ~ symbol)* ~ "->")? ~ form ~ ")" }
macrodef = { "[(" ~ (symbol ~ (!"->" ~ symbol)* ~ "->")? ~ form ~ ")" }
vacaimport = { "<)" ~ symbol ~ symbol ~ ("->" ~ symbol+)?~ "(>" }
call = { "(" ~ form+ ~ ")" }
code_block = { "{" ~ form* ~ "}" }

Expand Down
11 changes: 11 additions & 0 deletions vaca-build/src/program.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use vaca_core::Symbol;

pub struct Program {
imports: Vec<Import>
}

pub struct Import {
namespace: String,
path: String,
symbols: Vec<Symbol>
}
2 changes: 1 addition & 1 deletion vaca-core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "vaca-core"
version = "0.4.2"
version = "0.5.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
1 change: 0 additions & 1 deletion vaca-core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ pub enum ErrorStack {
// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// write!(f, "Error: {}", self.0)
// }
//}

impl From<String> for ErrorStack {
fn from(value: String) -> Self {
Expand Down
Loading

0 comments on commit 5608892

Please sign in to comment.