feat: start parser

This commit is contained in:
rvcas 2022-05-03 22:38:15 -04:00
parent ef13a08800
commit 501396450f
No known key found for this signature in database
GPG Key ID: C09B64E263F7D68C
6 changed files with 109 additions and 3 deletions

30
Cargo.lock generated
View File

@ -2,6 +2,12 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "anyhow"
version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
[[package]]
name = "atty"
version = "0.2.14"
@ -25,6 +31,12 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bytes"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
[[package]]
name = "clap"
version = "3.1.14"
@ -64,6 +76,16 @@ dependencies = [
"os_str_bytes",
]
[[package]]
name = "combine"
version = "4.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a604e93b79d1808327a6fca85a6f2d69de66461e7620f5a4cbf5fb4d1d7c948"
dependencies = [
"bytes",
"memchr",
]
[[package]]
name = "hashbrown"
version = "0.11.2"
@ -107,11 +129,19 @@ version = "0.2.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b"
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "neptune"
version = "0.1.0"
dependencies = [
"anyhow",
"clap",
"combine",
]
[[package]]

View File

@ -6,4 +6,6 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0.57"
clap = { version = "3.1.14", features = ["derive"] }
combine = "4.6.4"

View File

@ -1,8 +1,10 @@
#[derive(Debug)]
pub struct Program<'a> {
pub version: String,
pub term: &'a Term<'a>,
pub term: Term<'a>,
}
#[derive(Debug)]
pub enum Term<'a> {
// tag: 0
Var(String),
@ -28,6 +30,7 @@ pub enum Term<'a> {
// Builtin
}
#[derive(Debug)]
pub enum Constant {
// TODO: figure out the right size for this
// tag: 0

View File

@ -1,2 +1,3 @@
pub mod ast;
pub mod cli;
pub mod parser;

View File

@ -1,7 +1,14 @@
use neptune::cli::Cli;
use neptune::parser;
fn main() {
fn main() -> anyhow::Result<()> {
let args = Cli::default();
println!("loading {}", args.input.display());
let code = std::fs::read_to_string(&args.input)?;
let program = parser::program(&code)?;
println!("{:#?}", program);
Ok(())
}

63
src/parser.rs Normal file
View File

@ -0,0 +1,63 @@
use combine::{
between,
parser::char::{digit, spaces, string},
sep_by, token, ParseError, Parser, Stream,
};
use crate::ast::{Program, Term};
pub fn program(src: &str) -> anyhow::Result<Program> {
let mut parser = program_();
let result = parser.parse(src);
match result {
Ok((program, _)) => Ok(program),
Err(err) => Err(anyhow::anyhow!("{}", err)),
}
}
pub fn program_<'a, Input>() -> impl Parser<Input, Output = Program<'a>>
where
Input: Stream<Token = char>,
Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
{
let prog = string("program")
.with(spaces())
.with((version(), spaces(), term()).map(|(version, _, term)| Program { version, term }));
between(token('('), token(')'), prog).skip(spaces())
}
pub fn version<Input>() -> impl Parser<Input, Output = String>
where
Input: Stream<Token = char>,
Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
{
sep_by(digit(), token('.'))
}
pub fn term<'a, Input>() -> impl Parser<Input, Output = Term<'a>>
where
Input: Stream<Token = char>,
Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
{
string("var").map(|x| Term::Var(x.to_string()))
}
#[cfg(test)]
mod test {
use combine::Parser;
const CODE: &str = include_str!("../example/plutus-core");
#[test]
fn parse_program() {
let result = super::program_().parse(CODE);
assert!(result.is_ok());
let program = result.unwrap().0;
assert_eq!(program.version, "1.0.0");
}
}